hjkl_vim/operator.rs
1/// Operator identity carried by the reducer. Kept independent of
2/// `hjkl-engine` so `hjkl-vim` has no upstream dependency.
3///
4/// The five operators that can be entered directly from Normal mode via bare
5/// `d` / `y` / `c` / `>` / `<`, plus the g-prefix case/reflow operators
6/// (`gU` / `gu` / `g~` / `gq` / `gw`) bridged through the reducer in chunk 2c-v.
7/// Fold (`zf`) does not enter bare op-pending so it is omitted entirely.
8#[derive(Debug, Clone, Copy, PartialEq, Eq)]
9pub enum OperatorKind {
10 /// `d` — delete.
11 Delete,
12 /// `y` — yank.
13 Yank,
14 /// `c` — change (delete + enter Insert mode).
15 Change,
16 /// `>` — indent.
17 Indent,
18 /// `<` — outdent.
19 Outdent,
20 /// `gU` — uppercase.
21 Uppercase,
22 /// `gu` — lowercase.
23 Lowercase,
24 /// `g~` — toggle case.
25 ToggleCase,
26 /// `gq` — reflow / format text. Cursor moves to end of reflowed range.
27 Reflow,
28 /// `gw` — reflow like `gq` but cursor stays at its pre-reflow position.
29 ReflowKeepCursor,
30 /// `=` — auto-indent (v1 dumb shiftwidth bracket counting).
31 AutoIndent,
32 /// `!` — filter through external shell command. After the motion fixes the
33 /// range the grammar transitions to `PendingFilter` and waits for the
34 /// app to supply a command string before emitting `EngineCmd::ApplyFilter`.
35 Filter,
36 /// `gc` — toggle line comments on the range. `gcc` = current line (doubled-
37 /// char convention, like `dd`). `gc{motion}` = motion variant. All three
38 /// visual modes resolve to a row range and call `toggle_comment_range`.
39 Comment,
40}
41
42impl OperatorKind {
43 /// The doubled-letter char for this operator.
44 ///
45 /// Used by the `AfterOp` reducer arm to detect the line-op doubled form:
46 /// `dd`, `yy`, `cc`, `>>`, `<<`, `gUU`, `guu`, `g~~`, `gqq`, `gcc`.
47 /// Also used by the app's which-key popup to synthesise the prefix
48 /// shown when an operator is pending its motion.
49 pub fn double_char(self) -> char {
50 match self {
51 OperatorKind::Delete => 'd',
52 OperatorKind::Yank => 'y',
53 OperatorKind::Change => 'c',
54 OperatorKind::Indent => '>',
55 OperatorKind::Outdent => '<',
56 OperatorKind::Uppercase => 'U',
57 OperatorKind::Lowercase => 'u',
58 OperatorKind::ToggleCase => '~',
59 OperatorKind::Reflow => 'q',
60 // `gww` — doubled 'w' after `gw` enters the keep-cursor reflow.
61 OperatorKind::ReflowKeepCursor => 'w',
62 OperatorKind::AutoIndent => '=',
63 OperatorKind::Filter => '!',
64 // `gcc` — doubled 'c' after `gc` enters the comment operator.
65 OperatorKind::Comment => 'c',
66 }
67 }
68}