You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在字符串字面量中启用VSCode CompletionItemProvider?

解决VSCode CompletionItemProvider在XML属性值(双引号内)不触发补全的问题

问题描述

开发的VSCode扩展中,CompletionItemProvider在文件大部分区域正常提供补全,但在字符串字面量(比如XML属性的双引号内)时补全失效。早期版本的VSCode中该组件默认支持字符串内补全,后来官方修改了默认行为,现在需要手动配置来恢复XML属性值场景的补全功能。

示例XML文件:

<Input Name="Value1" Type="DIRECT">
            <Source>123456</Source>
        </Input>

补全功能在文件任意位置都能触发,唯独Name和Type的属性值(双引号包裹区域)无法生效,需要在此场景启用补全。

原补全提供者代码:

import * as vscode from 'vscode';

export function registerDefaultCompletion(context: vscode.ExtensionContext) 
{
    context.subscriptions.push(
        vscode.languages.registerCompletionItemProvider(
            { pattern: '**/*' },
            new DefaultCompletionItemProvider()
        )
    );
}

class DefaultCompletionItemProvider implements vscode.CompletionItemProvider {
    provideCompletionItems(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken, context: vscode.CompletionContext): vscode.ProviderResult<vscode.CompletionItem[]> {
        const completions: vscode.CompletionItem[] = [];

        // values
        completions.push(new vscode.CompletionItem('MULTIPLY_ALL', vscode.CompletionItemKind.Value));
        completions.push(new vscode.CompletionItem('SUM_ALL', vscode.CompletionItemKind.Value));
        completions.push(new vscode.CompletionItem('DIRECT', vscode.CompletionItemKind.Value));
        completions.push(new vscode.CompletionItem('LOGIC_OR', vscode.CompletionItemKind.Value));
        completions.push(new vscode.CompletionItem('LOGIC_AND', vscode.CompletionItemKind.Value));
        completions.push(new vscode.CompletionItem('LOGIC_NOT', vscode.CompletionItemKind.Value));

        return completions;
    }
}

解决方案

问题核心是VSCode默认会过滤字符串字面量内的补全请求,需要通过指定触发字符和取消字符串内的补全过滤来解决:

1. 添加触发字符

注册CompletionItemProvider时,显式添加触发字符(包括双引号和大小写字母),确保在字符串内输入时能触发补全请求。

2. 保留字符串内的补全逻辑

在provideCompletionItems中不需要过滤字符串内的场景,直接返回补全项即可;如果需要精准控制,可通过文本分析判断当前位置是否处于双引号内。

修改后的完整代码:

import * as vscode from 'vscode';

export function registerDefaultCompletion(context: vscode.ExtensionContext) 
{
    context.subscriptions.push(
        vscode.languages.registerCompletionItemProvider(
            { pattern: '**/*' },
            new DefaultCompletionItemProvider(),
            // 添加触发字符,覆盖字符串内输入场景
            '"', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
            'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'
        )
    );
}

class DefaultCompletionItemProvider implements vscode.CompletionItemProvider {
    provideCompletionItems(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken, context: vscode.CompletionContext): vscode.ProviderResult<vscode.CompletionItem[]> {
        // 可选:判断当前位置是否在双引号内(按需启用)
        const lineText = document.getText(new vscode.Range(position.line, 0, position.line, position.character));
        const quoteCount = (lineText.match(/"/g) || []).length;
        const isInQuotes = quoteCount % 2 !== 0;

        const completions: vscode.CompletionItem[] = [];

        // 补全项列表
        completions.push(new vscode.CompletionItem('MULTIPLY_ALL', vscode.CompletionItemKind.Value));
        completions.push(new vscode.CompletionItem('SUM_ALL', vscode.CompletionItemKind.Value));
        completions.push(new vscode.CompletionItem('DIRECT', vscode.CompletionItemKind.Value));
        completions.push(new vscode.CompletionItem('LOGIC_OR', vscode.CompletionItemKind.Value));
        completions.push(new vscode.CompletionItem('LOGIC_AND', vscode.CompletionItemKind.Value));
        completions.push(new vscode.CompletionItem('LOGIC_NOT', vscode.CompletionItemKind.Value));

        // 如果需要仅在字符串内返回补全,可替换为 return isInQuotes ? completions : [];
        return completions;
    }
}

额外优化(可选)

如果只需要在XML文件的属性值内触发补全,可以在注册时指定语言ID为xml,并结合VSCode的语法API做更精准的上下文判断:

// 注册时指定XML语言
vscode.languages.registerCompletionItemProvider(
    { language: 'xml', pattern: '**/*.xml' },
    new DefaultCompletionItemProvider(),
    // 触发字符...
)

内容的提问来源于stack exchange,提问作者Gistiv

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 07:55:56