获取 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.
中的代码
我希望它由 .如“发射”。最终在 keybindings.json 中的扩展命令中,但它在任何 json 文件中什么都不做。没有任何反应,没有错误。
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+ 的完成建议Space 触发智能感知。
我有这个设置:
"editor.quickSuggestions": {
"comments": true,
"other": true,
"strings": true // <===
},
并且我尝试了此处提供的各种替代方案来解决类似问题:
仍然感到困惑 - 在 javascript 文件中工作,但在 json 文件中不工作。我需要做一些特别的事情才能让 .
在 json 文件中被识别为触发字符(除了如下所示将其列在 vscode.languages.registerCompletionItemProvider
中)吗?
我已将其精简为:
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);
};
根据 关于什么是 JSON 中的单词的回答,整个字符串被认为是一个包含 "
个字符的单词。
如果您调整完成项应替换的范围,而不是在该位置查找当前单词,它就会起作用。
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
));
编辑:
同样有效但不好看的是
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
)
为了查看是否调用了完成提供程序,我在 return 和 CompletionItem
上放置了一个 LogPoint 断点。
CompletionItem
的文档非常简洁。
来自 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.
虽然他们在正文中讨论了 edit
,但 textEdit
文档告诉您它已被弃用,您需要使用 insertText
和 range
。但是 additionalTextEdits
并未弃用 (??)
range
属性 不是 很清楚 inserting
和 replacing
范围是如何使用的以及你的影响可以通过一定的方式设置来实现。
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 文件的单词的一部分。正如 Gamma11 指出的那样,如果您出于某种奇怪的原因将这些 "
添加到它在某些情况下起作用的标签中。设置相同内容的insertText
不起作用,可能是因为默认的range
选择不正确。
如果您自己设置 range
,您可以绕过奇怪的默认行为。
因为我们想在光标位置插入新内容,只需将 range
设置为光标位置的空范围即可。
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
));
我正在使用此代码尝试在我的扩展中注册 CompletionProvider。它本质上是示例 completionProvider 示例 https://github.com/microsoft/vscode-extension-samples/blob/master/completions-sample/src/extension.ts.
中的代码我希望它由 .如“发射”。最终在 keybindings.json 中的扩展命令中,但它在任何 json 文件中什么都不做。没有任何反应,没有错误。
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+ 的完成建议Space 触发智能感知。
我有这个设置:
"editor.quickSuggestions": {
"comments": true,
"other": true,
"strings": true // <===
},
并且我尝试了此处提供的各种替代方案来解决类似问题:
仍然感到困惑 - 在 javascript 文件中工作,但在 json 文件中不工作。我需要做一些特别的事情才能让 .
在 json 文件中被识别为触发字符(除了如下所示将其列在 vscode.languages.registerCompletionItemProvider
中)吗?
我已将其精简为:
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);
};
根据 "
个字符的单词。
如果您调整完成项应替换的范围,而不是在该位置查找当前单词,它就会起作用。
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
));
编辑:
同样有效但不好看的是
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
)
为了查看是否调用了完成提供程序,我在 return 和 CompletionItem
上放置了一个 LogPoint 断点。
CompletionItem
的文档非常简洁。
来自 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.
虽然他们在正文中讨论了 edit
,但 textEdit
文档告诉您它已被弃用,您需要使用 insertText
和 range
。但是 additionalTextEdits
并未弃用 (??)
range
属性 不是 很清楚 inserting
和 replacing
范围是如何使用的以及你的影响可以通过一定的方式设置来实现。
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 文件的单词的一部分。正如 Gamma11 指出的那样,如果您出于某种奇怪的原因将这些 "
添加到它在某些情况下起作用的标签中。设置相同内容的insertText
不起作用,可能是因为默认的range
选择不正确。
如果您自己设置 range
,您可以绕过奇怪的默认行为。
因为我们想在光标位置插入新内容,只需将 range
设置为光标位置的空范围即可。
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
));