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

如何在VS Code扩展的悬停提供程序中显示本地图片?

问题描述

开发VS Code扩展时,需要在自定义语言awscript的.aws文件中,实现悬停相对路径形式的图片路径(如../images/landscape.png)时,展示工作区内的对应本地图片。当前使用vscode-resource Scheme构建URI,验证路径正确但图片显示破碎图标,不清楚非WebView场景下的正确URI方案。

当前实现的TypeScript代码:

import * as vscode from 'vscode';
import * as path from 'path';

export function activateHoverProvider(context: vscode.ExtensionContext) {
    const hoverProvider = vscode.languages.registerHoverProvider({ scheme: 'file', language: 'awscript' }, {
        provideHover(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken) {
            const wordRange = document.getWordRangeAtPosition(position);
            if (!wordRange) {
                return;
            }
    
            const hoveredText = document.getText(wordRange);
            if (isValidImagePath(hoveredText)) {
                const documentPath = path.dirname(document.uri.fsPath);
                const imagePath = path.resolve(documentPath, hoveredText);
                const uri = vscode.Uri.file(imagePath).with({ scheme: 'vscode-resource' });
                const markdown = new vscode.MarkdownString(`![Image Preview](${uri})`);
                markdown.isTrusted = true;

                return new vscode.Hover(markdown);
            }
        }
    });    

    context.subscriptions.push(hoverProvider);
}

function isValidImagePath(filePath: string): boolean {
    return filePath.endsWith('.png') || filePath.endsWith('.jpg') || filePath.endsWith('.gif');
}
解决方案

问题出在两个关键点:vscode-resource Scheme已被VS Code弃用,且默认的getWordRangeAtPosition无法正确捕获包含../、目录分隔符的完整图片路径。

1. 替换URI Scheme

VS Code 1.56+版本已废弃vscode-resource,在悬停等非WebView场景下,直接使用file Scheme的URI即可,同时确保MarkdownString的isTrusted属性设为true(允许加载本地资源)。

2. 正确捕获完整图片路径

默认的getWordRangeAtPosition会按VS Code的单词分隔规则截取文本,无法识别包含../、/的相对路径。需要用自定义正则表达式匹配完整的图片路径格式。

修改后的完整代码

import * as vscode from 'vscode';
import * as path from 'path';
import * as fs from 'fs';

export function activateHoverProvider(context: vscode.ExtensionContext) {
    const hoverProvider = vscode.languages.registerHoverProvider({ scheme: 'file', language: 'awscript' }, {
        provideHover(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken) {
            // 用正则匹配包含相对路径的完整图片路径
            const pathRegex = /(\.\.\/|\/)?[\w\-\/]+\.(png|jpg|gif)/;
            const range = document.getWordRangeAtPosition(position, pathRegex);
            
            if (!range) {
                return;
            }
    
            const hoveredText = document.getText(range);
            if (isValidImagePath(hoveredText)) {
                const documentDir = path.dirname(document.uri.fsPath);
                const imageAbsolutePath = path.resolve(documentDir, hoveredText);
                
                // 验证图片文件是否存在
                if (!fs.existsSync(imageAbsolutePath)) {
                    return new vscode.Hover('图片文件不存在');
                }
                
                // 构建file Scheme的URI
                const imageUri = vscode.Uri.file(imageAbsolutePath);
                const markdown = new vscode.MarkdownString(`![图片预览](${imageUri.toString()})`);
                // 必须设为true,允许加载本地资源
                markdown.isTrusted = true;

                return new vscode.Hover(markdown);
            }
        }
    });    

    context.subscriptions.push(hoverProvider);
}

function isValidImagePath(filePath: string): boolean {
    return /\.(png|jpg|gif)$/i.test(filePath);
}

额外说明

  • 正则表达式/(\.\.\/|\/)?[\w\-\/]+\.(png|jpg|gif)/可匹配以下格式的路径:../images/landscape.png、./icon.jpg、assets/header.gif、logo.png。
  • 添加fs.existsSync检查可避免因路径错误显示破碎图标,同时给用户明确提示。
  • 若工作区包含远程文件(如WSL、SSH),需改用vscode.workspace.fs.stat异步检查文件存在性,避免同步IO阻塞。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 02:07:41