pi-vim 0.1.9 → 0.2.1
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 +62 -60
- package/index.ts +545 -129
- package/motions.ts +55 -13
- package/package.json +1 -1
- package/types.ts +1 -1
package/README.md
CHANGED
|
@@ -1,16 +1,12 @@
|
|
|
1
|
-
# pi-vim
|
|
1
|
+
# pi-vim
|
|
2
2
|
|
|
3
|
-
Modal vim-like editing for Pi's
|
|
4
|
-
Focus: the high-frequency 90% command surface, not full Vim.
|
|
3
|
+
Modal vim-like editing for Pi's input prompt. Covers the high-frequency 90% command surface.
|
|
5
4
|
|
|
6
|
-
##
|
|
5
|
+
## why
|
|
7
6
|
|
|
8
|
-
|
|
9
|
-
- Solution: modal editing (`INSERT`/`NORMAL`) with Vim-style motions,
|
|
10
|
-
operators, counts, and repeatable workflows.
|
|
11
|
-
- Install: `pi install npm:pi-vim`
|
|
7
|
+
You love Pi, you love Vim, you'll love pi-vim.
|
|
12
8
|
|
|
13
|
-
##
|
|
9
|
+
## install
|
|
14
10
|
|
|
15
11
|
```bash
|
|
16
12
|
pi install npm:pi-vim
|
|
@@ -18,19 +14,11 @@ pi install npm:pi-vim
|
|
|
18
14
|
|
|
19
15
|
Restart Pi after install.
|
|
20
16
|
|
|
21
|
-
|
|
17
|
+
## stats
|
|
22
18
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
Or add to `.pi/settings.json`:
|
|
28
|
-
|
|
29
|
-
```json
|
|
30
|
-
{
|
|
31
|
-
"extensions": ["./pi-extensions/pi-vim/index.ts"]
|
|
32
|
-
}
|
|
33
|
-
```
|
|
19
|
+
- **112 commands**: motions, operators, counts, text objects, undo/redo
|
|
20
|
+
- **sub-µs word motions** via precomputed boundary cache (~4ms startup, ~150KB memory)
|
|
21
|
+
- **0 dependencies**
|
|
34
22
|
|
|
35
23
|
## 30-second quickstart
|
|
36
24
|
|
|
@@ -41,27 +29,28 @@ Esc # NORMAL mode
|
|
|
41
29
|
3gg # jump to absolute line 3
|
|
42
30
|
2dw # delete two words
|
|
43
31
|
u # undo
|
|
32
|
+
<C-r> # redo last undone edit (safe no-op when empty)
|
|
44
33
|
2} # jump two paragraphs forward
|
|
45
34
|
```
|
|
46
35
|
|
|
47
36
|
Mode indicator (`INSERT` / `NORMAL`) appears at bottom-right.
|
|
48
37
|
|
|
49
|
-
##
|
|
38
|
+
## why pi-vim
|
|
50
39
|
|
|
51
40
|
- Fast modal editing without leaving Pi.
|
|
52
41
|
- Count-aware motions/operators (`2dw`, `3G`, `d2j`, `2}`).
|
|
53
42
|
- Strong REPL-focused defaults; safe out-of-scope boundaries documented.
|
|
54
43
|
- Clipboard/register behavior is explicit and tested.
|
|
55
44
|
|
|
56
|
-
##
|
|
45
|
+
## for you / not for you
|
|
57
46
|
|
|
58
47
|
Use pi-vim if you want fast Vim muscle-memory in Pi prompts.
|
|
59
48
|
Skip it if you need full Vim feature parity (visual mode, macros, search,
|
|
60
49
|
ex-commands, etc.).
|
|
61
50
|
|
|
62
|
-
##
|
|
51
|
+
## common recipes
|
|
63
52
|
|
|
64
|
-
|
|
|
53
|
+
| goal | keys |
|
|
65
54
|
|------|------|
|
|
66
55
|
| Jump to exact line 25 | `25gg` (or `25G`) |
|
|
67
56
|
| Delete two words | `2dw` |
|
|
@@ -71,14 +60,15 @@ ex-commands, etc.).
|
|
|
71
60
|
| Join 3 lines with spacing | `3J` |
|
|
72
61
|
| Jump 2 paragraphs forward | `2}` |
|
|
73
62
|
| Undo last edit | `u` |
|
|
63
|
+
| Redo last undone edit | `<C-r>` |
|
|
74
64
|
|
|
75
65
|
---
|
|
76
66
|
|
|
77
|
-
##
|
|
67
|
+
## full reference
|
|
78
68
|
|
|
79
|
-
###
|
|
69
|
+
### mode switching
|
|
80
70
|
|
|
81
|
-
|
|
|
71
|
+
| key | action |
|
|
82
72
|
|----------|----------------------------------------|
|
|
83
73
|
| `Esc` / `Ctrl+[` | Insert → Normal mode |
|
|
84
74
|
| `Esc` / `Ctrl+[` | Normal mode → pass to Pi (abort agent) |
|
|
@@ -91,7 +81,7 @@ ex-commands, etc.).
|
|
|
91
81
|
|
|
92
82
|
Insert-mode shortcuts (stay in Insert mode):
|
|
93
83
|
|
|
94
|
-
|
|
|
84
|
+
| key | action |
|
|
95
85
|
|-----------------|------------------------|
|
|
96
86
|
| `Shift+Alt+A` | Go to end of line |
|
|
97
87
|
| `Shift+Alt+I` | Go to start of line |
|
|
@@ -100,11 +90,11 @@ Insert-mode shortcuts (stay in Insert mode):
|
|
|
100
90
|
|
|
101
91
|
---
|
|
102
92
|
|
|
103
|
-
###
|
|
93
|
+
### navigation (normal mode)
|
|
104
94
|
|
|
105
95
|
A `{count}` prefix can be prepended to any navigation key (max: `9999`).
|
|
106
96
|
|
|
107
|
-
|
|
|
97
|
+
| key | action |
|
|
108
98
|
|---------------|-------------------------------|
|
|
109
99
|
| `h` | Left |
|
|
110
100
|
| `l` | Right |
|
|
@@ -114,6 +104,7 @@ A `{count}` prefix can be prepended to any navigation key (max: `9999`).
|
|
|
114
104
|
| `{count}j/k` | Move down/up `{count}` lines (clamped to buffer size) |
|
|
115
105
|
| `0` | Line start |
|
|
116
106
|
| `^` | First non-whitespace char of line |
|
|
107
|
+
| `_` | First non-whitespace char; with `{count}`, move down `count - 1` lines first |
|
|
117
108
|
| `$` | Line end |
|
|
118
109
|
| `gg` | Buffer start (line 1) |
|
|
119
110
|
| `{count}gg` | Go to line `{count}` (1-indexed, clamped) |
|
|
@@ -146,11 +137,11 @@ Operator forms with braces (`d{`, `d}`, `c{`, `c}`, `y{`, `y}`) are out of scope
|
|
|
146
137
|
|
|
147
138
|
---
|
|
148
139
|
|
|
149
|
-
###
|
|
140
|
+
### character-find motions (normal mode)
|
|
150
141
|
|
|
151
142
|
A `{count}` prefix finds the Nth occurrence of `{char}` on the line.
|
|
152
143
|
|
|
153
|
-
|
|
|
144
|
+
| key | action |
|
|
154
145
|
|------------------|------------------------------------------------|
|
|
155
146
|
| `f{char}` | Jump forward to `char` (inclusive) |
|
|
156
147
|
| `F{char}` | Jump backward to `char` (inclusive) |
|
|
@@ -164,17 +155,17 @@ Char-find motions compose with operators: `df{char}`, `ct{char}`, `d{count}t{cha
|
|
|
164
155
|
|
|
165
156
|
---
|
|
166
157
|
|
|
167
|
-
###
|
|
158
|
+
### edit operators (normal mode)
|
|
168
159
|
|
|
169
160
|
All operators write to the unnamed register and mirror to the system clipboard
|
|
170
161
|
(best-effort; clipboard failure never breaks editing).
|
|
171
162
|
|
|
172
|
-
####
|
|
163
|
+
#### delete `d{motion}` / `dd`
|
|
173
164
|
|
|
174
165
|
A `{count}` or dual-count prefix (`{pfx}d{op}{motion}`) is supported for
|
|
175
166
|
word, char-find, and linewise motions. Maximum total count: `9999`.
|
|
176
167
|
|
|
177
|
-
|
|
|
168
|
+
| command | deletes |
|
|
178
169
|
|-------------------|-----------------------------------------------------------|
|
|
179
170
|
| `dw` | Forward to next `word` start (exclusive, can cross lines) |
|
|
180
171
|
| `de` | Forward to `word` end (inclusive, can cross lines) |
|
|
@@ -187,6 +178,8 @@ word, char-find, and linewise motions. Maximum total count: `9999`.
|
|
|
187
178
|
| `d$` | To end of line |
|
|
188
179
|
| `d0` | To start of line |
|
|
189
180
|
| `d^` | To first non-whitespace char of line |
|
|
181
|
+
| `d_` | Current line (linewise, same as `dd`) |
|
|
182
|
+
| `d{count}_` | `{count}` lines (linewise, same as `{count}dd`) |
|
|
190
183
|
| `dd` | Current line (linewise) |
|
|
191
184
|
| `{count}dd` | `{count}` lines (linewise) |
|
|
192
185
|
| `d{count}j` | Current line + `{count}` lines below (linewise) |
|
|
@@ -201,11 +194,11 @@ word, char-find, and linewise motions. Maximum total count: `9999`.
|
|
|
201
194
|
| `daw` | Around word (includes surrounding spaces) |
|
|
202
195
|
| `d{count}aw` | Around `{count}` words |
|
|
203
196
|
|
|
204
|
-
####
|
|
197
|
+
#### change `c{motion}` / `cc`
|
|
205
198
|
|
|
206
199
|
Same motion and count set as `d`. Deletes text then enters Insert mode.
|
|
207
200
|
|
|
208
|
-
|
|
|
201
|
+
| command | action |
|
|
209
202
|
|-----------------|------------------------------------|
|
|
210
203
|
| `cw` | Change `word` + Insert |
|
|
211
204
|
| `ce` / `cb` | Change to `word` end / previous `word` start |
|
|
@@ -216,14 +209,16 @@ Same motion and count set as `d`. Deletes text then enters Insert mode.
|
|
|
216
209
|
| `ciw` | Change inner word |
|
|
217
210
|
| `caw` | Change around word |
|
|
218
211
|
| `cc` | Delete line content + Insert |
|
|
212
|
+
| `c_` | Change line (linewise, same as `cc`) |
|
|
213
|
+
| `c{count}_` | Change `{count}` lines (linewise) |
|
|
219
214
|
| `c$` / `c0` / `c^` | Delete to EOL / BOL / first non-whitespace + Insert |
|
|
220
215
|
| … | All `d` motions apply |
|
|
221
216
|
|
|
222
|
-
####
|
|
217
|
+
#### single-key edits
|
|
223
218
|
|
|
224
219
|
A `{count}` prefix is supported for `x`, `p`, `P`. Maximum: `9999`.
|
|
225
220
|
|
|
226
|
-
|
|
|
221
|
+
| key | action |
|
|
227
222
|
|--------------|---------------------------------------------------------------|
|
|
228
223
|
| `x` | Delete char under cursor (no-op at/past EOL) |
|
|
229
224
|
| `{count}x` | Delete `{count}` chars |
|
|
@@ -231,14 +226,16 @@ A `{count}` prefix is supported for `x`, `p`, `P`. Maximum: `9999`.
|
|
|
231
226
|
| `S` | Delete line content + Insert mode |
|
|
232
227
|
| `D` | Delete cursor to EOL (captures `\n` if at EOL with next line) |
|
|
233
228
|
| `C` | Delete cursor to EOL + Insert mode |
|
|
229
|
+
| `r{char}` | Replace char under cursor with `{char}` (stays in Normal) |
|
|
230
|
+
| `{count}r{char}` | Replace next `{count}` chars with `{char}` |
|
|
234
231
|
|
|
235
232
|
---
|
|
236
233
|
|
|
237
|
-
###
|
|
234
|
+
### yank `y{motion}` / `yy`
|
|
238
235
|
|
|
239
236
|
Same motion set as `d`. Writes to register, **no text mutation**.
|
|
240
237
|
|
|
241
|
-
|
|
|
238
|
+
| command | yanks |
|
|
242
239
|
|---------|---------------------------------|
|
|
243
240
|
| `yy` | Whole line + trailing `\n` |
|
|
244
241
|
| `{count}yy` | `{count}` whole lines + trailing `\n` |
|
|
@@ -254,6 +251,8 @@ Same motion set as `d`. Writes to register, **no text mutation**.
|
|
|
254
251
|
| `y$` | To end of line |
|
|
255
252
|
| `y0` | To start of line |
|
|
256
253
|
| `y^` | To first non-whitespace char of line |
|
|
254
|
+
| `y_` | Whole line (linewise, same as `yy`) |
|
|
255
|
+
| `y{count}_` | `{count}` whole lines (linewise) |
|
|
257
256
|
| `yf{c}` | To and including `char` |
|
|
258
257
|
| `yiw` | Inner word |
|
|
259
258
|
| `yaw` | Around word (includes spaces) |
|
|
@@ -264,9 +263,9 @@ Linewise counted yank (`{count}yy`, `y{count}j/k`) remains supported.
|
|
|
264
263
|
|
|
265
264
|
---
|
|
266
265
|
|
|
267
|
-
###
|
|
266
|
+
### put / paste
|
|
268
267
|
|
|
269
|
-
|
|
|
268
|
+
| key | action |
|
|
270
269
|
|--------------|-------------------------------------------------------------|
|
|
271
270
|
| `p` | Put after cursor (char-wise) / new line below (line-wise) |
|
|
272
271
|
| `P` | Put before cursor (char-wise) / new line above (line-wise) |
|
|
@@ -278,21 +277,22 @@ Line-wise detection: register content ending in `\n` is treated as line-wise.
|
|
|
278
277
|
|
|
279
278
|
---
|
|
280
279
|
|
|
281
|
-
###
|
|
282
|
-
|
|
283
|
-
| Key | Action |
|
|
284
|
-
|-----|-------------------------------------------------|
|
|
285
|
-
| `u` | Undo — sends `ctrl+_` (`\x1f`) to the underlying readline editor |
|
|
280
|
+
### undo / redo
|
|
286
281
|
|
|
287
|
-
|
|
282
|
+
| key | action |
|
|
283
|
+
|-----|--------|
|
|
284
|
+
| `u` | Undo in normal mode |
|
|
285
|
+
| `Ctrl+_` | Undo in normal mode (alias for `u`) |
|
|
286
|
+
| `<C-r>` | Redo one undone change in normal mode; safe no-op when redo history is empty |
|
|
287
|
+
| `{count}<C-r>` | Redo up to `{count}` undone changes in order; clamps at available history and consumes count state (no leak to the next command) |
|
|
288
288
|
|
|
289
289
|
---
|
|
290
290
|
|
|
291
|
-
##
|
|
291
|
+
## register and clipboard policy
|
|
292
292
|
|
|
293
293
|
- One unnamed register (like Vim's `""` register).
|
|
294
294
|
- Every `d`, `c`, `x`, `s`, `S`, `D`, `C`, `y` operator form
|
|
295
|
-
(including `dd`, `{count}dd`, `d{count}j/k`, `dG`, `yy`, `{count}yy`,
|
|
295
|
+
(including `dd`/`d_`, `{count}dd`, `d{count}j/k`, `dG`, `yy`/`y_`, `{count}yy`,
|
|
296
296
|
`y{count}j/k`, `yG`) writes to the register and mirrors to the OS clipboard
|
|
297
297
|
(via `copyToClipboard`, best-effort).
|
|
298
298
|
- `p` / `P` read from the unnamed register only (not the OS clipboard).
|
|
@@ -300,18 +300,18 @@ Redo (`<C-r>`) is **not implemented** — see [Out of scope](#out-of-scope).
|
|
|
300
300
|
|
|
301
301
|
---
|
|
302
302
|
|
|
303
|
-
##
|
|
303
|
+
## known differences from full Vim
|
|
304
304
|
|
|
305
|
-
|
|
|
305
|
+
| area | this extension | full Vim |
|
|
306
306
|
|-----------------------|----------------------------------------|-------------------------------|
|
|
307
307
|
| `$` motion | Moves past last char (readline CTRL+E) | Moves to last char |
|
|
308
308
|
| `w` / `e` / `b` + `W` / `E` / `B` | Cross-line for `word` + `WORD` motions | Cross-line |
|
|
309
309
|
| `0` / `$` operators | Exclusive of anchor col | `0` inclusive of col 0 |
|
|
310
310
|
| Undo depth | Delegates to underlying readline undo | Full per-change undo tree |
|
|
311
|
-
| Redo |
|
|
311
|
+
| Redo | Normal-mode `<C-r>` supported (safe no-op when empty; counted redo is stepwise, clamps to available history, and preserves single-step undo granularity) | `<C-r>` |
|
|
312
312
|
| Visual mode | Not implemented | `v`, `V`, `<C-v>` |
|
|
313
313
|
| Text objects | Supports `iw`/`aw` only | Full text-object set |
|
|
314
|
-
| Count prefix | Supported for operators, word/char motions, navigation, and edits (`x`, `p`/`P`); capped at `MAX_COUNT=9999` to prevent abuse | Full support |
|
|
314
|
+
| Count prefix | Supported for operators, word/char motions, navigation, and edits (`x`, `r`, `p`/`P`); capped at `MAX_COUNT=9999` to prevent abuse | Full support |
|
|
315
315
|
| Named registers | Not implemented (`"a`, etc.) | Supported |
|
|
316
316
|
| Macros | Not implemented (`q`, `@`) | Supported |
|
|
317
317
|
| Search | Not implemented (`/`, `?`, `n`, `N`) | Supported |
|
|
@@ -320,7 +320,7 @@ Redo (`<C-r>`) is **not implemented** — see [Out of scope](#out-of-scope).
|
|
|
320
320
|
|
|
321
321
|
---
|
|
322
322
|
|
|
323
|
-
##
|
|
323
|
+
## out of scope
|
|
324
324
|
|
|
325
325
|
These are **explicitly deferred** and not planned for this feature:
|
|
326
326
|
|
|
@@ -331,15 +331,17 @@ These are **explicitly deferred** and not planned for this feature:
|
|
|
331
331
|
- Ex command surface (`:s`, `:g`, `:r`, …)
|
|
332
332
|
- Search mode (`/`, `?`, `n`, `N`)
|
|
333
333
|
- Repeat (`.`)
|
|
334
|
+
- Replace mode (`R`) — only single-char `r{char}` is supported
|
|
334
335
|
- Extended count prefix beyond currently supported motions (e.g. `:`, global operator counts)
|
|
335
|
-
-
|
|
336
|
-
|
|
336
|
+
- No insert-mode `<C-r>` feature expansion beyond current underlying-editor behavior.
|
|
337
|
+
- No cross-session redo persistence.
|
|
338
|
+
- No upstream `pi-tui` redo prerequisite in this wave.
|
|
337
339
|
- Window / tab / buffer management
|
|
338
340
|
- Plugin / runtime ecosystem compatibility
|
|
339
341
|
|
|
340
342
|
---
|
|
341
343
|
|
|
342
|
-
##
|
|
344
|
+
## architecture notes
|
|
343
345
|
|
|
344
346
|
- `index.ts` — `ModalEditor` subclass of `CustomEditor`; all key handling.
|
|
345
347
|
- `motions.ts` — pure motion calculation helpers (`findWordMotionTarget`,
|