Skip to content

RFC: Visual mode (v charwise, V linewise, Ctrl-v blockwise) #35

Description

@renzorlive

From the issue #3 backlog: visual selection (v) and visual block (Ctrl-v). Filed as an RFC because it's the single largest requested feature and touches modes, motions, operators, and rendering.

Problem / motivation

There is no visual mode. Selecting text with v/V/Ctrl-v and operating on the selection is one of Vim's most-used features and several issue #3 items depend on it. It's also the biggest architectural change on the backlog, so it deserves a design decision before any code.

Detailed proposal

Modes. Add VISUAL (charwise). Recommend also VISUAL_LINE (V). Treat VISUAL_BLOCK (Ctrl-v) as a separate phase (see Scope).

State. Add visualAnchor: {row, col} (the fixed end). The cursor is the moving end; the selection is anchor..cursor.

Enter / extend / operate.

  • v -> VISUAL, anchor = cursor. V -> VISUAL_LINE.
  • Existing motions (h j k l w b e W B E 0 ^ $, later f) move the cursor and extend the selection — motions must work unchanged in visual mode.
  • d/x delete the selection, y yanks it, c changes it, then return to NORMAL. Esc cancels.

Rendering. renderEditor must highlight the selection range (reuse the search-highlight mechanism). Charwise: anchor->cursor. Linewise: whole lines. This is genuinely new UI work.

Validators / lessons. Most visual lessons assert on the resulting buffer after an operation (targetContent) — no new validator type needed to start. A selection-state goal ("you selected X") could be added later.

Scope decision (the real question for maintainers)

  • Phase 1: charwise v + linewise V with d/y/c. Covers the common case; fully teachable.
  • Phase 2: blockwise Ctrl-v — much more complex (column ranges, block insert I/A). Recommend deferring until there's demand; a teaching tool may not need block-visual at all.

The architectural insight (important)

Visual operations are "apply an operator to a selection" — the same abstraction as the c<motion>/d<motion> operator+motion work also requested in #3. That work is TD-14 (replace the 500-line handleNormalMode string-suffix parser with a real count->operator->motion parser).

Recommendation: do not bolt visual mode onto today's fragile handleNormalMode (the source of most bugs we fixed this cycle — stale state, 2dd never working, undo leaks). Build it with or after the operator/motion parser, which ADR-0002 already points toward (a pure dispatch(state, key) core). Visual mode and c<motion> should share the operator/selection abstraction rather than each growing another special case.

Alternatives considered

  • Do nothing — blocks a core skill and multiple Feature: more lessons #3 items.
  • Charwise only (no V, no Ctrl-v) — simplest, but V is very common and cheap once charwise exists.
  • Full block-visual now — high complexity for marginal teaching value; defer.
  • Bolt onto current handleNormalMode — fastest to a demo, but compounds TD-14 and the exact fragility we just spent a cycle fixing. Rejected.

Trade-offs, risks

  • Largest feature on the backlog: modes + state + motion reuse + operators + rendering.
  • Rendering multi-line selection is new UI surface.
  • Best sequenced with the parser refactor; may motivate finally doing TD-14.
  • No save-format impact (visual state is transient).

Recommendation

Approve Phase 1 (v + V) as a goal, defer Ctrl-v, and sequence it with the operator/motion parser (TD-14) rather than as a standalone patch. Bigger than a help wanted; wants a maintainer or experienced contributor.

Refs #3.

Metadata

Metadata

Assignees

No one assigned

    Labels

    engineVim engine / command handlingrfcRequest for Comments — design proposal under discussion

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions