vim-prose 0.1.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.
Files changed (33) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +264 -0
  3. package/dist/extensions/vim/commands.d.ts +26 -0
  4. package/dist/extensions/vim/commands.js +231 -0
  5. package/dist/extensions/vim/commands.js.map +1 -0
  6. package/dist/extensions/vim/index.d.ts +3 -0
  7. package/dist/extensions/vim/index.js +2 -0
  8. package/dist/extensions/vim/index.js.map +1 -0
  9. package/dist/extensions/vim/keyHandler.d.ts +6 -0
  10. package/dist/extensions/vim/keyHandler.js +1400 -0
  11. package/dist/extensions/vim/keyHandler.js.map +1 -0
  12. package/dist/extensions/vim/motions.d.ts +80 -0
  13. package/dist/extensions/vim/motions.js +437 -0
  14. package/dist/extensions/vim/motions.js.map +1 -0
  15. package/dist/extensions/vim/operators.d.ts +36 -0
  16. package/dist/extensions/vim/operators.js +350 -0
  17. package/dist/extensions/vim/operators.js.map +1 -0
  18. package/dist/extensions/vim/state.d.ts +8 -0
  19. package/dist/extensions/vim/state.js +174 -0
  20. package/dist/extensions/vim/state.js.map +1 -0
  21. package/dist/extensions/vim/tiptap.d.ts +17 -0
  22. package/dist/extensions/vim/tiptap.js +49 -0
  23. package/dist/extensions/vim/types.d.ts +55 -0
  24. package/dist/extensions/vim/types.js +29 -0
  25. package/dist/extensions/vim/types.js.map +1 -0
  26. package/dist/extensions/vim/utils.d.ts +76 -0
  27. package/dist/extensions/vim/utils.js +224 -0
  28. package/dist/extensions/vim/utils.js.map +1 -0
  29. package/dist/extensions/vim/vim-mode.css +81 -0
  30. package/dist/extensions/vim/visual.d.ts +15 -0
  31. package/dist/extensions/vim/visual.js +58 -0
  32. package/dist/extensions/vim/visual.js.map +1 -0
  33. package/package.json +64 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,264 @@
