From aa88ce3ac17b27adcc1ee1b60ecdf5d693af7a55 Mon Sep 17 00:00:00 2001 From: Neil <4138956+nwparker@users.noreply.github.com> Date: Mon, 23 Mar 2026 23:32:55 -0700 Subject: [PATCH] fix: add copy path to line in Monaco editor context menu Adds "Copy Path to Line" and "Copy Relative Path to Line" as Monaco editor context menu actions so they appear on right-click anywhere in the editor. Also handles right-click on line number gutter to show the context menu there too. Co-Authored-By: Claude Opus 4.6 --- .../src/components/editor/EditorPanel.tsx | 1 + .../src/components/editor/MonacoEditor.tsx | 48 ++++++++++++++++++- 2 files changed, 47 insertions(+), 2 deletions(-) diff --git a/src/renderer/src/components/editor/EditorPanel.tsx b/src/renderer/src/components/editor/EditorPanel.tsx index 9b9f0ebd814..c1fe04512d8 100644 --- a/src/renderer/src/components/editor/EditorPanel.tsx +++ b/src/renderer/src/components/editor/EditorPanel.tsx @@ -215,6 +215,7 @@ export default function EditorPanel(): React.JSX.Element | null { return ( void @@ -17,6 +18,7 @@ type MonacoEditorProps = { export default function MonacoEditor({ filePath, + relativePath, content, language, onContentChange, @@ -45,11 +47,53 @@ export default function MonacoEditor({ // Track cursor line for "copy path to line" feature const pos = editorInstance.getPosition() - if (pos) setEditorCursorLine(filePath, pos.lineNumber) + if (pos) { + setEditorCursorLine(filePath, pos.lineNumber) + } editorInstance.onDidChangeCursorPosition((e) => { setEditorCursorLine(filePath, e.position.lineNumber) }) + // Show context menu on line number gutter right-click + editorInstance.onMouseDown((e) => { + if ( + e.event.rightButton && + e.target.type === monaco.editor.MouseTargetType.GUTTER_LINE_NUMBERS + ) { + e.event.preventDefault() + e.event.stopPropagation() + // Move cursor to the clicked line so actions use the right line number + const line = e.target.position?.lineNumber + if (line) { + editorInstance.setPosition({ lineNumber: line, column: 1 }) + } + // Trigger Monaco's context menu programmatically + editorInstance.trigger('gutter', 'editor.action.showContextMenu', null) + } + }) + + // Add "Copy Path to Line" actions to Monaco's right-click context menu + editorInstance.addAction({ + id: 'orca.copyPathToLine', + label: 'Copy Path to Line', + contextMenuGroupId: '9_cutcopypaste', + contextMenuOrder: 100, + run: (ed) => { + const line = ed.getPosition()?.lineNumber ?? 1 + navigator.clipboard.writeText(`${filePath}#L${line}`) + } + }) + editorInstance.addAction({ + id: 'orca.copyRelativePathToLine', + label: 'Copy Relative Path to Line', + contextMenuGroupId: '9_cutcopypaste', + contextMenuOrder: 101, + run: (ed) => { + const line = ed.getPosition()?.lineNumber ?? 1 + navigator.clipboard.writeText(`${relativePath}#L${line}`) + } + }) + // If there's a pending reveal at mount time, execute it now const reveal = useAppStore.getState().pendingEditorReveal if (reveal) { @@ -59,7 +103,7 @@ export default function MonacoEditor({ editorInstance.focus() } }, - [onSave, filePath, setEditorCursorLine, setPendingEditorReveal] + [onSave, filePath, relativePath, setEditorCursorLine] ) const handleChange = useCallback(