1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
|
#pragma once
#include <stdbool.h>
#include "klib/kvec.h"
#include "nvim/buffer_defs.h"
#include "nvim/eval/typval_defs.h"
#include "nvim/input_defs.h"
// Concepts (see :help dev-cmdatom):
// - atom, span, composite (atom with subatoms)
// - insert-session, insertion
// - payload
// - replay, cascade, insert-cascade
typedef enum CmdAtomType {
kAComp, ///< Composite: complex mapping/macro. >=2 subatoms, or 0 (captured nothing).
kAExcmd, ///< Ex command (":cnext<CR>"): the typed cmdline is the payload.
kAInsert, ///< Insert session: entry command + text + <Esc>.
kAInsertSpan, ///< Span (chunk) of an ongoing insert-session, cascaded mid-session.
kAJump, ///< Cursor movement by absolute/shared navigation (jumplist, marks, `*`):
///< not followable (its target would collapse cursors onto one position).
kAMotion, ///< Motion (cascades in "q=" follow-motion mode).
kAMouse, ///< Mouse action: emit-only (not replayable).
kANormal, ///< Normal-mode command that is not a motion or jump ("u", CTRL-R, "za", …).
///< Never cascades, except as part of a mapping's composite.
kAOperator, ///< Operator+motion, or a self-contained edit command.
kAScroll, ///< Scroll (CTRL-Y/D/…, wheel): emit-only, like kAMouse.
kAVisual, ///< Visual-mode sequence ("viwee" + operator). Captures subatoms.
kAVisualSpan, ///< Span (chunk) of an ongoing Visual session, cascaded mid-session.
} CmdAtomType;
/// State gathered at start of a command, composite, or insert. For calculating the "delta" at end.
typedef struct {
bufref_T buf; ///< Buffer.
const win_T *win; ///< Window.
pos_T pos; ///< Primary cursor position at the start (`win.w_cursor` moves after).
uint32_t mcursor; ///< Mcursor overlapping primary at `pos` (mark id, 0: none). Not replayed.
varnumber_T tick; ///< b:changedtick.
int maptick; ///< Advances on typed input (globals.h:maptick).
} CmdOrigin;
/// How an insert-session was entered from Visual mode.
typedef enum {
kVInsNone, ///< Not entered from Visual mode.
kVInsKeys, ///< (Replayable) Redo opens with the selection's captured keys.
kVInsMotion, ///< (Replayable) Motion selected the region: Ex/Lua omap ("c" + Lua textobj), "gn".
kVInsOther, ///< Redo without captured keys: forced motion, "gv", or "1v" fixed-size fallback.
} VisualIns;
/// The insert-session delimited by atom_ins_start()/atom_ins_end().
typedef struct {
CmdOrigin origin; ///< State at start.
bool typed; ///< Session is user input (typed, or via mapping/macro).
VisualIns vis; ///< Session was entered from Visual mode.
char *vsel; ///< Visual keys ("gv…"); supplants redo's "1v" in atom+cascade. Owned.
} InsSession;
typedef struct CmdAtom CmdAtom;
typedef kvec_t(CmdAtom) CmdAtomVec;
/// One repeatable operation. `keys` is the replay bytes; `spec` is the structured form.
struct CmdAtom {
CmdAtomType type;
CmdSpec spec; ///< Structured fields.
CmdOrigin origin; ///< Pre-command state.
CmdAtomVec atoms; ///< Composite (multi-command mapping, Visual sequence): its subatoms,
///< in order; their keys concatenate to `keys`. Empty: non-composite.
char *keys; ///< Resolved keysequence (typeahead encoding), including `["x][count]` prefix
///< (unlike `CmdSpec.body`, the raw unprefixed form).
char *text; ///< Insert-session text, or Ex/search cmdline payload.
char *lhs; ///< Unresolved user input: mapping LHS, macro ("@q"), Visual op, or translation
///< ("x" => "dl"). NULL: untranslated, same as `keys`.
int undoseq; ///< Undo state at settlement. Not monotonic (decreases on undo).
bool changed; ///< The command changed the buffer.
bool moved; ///< The command moved the cursor.
bool remap; ///< True if `keys` cannot replay (lossy/empty capture). Replay `lhs` instead.
bool cascaded; ///< This atom already cascaded as spans: emit-only.
};
/// Key classes (atom_key_class()).
/// Flags, bc same char can mean different things per mode (CTRL-T: tag-jump vs i_CTRL-T indent).
enum {
kKeyOpaque = 1 << 0, ///< Cmds not reified from subatoms (<Cmd>, K_LUA), plus kKeySynthetic.
///< The cmd itself is the atom, else its only trace is its effect.
kKeySynthetic = 1 << 1, ///< Not a user keystroke (K_EVENT, K_IGNORE): unlike <Cmd>/K_LUA, never
///< reaches us from a mapping.
kKeyPayload = 1 << 2, ///< Interactively-typed payload (/, ?, :, !).
kKeyScrollMove = 1 << 3, ///< Scroll may move cursor (C-D/…): viewport-dependent, unreplayable.
kKeyScrollView = 1 << 4, ///< Viewport-only scroll (C-Y,wheel): cursor stays, unless 'scrolloff'.
kKeyJump = 1 << 5, ///< Absolute motion (multiplexed "gg", "g;", …), see NV_JUMP.
kKeyMotion = 1 << 6, ///< Cursor-relative motion (multiplexed, special keys), see NV_MOTION.
kKeyInsFlush = 1 << 7, ///< Insert-mode cmd a literal preview cannot represent:
///< - deletions/indent-shifts (<Del>, CTRL-W, …) may edit text
///< outside the tracked region by per-cursor amounts;
///< - cursor-moves (start_arrow()) move the insertion point itself.
kKeyMouse = 1 << 8, ///< Mouse button press (<LeftMouse>, …). Drag/release/move are the
///< press's continuation: no class, invisible to capture.
};
|