# clide Vim keymap preset (T-65). # # Modal editing built on the keymap sequence layer (D-82). The Vim mode # service (builtin.vim) publishes vim.normal / vim.insert / vim.visual # scope flags; bindings here are guarded on them. Motions/edits resolve to # `command:editor.vim.`, which the editor applies to the buffer # (read-only in command mode so keys never type); mode changes resolve to # `command:vim.mode.`. # # Notation (D-82): `+` joins a chord, a space sequences (`d d`), a YAML # list alternates (`[d, x]`). Repeat counts (`5j`) are captured by the # matcher — no binding needed. # # Scope: the muscle-memory set, not bit-exact Vim. cw/$/^ are # approximations; see vim_edit_ops.dart. name: vim bindings: # ---- App shortcuts (shared with the default preset) ----------------- # Modified chords bubble past the editor to the global handler, so these # keep working with the editor focused and under every mode. - intent: palette.open keys: [ctrl+shift+p, meta+shift+p] - intent: palette.selectNext keys: [down, ctrl+n] when: palette.open - intent: palette.selectPrevious keys: [up, ctrl+p] when: palette.open - intent: palette.accept keys: enter when: palette.open - intent: dismiss keys: escape when: palette.open # `shift shift` (double-tap) aliases to quick-open across presets (T-341). - intent: quickOpen.open keys: [ctrl+p, meta+p, shift shift] when: "!palette.open" - intent: quickOpen.selectNext keys: [down, ctrl+n] when: quickOpen.open - intent: quickOpen.selectPrevious keys: up when: quickOpen.open - intent: quickOpen.accept keys: enter when: quickOpen.open - intent: dismiss keys: escape when: quickOpen.open # Ex command-line overlay (T-407): Esc dismisses it back to normal mode (the # overlay's own EditableText handles Enter via onSubmitted). - intent: dismiss keys: escape when: exline.open - intent: findInFiles.open keys: [ctrl+shift+f, meta+shift+f] - intent: focus.nextPanel keys: f6 - intent: focus.previousPanel keys: shift+f6 - intent: text.scaleIncrease keys: [ctrl+equal, ctrl+shift+equal, meta+equal, meta+shift+equal] - intent: text.scaleDecrease keys: [ctrl+minus, meta+minus] - intent: text.scaleReset keys: [ctrl+0, meta+0] # ---- Pane navigation (non-editor panes) ------------------------------ # When a non-editor pane holds focus (file tree, conversation, lists), the # same motion keys mean NAVIGATION, not buffer edits (T-406). The # `!editor.focused` guard keeps these out of the editor's way; the editor # publishes `editor.focused` while it has focus. These MUST precede the # editor motions below — the resolver takes the first matching binding in # file order, so with a pane focused (editor.focused false) nav wins, and # with the editor focused the `!editor.focused` clause fails and the buffer # motion below wins. Each pane runs its own SequenceMatcher (PaneKeyNav). - intent: nav.down keys: j when: "vim.normal && !editor.focused" - intent: nav.up keys: k when: "vim.normal && !editor.focused" - intent: nav.pageDown keys: ctrl+d when: "vim.normal && !editor.focused" - intent: nav.pageUp keys: ctrl+u when: "vim.normal && !editor.focused" - intent: nav.top keys: "g g" # gg when: "vim.normal && !editor.focused" - intent: nav.bottom keys: shift+g # G when: "vim.normal && !editor.focused" - intent: nav.expandOrRight keys: l when: "vim.normal && !editor.focused" - intent: nav.collapseOrLeft keys: h when: "vim.normal && !editor.focused" - intent: nav.activate keys: [o, enter] when: "vim.normal && !editor.focused" # ---- ctrl+w window-command family (T-404) ---------------------------- # Multi-chord sequences resolved by the GLOBAL matcher (root_shell), so they # work from any focus. Bare ctrl+w still closes the editor after the ambiguity # timeout (the editor.close binding below / contributions layer). The 3-column # clide layout approximates vim's window grid: h/l focus left/right panels, # j toggles the dock, o is "only" (focus mode), q/c close the editor. - intent: command:panel.focus.left keys: ctrl+w h when: "vim.normal || vim.visual" - intent: command:panel.focus.right keys: ctrl+w l when: "vim.normal || vim.visual" - intent: command:dock.toggle keys: ctrl+w j when: "vim.normal || vim.visual" - intent: focus.nextPanel keys: [ctrl+w w, ctrl+w ctrl+w] when: "vim.normal || vim.visual" - intent: focus.previousPanel keys: ctrl+w shift+w # ctrl+w W when: "vim.normal || vim.visual" - intent: command:panel.focusMode keys: ctrl+w o when: "vim.normal || vim.visual" - intent: command:editor.close keys: [ctrl+w q, ctrl+w c] when: "vim.normal || vim.visual" # ---- Tab motions (T-405) --------------------------------------------- # gt / gT cycle the workspace tab strip via the preset-neutral # workspace.tab.* commands (also on ctrl+pagedown/up everywhere). Bare-`g` # sequences are editor/pane-local — the focused editor's matcher or a pane's # PaneKeyNav resolves them and runs the command; they share the `g` prefix # with `g g` (docStart / nav.top), distinguished by the final chord. - intent: command:workspace.tab.next keys: g t # gt when: vim.normal - intent: command:workspace.tab.previous keys: g shift+t # gT when: vim.normal # ---- Ex command-line (T-407) ----------------------------------------- # `:` opens the transient ex overlay (`:w` `:q` `:wq` `:x` `:e ` `:N`); # `ZZ` runs `:wq` directly. Both are typed app intents the editor's command # matcher and a pane's nav matcher bubble to the app-root Actions, so they # fire from any focus. Editor-targeted: no-op when no buffer is active. - intent: exline.open keys: shift+semicolon # : when: vim.normal - intent: exline.writeQuit keys: shift+z shift+z # ZZ when: vim.normal # ---- Mode transitions ------------------------------------------------ - intent: command:vim.mode.visual keys: v when: vim.normal - intent: command:vim.mode.normal keys: escape when: "vim.insert || vim.visual" # ---- Insert entry (normal → insert), positioned by the editor -------- - intent: command:editor.vim.insert keys: i when: vim.normal - intent: command:editor.vim.append keys: a when: vim.normal - intent: command:editor.vim.insertLineStart keys: shift+i # I when: vim.normal - intent: command:editor.vim.appendLineEnd keys: shift+a # A when: vim.normal - intent: command:editor.vim.openBelow keys: o when: vim.normal - intent: command:editor.vim.openAbove keys: shift+o # O when: vim.normal # ---- Motions (normal + visual) --------------------------------------- - intent: command:editor.vim.left keys: h when: "vim.normal || vim.visual" - intent: command:editor.vim.down keys: j when: "vim.normal || vim.visual" - intent: command:editor.vim.up keys: k when: "vim.normal || vim.visual" - intent: command:editor.vim.right keys: l when: "vim.normal || vim.visual" - intent: command:editor.vim.wordForward keys: w when: "vim.normal || vim.visual" - intent: command:editor.vim.wordBackward keys: b when: "vim.normal || vim.visual" - intent: command:editor.vim.wordEnd keys: e when: "vim.normal || vim.visual" - intent: command:editor.vim.lineStart keys: "0" when: "vim.normal || vim.visual" - intent: command:editor.vim.lineEnd keys: shift+4 # $ when: "vim.normal || vim.visual" - intent: command:editor.vim.firstNonBlank keys: shift+6 # ^ when: "vim.normal || vim.visual" - intent: command:editor.vim.docStart keys: "g g" # gg when: "vim.normal || vim.visual" - intent: command:editor.vim.docEnd keys: shift+g # G when: "vim.normal || vim.visual" # ---- Normal-mode edits ---------------------------------------------- - intent: command:editor.vim.deleteChar keys: x when: vim.normal - intent: command:editor.vim.deleteLine keys: "d d" when: vim.normal - intent: command:editor.vim.deleteWord keys: "d w" when: vim.normal - intent: command:editor.vim.deleteToEnd keys: shift+d # D when: vim.normal - intent: command:editor.vim.changeLine keys: "c c" when: vim.normal - intent: command:editor.vim.changeWord keys: "c w" when: vim.normal - intent: command:editor.vim.yankLine keys: "y y" when: vim.normal - intent: command:editor.vim.paste keys: p when: vim.normal - intent: command:editor.vim.pasteBefore keys: shift+p # P when: vim.normal # ---- Visual-mode operators ------------------------------------------ - intent: command:editor.vim.visualDelete keys: [d, x] when: vim.visual - intent: command:editor.vim.visualYank keys: y when: vim.visual - intent: command:editor.vim.visualChange keys: c when: vim.visual