From f91940c472d95083cf498f79853a0d4f41377924 Mon Sep 17 00:00:00 2001 From: Alex Bates Date: Thu, 26 Mar 2026 17:26:32 +0000 Subject: [PATCH] fix doc-comment hover for API_CALLABLE declarations - Only show custom hover for API_CALLABLE functions, not #define or regular functions - Skip hover when cursor is on the API_CALLABLE token itself - Check the current line directly for doc comments so hovering at the declaration site works even when clangd resolves elsewhere - Pick the location with the most doc comment lines across all declaration/definition results --- .../browser/c-language/doc-comment-hover.ts | 34 ++++++++++++++++--- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/extensions/studio/src/browser/c-language/doc-comment-hover.ts b/extensions/studio/src/browser/c-language/doc-comment-hover.ts index efe62e5..055608d 100644 --- a/extensions/studio/src/browser/c-language/doc-comment-hover.ts +++ b/extensions/studio/src/browser/c-language/doc-comment-hover.ts @@ -13,6 +13,7 @@ import type { import type { ITextModel } from "@theia/monaco-editor-core/esm/vs/editor/common/model"; import { CDeclarationService, + parseDocComment, parseEvtParams, parseEvtOutputs, stripEvtTags, @@ -134,6 +135,10 @@ export class DocCommentHoverContribution context, ); try { + const word = model.getWordAtPosition(position); + if (word?.word === "API_CALLABLE") { + return original; + } const docHover = await self.resolveDocHover( featuresService, model, @@ -186,6 +191,19 @@ export class DocCommentHoverContribution position: Position, token: CancellationToken, ): Promise { + // Check the current line first — when hovering at the declaration site, + // clangd may not return it via go-to-declaration/definition. + const currentLine = model.getLineContent(position.lineNumber); + if (currentLine.match(/API_CALLABLE\(/)) { + const fileLines = model.getLinesContent(); + const lineIndex = position.lineNumber - 1; + const docLines = parseDocComment(fileLines, lineIndex); + const hover = buildHover(fileLines, lineIndex, docLines); + if (hover && (docLines?.length ?? 0) > 0) { + return hover; + } + } + const locations = await this.declarationService.findLocations( featuresService, model, @@ -193,20 +211,28 @@ export class DocCommentHoverContribution token, ); + let bestHover: string | null = null; + let bestDocCount = -1; + for (const loc of locations) { const info = await this.declarationService.getDeclarationInfo( loc.uri, loc.line, ); - if (!info) { + if (!info || !info.declLine.match(/API_CALLABLE\(/)) { continue; } const hover = buildHover(info.fileLines, info.lineIndex, info.docLines); - if (hover) { - return hover; + if (!hover) { + continue; + } + const docCount = info.docLines?.length ?? 0; + if (docCount > bestDocCount) { + bestHover = hover; + bestDocCount = docCount; } } - return null; + return bestHover; } } -- 2.51.2