rwb-codemirror-helix 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,331 @@
1
+ # codemirror-helix
2
+
3
+ A vibe-coded, in the sense that I literally have not looked at the code, set of Helix keybindings for CodeMirror 6.
4
+ That said, it's fairly complete and works for my purposes (read: getting Helix keybindings in Obsidian).
5
+
6
+ --- Everything past this is LLM generated; read at your own risk. ---
7
+
8
+ ## Features
9
+
10
+ - **Normal / Insert / Select modes** with block cursor and per-mode CSS classes
11
+ - **Motions**: `h j k l w b e W B E f F t T ; , Alt-. 0 Home End G %`
12
+ - **Count prefixes**: `5j`, `3w`, `10l`, …
13
+ - **g-prefix** (goto): `gg` `ge` `gh` `gl` `gs` `gt` `gc` `gb` `gj` `gk` `g.` `gw` `g|`
14
+ - **z-prefix** (view): `zz` `zt` `zb` `zj` `zk`; `Z` sticky view mode
15
+ - **m-prefix** (match/surround/text-objects): `mm` `ms` `mr` `md` `mi` `ma`
16
+ - **`[ ]` prefixes**: `]p` `[p` `]Space` `[Space`
17
+ - **Editing**: `d` `Alt-d` `c` `Alt-c` `y` `p` `P` `R` `r` `~` `` ` `` `Alt-`` ` `` `>` `<` `J` `Alt-J` `.` `u` `U` `Ctrl-a` `Ctrl-x` `&` `_`
18
+ - **Multi-cursor**: `C` `Alt-C` `s` `S` `Alt-s` `K` `Alt-K` `)` `(` `Alt-)` `Alt-(` `Alt--` `Alt-_` `Alt-,` `,`
19
+ - **Named registers**: `"ay` `"ap` — yank/paste with any letter register
20
+ - **Surround**: `ms(` `md(` `mr('`
21
+ - **Text objects**: `miw` `maw` `mi(` `ma{` `mi"` …
22
+ - **Search**: `/` `?` `n` `N` `*` `Alt-*` — regex-capable inline panel
23
+ - **Jump list**: `Ctrl-s` `Ctrl-o` `Ctrl-i`
24
+ - **Insert mode helpers**: `Ctrl-w` `Alt-Backspace` `Alt-d` `Alt-Delete` `Ctrl-h` `Ctrl-d` `Delete` `Ctrl-u` `Ctrl-k` `Ctrl-s` `Enter` `Ctrl-r`
25
+ - **Status bar** showing current mode, count, pending operation, active register, and cursor position
26
+ - **Dot-repeat** (`.`) and **undo/redo** (`u` / `U`)
27
+
28
+ ## Installation
29
+
30
+ ```bash
31
+ npm install rwb-codemirror-helix
32
+ ```
33
+
34
+ `@codemirror/state` and `@codemirror/view` are peer dependencies and must be installed separately.
35
+
36
+ ## Usage
37
+
38
+ ```ts
39
+ import { EditorView } from "@codemirror/view";
40
+ import { EditorState } from "@codemirror/state";
41
+ import { helixKeymap } from "codemirror-helix";
42
+
43
+ const view = new EditorView({
44
+ state: EditorState.create({
45
+ doc: "Hello, world!",
46
+ extensions: [
47
+ helixKeymap(),
48
+ // ... your other extensions
49
+ ],
50
+ }),
51
+ parent: document.getElementById("editor"),
52
+ });
53
+ ```
54
+
55
+ ### Options
56
+
57
+ ```ts
58
+ helixKeymap({
59
+ // Show the status bar panel at the bottom of the editor. Default: true
60
+ statusBar: true,
61
+ })
62
+ ```
63
+
64
+ ### Reading the current mode
65
+
66
+ ```ts
67
+ import { getHelixMode } from "codemirror-helix";
68
+
69
+ const mode = getHelixMode(view.state); // "normal" | "insert" | "select"
70
+ ```
71
+
72
+ You can also subscribe to mode changes via the exported `helixStateField`:
73
+
74
+ ```ts
75
+ import { helixStateField } from "codemirror-helix";
76
+
77
+ // Inside a ViewPlugin or updateListener:
78
+ const { mode } = update.state.field(helixStateField);
79
+ ```
80
+
81
+ ### CSS customisation
82
+
83
+ The editor root element receives a class for the current mode:
84
+
85
+ | Mode | Class |
86
+ |--------|-----------------------|
87
+ | Normal | `helix-mode-normal` |
88
+ | Insert | `helix-mode-insert` |
89
+ | Select | `helix-mode-select` |
90
+
91
+ Status bar colours and the block cursor can be overridden with CSS variables.
92
+ By default the status bar inherits the editor's background and foreground, so
93
+ it blends in with any theme. The mode indicator colours are chosen to be legible
94
+ on light backgrounds; override them for a dark theme:
95
+
96
+ ```css
97
+ /* Example: dark theme overrides */
98
+ .cm-editor {
99
+ --helix-status-bg: #2d2d2d;
100
+ --helix-status-fg: #ccc;
101
+ --helix-status-border: #444;
102
+ --helix-normal-color: #5af;
103
+ --helix-insert-color: #8f8;
104
+ --helix-select-color: #fa8;
105
+ --helix-count-color: #ff8;
106
+ --helix-pending-color: #aaa;
107
+ --helix-register-color: #c8f;
108
+ }
109
+ ```
110
+
111
+ ## Keybinding reference
112
+
113
+ ### Normal mode
114
+
115
+ #### Movement
116
+
117
+ | Key | Action |
118
+ |-----|--------|
119
+ | `h` / `←` | Move left |
120
+ | `l` / `→` | Move right |
121
+ | `j` / `↓` | Move down |
122
+ | `k` / `↑` | Move up |
123
+ | `w` | Next word start |
124
+ | `b` | Previous word start |
125
+ | `e` | Next word end |
126
+ | `W` `B` `E` | Same, WORD (whitespace-delimited) |
127
+ | `f<c>` | Find char forward on line |
128
+ | `F<c>` | Find char backward on line |
129
+ | `t<c>` | Till char forward (one before) |
130
+ | `T<c>` | Till char backward (one after) |
131
+ | `Alt-.` | Repeat last `f`/`F`/`t`/`T` |
132
+ | `0` / `Home` | Line start |
133
+ | `End` | Line end |
134
+ | `%` | Select entire file |
135
+ | `Ctrl-d` | Scroll half page down |
136
+ | `Ctrl-u` | Scroll half page up |
137
+ | `Ctrl-f` / `PageDown` | Scroll page down |
138
+ | `Ctrl-b` / `PageUp` | Scroll page up |
139
+
140
+ #### g-prefix (goto)
141
+
142
+ | Key | Action |
143
+ |-----|--------|
144
+ | `gg` | Go to file start (or line N with count) |
145
+ | `ge` | Go to file end |
146
+ | `gh` | Go to line start |
147
+ | `gl` | Go to line end |
148
+ | `gs` | Go to first non-whitespace |
149
+ | `gt` | Go to top of screen |
150
+ | `gc` | Go to middle of screen |
151
+ | `gb` | Go to bottom of screen |
152
+ | `gj` | Move down (same as `j`) |
153
+ | `gk` | Move up (same as `k`) |
154
+ | `g.` | Go to last modification |
155
+ | `gw` | Jump-to-word (two-key label overlay) |
156
+ | `g|` | Go to column N (1-based, with count) or line start |
157
+ | `G` | Go to last line (or line N with count) |
158
+
159
+ #### z-prefix (view)
160
+
161
+ | Key | Action |
162
+ |-----|--------|
163
+ | `zz` / `zc` | Center cursor on screen |
164
+ | `zt` | Scroll cursor to top |
165
+ | `zb` | Scroll cursor to bottom |
166
+ | `zj` / `zk` | Scroll one line down / up |
167
+ | `Z` | Enter sticky view mode (view keys stay active until `Escape`) |
168
+
169
+ #### Selection
170
+
171
+ | Key | Action |
172
+ |-----|--------|
173
+ | `v` | Enter Select mode |
174
+ | `V` | Select current line and enter Select mode |
175
+ | `x` | Select current line |
176
+ | `X` | Extend to full line bounds |
177
+ | `Alt-x` | Shrink to line content |
178
+ | `;` | Collapse selection to cursor |
179
+ | `Alt-;` | Flip selection anchor/head |
180
+ | `Alt-:` | Ensure selection is forward |
181
+ | `,` | Keep only primary selection |
182
+ | `Alt-,` | Remove primary selection |
183
+ | `)` | Rotate primary selection forward |
184
+ | `(` | Rotate primary selection backward |
185
+
186
+ #### Multi-cursor
187
+
188
+ | Key | Action |
189
+ |-----|--------|
190
+ | `C` | Copy selection to next line |
191
+ | `Alt-C` | Copy selection to previous line |
192
+ | `s` | Select within selection (regex prompt) |
193
+ | `S` | Split selection on delimiter (regex prompt) |
194
+ | `Alt-s` | Split selections on newlines |
195
+ | `K` | Keep selections matching regex |
196
+ | `Alt-K` | Remove selections matching regex |
197
+ | `Alt-_` | Merge consecutive/overlapping selections |
198
+ | `Alt--` | Merge all selections into one |
199
+ | `Alt-)` | Rotate selection contents forward |
200
+ | `Alt-(` | Rotate selection contents backward |
201
+
202
+ #### Editing
203
+
204
+ | Key | Action |
205
+ |-----|--------|
206
+ | `d` | Delete selection (yanked) |
207
+ | `Alt-d` | Delete without yanking |
208
+ | `c` | Change selection (delete + insert) |
209
+ | `Alt-c` | Change without yanking |
210
+ | `y` | Yank selection |
211
+ | `p` | Paste after |
212
+ | `P` | Paste before |
213
+ | `R` | Replace selection with yanked text |
214
+ | `r<c>` | Replace each char in selection with `<c>` |
215
+ | `u` | Undo |
216
+ | `U` | Redo |
217
+ | `J` | Join lines |
218
+ | `Alt-J` | Join lines and select the inserted space |
219
+ | `~` | Toggle case |
220
+ | `` ` `` | Lowercase selection |
221
+ | `Alt-`` ` `` | Uppercase selection |
222
+ | `>` | Indent |
223
+ | `<` | Unindent |
224
+ | `_` | Trim leading/trailing whitespace from selection |
225
+ | `.` | Repeat last change |
226
+ | `Ctrl-a` | Increment number under cursor |
227
+ | `Ctrl-x` | Decrement number under cursor |
228
+ | `Ctrl-c` | Toggle line comment |
229
+ | `&` | Align selections (insert spaces to align `from` positions) |
230
+ | `"<r>` | Select register `<r>` for next yank/paste |
231
+
232
+ #### m-prefix (match / surround / text objects)
233
+
234
+ | Key | Action |
235
+ |-----|--------|
236
+ | `mm` | Jump to matching bracket |
237
+ | `ms<c>` | Surround selection with `<c>` |
238
+ | `md<c>` | Delete surrounding `<c>` |
239
+ | `mr<from><to>` | Replace surrounding `<from>` with `<to>` |
240
+ | `miw` | Select inside word |
241
+ | `maw` | Select around word (includes trailing space) |
242
+ | `mi(` `mi[` `mi{` | Select inside bracket pair |
243
+ | `ma(` `ma[` `ma{` | Select around bracket pair |
244
+ | `mi"` `mi'` `` mi` `` | Select inside quotes |
245
+
246
+ Surround characters: `(` `)` `[` `]` `{` `}` `<` `>` and any symmetric char (e.g. `"`).
247
+
248
+ #### [ / ] prefixes
249
+
250
+ | Key | Action |
251
+ |-----|--------|
252
+ | `]p` | Move to next paragraph |
253
+ | `[p` | Move to previous paragraph |
254
+ | `]Space` | Add blank line below |
255
+ | `[Space` | Add blank line above |
256
+
257
+ #### Search
258
+
259
+ | Key | Action |
260
+ |-----|--------|
261
+ | `/` | Open search forward |
262
+ | `?` | Open search backward |
263
+ | `n` | Go to next match |
264
+ | `N` | Go to previous match |
265
+ | `*` | Search for word under cursor |
266
+ | `Alt-*` | Search for selection (no word boundaries) |
267
+
268
+ Search supports full JavaScript regex syntax.
269
+
270
+ #### Jump list
271
+
272
+ | Key | Action |
273
+ |-----|--------|
274
+ | `Ctrl-s` | Save current position to jump list |
275
+ | `Ctrl-o` | Jump back |
276
+ | `Ctrl-i` | Jump forward |
277
+
278
+ ### Insert mode
279
+
280
+ | Key | Action |
281
+ |-----|--------|
282
+ | `Escape` | Return to Normal mode |
283
+ | `Ctrl-w` / `Alt-Backspace` | Delete previous word |
284
+ | `Alt-d` / `Alt-Delete` | Delete next word |
285
+ | `Ctrl-h` | Delete previous character |
286
+ | `Ctrl-d` / `Delete` | Delete next character |
287
+ | `Ctrl-u` | Delete to line start |
288
+ | `Ctrl-k` | Delete to line end |
289
+ | `Enter` / `Ctrl-j` | New line with indentation |
290
+ | `Ctrl-s` | Commit undo checkpoint |
291
+ | `Ctrl-r<r>` | Paste from register `<r>` |
292
+
293
+ ### Entering Insert mode (from Normal)
294
+
295
+ | Key | Action |
296
+ |-----|--------|
297
+ | `i` | Insert before selection |
298
+ | `a` | Insert after selection |
299
+ | `I` | Insert at line start |
300
+ | `A` | Insert at line end |
301
+ | `o` | Open new line below |
302
+ | `O` | Open new line above |
303
+
304
+ ## Development
305
+
306
+ ```bash
307
+ # Install dependencies
308
+ npm install
309
+
310
+ # Run the demo app (hot-reloading)
311
+ npm run dev
312
+
313
+ # Run tests
314
+ npm test
315
+
316
+ # Type-check
317
+ npm run typecheck
318
+
319
+ # Build the library
320
+ npm run build
321
+ ```
322
+
323
+ ## What's not implemented
324
+
325
+ - **Macros** (`q` / `@`)
326
+ - **Command-line mode** (`:` prompt)
327
+ - **LSP commands** (`gd`, `gr`, Space-mode) — require a language server
328
+
329
+ ## License
330
+
331
+ MIT