Просмотр исходного кода

fix(editor): use Prec.high for Emacs/Vim keymap extensions to fix keybinding conflicts

Emacs and Vim plugins use ViewPlugin DOM event handlers (keydown) to
intercept key events. When wrapped in Prec.low, these handlers run
after CodeMirror's built-in keymap handler (Prec.default), causing
conflicts with defaultKeymap Mac Ctrl-* bindings and completionKeymap
Ctrl-Space. This prevents Emacs keybindings like Ctrl-Y, Ctrl-W, and
Ctrl-SPC from being processed.

Change Emacs and Vim extensions to Prec.high so their DOM event
handlers run before the keymap handler, while keeping Prec.low for
VSCode and default keymaps that use keymap.of() and integrate with the
keymap handler directly.

Closes #10936

https://claude.ai/code/session_01UAUcoiWnFEh86tDeug4hCH
Claude 6 дней назад
Родитель
Сommit
13ea44727b
1 измененных файлов с 17 добавлено и 2 удалено
  1. 17 2
      packages/editor/src/client/stores/use-editor-settings.ts

+ 17 - 2
packages/editor/src/client/stores/use-editor-settings.ts

@@ -84,6 +84,20 @@ const useThemeExtension = (
   }, [codeMirrorEditor, themeExtension]);
   }, [codeMirrorEditor, themeExtension]);
 };
 };
 
 
+// Emacs and Vim plugins use ViewPlugin DOM event handlers (keydown) to intercept keys.
+// They must run BEFORE CodeMirror's built-in keymap handler (Prec.default) to prevent
+// conflicts with defaultKeymap Mac Ctrl-* bindings and completionKeymap Ctrl-Space.
+// VSCode and default keymaps use keymap.of() which integrates with the keymap handler directly,
+// so Prec.low is appropriate for them.
+const getKeymapPrecedence = (
+  keymapMode?: KeyMapMode,
+): ((ext: Extension) => Extension) => {
+  if (keymapMode === 'emacs' || keymapMode === 'vim') {
+    return Prec.high;
+  }
+  return Prec.low;
+};
+
 const useKeymapExtension = (
 const useKeymapExtension = (
   codeMirrorEditor?: UseCodeMirrorEditor,
   codeMirrorEditor?: UseCodeMirrorEditor,
   keymapMode?: KeyMapMode,
   keymapMode?: KeyMapMode,
@@ -113,11 +127,12 @@ const useKeymapExtension = (
     if (keymapExtension == null) {
     if (keymapExtension == null) {
       return;
       return;
     }
     }
+    const wrapWithPrecedence = getKeymapPrecedence(keymapMode);
     const cleanupFunction = codeMirrorEditor?.appendExtensions(
     const cleanupFunction = codeMirrorEditor?.appendExtensions(
-      Prec.low(keymapExtension),
+      wrapWithPrecedence(keymapExtension),
     );
     );
     return cleanupFunction;
     return cleanupFunction;
-  }, [codeMirrorEditor, keymapExtension]);
+  }, [codeMirrorEditor, keymapExtension, keymapMode]);
 };
 };
 
 
 export const useEditorSettings = (
 export const useEditorSettings = (