* Clamped half-page scroll for the editor, bound to Ctrl+D / Ctrl+U. * * Replaces CodeMirror-Vim's built-in ` `/` ` (`moveByScroll`), which * derives its scroll target from the cursor's pixel coordinates. With live- * preview decorations and folded headings shifting block heights, that m
(view: EditorView | undefined, forward: boolean)
| 155 | * wrap. Mirrors the clamped preview scroll (`scrollPreviewBy`) in VimNav. |
| 156 | */ |
| 157 | function editorHalfPage(view: EditorView | undefined, forward: boolean): void { |
| 158 | if (!view) return |
| 159 | const scroller = view.scrollDOM |
| 160 | const half = Math.max(1, Math.round(scroller.clientHeight / 2)) |
| 161 | const lineHeight = view.defaultLineHeight || 18 |
| 162 | const steps = Math.max(1, Math.round(half / lineHeight)) |
| 163 | let range = view.state.selection.main |
| 164 | for (let i = 0; i < steps; i++) { |
| 165 | const next = view.moveVertically(range, forward) |
| 166 | if (next.head === range.head) break // reached the first/last line — stop, never wrap |
| 167 | range = next |
| 168 | } |
| 169 | const maxTop = Math.max(0, scroller.scrollHeight - scroller.clientHeight) |
| 170 | const nextTop = Math.max(0, Math.min(maxTop, scroller.scrollTop + (forward ? half : -half))) |
| 171 | view.dispatch({ selection: { anchor: range.head } }) |
| 172 | scroller.scrollTop = nextTop |
| 173 | } |
| 174 | |
| 175 | function syncVimKeymaps(overrides: KeymapOverrides): void { |
| 176 | const mappings: Array<{ id: KeymapId; action: string; bindings: string[] }> = [ |
no outgoing calls
no test coverage detected