From bae7cdc234a2187d861ad7de03ac880deb168ec0 Mon Sep 17 00:00:00 2001 From: Bohdan Triapitsyn Date: Fri, 17 Apr 2026 11:36:31 +0300 Subject: [PATCH] fix: make go-to-line shortcut work reliably in editor Option+G now matches correctly on macOS keyboard layouts Go-to-line shortcut no longer gets blocked by editor textbox guards Prevents accidental symbol insertion when triggering go-to-line --- packages/ui/src/components/views/FilesView.tsx | 11 ++++++++--- packages/ui/src/lib/shortcuts.ts | 18 +++++++++++++++++- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/packages/ui/src/components/views/FilesView.tsx b/packages/ui/src/components/views/FilesView.tsx index 8b88f983..8e8aa187 100644 --- a/packages/ui/src/components/views/FilesView.tsx +++ b/packages/ui/src/components/views/FilesView.tsx @@ -83,6 +83,7 @@ import { getDefaultTheme } from '@/lib/theme/themes'; import { openDesktopPath, openDesktopProjectInApp } from '@/lib/desktop'; import { OPEN_DIRECTORY_APP_IDS } from '@/lib/openInApps'; import { useOpenInAppsStore } from '@/stores/useOpenInAppsStore'; +import { eventMatchesShortcut, getEffectiveShortcutCombo } from '@/lib/shortcuts'; type FileNode = { name: string; @@ -684,6 +685,7 @@ export const FilesView: React.FC = ({ mode = 'full' }) => { const setPendingFileNavigation = useUIStore((state) => state.setPendingFileNavigation); const pendingFileFocusPath = useUIStore((state) => state.pendingFileFocusPath); const setPendingFileFocusPath = useUIStore((state) => state.setPendingFileFocusPath); + const shortcutOverrides = useUIStore((state) => state.shortcutOverrides); // Global mouseup to end drag selection React.useEffect(() => { @@ -2071,16 +2073,19 @@ export const FilesView: React.FC = ({ mode = 'full' }) => { return; } + const goToLineCombo = getEffectiveShortcutCombo('open_go_to_line', shortcutOverrides); + const handleKeyDown = (event: KeyboardEvent) => { const target = event.target as Element | null; if (target?.closest('[role="dialog"]')) { return; } + const isEditorTarget = Boolean(target?.closest('.cm-editor')); const isTypingTarget = Boolean( target?.closest('input, textarea, [contenteditable="true"], [role="textbox"]') ); - if (isTypingTarget) { + if (isTypingTarget && !isEditorTarget) { return; } @@ -2090,7 +2095,7 @@ export const FilesView: React.FC = ({ mode = 'full' }) => { return; } - if (event.altKey && !event.metaKey && !event.ctrlKey && !event.shiftKey && event.code === 'KeyG') { + if (eventMatchesShortcut(event, goToLineCombo)) { event.preventDefault(); setIsGoToLineOpen(true); } @@ -2098,7 +2103,7 @@ export const FilesView: React.FC = ({ mode = 'full' }) => { window.addEventListener('keydown', handleKeyDown); return () => window.removeEventListener('keydown', handleKeyDown); - }, [canEdit, isMobile, textViewMode]); + }, [canEdit, isMobile, shortcutOverrides, textViewMode]); const editorExtensions = React.useMemo(() => { if (!selectedFile?.path) { diff --git a/packages/ui/src/lib/shortcuts.ts b/packages/ui/src/lib/shortcuts.ts index fa769fa2..731e698d 100644 --- a/packages/ui/src/lib/shortcuts.ts +++ b/packages/ui/src/lib/shortcuts.ts @@ -111,6 +111,13 @@ const SHORTCUT_ACTIONS: ReadonlyArray = [ description: 'Open the quick open dialog', customizable: true, }, + { + id: 'open_go_to_line', + defaultCombo: 'alt+g', + label: 'Go to line (files editor)', + description: 'Open go to line in the files editor', + customizable: true, + }, { id: 'open_command_palette', defaultCombo: 'mod+k', @@ -571,7 +578,16 @@ export function eventMatchesShortcut( } } - const eventKey = keyToShortcutToken(event.key); + let eventKeyRaw = event.key; + if (event.altKey) { + if (event.code.startsWith('Key') && event.code.length === 4) { + eventKeyRaw = event.code.slice(3).toLowerCase(); + } else if (event.code.startsWith('Digit') && event.code.length === 6) { + eventKeyRaw = event.code.slice(5); + } + } + + const eventKey = keyToShortcutToken(eventKeyRaw); const expectedKey = keyToShortcutToken(parsed.key); return eventKey === expectedKey;