Files
core/editor/vscode/hover.cjs
T
2026-11-03 03:32:07 +00:00

61 lines
3.0 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
const vscode = require('vscode');
const { relations } = require('./graph.cjs');
const { uri } = require('./inspection.cjs');
function command(name, args) {
return `command:${name}?${encodeURIComponent(JSON.stringify(args))}`;
}
async function description(inspection, index, symbol, root) {
const value = index.documentation.find(item => item.symbol === symbol.name);
if (!value) return undefined;
const documentIndex = { files: [index.documentation_files[value.file]] };
await inspection.verify(documentIndex, 0, root);
return { ...value, uri: uri(documentIndex, 0, root) };
}
function registerHover(context, selector, inspection, lookup) {
context.subscriptions.push(vscode.languages.registerHoverProvider(selector, {
async provideHover(document, position) {
const state = await lookup(document, position);
if (!state?.symbols.length) return undefined;
const contents = [];
for (const symbol of state.symbols) {
const page = new vscode.MarkdownString();
page.isTrusted = { enabledCommands: ['dever.showCalls', 'dever.openDomainLinks', 'dever.previewDocumentation'] };
page.appendMarkdown(`**${symbol.name}**\n\n`);
if (state.index.documentation_errors.length) {
page.appendMarkdown('**说明校验未通过。** 失效或重复的标题详见“Dever”输出;签名和调用关系仍来自源码。\n\n');
}
for (const signature of symbol.signatures) page.appendCodeblock(signature, 'dever');
const detail = await description(inspection, state.index, symbol, state.root);
if (detail) {
page.baseUri = detail.uri;
page.appendMarkdown(`${detail.markdown}\n\n`);
} else {
page.appendMarkdown('尚未提供领域说明;签名和关系来自已保存源码。\n\n');
}
for (const incoming of [true, false]) {
const related = relations(state.index, symbol.id, incoming);
const label = incoming ? '调用方' : '调用目标';
const names = related.slice(0, 4).map(item => `\`${item.symbol.name}\``).join('、');
page.appendMarkdown(`${label}:${names || '当前静态索引中无记录'}${related.length > 4 ? `,共 ${related.length} 个` : ''}。\n\n`);
}
const links = [];
for (const site of symbol.declarations.slice(0, 1)) {
const target = uri(state.index, site.file, state.root).with({ fragment: `L${site.start.line + 1},${site.start.character + 1}` });
links.push(`[源码](${target.toString()})`);
}
if (detail) links.push(`[说明](${command('dever.previewDocumentation', [state.root, symbol.name])})`);
links.push(`[调用详情](${command('dever.showCalls', [state.root, symbol.name])})`);
links.push(`[领域流程](${command('dever.openDomainLinks', [state.root, symbol.name])})`);
page.appendMarkdown(links.join(' · '));
contents.push(page);
}
return new vscode.Hover(contents);
}
}));
}
module.exports = { registerHover, description, command };