Skip to main content

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 four g-prefix case/reflow operators
6/// (`gU` / `gu` / `g~` / `gq`) 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.
27    Reflow,
28    /// `=` — auto-indent (v1 dumb shiftwidth bracket counting).
29    AutoIndent,
30    /// `!` — filter through external shell command. After the motion fixes the
31    /// range the grammar transitions to `PendingFilter` and waits for the
32    /// app to supply a command string before emitting `EngineCmd::ApplyFilter`.
33    Filter,
34    /// `gc` — toggle line comments on the range. `gcc` = current line (doubled-
35    /// char convention, like `dd`). `gc{motion}` = motion variant. All three
36    /// visual modes resolve to a row range and call `toggle_comment_range`.
37    Comment,
38}
39
40impl OperatorKind {
41    /// The doubled-letter char for this operator.
42    ///
43    /// Used by the `AfterOp` reducer arm to detect the line-op doubled form:
44    /// `dd`, `yy`, `cc`, `>>`, `<<`, `gUU`, `guu`, `g~~`, `gqq`, `gcc`.
45    pub(crate) fn double_char(self) -> char {
46        match self {
47            OperatorKind::Delete => 'd',
48            OperatorKind::Yank => 'y',
49            OperatorKind::Change => 'c',
50            OperatorKind::Indent => '>',
51            OperatorKind::Outdent => '<',
52            OperatorKind::Uppercase => 'U',
53            OperatorKind::Lowercase => 'u',
54            OperatorKind::ToggleCase => '~',
55            OperatorKind::Reflow => 'q',
56            OperatorKind::AutoIndent => '=',
57            OperatorKind::Filter => '!',
58            // `gcc` — doubled 'c' after `gc` enters the comment operator.
59            OperatorKind::Comment => 'c',
60        }
61    }
62}