【问题标题】:ACE editor auto-completion duplicating prefixACE 编辑器自动完成复制前缀
【发布时间】:2022-12-03 02:16:39
【问题描述】:

我正在尝试为我的编辑器添加美人鱼图的自动完成功能:

    const mermaids = Object.entries({
        "mermaid graph": `graph LR\n    x --> y`,
    }).map(([name, autocompletion]) => ({
        caption: name,
        meta: name,
        value: "``mermaid\n" + autocompletion + "\n```"
    }));

    aceeditor.setOptions({
        enableBasicAutocompletion: [{
            getCompletions: (editor, session, pos, prefix, callback) => {
                callback(null, [
                    ...mermaids
                ])
            }
        }],
        enableSnippets: false,
        enableLiveAutocompletion: true
    });

在生成的编辑器中,如果用户键入“graph”或“mermaid”并按回车键自动完成,它会按预期工作。 (完成后光标位置不理想除外。)如果用户键入“```”并按回车键,则会发生自动完成最初键入的“```”。例如。,

``````mermaid
graph LR
    x --> y
\```                  <-- just escaped here for SO's sake

有没有有效的方法来纠正这个问题?如果没有,我可以使用什么事件来确定自动完成实际发生的时间并搜索重复标记?

通常有更好的方法来做到这一点吗?

【问题讨论】:

    标签: ace-editor


    【解决方案1】:

    我认为这里更广泛的问题是您的完成项目更类似于 sn-p。使用 sn-ps 还可以让您更好地控制插入后光标的位置。

    回答你的第二个问题,Autocomplete.insertMatch 是负责插入所选完成项的函数。您可以挂钩它,或者在完成项上使用神秘的未记录的 .completer 字段? 9 years now 一直在那里,也许这不是偶然的。

    const FakeCompleter = {
        insertMatch: (editor, data) => {
            // stolen from default insertMatch, needed to erase text that triggered our completion:
            if (editor.completer.completions.filterText) {
                var ranges = editor.selection.getAllRanges()
                for (var i = 0, range; range = ranges[i]; i++) {
                    range.start.column -= editor.completer.completions.filterText.length
                    editor.session.remove(range)
                }
            }
            
            // if there are ` symbols immediately before cursor, omit those from completion:
            let text = (data.value || data)
            const lead = editor.selection.lead
            const prefix = editor.session.getLine(lead.row).substring(0, lead.column)
            const mt = /.*?(`{1,3})$/.exec(prefix)
            if (mt && text.startsWith(mt[1])) text = text.substring(mt[1].length)
            
            // and finally call the regular insertion:
            editor.execCommand("insertstring", text)
        }
    }
    const mermaids = Object.entries({
        "mermaid graph": `graph LR
        x --> y`,
    }).map(([name, autocompletion]) => ({
        caption: name,
        meta: name,
        value: "``mermaid
    " + autocompletion + "
    ```",
        completer: FakeCompleter
    }));
    
    

    【讨论】:

      最近更新 更多