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