VSCode插件中如何正确注册HTML语言的CompletionItemProvider?

令狐焕焕 阅读 5

我在写一个VSCode扩展,想给HTML文件添加自定义代码补全,但注册后完全没反应。是不是provider的triggerCharacters或者documentSelector写错了?

我试过用vscode.languages.registerCompletionItemProvider('html', provider, '<'),也试过把documentSelector设成{ language: 'html' },但输入<的时候还是没触发。

<div>
  <!-- 在这里输入 < 时希望触发我的补全 -->
</div>
我来解答 赞 3 收藏
二维码
手机扫码查看
1 条解答
程序猿瑞娜
这个问题我之前踩过坑,给你几个关键点。

第一个坑是triggerCharacters的问题。你只设置了<作为触发字符,但VSCode内置的HTML补全已经把<占用了,你的provider可能被覆盖或者优先级不够。

第二个坑是documentSelector的写法。字符串写法虽然能用,但建议用对象形式,更精确。

代码给你,直接用这个:

const vscode = require('vscode');

function activate(context) {
const provider = vscode.languages.registerCompletionItemProvider(
{ language: 'html', scheme: 'file' },
{
provideCompletionItems(document, position, token, context) {
// 获取当前行内容,判断触发条件
const linePrefix = document.lineAt(position).text.substring(0, position.character);

// 可以根据前缀做过滤
if (!linePrefix.endsWith('<')) {
return undefined;
}

const item1 = new vscode.CompletionItem('my-div', vscode.CompletionItemKind.Snippet);
item1.insertText = new vscode.SnippetString('div class="$1">$2
');
item1.documentation = '自定义div片段';
item1.detail = 'My Extension';
// 关键:设置sortText让你的补全排在前面
item1.sortText = '0';

const item2 = new vscode.CompletionItem('my-span', vscode.CompletionItemKind.Snippet);
item2.insertText = new vscode.SnippetString('span>$1');
item2.sortText = '0';

return [item1, item2];
}
},
'<', ' ' // 多加几个触发字符
);

context.subscriptions.push(provider);
}

module.exports = { activate };


还有几个要注意的地方。

确保你的package.json里activationEvents包含了html文件,不然扩展压根没激活:

"activationEvents": [
"onLanguage:html"
],
"main": "./extension.js"


调试的时候,在provideCompletionItems里打个断点或者console.log,看看方法有没有被调用。如果根本没进这个方法,说明provider没注册成功或者扩展没激活。

如果进了方法但补全没显示,检查返回的CompletionItem数组是不是空的,或者insertText有没有问题。

另外,VSCode内置的HTML补全确实很强势,你可以试试在空行输入<,或者把triggerCharacters去掉让它自动触发,不要只依赖<这一个字符。
点赞
2026-03-01 14:37