feat(cmdatom)!: eliminate the need for vim-repeat #41414

Problem:
- `lhs` is not fully realized. E.g. for a "payload" mapping
  `lhs` omits the `getchar()` payload during a mapping (vim-surround
  `ds'` reports `lhs="ds"`). This means plugins like vim-repeat are
  still needed...
- The "delta" fields of a CmdAtom are calculated too late.
  - `<abuf>` and `changed` check whatever (wrong) buffer a command
    (":bnext") might land in.
  - CTRL-W_w between two windows on the same buffer reports type="motion".

Solution:
- `CmdOrigin` samples (buf/win/cursor/changedtick) at each "scope" entry
  (CmdFrame, composite, Visual session, insert session).
- `dd<C-w>l` reports `changed=true` for the buffer it edited, regardless
  of where the cursor ends up.
- New fields:
  - `pos`: cursor position at command start.
  - `moved`: indicates whether the cursor moved (in same buffer).
  - `undoseq`: undo state at settlement.
- lhs now includes the payload: "ds)" reports lhs="ds)" instead of "ds".
  - Easy for users to "replay" any atom.
- Rename: type "command" => "normal", "ex" => "excmd"; `arg` => `cmdarg`
- Drop `cascade` field (no reason to expose it)
This commit is contained in:
Justin M. Keyes
2026-08-21 13:42:17 -04:00
committed by GitHub
parent 8e0e19c08b
commit 6423657352
10 changed files with 631 additions and 155 deletions

View File

@@ -6,20 +6,23 @@ error('Cannot require a meta file')
--- Data for the CmdAtom event.
--- @class vim.event.cmdatom.data
--- @field arg? string Typed operand of `cmd` ("fx" => "x").
--- @field atoms? vim.event.cmdatom.data[] Subatoms of a composite (mapping, Visual sequence).
--- @field cascade boolean Queued for multicursor replay.
--- @field changed boolean Changed the buffer.
--- @field cmd? string Command/motion/object name ("w", "f", "iw", "gJ").
--- @field cmdarg? string Operand of `cmd` ("fx" => "x").
--- @field count? integer Effective count.
--- @field keys string Resolved keysequence, raw bytes: feed to nvim_feedkeys() to replay.
--- @field lhs? string Mapping LHS or macro register ("gj", "@q"). Raw bytes, like `keys`.
--- @field lhs? string High-level user input: mapping LHS + any payload it read, or macro register ("gj", "ds'", "@q"). Raw bytes.
--- @field motionforce? 'v'|'V'|'<C-V>' forced-motion type.
--- @field moved? boolean Moved the cursor.
--- @field operator? string Operator name ("d", "g~", "g@"). key-notation.
--- @field pending? 'operator'|'visual' Mapping ended mid-operation.
--- @field pending? 'mapping'|'operator'|'visual' The next atom completes what this started.
--- @field pos? [integer,integer] Cursor before the action: 1-indexed row, 0-indexed column.
--- @field reg? string Register name.
--- @field remap? true `keys` cannot replay this (the mapping reads its own args): feed `lhs` with remapping.
--- @field text? string Inserted text, or the Ex/search cmdline.
--- @field type 'command'|'ex'|'insert'|'jump'|'mapping'|'motion'|'mouse'|'operator'|'scroll'|'visual'
--- @field type 'excmd'|'insert'|'jump'|'mapping'|'motion'|'mouse'|'normal'|'operator'|'scroll'|'visual'
--- @field undoseq? integer Undo state after the action (`undotree().seq_cur`). Decreases on undo.
--- @class vim.event.lspattach.data
--- @field client_id integer