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

执行vscode.executeInlayHintProvider命令时内嵌提示异常求助

VSCode 1.82.2自定义InlayHintsProvider的两个问题及解决方法

我在VSCode 1.82.2编辑器的上下文菜单中执行vscode.executeInlayHintProvider内置命令时,遇到以下两个问题:

  • 执行该命令时,已实现vscode.InlayHintsProvider接口的自定义HintsProvider虽被调用,但内嵌提示未在文档中显示;而在编辑器输入字符时提示可正常显示。
  • 自定义HintsProvider会在文档输入内容时被自动调用,我希望它仅在执行vscode.executeInlayHintProvider命令时触发。

自定义HintsProvider代码如下:

export class HintsProvider implements vscode.InlayHintsProvider {
    onDidChangeInlayHints?: vscode.Event<void>;
    static counter: number = 90;

    provideInlayHints(document: vscode.TextDocument, range: vscode.Range, token: vscode.CancellationToken): vscode.ProviderResult<vscode.InlayHint[]> {
        var provider = new HintsProvider();
        return new Promise<vscode.InlayHint[]> ((resolve,reject) =>{
            let ret: Array<vscode.InlayHint> = new Array();
            HintsProvider.counter++;
            let tempList: Array<vscode.InlayHintLabelPart> = new Array();
            let temp: vscode.InlayHintLabelPart = new vscode.InlayHintLabelPart(`labelHint${HintsProvider.counter}`);
            temp.tooltip = "hint tooltip";
            tempList.push(temp);
            let start = range && range.start ? range.start : new vscode.Position(1, 0);
            let retValue: vscode.InlayHint = new vscode.InlayHint(start, tempList, vscode.InlayHintKind.Parameter);
            let textRange = (range && range.start && range.end) ? range : new vscode.Range(new vscode.Position(1, 1), new vscode.Position(5, 10));
            let edit: vscode.TextEdit = new vscode.TextEdit(textRange, "hint text to be inserted");
            retValue.textEdits = new Array();
            retValue.textEdits.push(edit);
            ret.push(retValue);        
            resolve(ret);            
        });        
    }

    resolveInlayHint?(hint: vscode.InlayHint, token: vscode.CancellationToken): vscode.ProviderResult<vscode.InlayHint> {
        return new Promise<vscode.InlayHint>((resolve, reject) => {
            resolve(hint);
        })
    }

    private onGeneratEvent = async (event:GenerateNLtoSQLErrorEventParams):Promise<any> =>{
        var pos = new vscode.Position(10, 0);
        var endPos = new vscode.Position(12, 0);
        let range:vscode.Range = new vscode.Range(pos,endPos);
        vscode.window.showErrorMessage(event.message);
        return vscode.commands.executeCommand("vscode.executeInlayHintProvider",vscode.Uri.parse(event.ownerUri),range).then ( (temp1) =>{
            let ret = new Array();          
            let list = new Array();          
            let hintLabelPart = new vscode.InlayHintLabelPart(`hint1`);
            hintLabelPart.tooltip = "hint tooltip";
            list.push(hintLabelPart);
            let inlayHint = new vscode.InlayHint(new vscode.Position(1, 0), list, vscode.InlayHintKind.Parameter);
            let edit = new vscode.TextEdit(new vscode.Range(new vscode.Position(1, 1), new vscode.Position(5, 10)), "textTobeInserted");
            inlayHint.textEdits = new Array();
            inlayHint.textEdits.push(edit);
            return inlayHint;
        });
    }
}

问题1:执行命令后内嵌提示不显示

vscode.executeInlayHintProvider仅负责查询指定范围的内嵌提示数据,不会自动触发编辑器渲染。编辑器输入时自动显示提示,是因为VSCode内置机制会主动调用provider并处理渲染逻辑。要实现执行命令后显示提示,可按以下步骤修改:

  1. 在HintsProvider中添加事件触发器,用于通知VSCode更新提示:
private _onDidChangeInlayHints = new vscode.EventEmitter<void>();
readonly onDidChangeInlayHints = this._onDidChangeInlayHints.event;
  1. 注册自定义命令,通过触发事件让VSCode主动调用provider渲染提示,而非直接调用vscode.executeInlayHintProvider:
// 实例化provider
const hintsProvider = new HintsProvider();

// 注册自定义命令
vscode.commands.registerCommand('yourExtension.triggerInlayHints', async () => {
    const editor = vscode.window.activeTextEditor;
    if (!editor) return;
    // 触发提示更新事件,VSCode会自动调用provideInlayHints并渲染结果
    hintsProvider._onDidChangeInlayHints.fire();
});

问题2:限制Provider仅在命令触发时调用

默认情况下VSCode会在文档变更、光标移动等场景自动调用provideInlayHints,可通过开关控制实现仅命令触发:

  1. 在HintsProvider中添加开关变量:
private shouldProvide = false;
  1. 修改provideInlayHints方法,仅当开关开启时返回提示:
provideInlayHints(document: vscode.TextDocument, range: vscode.Range, token: vscode.CancellationToken): vscode.ProviderResult<vscode.InlayHint[]> {
    if (!this.shouldProvide) {
        return []; // 不返回任何提示
    }
    // 原有生成提示的逻辑保持不变...
}
  1. 在自定义命令中控制开关状态:
vscode.commands.registerCommand('yourExtension.triggerInlayHints', async () => {
    const editor = vscode.window.activeTextEditor;
    if (!editor) return;
    // 开启开关
    hintsProvider.shouldProvide = true;
    // 触发提示更新
    hintsProvider._onDidChangeInlayHints.fire();
    // 可选:一段时间后关闭开关并清除提示
    setTimeout(() => {
        hintsProvider.shouldProvide = false;
        hintsProvider._onDidChangeInlayHints.fire();
    }, 5000);
});
  1. 注册provider时限制触发字符,减少不必要的自动调用:
vscode.languages.registerInlayHintsProvider('yourLanguageId', hintsProvider, {
    triggerCharacters: []
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 22:24:51