@replit/codemirror-emacs EmacsHandler supports multi-stroke key chains natively via bindKey and addCommands; no C-x C-s save built-intoggleMarkdownSymbol in emacs.ts duplicates logic from useInsertMarkdownElements hook; both perform wrap/unwrap but with different APIs (EditorView direct vs hook-based)getKeymap) mixes mode-specific concerns (inline vscode/default construction, precedence branching in consumer)node_modules/@replit/codemirror-emacs/dist/index.d.ts, compiled sourceEmacsHandler.bindKey(keyGroup: string, command: any) supports pipe-separated alternatives and multi-stroke chainsEmacsHandler.addCommands(commands: object) registers named commands; command receives { view: EditorView }$data.keyChain; intermediate keys store null in binding maptoggleMarkdownSymbol(view, prefix, suffix) while editor-shortcuts use useInsertMarkdownElements hookinsert-markdown-elements.ts, emacs.ts, generate-add-markdown-symbol-command.tsuseInsertMarkdownElements is a React hook returning (prefix: string, suffix: string) => voidtoggleMarkdownSymbol is a pure function taking (view: EditorView, prefix: string, suffix: string) => voidview property, not a React contextEmacsHandler.addCommands since it's not a React componentinsert-prefix.ts, insert-blockquote.ts, insert-numbered-list.tsuseInsertPrefix is also a React hook: (prefix: string, noSpaceIfPrefixExists?: boolean) => voiduse-editor-settings.ts lines 87-99keymap.of() which integrates with CodeMirror's handler directly| Option | Description | Strengths | Risks / Limitations | Notes |
|---|---|---|---|---|
| A: Return-object factory | Each module returns { extension, precedence, overrides } |
Clean interface, no consumer branching | Slightly more complex return type | Preferred |
| B: Pre-wrapped extension | Each module returns Prec.high(extension) directly |
Simplest consumer code | Consumer loses control over precedence | Less flexible |
| C: Config registry | Central registry maps mode → config | Extensible | Over-engineering for 4 modes | Rejected |
{ extension, precedence, overrides } objectif (keymapModeName === 'emacs') hard-codingoverrides: ShortcutCategory[] where categories are 'formatting' | 'navigation' | 'structural'CategorizedKeyBindings wrapper type groups KeyBinding[] with a category field, allowing useEditorShortcuts to filter by category match against overridesemacs/ directory with submodules per responsibilityeditor-shortcuts/ is currently under services/use-codemirror-editor/utils/ (public layer) but is never exported — only consumed by stores/use-editor-shortcuts.ts