I am trying to make a simple autocomplete for the LSP using:
import * as vscode from 'vscode';
export function activate(context: vscode.ExtensionContext) {
const provider = vscode.languages.registerCompletionItemProvider('exa', {
provideCompletionItems(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken, context: vscode.CompletionContext) {
const completions = [];
const linePrefix = document.lineAt(position).text.slice(0, position.character);
if (linePrefix.includes('@')) {
completions.push(new vscode.CompletionItem("@END"));
return completions;
}
}
});
context.subscriptions.push(provider);
}
But when I type @
, no autocomplete is triggered:
It isn't until I start typing alphanumeric characters that it is triggered. Notice that it seems to actively ignore the @
sign as part of the autocomplete trigger:
This is confirmed if the alphanumeric trigger is then selected and an extra @
sign is added as if the first hadn't even been typed:
How could I correct this code to accept @
as part of the autocomplete trigger and completion?
I am not sure why your code doesn't work. It may be related to @
not being a word character in the exa
language and thus needing to be specifically listed as a trigger character.
Making 2 CompletionProviders
does work. Try this code:
// const provider = vscode.languages.registerCompletionItemProvider('exa', {
const provider = vscode.languages.registerCompletionItemProvider('plaintext', {
provideCompletionItems(document, position, token, context) {
const completions = [];
const linePrefix = document.lineAt(position).text.slice(0, position.character);
let item;
if (linePrefix.startsWith('@')) item = new vscode.CompletionItem("@END");
if (linePrefix.startsWith('!')) item = new vscode.CompletionItem("!START");
if (item) {
item.range = new vscode.Range(position.translate(0, -1), position);
completions.push(item);
return completions;
}
}
},
'@', '!' // list any special characters here
);
context.subscriptions.push(provider);
const provider2 = vscode.languages.registerCompletionItemProvider('plaintext', {
provideCompletionItems(document, position, token, context) {
const completions = [];
const linePrefix = document.lineAt(position).text.slice(0, position.character);
if (linePrefix.includes('H')) {
completions.push(new vscode.CompletionItem("HOWDY"));
return completions;
}
}
});
context.subscriptions.push(provider2);
Note: I used 'plaintext'
for my testing so change that. provider1
gets called for its list of trigger characters. provider2
gets called for regular word characters.
Possibly related to @
not being a word character is the double @@END
you were seeing. I fixed that with
const item = new vscode.CompletionItem("@END");
item.range = new vscode.Range(position.translate(0, -1), position);
so that the range would include that first @
character.