highlight the selected reference

This commit is contained in:
bkellam 2025-11-30 16:35:24 -08:00
parent 2767c2b088
commit 23057d8a05
2 changed files with 60 additions and 17 deletions

View file

@ -163,7 +163,11 @@ export const SymbolHoverPopup: React.FC<SymbolHoverPopupProps> = ({
symbolInfo symbolInfo
]); ]);
const onFindReferences = useCallback((symbolName: string) => { const onFindReferences = useCallback(() => {
if (!symbolInfo) {
return;
}
captureEvent('wa_find_references_pressed', { captureEvent('wa_find_references_pressed', {
source, source,
}); });
@ -171,7 +175,7 @@ export const SymbolHoverPopup: React.FC<SymbolHoverPopupProps> = ({
createAuditAction({ createAuditAction({
action: "user.performed_find_references", action: "user.performed_find_references",
metadata: { metadata: {
message: symbolName, message: symbolInfo.symbolName,
}, },
}) })
@ -180,9 +184,10 @@ export const SymbolHoverPopup: React.FC<SymbolHoverPopupProps> = ({
revisionName, revisionName,
path: fileName, path: fileName,
pathType: 'blob', pathType: 'blob',
highlightRange: symbolInfo.range,
setBrowseState: { setBrowseState: {
selectedSymbolInfo: { selectedSymbolInfo: {
symbolName, symbolName: symbolInfo.symbolName,
repoName, repoName,
revisionName, revisionName,
language, language,
@ -191,15 +196,7 @@ export const SymbolHoverPopup: React.FC<SymbolHoverPopupProps> = ({
isBottomPanelCollapsed: false, isBottomPanelCollapsed: false,
} }
}) })
}, [ }, [captureEvent, fileName, language, navigateToPath, repoName, revisionName, source, symbolInfo]);
captureEvent,
fileName,
language,
navigateToPath,
repoName,
revisionName,
source
]);
// @todo: We should probably make the behaviour s.t., the ctrl / cmd key needs to be held // @todo: We should probably make the behaviour s.t., the ctrl / cmd key needs to be held
// down to navigate to the definition. We should also only show the underline when the key // down to navigate to the definition. We should also only show the underline when the key
@ -216,9 +213,7 @@ export const SymbolHoverPopup: React.FC<SymbolHoverPopupProps> = ({
}, [symbolInfo, onGotoDefinition]); }, [symbolInfo, onGotoDefinition]);
useHotkeys('alt+shift+f12', () => { useHotkeys('alt+shift+f12', () => {
if (symbolInfo?.symbolName) { onFindReferences();
onFindReferences(symbolInfo.symbolName);
}
}, { }, {
enableOnFormTags: true, enableOnFormTags: true,
enableOnContentEditable: true, enableOnContentEditable: true,
@ -302,7 +297,7 @@ export const SymbolHoverPopup: React.FC<SymbolHoverPopupProps> = ({
<Button <Button
variant="outline" variant="outline"
size="sm" size="sm"
onClick={() => onFindReferences(symbolInfo.symbolName)} onClick={onFindReferences}
> >
Find references Find references
</Button> </Button>

View file

@ -27,6 +27,7 @@ export type SymbolDefinition = {
interface HoveredOverSymbolInfo { interface HoveredOverSymbolInfo {
element: HTMLElement; element: HTMLElement;
symbolName: string; symbolName: string;
range: SourceRange;
isSymbolDefinitionsLoading: boolean; isSymbolDefinitionsLoading: boolean;
symbolDefinitions?: SymbolDefinition[]; symbolDefinitions?: SymbolDefinition[];
} }
@ -127,17 +128,64 @@ export const useHoveredOverSymbolInfo = ({
}; };
}, [editorRef, domain, clearTimers]); }, [editorRef, domain, clearTimers]);
// Extract the highlight range of the symbolElement from the editor view.
const highlightRange = useMemo((): SourceRange | undefined => {
if (!symbolElement || !editorRef.view) {
return undefined;
}
const view = editorRef.view;
const rect = symbolElement.getBoundingClientRect();
// Get the start position (left edge, middle vertically)
const startPos = view.posAtCoords({
x: rect.left,
y: rect.top + rect.height / 2,
});
// Get the end position (right edge, middle vertically)
const endPos = view.posAtCoords({
x: rect.right,
y: rect.top + rect.height / 2,
});
if (startPos === null || endPos === null) {
return undefined;
}
// Convert CodeMirror positions to SourceRange format
const startLine = view.state.doc.lineAt(startPos);
const endLine = view.state.doc.lineAt(endPos);
const startColumn = startPos - startLine.from + 1; // 1-based column
const endColumn = endPos - endLine.from + 1; // 1-based column
return {
start: {
byteOffset: startPos, // 0-based byte offset
lineNumber: startLine.number, // 1-based line number
column: startColumn, // 1-based column
},
end: {
byteOffset: endPos, // 0-based byte offset
lineNumber: endLine.number, // 1-based line number
column: endColumn, // 1-based column
},
};
}, [symbolElement, editorRef.view]);
if (!isVisible && !isSticky) { if (!isVisible && !isSticky) {
return undefined; return undefined;
} }
if (!symbolElement || !symbolName) { if (!symbolElement || !symbolName || !highlightRange) {
return undefined; return undefined;
} }
return { return {
element: symbolElement, element: symbolElement,
symbolName, symbolName,
range: highlightRange,
isSymbolDefinitionsLoading: isSymbolDefinitionsLoading, isSymbolDefinitionsLoading: isSymbolDefinitionsLoading,
symbolDefinitions, symbolDefinitions,
}; };