Skip to main content

vtcode_vim/
types.rs

1/// Active Vim editing mode.
2#[derive(Clone, Copy, Debug, PartialEq, Eq)]
3pub enum VimMode {
4    Insert,
5    Normal,
6}
7
8#[derive(Clone, Copy, Debug, PartialEq, Eq)]
9pub(crate) enum ClipboardKind {
10    CharWise,
11    LineWise,
12}
13
14#[derive(Clone, Copy, Debug, PartialEq, Eq)]
15pub(crate) enum Operator {
16    Delete,
17    Change,
18    Yank,
19    Indent,
20    Outdent,
21}
22
23#[derive(Clone, Copy, Debug, PartialEq, Eq)]
24pub(crate) enum Motion {
25    WordForward,
26    EndWord,
27    WordBackward,
28}
29
30#[derive(Clone, Copy, Debug, PartialEq, Eq)]
31pub(crate) enum TextObjectSpec {
32    Word {
33        around: bool,
34        big: bool,
35    },
36    Delimited {
37        around: bool,
38        open: char,
39        close: char,
40    },
41}
42
43#[derive(Clone, Copy, Debug, PartialEq, Eq)]
44pub(crate) enum PendingState {
45    Operator(Operator),
46    TextObject(Operator, bool),
47    Find { till: bool, forward: bool },
48    GoToLine,
49}
50
51#[derive(Clone, Copy, Debug, PartialEq, Eq)]
52pub(crate) enum InsertKind {
53    Insert,
54    InsertStart,
55    Append,
56    AppendEnd,
57    OpenBelow,
58    OpenAbove,
59}
60
61#[derive(Clone, Copy, Debug, PartialEq, Eq)]
62pub(crate) enum ChangeTarget {
63    Motion(Motion),
64    TextObject(TextObjectSpec),
65    Line,
66    LineEnd,
67}
68
69#[derive(Clone, Copy, Debug, PartialEq, Eq)]
70pub(crate) enum InsertRepeat {
71    Insert(InsertKind),
72    Change(ChangeTarget),
73}
74
75#[derive(Clone, Debug, PartialEq, Eq)]
76pub(crate) enum RepeatableCommand {
77    DeleteChar,
78    PasteAfter,
79    PasteBefore,
80    JoinLines,
81    InsertText {
82        kind: InsertKind,
83        text: String,
84    },
85    OperateMotion {
86        operator: Operator,
87        motion: Motion,
88    },
89    OperateTextObject {
90        operator: Operator,
91        object: TextObjectSpec,
92    },
93    OperateLine {
94        operator: Operator,
95    },
96    DeleteToLineEnd,
97    Change {
98        target: ChangeTarget,
99        text: String,
100    },
101}
102
103#[derive(Clone, Copy, Debug, PartialEq, Eq)]
104pub(crate) struct FindState {
105    pub(crate) ch: char,
106    pub(crate) till: bool,
107    pub(crate) forward: bool,
108}
109
110#[derive(Clone, Debug, PartialEq, Eq)]
111pub(crate) struct InsertCapture {
112    pub(crate) repeat: InsertRepeat,
113    pub(crate) start: usize,
114}
115
116#[derive(Clone, Debug)]
117pub struct VimState {
118    enabled: bool,
119    mode: VimMode,
120    pub(crate) preferred_column: Option<usize>,
121    pub(crate) pending: Option<PendingState>,
122    pub(crate) last_find: Option<FindState>,
123    pub(crate) last_change: Option<RepeatableCommand>,
124    pub(crate) clipboard_kind: ClipboardKind,
125    pub(crate) insert_capture: Option<InsertCapture>,
126}
127
128impl VimState {
129    /// Create a new Vim state container.
130    #[must_use]
131    pub fn new(enabled: bool) -> Self {
132        Self {
133            enabled,
134            mode: VimMode::Insert,
135            preferred_column: None,
136            pending: None,
137            last_find: None,
138            last_change: None,
139            clipboard_kind: ClipboardKind::CharWise,
140            insert_capture: None,
141        }
142    }
143
144    pub fn set_enabled(&mut self, enabled: bool) {
145        self.enabled = enabled;
146        self.mode = VimMode::Insert;
147        self.pending = None;
148        self.preferred_column = None;
149        self.insert_capture = None;
150    }
151
152    #[must_use]
153    pub fn enabled(&self) -> bool {
154        self.enabled
155    }
156
157    #[must_use]
158    pub fn mode(&self) -> VimMode {
159        self.mode
160    }
161
162    #[must_use]
163    pub fn status_label(&self) -> Option<&'static str> {
164        if !self.enabled {
165            return None;
166        }
167
168        Some(match self.mode {
169            VimMode::Insert => "INSERT",
170            VimMode::Normal => "NORMAL",
171        })
172    }
173
174    pub(crate) fn set_mode(&mut self, mode: VimMode) {
175        self.mode = mode;
176    }
177}