Reputation: 111
Using the ace editor I'd like to provide automated completion as the user types in addition to the snippet completion. To give an example, I've got the following snippet
\begin{${1:something}}
\end{${1:something}}
Now this works as a general purpose snippet. Now as the user types
\begin{equation}
and hits ENTER I'd like to insert a matching end block as seen in the first snippet. Is there any better way than adding a keyboardHandler and checking the preceding text? Possibly a way to display the customized "snippet" which includes the value for ${1} as an autocompletion as well?
Upvotes: 1
Views: 893
Reputation: 111
I have now solved the problem by triggering the autocompletion when there is a command preceding the cursor. This fixes both problems since the the ENTER key inserts the currently selected snippet. I triggered autocompletion using the following code:
editor.commands.on("afterExec", function(e) {
if (e.command.name === "insertstring") {
if (getCommand(editor)) {
editor.execCommand("startAutocomplete");
}
}
});
getCommand basically determines whether or not there is a command behind the cursor. Now that the autocompletion gets triggered when there is a command a custom completer was necessary to dynamically build snippets from the entered command that includes the \end tag.
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);
}
Note the identifierRegexps, which is required to prevent the editor from keeping the old command, which the user entered before triggering the autocomplete. It basically matches all alphanumeric characters as well as brackets and backslashes. I then added this code to the editor by executing the following:
langTools.addCompleter(customCompleter);
Where customCompleter is the object shown above.
Upvotes: 1