From 7d0ed35d7f536c2825588bd56be06ad13dd3604e Mon Sep 17 00:00:00 2001 From: bigsunnyboy <415781593@qq.com> Date: Tue, 12 May 2026 00:25:25 +0800 Subject: [PATCH] Restore copy behavior in Vim keymap CodeMirror's Vim keymap consumes Ctrl-C on Windows and Linux before the editor can copy selected text. The fix adds a small shared extraKeys handler that invokes the browser copy command for Vim editors and then returns CodeMirror.Pass so CodeMirror can continue its normal handling. Constraint: Keep the change scoped to the existing CodeMirror editor configuration Rejected: Rework user-customizable keybindings | larger UI and settings change than the bounty issue requires Confidence: medium Scope-risk: narrow Directive: Keep this handler attached to every cloud editor configuration that supports the Vim keymap Tested: npx eslint src/cloud/lib/editor/vimKeyMap.ts src/cloud/components/Editor/index.tsx src/cloud/lib/hooks/editor/docEditor.ts --ext .ts,.tsx Tested: npx tsc --noEmit --pretty false Not-tested: Manual Windows/Linux Electron clipboard flow --- src/cloud/components/Editor/index.tsx | 2 ++ src/cloud/lib/editor/vimKeyMap.ts | 9 +++++++++ src/cloud/lib/hooks/editor/docEditor.ts | 2 ++ 3 files changed, 13 insertions(+) create mode 100644 src/cloud/lib/editor/vimKeyMap.ts diff --git a/src/cloud/components/Editor/index.tsx b/src/cloud/components/Editor/index.tsx index 639530cb0a..cc8924bf23 100644 --- a/src/cloud/components/Editor/index.tsx +++ b/src/cloud/components/Editor/index.tsx @@ -104,6 +104,7 @@ import { CodeMirrorEditorModeHints, getModeSuggestions, } from '../../lib/editor/CodeMirror' +import { copySelectionOnVimCtrlC } from '../../lib/editor/vimKeyMap' import { scrollEditorToLine } from '../../lib/hooks/editor/docEditor' type LayoutMode = 'split' | 'preview' | 'editor' @@ -269,6 +270,7 @@ const Editor = ({ Enter: 'newlineAndIndentContinueMarkdownList', Tab: 'indentMore', 'Ctrl-Space': 'autocomplete', + 'Ctrl-C': copySelectionOnVimCtrlC, }, scrollPastEnd: true, // fixes IME being on top of current line, Codemirror issue: https://github.com/codemirror/CodeMirror/issues/3137 diff --git a/src/cloud/lib/editor/vimKeyMap.ts b/src/cloud/lib/editor/vimKeyMap.ts new file mode 100644 index 0000000000..1cc71a8776 --- /dev/null +++ b/src/cloud/lib/editor/vimKeyMap.ts @@ -0,0 +1,9 @@ +import CodeMirror from 'codemirror' + +export function copySelectionOnVimCtrlC(cm: CodeMirror.Editor) { + if (`${cm.getOption('keyMap')}`.startsWith('vim')) { + document.execCommand('copy') + } + + return CodeMirror.Pass +} diff --git a/src/cloud/lib/hooks/editor/docEditor.ts b/src/cloud/lib/hooks/editor/docEditor.ts index afc4f3d860..a463ecbb85 100644 --- a/src/cloud/lib/hooks/editor/docEditor.ts +++ b/src/cloud/lib/hooks/editor/docEditor.ts @@ -12,6 +12,7 @@ import { SerializedTeam } from '../../../interfaces/db/team' import { SerializedTemplate } from '../../../interfaces/db/template' import { SerializedUser } from '../../../interfaces/db/user' import useRealtime from '../../editor/hooks/useRealtime' +import { copySelectionOnVimCtrlC } from '../../editor/vimKeyMap' import attachFileHandlerToCodeMirrorEditor, { OnFileCallback, } from '../../editor/plugins/fileHandler' @@ -132,6 +133,7 @@ export function useDocEditor({ extraKeys: { Enter: 'newlineAndIndentContinueMarkdownList', Tab: 'indentMore', + 'Ctrl-C': copySelectionOnVimCtrlC, }, scrollPastEnd: true, // fixes IME being on top of current line, Codemirror issue: https://github.com/codemirror/CodeMirror/issues/3137