Based on the answer by Gamma11 about what is a word in JSON, the whole string is considered a word including the "
chars.
It works if you adjust the range the completion item should replace, and not look for the current word at the position.
context.subscriptions.push(vscode.languages.registerCompletionItemProvider (
{ language: 'json', scheme: 'file' },
// 'json',
{
// eslint-disable-next-line no-unused-vars
provideCompletionItems(document, position, token, context) {
// get all text until the `position` and check if it reads `"launches.`
const linePrefix = document.lineAt(position).text.substring(0, position.character);
if (!linePrefix.endsWith('"launches.')) {
return undefined;
}
let myitem = (text) => {
let item = new vscode.CompletionItem(text, vscode.CompletionItemKind.Text);
item.range = new vscode.Range(position, position);
return item;
}
return [
myitem('log'),
myitem('warn'),
myitem('error'),
];
}
},
'.' // trigger
));
Edit:
What also works but does not look nice is
return [
new vscode.CompletionItem('"launches.log"', vscode.CompletionItemKind.Text),
new vscode.CompletionItem('"launches.warn"', vscode.CompletionItemKind.Text),
new vscode.CompletionItem('"launches.error"', vscode.CompletionItemKind.Text),
];
Edit:
Just to supply a completion on any .
typed I just removed the test (endsWith
) of what was in front of the .
.
To see if the completion provider is called I place a LogPoint breakpoint on the return with the CompletionItem
s.
The documentation of the CompletionItem
is very terse.
From the doc of CompletionItem
:
It is sufficient to create a completion item from just a label. In that case the completion item will replace the word until the cursor with the given label or insertText. Otherwise the given edit is used.
Although they talk about an edit
in the main text, the textEdit
doc tells you it is deprecated and you need to use insertText
and range
. But the additionalTextEdits
are not deprecated (??)
The range
property is not very clear how an inserting
and replacing
range are used and what effect you can achieve by setting it a certain way.
When omitted, the range of the current word is used as replace-range and as insert-range the start of the current word to the current position is used.
And then part of the problem is that "
is part of a word for JSON files. And as Gamma11 has pointed out if you, for some odd reason, add these "
‘s to the label it works in some cases. Setting the insertText
with the same content does not work, probably because the default range
is chosen incorrectly.
If you set the range
yourself you bypass the strange default behavior.
Because we want to insert new stuff at the position of the cursor just set range
to an empty range at the cursor position.
context.subscriptions.push(vscode.languages.registerCompletionItemProvider (
// { language: 'json', scheme: 'file' },
'json',
{
// eslint-disable-next-line no-unused-vars
provideCompletionItems(document, position, token, context) {
let myitem = (text) => {
let item = new vscode.CompletionItem(text, vscode.CompletionItemKind.Text);
item.range = new vscode.Range(position, position);
return item;
}
return [
myitem('howdy1'),
myitem('howdy2'),
myitem('howdy3'),
];
}
},
'.' // trigger
));
CLICK HERE to find out more related problems solutions.