获取 vscode registerCompletionItemProvider 以在带有 `word.` 触发器的 json 文件中工作 [英] Get vscode registerCompletionItemProvider to work in a json file with a `word.` trigger
问题描述
我正在使用此代码尝试在我的扩展程序中注册 CompletionProvider.它本质上是来自示例 completionProvider 示例的代码 https://github.com/microsoft/vscode-extension-samples/blob/master/completions-sample/src/extension.ts.
I am using this code to try to register a CompletionProvider in my extension. It is essentially the code from the sample completionProvider sample https://github.com/microsoft/vscode-extension-samples/blob/master/completions-sample/src/extension.ts.
我希望它由 .如在发射"中.在我最终在 keybindings.json 中的扩展命令中,但它在任何 json 文件中什么都不做.没有任何反应,没有错误.
I want it triggered by a . as in "launches." in my extension command in keybindings.json ultimately but it is doing nothing in any json file. Nothing happens, no error.
function activate(context) {
loadLaunchSettings(context);
activeContext = context;
const configCompletionProvider = vscode.languages.registerCompletionItemProvider (
{ language: 'json', scheme: 'file' }, // tried scheme: 'untitled' too
{
// 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.substr(0, position.character);
if (!linePrefix.endsWith('\"launches.\"')) { // tried without the escapes too
return undefined;
}
return [
new vscode.CompletionItem('log', vscode.CompletionItemKind.Text),
new vscode.CompletionItem('warn', vscode.CompletionItemKind.Text),
new vscode.CompletionItem('error', vscode.CompletionItemKind.Text),
];
}
},
'.' // trigger
);
context.subscriptions.push(configCompletionProvider);
}
在这段代码中:
{
"key": "alt+f",
"command": "launches." <= provider completion options here
},
我找不到任何有用的东西,并认为我密切关注示例,但没有关于键入 "launches."
或使用 Ctrl+空格触发智能感知.
I couldn't find anything helpful and thought I followed the sample closely but no completion suggestions either on typing "launches."
or using Ctrl+Space to trigger intellisense.
我确实有这个设置:
"editor.quickSuggestions": {
"comments": true,
"other": true,
"strings": true // <===
},
我尝试了这里提出的各种替代方案来解决类似的问题:JSON 完成的自定义扩展在双引号中不起作用
And I tried various alternatives presented here to a similar problem: Custom Extension for JSON Completion Does Not Work in Double Quotes
仍然感到困惑 - 可以在 javascript 文件中使用,但不能在 json 文件中使用.有什么特别的我必须做才能在 json 文件中将 .
识别为触发字符(除了在 vscode.languages.registerCompletionItemProvider
中列出它,如下所示)?
Still baffled - works in a javascript file but not a json file. Is there something special I have to do to get a .
recognised as a trigger character in a json file (other than listing it in the vscode.languages.registerCompletionItemProvider
as below)?
我已将其精简为:
function activate(context) {
loadLaunchSettings(context);
activeContext = context;
let docFilter = { scheme: 'file', language: 'json' };
const configCompletionProvider = vscode.languages.registerCompletionItemProvider (
// { language: 'json', pattern: './**/test.json' }, // does not work
// 'javascript', // works
// 'json', // does not work
docFilter, // does not work
{
// eslint-disable-next-line no-unused-vars
provideCompletionItems(document, position, token, context) {
return [
new vscode.CompletionItem('howdy1', vscode.CompletionItemKind.Text),
new vscode.CompletionItem('howdy2', vscode.CompletionItemKind.Text),
new vscode.CompletionItem('howdy3', vscode.CompletionItemKind.Text),
];
}
},
"." // trigger
);
context.subscriptions.push(configCompletionProvider);
};
推荐答案
基于 Gamma11 关于什么是JSON 中的一个单词,整个字符串被认为是一个包含 "
字符的单词.
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.substr(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
));
编辑:
同样有效但不好看的是
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),
];
编辑:
只是为了在任何输入的 .
上提供补全,我只是删除了 .
前面的测试 (endsWith
).
Just to supply a completion on any .
typed I just removed the test (endsWith
) of what was in front of the .
.
要查看是否调用了完成提供程序,我将使用 CompletionItem
s 在返回上放置一个 LogPoint 断点.
To see if the completion provider is called I place a LogPoint breakpoint on the return with the CompletionItem
s.
CompletionItem
的文档非常简洁.
来自CompletionItem
的文档:
仅从标签创建完成项就足够了.在这种情况下,完成项将替换单词,直到光标带有给定的标签或 insertText.否则使用给定的编辑.
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.
尽管他们在正文中讨论了 edit
,textEdit
文档告诉您它已被弃用,您需要使用 insertText
和<代码>范围代码>.但是 additionalTextEdits
没有被弃用 (??)
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 (??)
range
属性不太很清楚 inserting
和 replaceing
范围是如何使用的,以及对你有什么影响可以通过某种方式设置来实现.
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.
然后部分问题是 "
是 JSON 文件单词的一部分.正如 Gamme11 所指出的,如果您出于某种奇怪的原因将这些 "
添加到它在某些情况下有效的标签中.将 insertText
设置为相同的内容不起作用,可能是因为默认的 range
选择不正确.
And then part of the problem is that "
is part of a word for JSON files. And as Gamme11 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.
如果你自己设置range
,你就绕过了奇怪的默认行为.
If you set the range
yourself you bypass the strange default behavior.
因为我们想在光标位置插入新的东西,只需将 range
设置为光标位置的空范围即可.
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
));
这篇关于获取 vscode registerCompletionItemProvider 以在带有 `word.` 触发器的 json 文件中工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!