1#[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 #[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}