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
This commit is contained in:
@@ -83,6 +83,7 @@ import { getDefaultTheme } from '@/lib/theme/themes';
|
|||||||
import { openDesktopPath, openDesktopProjectInApp } from '@/lib/desktop';
|
import { openDesktopPath, openDesktopProjectInApp } from '@/lib/desktop';
|
||||||
import { OPEN_DIRECTORY_APP_IDS } from '@/lib/openInApps';
|
import { OPEN_DIRECTORY_APP_IDS } from '@/lib/openInApps';
|
||||||
import { useOpenInAppsStore } from '@/stores/useOpenInAppsStore';
|
import { useOpenInAppsStore } from '@/stores/useOpenInAppsStore';
|
||||||
|
import { eventMatchesShortcut, getEffectiveShortcutCombo } from '@/lib/shortcuts';
|
||||||
|
|
||||||
type FileNode = {
|
type FileNode = {
|
||||||
name: string;
|
name: string;
|
||||||
@@ -684,6 +685,7 @@ export const FilesView: React.FC<FilesViewProps> = ({ mode = 'full' }) => {
|
|||||||
const setPendingFileNavigation = useUIStore((state) => state.setPendingFileNavigation);
|
const setPendingFileNavigation = useUIStore((state) => state.setPendingFileNavigation);
|
||||||
const pendingFileFocusPath = useUIStore((state) => state.pendingFileFocusPath);
|
const pendingFileFocusPath = useUIStore((state) => state.pendingFileFocusPath);
|
||||||
const setPendingFileFocusPath = useUIStore((state) => state.setPendingFileFocusPath);
|
const setPendingFileFocusPath = useUIStore((state) => state.setPendingFileFocusPath);
|
||||||
|
const shortcutOverrides = useUIStore((state) => state.shortcutOverrides);
|
||||||
|
|
||||||
// Global mouseup to end drag selection
|
// Global mouseup to end drag selection
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
@@ -2071,16 +2073,19 @@ export const FilesView: React.FC<FilesViewProps> = ({ mode = 'full' }) => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const goToLineCombo = getEffectiveShortcutCombo('open_go_to_line', shortcutOverrides);
|
||||||
|
|
||||||
const handleKeyDown = (event: KeyboardEvent) => {
|
const handleKeyDown = (event: KeyboardEvent) => {
|
||||||
const target = event.target as Element | null;
|
const target = event.target as Element | null;
|
||||||
if (target?.closest('[role="dialog"]')) {
|
if (target?.closest('[role="dialog"]')) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const isEditorTarget = Boolean(target?.closest('.cm-editor'));
|
||||||
const isTypingTarget = Boolean(
|
const isTypingTarget = Boolean(
|
||||||
target?.closest('input, textarea, [contenteditable="true"], [role="textbox"]')
|
target?.closest('input, textarea, [contenteditable="true"], [role="textbox"]')
|
||||||
);
|
);
|
||||||
if (isTypingTarget) {
|
if (isTypingTarget && !isEditorTarget) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2090,7 +2095,7 @@ export const FilesView: React.FC<FilesViewProps> = ({ mode = 'full' }) => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event.altKey && !event.metaKey && !event.ctrlKey && !event.shiftKey && event.code === 'KeyG') {
|
if (eventMatchesShortcut(event, goToLineCombo)) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
setIsGoToLineOpen(true);
|
setIsGoToLineOpen(true);
|
||||||
}
|
}
|
||||||
@@ -2098,7 +2103,7 @@ export const FilesView: React.FC<FilesViewProps> = ({ mode = 'full' }) => {
|
|||||||
|
|
||||||
window.addEventListener('keydown', handleKeyDown);
|
window.addEventListener('keydown', handleKeyDown);
|
||||||
return () => window.removeEventListener('keydown', handleKeyDown);
|
return () => window.removeEventListener('keydown', handleKeyDown);
|
||||||
}, [canEdit, isMobile, textViewMode]);
|
}, [canEdit, isMobile, shortcutOverrides, textViewMode]);
|
||||||
|
|
||||||
const editorExtensions = React.useMemo(() => {
|
const editorExtensions = React.useMemo(() => {
|
||||||
if (!selectedFile?.path) {
|
if (!selectedFile?.path) {
|
||||||
|
|||||||
@@ -111,6 +111,13 @@ const SHORTCUT_ACTIONS: ReadonlyArray<ShortcutAction> = [
|
|||||||
description: 'Open the quick open dialog',
|
description: 'Open the quick open dialog',
|
||||||
customizable: true,
|
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',
|
id: 'open_command_palette',
|
||||||
defaultCombo: 'mod+k',
|
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);
|
const expectedKey = keyToShortcutToken(parsed.key);
|
||||||
|
|
||||||
return eventKey === expectedKey;
|
return eventKey === expectedKey;
|
||||||
|
|||||||
Reference in New Issue
Block a user