refactor: name configurable viewport scroll steps accurately

This commit is contained in:
Valdemar Lorenzen
2026-10-16 10:31:36 +02:00
parent 284ddd3713
commit d1048df345
12 changed files with 80 additions and 54 deletions
+1 -1
View File
@@ -84,7 +84,7 @@ Resolution exposes its projected comparison through the same active DiffState an
`Editor::scroll_distance()` supplies the session-wide optional edge margin. The TUI applies it to document/diff visual rows and unwrapped text columns, and retains independent picker offsets across navigation frames. Picker windows exclude their fixed chrome and align whole multi-row entries. File projections carry a monotonic viewport revision, so catalog/filter/expansion changes invalidate picker identity without hashing the entire catalog on every redraw. Metadata-only status changes do not move the viewport. Explicit LSP/wrap-toggle anchors and detached wheel views retain precedence.
Keyboard viewport actions queue per-view row and half-page counts without moving carets. `Editor::take_viewport_scroll(height)` resolves half-page counts using the session-wide `scroll_half_page_lines` preference, or half the focused viewport when unset, and saturates multiplication before the frontend clamps movement to content bounds. Ordinary, diff, and conflict-history rendering share this resolution.
Keyboard viewport actions queue per-view row and configured-step counts without moving carets. `Editor::take_viewport_scroll(height)` resolves step counts using the session-wide `scroll_step_lines` preference, or half the focused viewport when unset, and saturates multiplication before the frontend clamps movement to content bounds. Ordinary, diff, and conflict-history rendering share this resolution.
Mouse wheel input uses the last rendered document/panel rectangles for hit-testing. Document offsets and explorer scroll state remain frontend-owned; three-row wheel steps never become document cursor motions. Manual document views persist until logical caret-reveal, caret/selection, mode, revision, or buffer changes; offscreen primary and browsing-selection cursors are not placed. Hover wheel input reuses the existing editor-owned popup scrolling.
+4 -4
View File
@@ -16,7 +16,7 @@ Vamp.configure do |config|
config.git_blame = true # false disables current-line attribution
config.git_gutter = "bar" # or "symbols", "line_numbers", "none"
config.scroll_distance = 0 # nonnegative edge distance, or nil to center
config.scroll_half_page_lines = nil # Ctrl+u/d: half viewport, or a positive screen-row count
config.scroll_step_lines = nil # Ctrl+u/d: half viewport, or a positive screen-row count
config.highlight_trailing_whitespace = false # true marks line-end whitespace in red
config.whitespace_characters = {} # opt in: { " " => "·", "\t" => "→", "\n" => "↵" }
config.whitespace_scope = "all" # or "leading" for indentation only
@@ -58,7 +58,7 @@ Plugin paths resolve relative to the config file, not the shell's working direct
The setting applies to ordinary and historical buffers, split/unified diff panes, file pickers and explorers, command/buffer palettes, completion lists, and revision selectors. Wrapped text measures visual rows, not source lines; picker distances use result rows, excluding borders, search fields, and help. Manual mouse-wheel scrolling remains detached until keyboard navigation resumes. Only `nil` or integers from `0` through the platform's Rust `usize` maximum (`18446744073709551615` on 64-bit systems) are accepted; other values reject the configuration.
`config.scroll_half_page_lines` controls Normal/Visual Ctrl+u/Ctrl+d (`core.scroll_half_up` / `core.scroll_half_down`). The default `nil` scrolls half the focused text viewport, rounded down with a minimum of one screen row. A positive integer, such as `config.scroll_half_page_lines = 3`, fixes the distance in screen rows, including wrapped continuations and diff display rows. Counts multiply that distance; `2` then Ctrl+d scrolls six rows with this example. This session-wide setting applies to ordinary, historical, diff, and conflict text panes without moving carets or selections. It does not change the cursor-edge margin, one-row scroll actions, mouse wheel, or picker navigation. Only `nil` or integers from `1` through the platform's Rust `usize` maximum are accepted; other values reject the configuration. Distances and count multiplication saturate at Rust's `isize` limit before the viewport clamps to content bounds.
`config.scroll_step_lines` controls Normal/Visual Ctrl+u/Ctrl+d (`core.scroll_step_up` / `core.scroll_step_down`). The default `nil` scrolls half the focused text viewport, rounded down with a minimum of one screen row. A positive integer, such as `config.scroll_step_lines = 3`, fixes the distance in screen rows, including wrapped continuations and diff display rows. Counts multiply that distance; `2` then Ctrl+d scrolls six rows with this example. This session-wide setting applies to ordinary, historical, diff, and conflict text panes without moving carets or selections. It does not change the cursor-edge margin, one-row scroll actions, mouse wheel, or picker navigation. Only `nil` or integers from `1` through the platform's Rust `usize` maximum are accepted; other values reject the configuration. Distances and count multiplication saturate at Rust's `isize` limit before the viewport clamps to content bounds.
`config.highlight_trailing_whitespace` defaults to `false`. Set it to `true` to give trailing whitespace a red background in ordinary and historical buffers and both sides of split/unified diffs, including wrapped and horizontally scrolled text. Spaces, expanded tab cells, and Unicode whitespace at the end of a source line are highlighted; whitespace-only lines are included, but empty lines and padding beyond the text are not. Wrapping does not make interior whitespace trailing. Search, selections, and secondary carets retain their background precedence; diagnostic underlines remain visible. This changes display only, not file contents. Only literal Ruby booleans are accepted; other values reject the configuration.
@@ -211,7 +211,7 @@ Normal `C` / `D` / `Y` change/delete/copy the cursor-to-line-end suffix through
`f<char>` / `F<char>` seeks forward/backward on the current line in Normal and Visual, with counts such as `2fx`. Rebind `config.core.seek_forward` / `config.core.seek_backward` to a single key or leader sequence; the action then waits for a literal target character. For example, `config.bind "s", config.core.seek_forward` makes `2sx` seek the second following `x`. Pass `mode: config.modes.visual` to install a Visual route. These native-only actions do not have Ex commands.
Normal and Visual Ctrl+u/Ctrl+d invoke `config.core.scroll_half_up` / `config.core.scroll_half_down` without moving carets or selection endpoints. Counts multiply the configured `scroll_half_page_lines` distance (half a viewport by default). Bind `config.core.scroll_up` / `config.core.scroll_down` for one screen row per count, for example `config.bind "ctrl+e", config.core.scroll_down` to replace clone-below in Normal. Pass `mode: config.modes.visual` to rebind Visual too. These actions work in ordinary and diff text panes, use wrapped screen rows, and have no Ex commands. Cursor navigation or editing resumes caret following.
Normal and Visual Ctrl+u/Ctrl+d invoke `config.core.scroll_step_up` / `config.core.scroll_step_down` without moving carets or selection endpoints. Counts multiply the configured `scroll_step_lines` distance (half a viewport by default). Bind `config.core.scroll_up` / `config.core.scroll_down` for one screen row per count, for example `config.bind "ctrl+e", config.core.scroll_down` to replace clone-below in Normal. Pass `mode: config.modes.visual` to rebind Visual too. These actions work in ordinary and diff text panes, use wrapped screen rows, and have no Ex commands. Cursor navigation or editing resumes caret following.
## Action reference
@@ -243,7 +243,7 @@ Normal and Visual Ctrl+u/Ctrl+d invoke `config.core.scroll_half_up` / `config.co
| Normal, Visual | `file_picker`, `file_explorer` |
| Normal, Visual | `document_start`, `document_end`, `go_to_line` |
| Normal, Visual | `seek_forward`, `seek_backward` |
| Normal, Visual | `scroll_up`, `scroll_down`, `scroll_half_up`, `scroll_half_down` |
| Normal, Visual | `scroll_up`, `scroll_down`, `scroll_step_up`, `scroll_step_down` |
| Normal, Insert, Visual | `line_start`, `line_end` |
| Normal, Insert, Visual, Tree | `left`, `right` |
| Normal, Insert, Visual, Selection, Tree | `down`, `up` |
+1 -1
View File
@@ -76,7 +76,7 @@ Diff styling checks cover independent snapshot language/shebang/injection detect
- Undo uses full-buffer snapshots and movement scans the current line. This favors straightforward correctness over large-file performance.
- Rapid-wheel verification must replay bursts against the running editor and measure arrival at the final viewport after input stops, not just individual frame duration. Cheap frames can still accumulate a visible backlog if each queued report requires its own redraw.
- Keyboard viewport scrolling coalesces up to 64 consecutive inputs for the same resolved scroll action into one redraw. Reversals, changes between row/half-page scrolling, and cursor motions end the batch so boundary clamping and caret reveal happen before the next action. Burst checks must include direction changes at the start/end of the buffer, not just throughput.
- Keyboard viewport scrolling coalesces up to 64 consecutive inputs for the same resolved scroll action into one redraw. Reversals, changes between row/configured-step scrolling, and cursor motions end the batch so boundary clamping and caret reveal happen before the next action. Burst checks must include direction changes at the start/end of the buffer, not just throughput.
- PTY throughput alone cannot prove terminal presentation stays smooth: capture the editor and terminal while the user reproduces a pause. Synchronized-output commands must not reach the terminal during frame computation, even when individual frames and queued-input catch-up appear fast.
- Annotation coordinate validation fast-paths ASCII grapheme lengths using byte lengths with CRLF pair accounting, retaining Unicode segmentation for non-ASCII text. Validation remains atomic and still checks every token; large Unicode buffers or diagnostic batches can require foreground work.
- Legacy synchronous plugin invocation may pause input for up to 500 ms before a host timeout. Async plugins opt into background replies; pending requests and transport queues are bounded. Config/plugin startup has a 2-second deadline per host. Buffer context/document snapshots must fit within a 4 MiB JSON frame; a too-large frame disables that plugin, not editing.
+1 -1
View File
@@ -31,7 +31,7 @@ Indicators refresh asynchronously. Typing and undo/redo retain the last complete
| Normal, Visual | `<line>g` jumps immediately to that one-based source line at first nonblank (`42g`); clamps at EOF and extends Visual selections |
| Normal | Ctrl+o goes to an older jump location; Ctrl+i/Tab goes forward; counts select multiple locations |
| Normal, Visual | Decimal prefixes repeat cursor/word/search motions: `5j`, `3k`, `2w`, `4e`, `2n`; Esc cancels a pending count |
| Normal, Visual | Ctrl+u/Ctrl+d scroll up/down without moving carets or selections; half a viewport by default, configurable with `config.scroll_half_page_lines`; counts multiply the distance |
| Normal, Visual | Ctrl+u/Ctrl+d scroll up/down without moving carets or selections; half a viewport by default, configurable with `config.scroll_step_lines`; counts multiply the distance |
| Normal | `J` (Shift+j) joins each targeted line with the next line |
| Normal | `x`/Delete delete; `u` undo; `U` (Shift+u) redo; `:` enter command mode |
| Normal | `yy` copies whole lines without moving; `dd` deletes them; `cc` changes them and enters Insert; counts work (`3yy`, `2dd`, `2cc`) |