王牌编辑|自动代码块完成

时间:2017-04-16 09:38:16

标签: javascript autocomplete editor ace-editor

使用ace编辑器我想提供自动完成功能,因为除了代码片段完成之外,用户还会输入。举个例子,我有以下代码片段

\begin{${1:something}}

\end{${1:something}}

现在这可用作通用代码段。现在用户输入

\begin{equation}

并点击ENTER我想插入一个匹配的结束块,如第一个片段中所示。有没有比添加keyboardHandler和检查前面的文本更好的方法?可能是一种显示自定义“片段”的方法,其中包含$ {1}的值作为自动完成功能?

1 个答案:

答案 0 :(得分:1)

我现在通过在光标前面有命令时触发自动完成来解决问题。这解决了这两个问题,因为ENTER键插入了当前选定的片段。我使用以下代码触发了自动完成:

editor.commands.on("afterExec", function(e) {
        if (e.command.name === "insertstring") {
            if (getCommand(editor)) {
                editor.execCommand("startAutocomplete");
            }
        }
});

getCommand基本上确定光标后面是否有命令。既然在有命令时触发了自动完成,则需要自定义完成符来从输入的包含\ end标记的命令动态构建片段。

identifierRegexps: [/[\\a-zA-Z0-9{}\[\]]/],
getCompletions: function(editor, session, pos, prefix, callback) {
    const command = getCommand(editor);
    if (!command) { callback(null, []); return }
    const completions = [];

    let caption = command.cmd;
    if (command.mods.length > 0) caption += `[${command.mods}]`;
    if (command.args.length > 0) caption += `{${command.args}}`;

    let snippet = command.cmd;
    if (command.mods.length > 0) snippet += `[${command.mods}]`;
    if (command.args.length > 0) snippet += `{${command.args}}`;

    if (command.cmd === '\\begin') {
        snippet += '\n\t${1}';
        snippet += `\n\\end{${command.args}}`
    }

    completions.push({
        caption: caption,
        snippet: snippet,
        meta: command.cmd === '\\begin' ? 'env' : 'cmd',
    });

    callback(null, completions);
}

请注意identifierRegexps,它是阻止编辑器保留旧命令所必需的,用户在触发自动完成之前输入了旧命令。它基本上匹配所有字母数字字符以及括号和反斜杠。然后,我通过执行以下操作将此代码添加到编辑器中:

langTools.addCompleter(customCompleter);

其中customCompleter是上面显示的对象。