|
| 1 | +<!-- Keep this file in sync with: |
| 2 | + - src/components/VimTextArea.tsx (implementation) |
| 3 | + - src/utils/vim.ts (core logic) |
| 4 | + - src/utils/vim.test.ts (test suite) |
| 5 | +--> |
| 6 | + |
| 7 | +# Vim Mode |
| 8 | + |
| 9 | +cmux includes a built-in Vim mode for the chat input, providing familiar Vim-style editing for power users. |
| 10 | + |
| 11 | +## Enabling Vim Mode |
| 12 | + |
| 13 | +Vim mode is always enabled. Press **ESC** to enter normal mode from insert mode. |
| 14 | + |
| 15 | +## Modes |
| 16 | + |
| 17 | +### Insert Mode (Default) |
| 18 | +- This is the default mode when typing in the chat input |
| 19 | +- Type normally, all characters are inserted |
| 20 | +- Press **ESC** or **Ctrl-[** to enter normal mode |
| 21 | + |
| 22 | +### Normal Mode |
| 23 | +- Command mode for navigation and editing |
| 24 | +- Indicated by "NORMAL" text above the input |
| 25 | +- Pending commands are shown (e.g., "NORMAL d" when delete is pending) |
| 26 | +- Press **i**, **a**, **I**, **A**, **o**, or **O** to return to insert mode |
| 27 | + |
| 28 | +## Navigation |
| 29 | + |
| 30 | +### Basic Movement |
| 31 | +- **h** - Move left one character |
| 32 | +- **j** - Move down one line |
| 33 | +- **k** - Move up one line |
| 34 | +- **l** - Move right one character |
| 35 | + |
| 36 | +### Word Movement |
| 37 | +- **w** - Move forward to start of next word |
| 38 | +- **W** - Move forward to start of next WORD (whitespace-separated) |
| 39 | +- **b** - Move backward to start of previous word |
| 40 | +- **B** - Move backward to start of previous WORD |
| 41 | +- **e** - Move to end of current/next word |
| 42 | +- **E** - Move to end of current/next WORD |
| 43 | + |
| 44 | +### Line Movement |
| 45 | +- **0** - Move to beginning of line |
| 46 | +- **$** - Move to end of line |
| 47 | +- **Home** - Same as **0** |
| 48 | +- **End** - Same as **$** |
| 49 | + |
| 50 | +### Column Preservation |
| 51 | +When moving up/down with **j**/**k**, the cursor attempts to stay in the same column position. If a line is shorter, the cursor moves to the end of that line, but will return to the original column on longer lines. |
| 52 | + |
| 53 | +## Entering Insert Mode |
| 54 | + |
| 55 | +- **i** - Insert at cursor |
| 56 | +- **a** - Append after cursor |
| 57 | +- **I** - Insert at beginning of line |
| 58 | +- **A** - Append at end of line |
| 59 | +- **o** - Open new line below and insert |
| 60 | +- **O** - Open new line above and insert |
| 61 | + |
| 62 | +## Editing Commands |
| 63 | + |
| 64 | +### Simple Edits |
| 65 | +- **x** - Delete character under cursor |
| 66 | +- **p** - Paste after cursor |
| 67 | +- **P** - Paste before cursor |
| 68 | + |
| 69 | +### Undo/Redo |
| 70 | +- **u** - Undo last change |
| 71 | +- **Ctrl-r** - Redo |
| 72 | + |
| 73 | +### Line Operations |
| 74 | +- **dd** - Delete line (yank to clipboard) |
| 75 | +- **yy** - Yank (copy) line |
| 76 | +- **cc** - Change line (delete and enter insert mode) |
| 77 | + |
| 78 | +## Operators + Motions |
| 79 | + |
| 80 | +Vim's power comes from combining operators with motions. All operators work with all motions: |
| 81 | + |
| 82 | +### Operators |
| 83 | +- **d** - Delete |
| 84 | +- **c** - Change (delete and enter insert mode) |
| 85 | +- **y** - Yank (copy) |
| 86 | + |
| 87 | +### Motions |
| 88 | +- **w** - To next word |
| 89 | +- **b** - To previous word |
| 90 | +- **e** - To end of word |
| 91 | +- **$** - To end of line |
| 92 | +- **0** - To beginning of line |
| 93 | + |
| 94 | +### Examples |
| 95 | +- **dw** - Delete to next word |
| 96 | +- **de** - Delete to end of word |
| 97 | +- **d$** - Delete to end of line |
| 98 | +- **cw** - Change to next word |
| 99 | +- **ce** - Change to end of word |
| 100 | +- **c0** - Change to beginning of line |
| 101 | +- **y$** - Yank to end of line |
| 102 | +- **ye** - Yank to end of word |
| 103 | +- **yy** - Yank line (doubled operator) |
| 104 | + |
| 105 | +### Shortcuts |
| 106 | +- **D** - Same as **d$** (delete to end of line) |
| 107 | +- **C** - Same as **c$** (change to end of line) |
| 108 | + |
| 109 | +## Text Objects |
| 110 | + |
| 111 | +Text objects let you operate on semantic units: |
| 112 | + |
| 113 | +### Inner Word (iw) |
| 114 | +- **diw** - Delete inner word (word under cursor) |
| 115 | +- **ciw** - Change inner word |
| 116 | +- **yiw** - Yank inner word |
| 117 | + |
| 118 | +Text objects work from anywhere within the word - you don't need to be at the start. |
| 119 | + |
| 120 | +## Visual Feedback |
| 121 | + |
| 122 | +- **Cursor**: Thin blinking cursor in insert mode, solid block in normal mode |
| 123 | +- **Mode Indicator**: Shows current mode and pending commands (e.g., "NORMAL d" when waiting for motion) |
| 124 | + |
| 125 | +## Keybind Conflicts |
| 126 | + |
| 127 | +### ESC Key |
| 128 | +ESC is used for: |
| 129 | +1. Exiting Vim normal mode (highest priority) |
| 130 | +2. NOT used for canceling edits (use **Ctrl-Q** instead) |
| 131 | +3. NOT used for interrupting streams (use **Ctrl-C** instead) |
| 132 | + |
| 133 | + |
| 134 | + |
| 135 | +## Tips |
| 136 | + |
| 137 | +1. **Learn operators + motions**: Instead of memorizing every command, learn the operators (d, c, y) and motions (w, b, $, 0). They combine naturally. |
| 138 | + |
| 139 | +2. **Use text objects**: `ciw` to change a word is more reliable than `cw` because it works from anywhere in the word. |
| 140 | + |
| 141 | +3. **Column preservation**: When navigating up/down, your column position is preserved across lines of different lengths. |
| 142 | + |
| 143 | +## Not Yet Implemented |
| 144 | + |
| 145 | +Features that may be added in the future: |
| 146 | +- **ge** - Backward end of word motion |
| 147 | +- **f{char}**, **t{char}** - Find character motions |
| 148 | +- **i"**, **i'**, **i(**, **i[**, **i{** - More text objects |
| 149 | +- **2w**, **3dd**, **5x** - Count prefixes |
| 150 | +- **Visual mode** - Character, line, and block selection |
| 151 | +- **Macros** - Recording and replaying command sequences |
| 152 | +- **Marks** - Named cursor positions |
0 commit comments