1
+ # vim-prose
2
+
3
+ A Vim keybinding extension for [Tiptap v3](https://tiptap.dev) / ProseMirror. Implements a useful subset of Vim modal editing directly in a rich-text editor, treating each paragraph node as a Vim "line".
4
+
5
+ Built from scratch against the ProseMirror API — no third-party vim emulation library.
6
+
7
+ ---
8
+
9
+ ## Installation
10
+
11
+ ```bash
12
+ npm install vim-prose
13
+ ```
14
+
15
+ Peer dependencies: `prosemirror-state`, `prosemirror-view`, `prosemirror-model`
16
+
17
+ ---
18
+
19
+ ## Usage
20
+
21
+ ### With Tiptap v3
22
+
23
+ ```typescript
24
+ import { VimMode } from 'vim-prose/tiptap'
25
+ import { Editor } from '@tiptap/core'
26
+ import StarterKit from '@tiptap/starter-kit'
27
+
28
+ const editor = new Editor({
29
+ extensions: [StarterKit, VimMode],
30
+ })
31
+ ```
32
+
33
+ Read the current mode and status (e.g. to render a status bar):
34
+
35
+ ```typescript
36
+ import { getVimMode, getVimStatus } from 'vim-prose/tiptap'
37
+
38
+ const mode = getVimMode(editor) // 'normal' | 'insert' | 'visual' | 'visual-line'
39
+ const status = getVimStatus(editor) // e.g. '3/14', 'mark a set', ''
40
+ ```
41
+
42
+ ### With ProseMirror directly
43
+
44
+ ```typescript
45
+ import { createVimPlugin } from 'vim-prose'
46
+ import { EditorState } from 'prosemirror-state'
47
+ import { history, undo, redo } from 'prosemirror-history'
48
+
49
+ const vimPlugin = createVimPlugin({
50
+ undo: () => undo(view.state, view.dispatch),
51
+ redo: () => redo(view.state, view.dispatch),
52
+ indent: () => {
53
+ /* your indent logic */ return true
54
+ },
55
+ outdent: () => {
56
+ /* your outdent logic */ return true
57
+ },
58
+ })
59
+
60
+ const state = EditorState.create({
61
+ plugins: [history(), vimPlugin],
62
+ })
63
+ ```
64
+
65
+ ### Optional CSS
66
+
67
+ Import the bundled CSS for basic mode-indicator styling:
68
+
69
+ ```css
70
+ @import 'vim-prose/style.css';
71
+ ```
72
+
73
+ ---
74
+
75
+ ## Supported Features
76
+
77
+ ### Modes
78
+
79
+ | Mode | Description |
80
+ | ------------- | ------------------------------------------------------- |
81
+ | `normal` | Default mode — motions, operators, commands |
82
+ | `insert` | Native editor input; only `Esc`/`Ctrl-c` is intercepted |
83
+ | `visual` | Characterwise selection |
84
+ | `visual-line` | Linewise (full paragraph) selection |
85
+
86
+ ### Mode Switching
87
+
88
+ | Key | Action |
89
+ | ---------------- | ------------------------------------------ |
90
+ | `i` | Insert before cursor |
91
+ | `I` | Insert at first non-blank character |
92
+ | `a` | Insert after cursor |
93
+ | `A` | Insert at end of line |
94
+ | `v` | Enter / toggle characterwise visual mode |
95
+ | `V` | Enter / toggle visual-line mode |
96
+ | `Esc` / `Ctrl-c` | Return to normal mode; clear pending state |
97
+
98
+ ### Motions
99
+
100
+ Work in normal mode, visual mode, and operator-pending mode.
101
+
102
+ | Key | Motion |
103
+ | --------- | ----------------------------------------------------------- |
104
+ | `h` / `l` | Left / right by character |
105
+ | `j` / `k` | Down / up by line (paragraph) |
106
+ | `0` | Start of line |
107
+ | `^` | First non-blank character of line |
108
+ | `$` | End of line |
109
+ | `gg` | Start of document |
110
+ | `G` | End of document |
111
+ | `w` | Forward by word |
112
+ | `b` | Backward by word |
113
+ | `f{char}` | Forward to next occurrence of char on line (inclusive) |
114
+ | `F{char}` | Backward to previous occurrence of char on line (inclusive) |
115
+ | `t{char}` | Forward till char (exclusive — stops one before) |
116
+ | `T{char}` | Backward till char (exclusive — stops one after) |
117
+ | `Ctrl-d` | Half-page down |
118
+ | `Ctrl-u` | Half-page up |
119
+ | `Ctrl-f` | Full-page down |
120
+ | `Ctrl-b` | Full-page up |
121
+
122
+ ### Operators
123
+
124
+ Operators combine with motions and text objects in normal mode, or act on the selection in visual mode.
125
+
126
+ | Operator | Action |
127
+ | -------- | ----------------------------------- |
128
+ | `d` | Delete |
129
+ | `y` | Yank (copy to register) |
130
+ | `c` | Change (delete + enter insert mode) |
131
+
132
+ Examples: `dw`, `y$`, `ciw`, `da(`, `df,`
133
+
134
+ ### Linewise Shortcuts
135
+
136
+ | Key | Action |
137
+ | ---- | ------------------------------------------------- |
138
+ | `dd` | Delete current line |
139
+ | `yy` | Yank current line |
140
+ | `cc` | Change current line (clear content, enter insert) |
141
+ | `D` | Delete to end of line |
142
+ | `Y` | Yank to end of line |
143
+ | `C` | Change to end of line |
144
+
145
+ ### Text Objects
146
+
147
+ Used with operators (`d`, `y`, `c`) or in visual mode.
148
+
149
+ | Object | Inner (`i`) | Around (`a`) |
150
+ | -------------- | ----------- | ------------------- |
151
+ | Word | `iw` | `aw` (same as `iw`) |
152
+ | Parentheses | `i(` / `i)` | `a(` / `a)` |
153
+ | Brackets | `i[` / `i]` | `a[` / `a]` |
154
+ | Braces | `i{` / `i}` | `a{` / `a}` |
155
+ | Angle brackets | `i<` / `i>` | `a<` / `a>` |
156
+ | Single quotes | `i'` | `a'` |
157
+ | Double quotes | `i"` | `a"` |
158
+ | Backticks | `` i` `` | `` a` `` |
159
+
160
+ `i` selects content inside delimiters; `a` includes the delimiters themselves.
161
+
162
+ ### Editing Commands
163
+
164
+ | Key | Action |
165
+ | ---- | ---------------------------------------------------------------- |
166
+ | `x` | Delete character under cursor |
167
+ | `p` | Paste register after cursor (linewise: inserts paragraph below) |
168
+ | `P` | Paste register before cursor (linewise: inserts paragraph above) |
169
+ | `o` | Open new line below, enter insert mode |
170
+ | `O` | Open new line above, enter insert mode |
171
+ | `J` | Join current line with the next line |
172
+ | `>>` | Indent current line (list item sink) |
173
+ | `<<` | Outdent current line (list item lift) |
174
+
175
+ ### Undo / Redo
176
+
177
+ | Key | Action |
178
+ | -------- | ------ |
179
+ | `u` | Undo |
180
+ | `Ctrl-r` | Redo |
181
+
182
+ ### Search
183
+
184
+ | Key | Action |
185
+ | --- | --------------------------------------------------- |
186
+ | `/` | Open search bar, type query, press Enter to search |
187
+ | `n` | Jump to next search match (wraps around) |
188
+ | `N` | Jump to previous search match (wraps around) |
189
+ | `*` | Search for the word under cursor (whole-word match) |
190
+
191
+ The search bar appears below the editor with incremental highlighting as you type. All matches are highlighted in yellow, with the current match in orange. The status line shows the current result index (e.g. `3/14`).
192
+
193
+ After `*`, `n` and `N` continue navigating with whole-word matching.
194
+
195
+ ### Marks
196
+
197
+ | Key | Action |
198
+ | --------- | --------------------------------------------------------------- |
199
+ | `m{char}` | Set mark at current cursor position (`a`-`z`, `A`-`Z`, `0`-`9`) |
200
+ | `'{char}` | Jump to mark position |
201
+
202
+ Mark positions are automatically updated through document changes. Jumping to a mark centers the cursor in the editor. Works with operators (e.g. `d'a` deletes to mark `a`).
203
+
204
+ The status line shows feedback: `mark a set`, `mark a`, `mark x not set`.
205
+
206
+ ### Dot Repeat
207
+
208
+ | Key | Action |
209
+ | --- | ------------------------------------ |
210
+ | `.` | Repeat last document-changing action |
211
+
212
+ Repeatable actions include:
213
+
214
+ - Simple commands: `x`, `p`, `P`, `J`, `D`, `>>`, `<<`
215
+ - Doubled operators: `dd`, `cc`
216
+ - Operator + motion: `dw`, `cw`, `d$`, `df{char}`, etc.
217
+ - Operator + text object: `diw`, `ci"`, etc.
218
+ - Insert commands: `i`, `a`, `A`, `I`, `o`, `O`, `C` — replays typed text
219
+
220
+ A count prefix overrides the stored count (e.g. `3x` then `2.` deletes 2 chars).
221
+
222
+ ### Scrolling
223
+
224
+ | Key | Action |
225
+ | ---- | ------------------------------------------ |
226
+ | `zz` | Center cursor vertically within the editor |
227
+
228
+ Centering only scrolls the editor's own container — it never scrolls the surrounding page.
229
+
230
+ ### Count Prefix
231
+
232
+ All motions, operators, and find/till commands accept a numeric count prefix.
233
+
234
+ ```
235
+ 3w → move forward 3 words
236
+ 2dd → delete 2 lines
237
+ 3fa → jump to the 3rd 'a' to the right
238
+ 2j → move down 2 lines
239
+ 3>> → indent 3 times
240
+ ```
241
+
242
+ ### Register
243
+
244
+ A single unnamed register stores the most recent yank or delete. Deletes from `d`/`x`/`c` and yanks from `y` all write to it. The register carries a linewise flag: pasting a linewise register inserts full paragraphs rather than inline text.
245
+
246
+ ### Status Line
247
+
248
+ The plugin exposes status messages via `getVimStatus(editor)` (Tiptap) or `vimState.statusMessage` (ProseMirror). Messages include:
249
+
250
+ - Search result index: `3/14`
251
+ - Mark set: `mark a set`
252
+ - Mark jump: `mark a`
253
+ - Mark not found: `mark x not set`
254
+ - No results: `pattern not found`
255
+
256
+ ---
257
+
258
+ ## Design Notes
259
+
260
+ - **Paragraph = line** — ProseMirror paragraph nodes are treated as Vim lines. All line-boundary motions (`0`, `^`, `$`, `j`, `k`) operate at the paragraph level.
261
+ - **No system clipboard** — the register is in-memory only; browser clipboard is not used.
262
+ - **Single ProseMirror plugin** — all state lives in a `PluginKey` inside a single `Plugin`.
263
+ - **Insert mode passthrough** — in insert mode, only `Esc`/`Ctrl-c` is intercepted; all other keys are passed through to ProseMirror's default input handling.
264
+ - **Scroll containment** — centering (`zz`) and search navigation (`n`/`N`) only scroll the editor element, never the outer page.
@@ -0,0 +1,26 @@
1
+ import { EditorState, Transaction } from 'prosemirror-state';
2
+ import { VimState } from './types';
3
+ /**
4
+ * Delete character under cursor (x command).
5
+ */
6
+ export declare function deleteChar(state: EditorState, pos: number, vimState: VimState, count?: number): Transaction;
7
+ /**
8
+ * Paste after cursor (p command).
9
+ */
10
+ export declare function pasteAfter(state: EditorState, pos: number, vimState: VimState, count?: number): Transaction;
11
+ /**
12
+ * Paste before cursor (P command).
13
+ */
14
+ export declare function pasteBefore(state: EditorState, pos: number, vimState: VimState, count?: number): Transaction;
15
+ /**
16
+ * Open line below and enter insert mode (o command).
17
+ */
18
+ export declare function openLineBelow(state: EditorState, pos: number, vimState: VimState): Transaction;
19
+ /**
20
+ * Open line above and enter insert mode (O command).
21
+ */
22
+ export declare function openLineAbove(state: EditorState, pos: number, vimState: VimState): Transaction;
23
+ /**
24
+ * Join current line with next line (J command).
25
+ */
26
+ export declare function joinLines(state: EditorState, pos: number, count?: number): Transaction;
@@ -0,0 +1,231 @@
1
+ import { TextSelection, Selection, } from 'prosemirror-state';
2
+ import { Fragment } from 'prosemirror-model';
3
+ import { lineEndAt, paragraphBounds, } from './utils';
4
+ /**
5
+ * Delete character under cursor (x command).
6
+ */
7
+ export function deleteChar(state, pos, vimState, count = 1) {
8
+ const lineE = lineEndAt(state, pos);
9
+ const to = Math.min(pos + count, lineE);
10
+ if (pos >= lineE) {
11
+ // Nothing to delete, return no-op
12
+ return state.tr;
13
+ }
14
+ const text = state.doc.textBetween(pos, to, '\n', '\n');
15
+ vimState.register = { text, linewise: false, content: null };
16
+ const tr = state.tr.delete(pos, to);
17
+ const newPos = Math.min(pos, tr.doc.content.size);
18
+ try {
19
+ tr.setSelection(TextSelection.create(tr.doc, newPos));
20
+ }
21
+ catch {
22
+ // leave as-is
23
+ }
24
+ return tr;
25
+ }
26
+ /**
27
+ * Paste after cursor (p command).
28
+ */
29
+ export function pasteAfter(state, pos, vimState, count = 1) {
30
+ if (!vimState.register.text)
31
+ return state.tr;
32
+ if (vimState.register.linewise) {
33
+ // Find the top-level block boundary to insert after
34
+ let $pos = state.doc.resolve(pos);
35
+ if ($pos.depth === 0 && pos < state.doc.content.size) {
36
+ $pos = state.doc.resolve(pos + 1);
37
+ }
38
+ const insertPos = $pos.depth >= 1 ? $pos.after(1) : state.doc.content.size;
39
+ const tr = state.tr;
40
+ if (vimState.register.content && vimState.register.content.length > 0) {
41
+ // Use stored nodes to preserve formatting
42
+ const allNodes = [];
43
+ for (let c = 0; c < count; c++) {
44
+ allNodes.push(...vimState.register.content);
45
+ }
46
+ tr.insert(insertPos, Fragment.from(allNodes));
47
+ }
48
+ else {
49
+ // Fallback: text-based paste
50
+ const textToInsert = vimState.register.text.repeat(count);
51
+ const paragraphType = state.schema.nodes.paragraph;
52
+ if (!paragraphType)
53
+ return state.tr;
54
+ const lines = textToInsert.split('\n');
55
+ let currentInsertPos = insertPos;
56
+ for (const line of lines) {
57
+ const newNode = paragraphType.create(null, line ? state.schema.text(line) : undefined);
58
+ tr.insert(currentInsertPos, newNode);
59
+ currentInsertPos += newNode.nodeSize;
60
+ }
61
+ }
62
+ // Position cursor at start of first inserted content
63
+ try {
64
+ const $p = tr.doc.resolve(insertPos + 1);
65
+ const sel = Selection.findFrom($p, 1, true);
66
+ if (sel)
67
+ tr.setSelection(sel);
68
+ }
69
+ catch {
70
+ // leave as-is
71
+ }
72
+ return tr;
73
+ }
74
+ else {
75
+ // Insert text after cursor
76
+ const textToInsert = vimState.register.text.repeat(count);
77
+ const insertPos = pos + 1;
78
+ const clampedPos = Math.min(insertPos, lineEndAt(state, pos));
79
+ const tr = state.tr.insertText(textToInsert, clampedPos);
80
+ // Position cursor at end of inserted text
81
+ const newPos = clampedPos + textToInsert.length - 1;
82
+ try {
83
+ tr.setSelection(TextSelection.create(tr.doc, Math.max(clampedPos, newPos)));
84
+ }
85
+ catch {
86
+ // leave as-is
87
+ }
88
+ return tr;
89
+ }
90
+ }
91
+ /**
92
+ * Paste before cursor (P command).
93
+ */
94
+ export function pasteBefore(state, pos, vimState, count = 1) {
95
+ if (!vimState.register.text)
96
+ return state.tr;
97
+ if (vimState.register.linewise) {
98
+ // Find the top-level block boundary to insert before
99
+ let $pos = state.doc.resolve(pos);
100
+ if ($pos.depth === 0 && pos < state.doc.content.size) {
101
+ $pos = state.doc.resolve(pos + 1);
102
+ }
103
+ const insertPos = $pos.depth >= 1 ? $pos.before(1) : 0;
104
+ const tr = state.tr;
105
+ if (vimState.register.content && vimState.register.content.length > 0) {
106
+ // Use stored nodes to preserve formatting
107
+ const allNodes = [];
108
+ for (let c = 0; c < count; c++) {
109
+ allNodes.push(...vimState.register.content);
110
+ }
111
+ tr.insert(insertPos, Fragment.from(allNodes));
112
+ }
113
+ else {
114
+ // Fallback: text-based paste
115
+ const textToInsert = vimState.register.text.repeat(count);
116
+ const paragraphType = state.schema.nodes.paragraph;
117
+ if (!paragraphType)
118
+ return state.tr;
119
+ const lines = textToInsert.split('\n');
120
+ let currentInsertPos = insertPos;
121
+ for (const line of lines) {
122
+ const newNode = paragraphType.create(null, line ? state.schema.text(line) : undefined);
123
+ tr.insert(currentInsertPos, newNode);
124
+ currentInsertPos += newNode.nodeSize;
125
+ }
126
+ }
127
+ // Position cursor at start of first inserted content
128
+ try {
129
+ const $p = tr.doc.resolve(insertPos + 1);
130
+ const sel = Selection.findFrom($p, 1, true);
131
+ if (sel)
132
+ tr.setSelection(sel);
133
+ }
134
+ catch {
135
+ // leave as-is
136
+ }
137
+ return tr;
138
+ }
139
+ else {
140
+ // Insert text before cursor
141
+ const textToInsert = vimState.register.text.repeat(count);
142
+ const tr = state.tr.insertText(textToInsert, pos);
143
+ // Position cursor at the start of inserted text
144
+ try {
145
+ tr.setSelection(TextSelection.create(tr.doc, pos));
146
+ }
147
+ catch {
148
+ // leave as-is
149
+ }
150
+ return tr;
151
+ }
152
+ }
153
+ /**
154
+ * Open line below and enter insert mode (o command).
155
+ */
156
+ export function openLineBelow(state, pos, vimState) {
157
+ const bounds = paragraphBounds(state, pos);
158
+ const insertPos = bounds.to;
159
+ const paragraphType = state.schema.nodes.paragraph;
160
+ if (!paragraphType)
161
+ return state.tr;
162
+ const tr = state.tr;
163
+ const newNode = paragraphType.create();
164
+ tr.insert(insertPos, newNode);
165
+ // Move cursor into the new paragraph
166
+ try {
167
+ const newPos = insertPos + 1;
168
+ tr.setSelection(TextSelection.create(tr.doc, newPos));
169
+ }
170
+ catch {
171
+ // leave as-is
172
+ }
173
+ vimState.mode = 'insert';
174
+ return tr;
175
+ }
176
+ /**
177
+ * Open line above and enter insert mode (O command).
178
+ */
179
+ export function openLineAbove(state, pos, vimState) {
180
+ const bounds = paragraphBounds(state, pos);
181
+ const insertPos = bounds.from;
182
+ const paragraphType = state.schema.nodes.paragraph;
183
+ if (!paragraphType)
184
+ return state.tr;
185
+ const tr = state.tr;
186
+ const newNode = paragraphType.create();
187
+ tr.insert(insertPos, newNode);
188
+ // Move cursor into the new paragraph
189
+ try {
190
+ const newPos = insertPos + 1;
191
+ tr.setSelection(TextSelection.create(tr.doc, newPos));
192
+ }
193
+ catch {
194
+ // leave as-is
195
+ }
196
+ vimState.mode = 'insert';
197
+ return tr;
198
+ }
199
+ /**
200
+ * Join current line with next line (J command).
201
+ */
202
+ export function joinLines(state, pos, count = 1) {
203
+ const tr = state.tr;
204
+ let currentPos = pos;
205
+ for (let i = 0; i < count; i++) {
206
+ const $pos = tr.doc.resolve(currentPos);
207
+ const lineE = $pos.end($pos.depth);
208
+ const afterNode = $pos.after($pos.depth);
209
+ // Check if there's a next paragraph
210
+ if (afterNode >= tr.doc.content.size)
211
+ break;
212
+ // Check if we need to add a space
213
+ const lastChar = lineE > $pos.start($pos.depth) ? tr.doc.textBetween(lineE - 1, lineE) : '';
214
+ const needsSpace = lastChar !== '' && lastChar !== ' ';
215
+ // Delete the boundary between paragraphs
216
+ // The boundary is from the end of current paragraph node to the start of text in next paragraph
217
+ const nextNodePos = afterNode + 1; // start of next paragraph text
218
+ try {
219
+ if (needsSpace) {
220
+ tr.replaceWith(lineE, nextNodePos, state.schema.text(' '));
221
+ }
222
+ else {
223
+ tr.delete(lineE, nextNodePos);
224
+ }
225
+ }
226
+ catch {
227
+ break;
228
+ }
229
+ }
230
+ return tr;
231
+ }
@@ -0,0 +1 @@
1
+ {"version":3,"file":"commands.js","sourceRoot":"","sources":["../../../src/extensions/vim/commands.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAC1E,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAE3C,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AAGjE;;GAEG;AACH,MAAM,UAAU,QAAQ,CACtB,EAAe,EACf,KAAkB,EAClB,EAAY,EACZ,KAAa;IAEb,MAAM,GAAG,GAAG,KAAK,CAAC,SAAS,CAAC,IAAI,CAAA;IAChC,MAAM,GAAG,GAAG,OAAO,CAAC,KAAK,CAAC,CAAA;IAC1B,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,KAAK,EAAE,GAAG,CAAC,CAAA;IAE5C,IAAI,GAAG,IAAI,GAAG;QAAE,OAAO,EAAE,CAAA;IAEzB,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,GAAG,EAAE,SAAS,CAAC,CAAA;IAClD,EAAE,CAAC,QAAQ,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAA;IAEvC,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,GAAG,EAAE,SAAS,CAAC,CAAA;IAC9B,OAAO,EAAE,CAAA;AACX,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAC/B,EAAe,EACf,KAAkB,EAClB,EAAY;IAEZ,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAA;IACtC,IAAI,CAAC,IAAI;QAAE,OAAO,EAAE,CAAA;IAEpB,IAAI,QAAQ,EAAE,CAAC;QACb,+CAA+C;QAC/C,MAAM,UAAU,GAAG,WAAW,CAAC,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,CAAA;QAC3D,IAAI,SAAS,GAAG,CAAC,CAAA;QACjB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC;YACrC,SAAS,IAAI,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAA;QAC1C,CAAC;QAED,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;QAC9B,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAC7B,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CACjF,CAAA;QACD,MAAM,QAAQ,GAAG,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QACrC,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAA;QACnC,8CAA8C;QAC9C,MAAM,MAAM,GAAG,SAAS,GAAG,CAAC,CAAA,CAAC,iCAAiC;QAC9D,EAAE,GAAG,EAAE,CAAC,YAAY,CAAC,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,CAAA;IAC5D,CAAC;SAAM,CAAC;QACN,MAAM,GAAG,GAAG,KAAK,CAAC,SAAS,CAAC,IAAI,GAAG,CAAC,CAAA;QACpC,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,CAAA;QAC/C,EAAE,GAAG,EAAE,CAAC,UAAU,CAAC,IAAI,EAAE,SAAS,CAAC,CAAA;QACnC,2CAA2C;QAC3C,MAAM,MAAM,GAAG,SAAS,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,CAAA;QAC1C,EAAE,GAAG,EAAE,CAAC,YAAY,CAAC,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC,CAAA;IACjF,CAAC;IAED,OAAO,EAAE,CAAA;AACX,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAChC,EAAe,EACf,KAAkB,EAClB,EAAY;IAEZ,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAA;IACtC,IAAI,CAAC,IAAI;QAAE,OAAO,EAAE,CAAA;IAEpB,IAAI,QAAQ,EAAE,CAAC;QACb,+CAA+C;QAC/C,MAAM,UAAU,GAAG,WAAW,CAAC,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,CAAA;QAC3D,IAAI,SAAS,GAAG,CAAC,CAAA;QACjB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC;YACpC,SAAS,IAAI,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAA;QAC1C,CAAC;QAED,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;QAC9B,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAC7B,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CACjF,CAAA;QACD,MAAM,QAAQ,GAAG,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QACrC,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAA;QACnC,8CAA8C;QAC9C,MAAM,MAAM,GAAG,SAAS,GAAG,CAAC,CAAA;QAC5B,EAAE,GAAG,EAAE,CAAC,YAAY,CAAC,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,CAAA;IAC5D,CAAC;SAAM,CAAC;QACN,MAAM,GAAG,GAAG,KAAK,CAAC,SAAS,CAAC,IAAI,CAAA;QAChC,EAAE,GAAG,EAAE,CAAC,UAAU,CAAC,IAAI,EAAE,GAAG,CAAC,CAAA;QAC7B,2CAA2C;QAC3C,MAAM,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,CAAA;QACpC,EAAE,GAAG,EAAE,CAAC,YAAY,CAAC,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC,CAAA;IAC3E,CAAC;IAED,OAAO,EAAE,CAAA;AACX,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAC9B,EAAe,EACf,KAAkB,EAClB,EAAY;IAEZ,MAAM,UAAU,GAAG,WAAW,CAAC,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,CAAA;IAC3D,IAAI,SAAS,GAAG,CAAC,CAAA;IACjB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,SAAS,IAAI,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAA;IAC1C,CAAC;IAED,MAAM,YAAY,GAAG,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,MAAM,EAAE,CAAA;IAC1D,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,CAAA;IACvC,EAAE,GAAG,EAAE,CAAC,YAAY,CAAC,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,SAAS,GAAG,CAAC,CAAC,CAAC,CAAA;IACjE,EAAE,CAAC,IAAI,GAAG,QAAQ,CAAA;IAClB,OAAO,EAAE,CAAA;AACX,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAC9B,EAAe,EACf,KAAkB,EAClB,EAAY;IAEZ,MAAM,UAAU,GAAG,WAAW,CAAC,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,CAAA;IAC3D,IAAI,SAAS,GAAG,CAAC,CAAA;IACjB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC;QACpC,SAAS,IAAI,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAA;IAC1C,CAAC;IAED,MAAM,YAAY,GAAG,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,MAAM,EAAE,CAAA;IAC1D,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,CAAA;IACvC,EAAE,GAAG,EAAE,CAAC,YAAY,CAAC,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,SAAS,GAAG,CAAC,CAAC,CAAC,CAAA;IACjE,EAAE,CAAC,IAAI,GAAG,QAAQ,CAAA;IAClB,OAAO,EAAE,CAAA;AACX,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW,CACzB,EAAe,EACf,KAAkB;IAElB,MAAM,UAAU,GAAG,WAAW,CAAC,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,CAAA;IAC3D,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC,CAAA;IAC9B,IAAI,UAAU,IAAI,KAAK,GAAG,CAAC;QAAE,OAAO,EAAE,CAAA;IAEtC,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,EAAE,UAAU,CAAC,CAAA;IACzC,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,EAAE,UAAU,GAAG,CAAC,CAAC,CAAA;IAC9C,IAAI,CAAC,OAAO,IAAI,CAAC,QAAQ;QAAE,OAAO,EAAE,CAAA;IAEpC,sEAAsE;IACtE,kDAAkD;IAClD,oDAAoD;IACpD,gDAAgD;IAChD,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAA;IAC5B,MAAM,MAAM,GAAG,QAAQ,CAAC,KAAK,CAAA;IAE7B,kCAAkC;IAClC,MAAM,QAAQ,GAAG,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAA;IACpE,MAAM,OAAO,GAAG,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,CAAA;IAEjE,4DAA4D;IAC5D,MAAM,SAAS,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAA;IACtE,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAA;IAChC,IAAI,SAAS,EAAE,CAAC;QACd,EAAE,GAAG,EAAE,CAAC,UAAU,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAA;IACzC,CAAC;IAED,OAAO,EAAE,CAAA;AACX,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,MAAc;IACvC,MAAM,CAAC,QAAgB,CAAC,IAAI,EAAE,CAAA;AACjC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,MAAc;IACvC,MAAM,CAAC,QAAgB,CAAC,IAAI,EAAE,CAAA;AACjC,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { createVimPlugin, vimPluginKey, getVimStateFromEditorState, } from './state';
2
+ export type { VimState, Mode, VimEditorCommands, Register } from './types';
3
+ export { defaultVimState } from './types';
@@ -0,0 +1,2 @@
1
+ export { createVimPlugin, vimPluginKey, getVimStateFromEditorState, } from './state';
2
+ export { defaultVimState } from './types';
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/extensions/vim/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import { EditorView } from 'prosemirror-view';
2
+ import { VimState, VimEditorCommands } from './types';
3
+ /**
4
+ * Main key handler for the vim plugin.
5
+ */
6
+ export declare function handleKeyDown(view: EditorView, event: KeyboardEvent, vimState: VimState, commands: VimEditorCommands): boolean;