feat: add word and WORD motions

This commit is contained in:
Valdemar Lorenzen
2026-10-06 12:26:43 +02:00
parent 3ad6ca1fe2
commit 6104b73fdb
6 changed files with 305 additions and 0 deletions
+8
View File
@@ -20,6 +20,7 @@ Without a file, vamp opens an unnamed buffer. A nonexistent file opens an empty
| Normal | `i` insert before cursor; `a` insert after cursor; `o`/`O` open line below/above |
| Normal | `I` (Shift+i) insert before the first nonblank, skipping spaces/tabs; `A` (Shift+a) insert at line end |
| Normal | `h`/`j`/`k`/`l` or arrows; `0`/`$` or Home/End |
| Normal | `w`/`b`/`e` next word start, previous/current word start, word end; `W`/`B`/`E` for whitespace-delimited WORDs |
| Normal | `J` (Shift+j) join the current line with the next line |
| Normal | `x`/Delete delete; `u` undo; `U` (Shift+u) redo; `:` enter command mode |
| Normal | `/` opens search; `n` finds the next match; `N` (Shift+n) finds the previous match |
@@ -29,6 +30,12 @@ Without a file, vamp opens an unnamed buffer. A nonexistent file opens an empty
`J` removes the next line's leading spaces/tabs and preserves existing trailing whitespace. It normally adds one space, two after `.`, `?`, or `!` (Vim's default), and none before `)` or when either side is empty. The cursor lands at the join point; the join is one undo action. On the last line, `J` does nothing.
Word motions separate runs of Unicode letters/numbers/underscore from runs of punctuation or emoji. Classification uses each grapheme's first character; combining sequences and ZWJ emoji stay intact. WORD motions treat any non-whitespace run as one WORD.
`w`/`W` move to the next start. `b`/`B` move to the current start, or the previous start when already at one. `e`/`E` move to the current end when before it, otherwise the next end. Motions cross lines but never wrap. Truly empty lines are stops for start motions; whitespace-only lines are skipped. End motions skip empty lines while looking for a word. With no further target, motions stop at the buffer edge, including trailing whitespace or an empty final line.
These keys type literal text in Insert mode. The corresponding actions can also be bound in Insert mode to move the insertion cursor without splitting its undo group. Motions never edit text, add history, or clear an active search highlight.
Search is case-sensitive and single-line, with no regular expressions or Unicode normalization. Matches start and end on whole grapheme boundaries, including combining marks and emoji. Next/previous navigation skips the current position and wraps through the buffer; a sole match wraps back to itself. The active match is highlighted yellow.
Submitting an empty search repeats the last query. Esc cancels without moving the cursor or replacing the previous query/match. A missing match reports the query, clears the highlight, and leaves the cursor unchanged; searching without a previous query also leaves the cursor unchanged. Search never edits text or adds undo history. Buffer edits and undo/redo clear the highlight but retain the query, so subsequent navigation searches the current text again.
@@ -91,6 +98,7 @@ Terminals share `ctrl+h` with `backspace`, `ctrl+i` with `tab`, and `ctrl+j`/`ct
| Normal | `join_lines`, `undo`, `redo`, `command` |
| Normal | `search`, `search_next`, `search_previous` |
| Normal, Insert | `left`, `down`, `up`, `right`, `line_start`, `line_end`, `delete` |
| Normal, Insert | `word_next`, `word_previous`, `word_end`, `big_word_next`, `big_word_previous`, `big_word_end` |
| Insert, Command, Search | `normal`, `backspace` |
| Insert | `newline` |
| Command, Search | `submit` |