pi-vim 0.9.0 → 0.11.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 +85 -78
- package/clipboard-policy.ts +7 -57
- package/index.ts +604 -309
- package/motions.ts +38 -15
- package/package.json +3 -3
- package/settings.ts +92 -0
- package/text-objects.ts +130 -82
- package/word-boundary-cache.ts +5 -4
package/README.md
CHANGED
|
@@ -12,25 +12,35 @@ Restart Pi after install.
|
|
|
12
12
|
|
|
13
13
|
## configure
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
Settings are read from `~/.pi/agent/settings.json` and project `.pi/settings.json`.
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
Default-equivalent `settings.json`:
|
|
18
18
|
|
|
19
19
|
```json
|
|
20
20
|
{
|
|
21
21
|
"piVim": {
|
|
22
|
-
"clipboardMirror": "all"
|
|
22
|
+
"clipboardMirror": "all",
|
|
23
|
+
"modeColors": {
|
|
24
|
+
"insert": "borderMuted",
|
|
25
|
+
"normal": "borderAccent",
|
|
26
|
+
"ex": "warning"
|
|
27
|
+
},
|
|
28
|
+
"syncBorderColorWithMode": false
|
|
23
29
|
}
|
|
24
30
|
}
|
|
25
31
|
```
|
|
26
32
|
|
|
27
|
-
|
|
28
|
-
|-------|----------|
|
|
29
|
-
| `all` | Mirror every unnamed-register write (default/current behavior) |
|
|
30
|
-
| `yank` | Mirror yanks only; deletes/changes update only pi-vim's internal register |
|
|
31
|
-
| `never` | Never mirror register writes to the OS clipboard |
|
|
33
|
+
All keys are optional; omitting `piVim` is equivalent. Project overrides global; project `modeColors` replaces global `modeColors`, with missing modes defaulting above.
|
|
32
34
|
|
|
33
|
-
|
|
35
|
+
`clipboardMirror`: `all` mirrors unnamed writes; `yank` mirrors yanks; `never` keeps writes internal. Non-mirrored writes stay local for `p` / `P`.
|
|
36
|
+
|
|
37
|
+
`syncBorderColorWithMode`: `false` keeps Pi thinking border; `true` follows mode colors.
|
|
38
|
+
|
|
39
|
+
### mode colors
|
|
40
|
+
|
|
41
|
+
`piVim.modeColors` accepts Pi theme foreground tokens. Missing, invalid, or unknown tokens use defaults above.
|
|
42
|
+
|
|
43
|
+
Usual/safest: `accent`, `border`, `borderAccent`, `borderMuted`, `success`, `error`, `warning`, `muted`, `dim`, `text`, `thinkingText`.
|
|
34
44
|
|
|
35
45
|
## wrapping pi-vim
|
|
36
46
|
|
|
@@ -55,7 +65,7 @@ npm run hooks:install
|
|
|
55
65
|
|
|
56
66
|
## stats
|
|
57
67
|
|
|
58
|
-
- **
|
|
68
|
+
- **192 commands**: motions, operators, counts, text objects, undo/redo, ex quit
|
|
59
69
|
- **sub-µs word motions** via precomputed boundary cache (~4ms startup, ~150KB memory)
|
|
60
70
|
- **0 dependencies**
|
|
61
71
|
|
|
@@ -72,7 +82,7 @@ u # undo
|
|
|
72
82
|
2} # jump two paragraphs forward
|
|
73
83
|
```
|
|
74
84
|
|
|
75
|
-
Mode indicator (`INSERT` / `NORMAL` / `EX`) appears bottom-right, theme-colored.
|
|
85
|
+
Mode indicator (`INSERT` / `NORMAL` / `EX`) appears bottom-right, theme-colored and configurable.
|
|
76
86
|
|
|
77
87
|
Requires `@mariozechner/pi-tui >= 0.47.0`. With `pi-tui >= 0.49.3` and DECSCUSR support, cursor shape follows mode; otherwise software cursor remains.
|
|
78
88
|
|
|
@@ -83,13 +93,12 @@ Requires `@mariozechner/pi-tui >= 0.47.0`. With `pi-tui >= 0.49.3` and DECSCUSR
|
|
|
83
93
|
- REPL-focused defaults; out-of-scope boundaries documented.
|
|
84
94
|
- Clipboard/register behavior is explicit and tested.
|
|
85
95
|
|
|
86
|
-
Use pi-vim for
|
|
87
|
-
full Vim parity (visual mode, macros, search, extended ex-commands, …).
|
|
96
|
+
Use pi-vim for Vim muscle-memory in Pi prompts. Skip it if you need full Vim parity (visual mode, macros, search, extended ex-commands, …).
|
|
88
97
|
|
|
89
98
|
## common recipes
|
|
90
99
|
|
|
91
100
|
| goal | keys |
|
|
92
|
-
|
|
101
|
+
|---|---|
|
|
93
102
|
| Jump to exact line 25 | `25gg` (or `25G`) |
|
|
94
103
|
| Delete two words | `2dw` |
|
|
95
104
|
| Change current whitespace-delimited WORD | `ciW` |
|
|
@@ -111,19 +120,19 @@ full Vim parity (visual mode, macros, search, extended ex-commands, …).
|
|
|
111
120
|
|
|
112
121
|
### mode switching
|
|
113
122
|
|
|
114
|
-
| key
|
|
115
|
-
|
|
116
|
-
| `Esc` / `Ctrl+[` | Insert → Normal mode
|
|
123
|
+
| key | action |
|
|
124
|
+
|---|---|
|
|
125
|
+
| `Esc` / `Ctrl+[` | Insert → Normal mode |
|
|
117
126
|
| `Esc` / `Ctrl+[` | Normal mode → pass to Pi (aborts the agent under default Pi keybindings) |
|
|
118
|
-
| `:`
|
|
119
|
-
| `i`
|
|
120
|
-
| `a`
|
|
121
|
-
| `I`
|
|
122
|
-
| `A`
|
|
123
|
-
| `o`
|
|
124
|
-
| `O`
|
|
127
|
+
| `:` | Normal → EX mini-mode |
|
|
128
|
+
| `i` | Normal → Insert at cursor |
|
|
129
|
+
| `a` | Normal → Insert after cursor |
|
|
130
|
+
| `I` | Normal → Insert at first non-whitespace |
|
|
131
|
+
| `A` | Normal → Insert at line end |
|
|
132
|
+
| `o` | Normal → open line below + Insert |
|
|
133
|
+
| `O` | Normal → open line above + Insert |
|
|
125
134
|
|
|
126
|
-
Optional:
|
|
135
|
+
Optional: move Pi's `app.interrupt` off bare `escape` in `~/.pi/agent/keybindings.json` if it overlaps with Insert→Normal; user config wins.
|
|
127
136
|
|
|
128
137
|
#### ex mini-mode
|
|
129
138
|
|
|
@@ -143,45 +152,48 @@ Quit-only ex flows.
|
|
|
143
152
|
|
|
144
153
|
Insert-mode shortcuts (stay in Insert mode):
|
|
145
154
|
|
|
146
|
-
| key
|
|
147
|
-
|
|
148
|
-
| `Shift+Alt+A`
|
|
149
|
-
| `Shift+Alt+I`
|
|
150
|
-
| `Alt+o`
|
|
151
|
-
| `Alt+Shift+O`
|
|
155
|
+
| key | action |
|
|
156
|
+
|---|---|
|
|
157
|
+
| `Shift+Alt+A` | Go to end of line |
|
|
158
|
+
| `Shift+Alt+I` | Go to start of line |
|
|
159
|
+
| `Alt+o` | Open line below |
|
|
160
|
+
| `Alt+Shift+O` | Open line above |
|
|
152
161
|
|
|
153
162
|
---
|
|
154
163
|
|
|
155
164
|
### navigation (normal mode)
|
|
156
165
|
|
|
157
|
-
|
|
166
|
+
Most navigation keys accept a `{count}` prefix (max: `9999`); `%` intentionally does not.
|
|
158
167
|
|
|
159
168
|
| key | action |
|
|
160
|
-
|
|
169
|
+
|---|---|
|
|
161
170
|
| `h` / `l` / `j` / `k`; `{count}h/l/j/k` | Move left/right/down/up; line moves clamp to the buffer |
|
|
162
171
|
| `0` / `^` / `_` / `$` | Line start / first non-whitespace / counted first non-whitespace / line end |
|
|
163
172
|
| `gg` / `G`; `{count}gg` / `{count}G` | Buffer start/end or absolute 1-indexed line |
|
|
164
173
|
| `w` / `b` / `e`; `{count}w/b/e` | `word` start/back/end motions |
|
|
165
174
|
| `W` / `B` / `E`; `{count}W/B/E` | whitespace-delimited `WORD` motions |
|
|
166
175
|
| `{` / `}`; `{count}{` / `{count}}` | Previous/next paragraph start |
|
|
176
|
+
| `%` | Jump to the matching `()`, `[]`, or `{}` partner |
|
|
167
177
|
|
|
168
178
|
`word` splits punctuation from keyword chars; `WORD` treats any non-whitespace run as one token (`foo-bar`, `path/to`). Paragraph starts are non-blank lines at BOF or after blank lines (`^\s*$`). `{` / `}` are navigation-only; brace operator forms (`d{`, `c}`, `y{`, …) are out of scope.
|
|
169
179
|
|
|
180
|
+
`%` uses a delimiter under the cursor or scans forward on the current logical line. It matches `()`, `[]`, `{}` buffer-wide with lexical, nested, same-delimiter, parser-unaware matching; quotes/comments and mixed delimiters are not special. Missing/unmatched sources no-op. Counts are unsupported: `{count}%` consumes the count and no-ops; counted `d%` / `y%` / `c%` cancel without writes.
|
|
181
|
+
|
|
170
182
|
---
|
|
171
183
|
|
|
172
184
|
### character-find motions (normal mode)
|
|
173
185
|
|
|
174
186
|
A `{count}` prefix finds the Nth occurrence of `{char}` on the line.
|
|
175
187
|
|
|
176
|
-
| key
|
|
177
|
-
|
|
178
|
-
| `f{char}`
|
|
179
|
-
| `F{char}`
|
|
180
|
-
| `t{char}`
|
|
181
|
-
| `T{char}`
|
|
182
|
-
| `{count}f{char}` | Jump to Nth occurrence of `char` forward
|
|
183
|
-
| `;`
|
|
184
|
-
| `,`
|
|
188
|
+
| key | action |
|
|
189
|
+
|---|---|
|
|
190
|
+
| `f{char}` | Jump forward to `char` (inclusive) |
|
|
191
|
+
| `F{char}` | Jump backward to `char` (inclusive) |
|
|
192
|
+
| `t{char}` | Jump forward to one before `char` (exclusive) |
|
|
193
|
+
| `T{char}` | Jump backward to one after `char` (exclusive) |
|
|
194
|
+
| `{count}f{char}` | Jump to Nth occurrence of `char` forward |
|
|
195
|
+
| `;` | Repeat last `f/F/t/T` motion |
|
|
196
|
+
| `,` | Repeat last motion in reverse direction |
|
|
185
197
|
|
|
186
198
|
Char-find motions compose with operators: `df{char}`, `ct{char}`, `d{count}t{char}`, etc.
|
|
187
199
|
|
|
@@ -196,7 +208,7 @@ Register-writing edits write to the unnamed register. With the default clipboard
|
|
|
196
208
|
Text objects compose as `d`/`c`/`y` + `i`/`a` + object. `i` means inner; `a` means around.
|
|
197
209
|
|
|
198
210
|
| object | keys | range |
|
|
199
|
-
|
|
211
|
+
|---|---|---|
|
|
200
212
|
| word | `iw` / `aw` | Keyword word; `aw` includes spaces |
|
|
201
213
|
| WORD | `iW` / `aW` | Line-local whitespace-delimited WORD; `aW` includes adjacent whitespace |
|
|
202
214
|
| quotes | `i"` / `a"`, `i'` / `a'`, <code>i`</code> / <code>a`</code> | Smallest containing quote pair on the line |
|
|
@@ -217,12 +229,13 @@ A `{count}` or dual-count prefix (`{pfx}d{op}{motion}`) is supported for word,
|
|
|
217
229
|
WORD, char-find, and linewise motions. Maximum total count: `9999`.
|
|
218
230
|
|
|
219
231
|
| command | deletes |
|
|
220
|
-
|
|
232
|
+
|---|---|
|
|
221
233
|
| `dw` / `de` / `db`; `dW` / `dE` / `dB` | word/WORD motion ranges; `{count}` repeats |
|
|
222
234
|
| `d$` / `d0` / `d^` | To EOL / BOL / first non-whitespace |
|
|
223
235
|
| `d_` / `dd`; `d{count}_` / `{count}dd` | Current or counted whole lines |
|
|
224
236
|
| `d{count}j` / `d{count}k` / `dG` | Linewise down/up/to EOF |
|
|
225
237
|
| `df{c}` / `dt{c}` / `dF{c}` / `dT{c}`; `d{count}f{c}` | Char-find ranges |
|
|
238
|
+
| `d%` | Inclusive range through the matching pair target |
|
|
226
239
|
| `diw` / `daw`; `diW` / `daW` | Inner/around word or WORD |
|
|
227
240
|
| `d{count}iw` / `d{count}iW`; `d{count}aw` / `d{count}aW` | Counted word/WORD text objects |
|
|
228
241
|
| `di"` / `da"` (`'`, <code>`</code>) | Inside/around quotes |
|
|
@@ -233,7 +246,7 @@ WORD, char-find, and linewise motions. Maximum total count: `9999`.
|
|
|
233
246
|
Same motion and count set as `d`. Deletes text then enters Insert mode.
|
|
234
247
|
|
|
235
248
|
| command | action |
|
|
236
|
-
|
|
249
|
+
|---|---|
|
|
237
250
|
| `cw` / `ce` / `cb`; `cW` / `cE` / `cB` | Change word/WORD motion ranges + Insert |
|
|
238
251
|
| `c{count}w/e/b`; `c{count}W/E/B` | Change counted word/WORD motions + Insert |
|
|
239
252
|
| `ciw` / `caw`; `ciW` / `caW` | Change word/WORD text objects + Insert |
|
|
@@ -242,22 +255,23 @@ Same motion and count set as `d`. Deletes text then enters Insert mode.
|
|
|
242
255
|
| `ci(` / `ca(`, `ci[` / `ca[`, `ci{` / `ca{` | Change inside/around brackets + Insert |
|
|
243
256
|
| `cc` / `c_`; `c{count}_` | Change current or counted whole lines + Insert |
|
|
244
257
|
| `c$` / `c0` / `c^` | Delete to EOL / BOL / first non-whitespace + Insert |
|
|
258
|
+
| `c%` | Change inclusive range through the matching pair target + Insert |
|
|
245
259
|
| … | All `d` motions apply |
|
|
246
260
|
|
|
247
261
|
#### single-key edits
|
|
248
262
|
|
|
249
263
|
A `{count}` prefix is supported for `x`, `p`, `P`. Maximum: `9999`.
|
|
250
264
|
|
|
251
|
-
| key
|
|
252
|
-
|
|
253
|
-
| `x`
|
|
254
|
-
| `{count}x`
|
|
255
|
-
| `s`
|
|
256
|
-
| `S`
|
|
257
|
-
| `D`
|
|
258
|
-
| `C`
|
|
259
|
-
| `r{char}`
|
|
260
|
-
| `{count}r{char}` | Replace next `{count}` chars with `{char}`
|
|
265
|
+
| key | action |
|
|
266
|
+
|---|---|
|
|
267
|
+
| `x` | Delete char under cursor (no-op at/past EOL) |
|
|
268
|
+
| `{count}x` | Delete `{count}` chars |
|
|
269
|
+
| `s` | Delete char under cursor + Insert mode |
|
|
270
|
+
| `S` | Delete line content + Insert mode |
|
|
271
|
+
| `D` | Delete cursor to EOL (captures `\n` if at EOL with next line) |
|
|
272
|
+
| `C` | Delete cursor to EOL + Insert mode |
|
|
273
|
+
| `r{char}` | Replace char under cursor with `{char}` (stays in Normal) |
|
|
274
|
+
| `{count}r{char}` | Replace next `{count}` chars with `{char}` |
|
|
261
275
|
|
|
262
276
|
---
|
|
263
277
|
|
|
@@ -266,11 +280,12 @@ A `{count}` prefix is supported for `x`, `p`, `P`. Maximum: `9999`.
|
|
|
266
280
|
Same motion set as `d`. Writes to register, **no text mutation**.
|
|
267
281
|
|
|
268
282
|
| command | yanks |
|
|
269
|
-
|
|
283
|
+
|---|---|
|
|
270
284
|
| `yy` / `Y`; `{count}yy` / `{count}Y` | Whole line(s) + trailing `\n` |
|
|
271
285
|
| `y{count}j` / `y{count}k` / `yG`; `y_` / `y{count}_` | Linewise ranges |
|
|
272
286
|
| `yw` / `ye` / `yb`; `yW` / `yE` / `yB` | word/WORD motion ranges |
|
|
273
287
|
| `y$` / `y0` / `y^`; `yf{c}` | EOL / BOL / first non-whitespace / char-find |
|
|
288
|
+
| `y%` | Inclusive range through the matching pair target |
|
|
274
289
|
| `yiw` / `yaw`; `yiW` / `yaW` | Inner/around word or WORD |
|
|
275
290
|
| `yi"` / `ya"` (`'`, <code>`</code>) | Inside/around quotes |
|
|
276
291
|
| `yi(` / `ya(`, `yi[` / `ya[`, `yi{` / `ya{` | Inside/around brackets; aliases `)`, `]`, `}`, `b`, `B` |
|
|
@@ -284,12 +299,12 @@ implemented and cancel the pending operator. Linewise counted yank (`{count}yy`,
|
|
|
284
299
|
|
|
285
300
|
### put / paste
|
|
286
301
|
|
|
287
|
-
| key
|
|
288
|
-
|
|
289
|
-
| `p`
|
|
290
|
-
| `P`
|
|
291
|
-
| `{count}p`
|
|
292
|
-
| `{count}P`
|
|
302
|
+
| key | action |
|
|
303
|
+
|---|---|
|
|
304
|
+
| `p` | Put after cursor (char-wise) / new line below (line-wise) |
|
|
305
|
+
| `P` | Put before cursor (char-wise) / new line above (line-wise) |
|
|
306
|
+
| `{count}p` | Put `{count}` times after cursor |
|
|
307
|
+
| `{count}P` | Put `{count}` times before cursor |
|
|
293
308
|
|
|
294
309
|
Put reads the OS clipboard first unless the last local register write was not mirrored. Paste text ending in `\n` is line-wise.
|
|
295
310
|
|
|
@@ -323,13 +338,14 @@ Put reads the OS clipboard first unless the last local register write was not mi
|
|
|
323
338
|
## known differences from full Vim
|
|
324
339
|
|
|
325
340
|
| area | this extension | full Vim |
|
|
326
|
-
|
|
341
|
+
|---|---|---|
|
|
327
342
|
| `$` motion | Moves past the last char (readline `Ctrl+E`) | Moves to the last char |
|
|
328
343
|
| `w` / `e` / `b` + `W` / `E` / `B` | Cross-line for both `word` and `WORD` motions | Cross-line |
|
|
329
344
|
| `0` / `$` operators | Exclusive of the anchor col | `0` is inclusive of col 0 |
|
|
330
345
|
| Undo / redo | Delegates undo to readline; normal-mode `<C-r>` redo is supported | Full per-change undo tree |
|
|
331
346
|
| Visual mode | Not implemented | `v`, `V`, `<C-v>` |
|
|
332
347
|
| Text objects | `iw` / `aw`, `iW` / `aW`, quote objects, and paren/bracket/brace objects; delimited counts cancel | Full text-object set |
|
|
348
|
+
| `%` matching | `()`, `[]`, `{}` only; lexical same-delimiter matching with no counts, quote/angle matching, parser/matchit logic, mixed-delimiter validation, or Visual `%` yet | Also supports percentage jumps and broader matching |
|
|
333
349
|
| Count prefix | Operators, motions, navigation, `x`, `r`, `p`, `P`; capped at `MAX_COUNT=9999` | Full support |
|
|
334
350
|
| Registers / macros / search | Not implemented | Supported |
|
|
335
351
|
| Ex commands | Quit-only EX mini-mode (`:q`, `:q!`, `:qa`, `:qa!`) | Full ex command-line surface |
|
|
@@ -341,18 +357,18 @@ Put reads the OS clipboard first unless the last local register write was not mi
|
|
|
341
357
|
|
|
342
358
|
Explicitly deferred:
|
|
343
359
|
|
|
344
|
-
- Visual modes (`v`, `V`, block visual)
|
|
360
|
+
- Visual modes (`v`, `V`, block visual), including Visual `%`
|
|
345
361
|
- Tag text objects (`it`, `at`)
|
|
346
362
|
- Paragraph/sentence text objects (`ip`, `ap`, `is`, `as`)
|
|
347
|
-
- Angle bracket text objects (`i<`, `a<`)
|
|
363
|
+
- Angle bracket text objects (`i<`, `a<`) or angle-bracket `%` matching
|
|
348
364
|
- Visual-mode text-object selection
|
|
349
|
-
-
|
|
365
|
+
- Quote matching via `%`, parser-aware delimiter matching, matchit-style matching, and mixed-delimiter structural validation
|
|
350
366
|
- Delimited-object counts (`d2i"`, `2ci(`, `y2a{`)
|
|
351
367
|
- Named registers (`"a`, `"b`, …), macros (`q{char}`, `@{char}`)
|
|
352
368
|
- Ex surface beyond quit (`:s`, `:g`, `:w`, `:r`, …)
|
|
353
369
|
- Search (`/`, `?`, `n`, `N`), repeat (`.`)
|
|
354
370
|
- Replace mode (`R`) — only `r{char}` is supported
|
|
355
|
-
- Count prefix beyond currently supported motions
|
|
371
|
+
- Count prefix beyond currently supported motions, including `{count}%` percent-of-file jumps
|
|
356
372
|
- No insert-mode `<C-r>` expansion, no cross-session redo persistence
|
|
357
373
|
- No upstream `pi-tui` redo prerequisite
|
|
358
374
|
- Window / tab / buffer management, plugin ecosystem compatibility
|
|
@@ -361,15 +377,6 @@ Explicitly deferred:
|
|
|
361
377
|
|
|
362
378
|
## architecture notes
|
|
363
379
|
|
|
364
|
-
- `index.ts`
|
|
365
|
-
- `motions.ts` — pure motion calculation helpers (`findWordMotionTarget`,
|
|
366
|
-
`findCharMotionTarget`); no side effects.
|
|
367
|
-
- `types.ts` — shared types and escape-sequence constants.
|
|
368
|
-
- `test/` — Node test runner suite; no browser / full runtime required.
|
|
380
|
+
- `index.ts` handles modal keys; `motions.ts` and `text-objects.ts` hold pure range logic; `types.ts` holds shared types/constants; `test/` uses Node's runner.
|
|
369
381
|
|
|
370
|
-
Run checks
|
|
371
|
-
|
|
372
|
-
```
|
|
373
|
-
cd pi-vim
|
|
374
|
-
npm run check
|
|
375
|
-
```
|
|
382
|
+
Run checks with `npm run check`.
|
package/clipboard-policy.ts
CHANGED
|
@@ -1,73 +1,23 @@
|
|
|
1
|
-
import { SettingsManager } from "@mariozechner/pi-coding-agent";
|
|
2
|
-
|
|
3
1
|
export type ClipboardMirrorPolicy = "all" | "yank" | "never";
|
|
4
2
|
export type RegisterWriteSource = "mutation" | "yank";
|
|
5
|
-
|
|
6
3
|
export const DEFAULT_CLIPBOARD_MIRROR_POLICY: ClipboardMirrorPolicy = "all";
|
|
7
4
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
type UnknownRecord = Record<string, unknown>;
|
|
11
|
-
|
|
12
|
-
const missing = Symbol();
|
|
13
|
-
|
|
14
|
-
function formatInvalid(value: unknown) {
|
|
15
|
-
const type = value === null ? "null" : Array.isArray(value) ? "array" : typeof value;
|
|
5
|
+
function fmt(v: unknown) {
|
|
6
|
+
const type = v === null ? "null" : Array.isArray(v) ? "array" : typeof v;
|
|
16
7
|
try {
|
|
17
|
-
return `${JSON.stringify(
|
|
8
|
+
return `${JSON.stringify(v) ?? type} (type ${type})`;
|
|
18
9
|
} catch {
|
|
19
10
|
return `(type ${type})`;
|
|
20
11
|
}
|
|
21
12
|
}
|
|
22
13
|
|
|
23
|
-
function readSetting(settings: unknown): unknown {
|
|
24
|
-
if (typeof settings !== "object" || settings === null || !Object.hasOwn(settings, "piVim")) return missing;
|
|
25
|
-
const piVim = (settings as UnknownRecord).piVim;
|
|
26
|
-
if (typeof piVim !== "object" || piVim === null || Array.isArray(piVim)) return piVim;
|
|
27
|
-
return Object.hasOwn(piVim, "clipboardMirror") ? (piVim as UnknownRecord).clipboardMirror : missing;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
14
|
export function resolveClipboardMirrorPolicy(value: unknown) {
|
|
31
15
|
if (value === undefined) return { policy: DEFAULT_CLIPBOARD_MIRROR_POLICY };
|
|
32
|
-
|
|
33
|
-
if (
|
|
34
|
-
|
|
35
|
-
if (policy === "all" || policy === "yank" || policy === "never") {
|
|
36
|
-
return { policy: policy as ClipboardMirrorPolicy };
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
16
|
+
const p = typeof value === "string" ? value.trim().toLowerCase() : "";
|
|
17
|
+
if (p === "all" || p === "yank" || p === "never")
|
|
18
|
+
return { policy: p as ClipboardMirrorPolicy };
|
|
40
19
|
return {
|
|
41
20
|
policy: DEFAULT_CLIPBOARD_MIRROR_POLICY,
|
|
42
|
-
warning: `Invalid piVim.clipboardMirror ${
|
|
43
|
-
};
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
export function readPiVimClipboardMirrorSetting(globalSettings: unknown, projectSettings: unknown): unknown | undefined {
|
|
47
|
-
const project = readSetting(projectSettings);
|
|
48
|
-
if (project !== missing) return project;
|
|
49
|
-
const global = readSetting(globalSettings);
|
|
50
|
-
return global === missing ? undefined : global;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
function readPiVimSettingsFromDisk(cwd: string): PiVimSettings {
|
|
54
|
-
const settings = SettingsManager.create(cwd);
|
|
55
|
-
return {
|
|
56
|
-
clipboardMirror: readPiVimClipboardMirrorSetting(settings.getGlobalSettings(), settings.getProjectSettings()),
|
|
57
|
-
};
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
let piVimSettingsReader = readPiVimSettingsFromDisk;
|
|
61
|
-
|
|
62
|
-
export function readPiVimSettings(cwd: string) {
|
|
63
|
-
return piVimSettingsReader(cwd);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
export function setPiVimSettingsReaderForTests(reader: typeof readPiVimSettingsFromDisk) {
|
|
67
|
-
const prev = piVimSettingsReader;
|
|
68
|
-
piVimSettingsReader = reader;
|
|
69
|
-
|
|
70
|
-
return () => {
|
|
71
|
-
piVimSettingsReader = prev;
|
|
21
|
+
warning: `Invalid piVim.clipboardMirror ${fmt(value)}; expected all, yank, never.`,
|
|
72
22
|
};
|
|
73
23
|
}
|