如何在VS Code扩展的悬浮提示中添加重载滚动箭头?
实现VS Code悬停提示中的重载列表滚动箭头
VS Code原生Hover API仅支持静态Markdown内容,要实现类似主流语言扩展的重载切换箭头,需要通过自定义HTML交互内容结合信任配置来实现,以下是具体步骤:
1. 配置扩展权限
在扩展的package.json中添加配置项,允许悬停内容执行脚本:
"contributes": { "configuration": { "properties": { "your-extension-id.allowUnsafeHover": { "type": "boolean", "default": false, "description": "允许悬停提示中的自定义HTML与脚本,用于重载切换功能" } } } }
2. 构建交互式Hover内容
在Hover Provider中,生成包含切换按钮的HTML内容,并启用VS Code的HTML支持与信任标记:
import * as vscode from 'vscode'; export function activate(context: vscode.ExtensionContext) { const hoverProvider = vscode.languages.registerHoverProvider('target-language', { async provideHover(doc: vscode.TextDocument, pos: vscode.Position): Promise<vscode.Hover | undefined> { // 替换为你的重载获取逻辑 const overloads = await fetchMethodOverloads(doc, pos); if (!overloads || overloads.length <= 1) { return new vscode.Hover(new vscode.MarkdownString(overloads?.[0].markdown || '')); } // 构建带切换箭头的HTML结构 const initialIndex = 0; const html = ` <div style="display: flex; align-items: center; gap: 8px;"> <button class="overload-btn" onclick="switchOverload(${initialIndex - 1})" style="padding: 4px 8px; border: none; border-radius: 4px; background: var(--vscode-button-background); color: var(--vscode-button-foreground); cursor: pointer;">←</button> <div id="overload-content" style="flex: 1;">${overloads[initialIndex].html}</div> <button class="overload-btn" onclick="switchOverload(${initialIndex + 1})" style="padding: 4px 8px; border: none; border-radius: 4px; background: var(--vscode-button-background); color: var(--vscode-button-foreground); cursor: pointer;">→</button> <span style="font-size: 12px; color: var(--vscode-descriptionForeground);">${initialIndex + 1}/${overloads.length}</span> </div> <script> let currentIdx = ${initialIndex}; const overloadList = ${JSON.stringify(overloads.map(o => o.html))}; const total = overloadList.length; function switchOverload(newIdx) { if (newIdx < 0 || newIdx >= total) return; currentIdx = newIdx; document.getElementById('overload-content').innerHTML = overloadList[currentIdx]; // 更新按钮状态 document.querySelectorAll('.overload-btn')[0].disabled = currentIdx === 0; document.querySelectorAll('.overload-btn')[1].disabled = currentIdx === total - 1; document.querySelector('span').textContent = \`\${currentIdx + 1}/\${total}\`; } // 初始化按钮禁用状态 document.querySelectorAll('.overload-btn')[0].disabled = currentIdx === 0; document.querySelectorAll('.overload-btn')[1].disabled = currentIdx === total - 1; </script> `; const md = new vscode.MarkdownString(html); md.supportHtml = true; md.isTrusted = true; // 必须开启才能执行脚本 return new vscode.Hover(md); } }); context.subscriptions.push(hoverProvider); } // 模拟获取方法重载的函数,需替换为实际解析逻辑 async function fetchMethodOverloads(doc: vscode.TextDocument, pos: vscode.Position) { return [ { markdown: `\`func calculate(a: int) -> int\``, html: `<code>func calculate(a: int) -> int</code>` }, { markdown: `\`func calculate(a: float, b: float) -> float\``, html: `<code>func calculate(a: float, b: float) -> float</code>` }, { markdown: `\`func calculate(values: [int]) -> int\``, html: `<code>func calculate(values: [int]) -> int</code>` } ]; }
3. 安全提示与适配
- 由于启用了
isTrusted,需在扩展文档中明确告知用户安全风险,建议仅在信任工作区开启对应配置。 - 样式使用VS Code的主题CSS变量(如
var(--vscode-button-background)),确保在不同主题下显示正常。
替代方案:复用快速选择框
若不想使用自定义HTML,可通过showQuickPick让用户选择重载,体验稍逊但无需处理脚本权限:
async function provideHover(doc: vscode.TextDocument, pos: vscode.Position) { const overloads = await fetchMethodOverloads(doc, pos); if (!overloads || overloads.length <= 1) { return new vscode.Hover(new vscode.MarkdownString(overloads?.[0].markdown || '')); } const selected = await vscode.window.showQuickPick( overloads.map((o, i) => ({ label: `${i+1}. ${o.markdown}`, detail: o.markdown })), { placeHolder: "选择方法重载" } ); return selected ? new vscode.Hover(new vscode.MarkdownString(selected.detail)) : undefined; }
内容的提问来源于stack exchange,提问作者FogyX
相关产品推荐
相关产品推荐

