state.rs

 1use editor::CursorShape;
 2use gpui::keymap::Context;
 3use serde::Deserialize;
 4
 5#[derive(Clone, Copy, Debug, PartialEq, Eq, Deserialize)]
 6pub enum Mode {
 7    Normal,
 8    Insert,
 9    Visual,
10}
11
12impl Default for Mode {
13    fn default() -> Self {
14        Self::Normal
15    }
16}
17
18#[derive(Copy, Clone, Debug, PartialEq, Eq, Deserialize)]
19pub enum Namespace {
20    G,
21}
22
23#[derive(Copy, Clone, Debug, PartialEq, Eq, Deserialize)]
24pub enum Operator {
25    Namespace(Namespace),
26    Change,
27    Delete,
28}
29
30#[derive(Default)]
31pub struct VimState {
32    pub mode: Mode,
33    pub operator_stack: Vec<Operator>,
34}
35
36impl VimState {
37    pub fn cursor_shape(&self) -> CursorShape {
38        match self.mode {
39            Mode::Normal => CursorShape::Block,
40            Mode::Visual => CursorShape::Block,
41            Mode::Insert => CursorShape::Bar,
42        }
43    }
44
45    pub fn vim_controlled(&self) -> bool {
46        !matches!(self.mode, Mode::Insert)
47    }
48
49    pub fn keymap_context_layer(&self) -> Context {
50        let mut context = Context::default();
51        context.map.insert(
52            "vim_mode".to_string(),
53            match self.mode {
54                Mode::Normal => "normal",
55                Mode::Visual => "visual",
56                Mode::Insert => "insert",
57            }
58            .to_string(),
59        );
60
61        if self.vim_controlled() {
62            context.set.insert("VimControl".to_string());
63        }
64
65        if let Some(operator) = &self.operator_stack.last() {
66            operator.set_context(&mut context);
67        }
68        context
69    }
70}
71
72impl Operator {
73    pub fn set_context(&self, context: &mut Context) {
74        let operator_context = match self {
75            Operator::Namespace(Namespace::G) => "g",
76            Operator::Change => "c",
77            Operator::Delete => "d",
78        }
79        .to_owned();
80
81        context
82            .map
83            .insert("vim_operator".to_string(), operator_context.to_string());
84    }
85}