feat: configure cursor appearance by editing mode

This commit is contained in:
2026-10-26 15:01:19 +01:00
parent 846803a3e2
commit ce434a1c17
13 changed files with 356 additions and 51 deletions
+8
View File
@@ -15,6 +15,8 @@ Vamp.configure do |config|
config.clipboard_mode = "system"
config.git_blame = true # false disables current-line attribution
config.git_gutter = "bar" # or "symbols", "line_numbers", "none"
config.cursor = {} # mode colors enabled; all modes use a block cursor
# config.cursor = { mode_colors: false, insert: :bar, visual: :underline }
config.scroll_distance = 0 # nonnegative edge distance, or nil to center
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
@@ -58,6 +60,12 @@ Plugin paths resolve relative to the config file, not the shell's working direct
`config.file_explorer_side` defaults to `"right"`; other choices are `"left"`, `"top"`, and `"bottom"`. Independent `file_explorer_view` / `file_picker_view` preferences both default to `"tree"` and accept `"list"` as an alternative. Invalid preference strings report notices and retain defaults while valid bindings still install. Non-string/empty values disable the whole configuration like other Ruby type errors.
`config.clipboard_mode` accepts `"system"` (default) or `"separate"`. An invalid policy string reports a notice and retains System while valid bindings still install; non-string/empty values reject the whole Ruby configuration.
`config.cursor` accepts a partial hash. `mode_colors` defaults to `true`: the primary terminal cursor and secondary text carets use cyan in Normal, green in Insert, purple in Visual (including Visual Line), yellow in Command, and orange in Search. Set `config.cursor = { mode_colors: false }` to use the terminal's default cursor color; secondary carets retain their uncolored-mode magenta highlight.
The `normal`, `insert`, `visual`, `command`, and `search` keys select native terminal cursor shapes: `:block`, `:bar`, or `:underline` (strings also work). Every mode defaults to a steady block. For example, `config.cursor = { insert: :bar, visual: :underline }` changes those two shapes without disabling mode colors. Each assignment replaces the cursor configuration; omitted keys retain built-in defaults. Unknown keys, nonboolean `mode_colors`, unsupported shapes, and non-hash values reject the configuration.
Shapes apply to the primary hardware cursor, including command/search prompts and historical/diff text; secondary carets remain cell highlights. This uses terminal cursor protocols (OSC 12/112 for color and DECSCUSR for shape), not replacement text glyphs. Unsupported terminals may ignore them. Normal exit, errors, panics, and restart restore the terminal's configured cursor color and shape. No file contents or cursor positions change.
`config.scroll_distance` defaults to `0`: keep the viewport still until its primary cursor or selected picker entry would leave it. A nonnegative integer reserves that many visible rows above/below the cursor, and terminal-cell columns left/right in unwrapped text. `nil` keeps it centered; integers at least half the current viewport dimension behave the same way until resizing makes that margin usable. The start of content limits centering, while trailing blank space allows centering near the end. Whole two-row picker entries stay aligned, using the nearest entry to the center when exact margins cannot fit.
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.
+1
View File
@@ -80,6 +80,7 @@ The two skipped shell cleanup checks execute `/bin/ps`, which macOS refuses to l
- Status redesign checks cover component-aware home abbreviation without save-path changes; floating command/search submit/cancel, Unicode/tiny/offset clipping and wheel isolation; footer-row reclamation; notification Escape/modal/prefix priority and covered-caret visibility; and ready-server metadata using real framed subprocess fixtures, including stacks, initialization gates, failure, and focus changes.
- Unix terminal-hook checks use isolated child processes and real PTYs to keep process-global hooks out of the parallel runner. They cover raw/alternate-screen/mouse-capture cleanup on entry failure, normal return, I/O errors, and panics during frame construction, including original panic-payload propagation.
- Redraw checks inspect actual Crossterm output during repeated scrolling: supporting terminals receive synchronized frames, terminals ignoring synchronization never paint with a visible hardware cursor, and the final caret remains visible. A protocol-state regression verifies that the terminal is not left in synchronized-output mode while the next frame is computed.
- Cursor checks cover native color/shape output through Normal, Insert, Visual, Command, and Search transitions, independent color disabling and shape overrides, unchanged source text, and guard cleanup on return/error/panic. Live PTY smoke exercises defaults, Insert bar/Visual underline overrides, color-disabled shapes, prompt transitions, and exit restoration; actual appearance depends on terminal support.
- Wheel checks render document/panel views and cover three-row scrolling, unchanged carets/selections/text, first/last-page clamping, offscreen cursor hiding, no-op/custom-bound navigation reveal, manual persistence through idle/resize/palette updates, and floating/unfocused-docked explorer selection and focus preservation. Queued-input checks verify that the next frame shows ordered wheel steps without crossing a key or resize boundary.
- Queued-navigation checks cover counted ordered motions through short rows, Normal/Visual ranges, remapped press/repeat keys, rendered caret visibility, edit/layout/prefix and non-key barriers, and the 64-key fairness bound. Burst smoke must verify the final cursor position as well as frame count; batching reduces queued redraws without increasing the OS/terminal repeat rate.
- Native LSP integration checks launch framed-protocol fixture subprocesses, covering initialization/settings, opt-in startup, synchronization, UTF-16/file-URI conversion, dirty targets, stale requests/diagnostics, and transport failures. Stack checks cover independent initialization, diagnostic merging/clearing, sibling failure isolation in active/parked buffers, same-revision rename/close identity, aggregate limits, first-server position routing, and both shutdowns. Semantic ordering uses protocol/file gates; elapsed deadlines only bound stuck subprocesses.