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}
30
31#[derive(Default)]
32pub struct VimState {
33    pub mode: Mode,
34    pub operator_stack: Vec<Operator>,
35}
36
37impl VimState {
38    pub fn cursor_shape(&self) -> CursorShape {
39        match self.mode {
40            Mode::Normal | Mode::Visual | Mode::VisualLine => 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 empty_selections_only(&self) -> bool {
50        self.mode != Mode::Visual && self.mode != Mode::VisualLine
51    }
52
53    pub fn keymap_context_layer(&self) -> Context {
54        let mut context = Context::default();
55        context.map.insert(
56            "vim_mode".to_string(),
57            match self.mode {
58                Mode::Normal => "normal",
59                Mode::Visual => "visual",
60                Mode::VisualLine => "visual_line",
61                Mode::Insert => "insert",
62            }
63            .to_string(),
64        );
65
66        if self.vim_controlled() {
67            context.set.insert("VimControl".to_string());
68        }
69
70        if let Some(operator) = &self.operator_stack.last() {
71            operator.set_context(&mut context);
72        }
73        context
74    }
75}
76
77impl Operator {
78    pub fn set_context(&self, context: &mut Context) {
79        let operator_context = match self {
80            Operator::Namespace(Namespace::G) => "g",
81            Operator::Change => "c",
82            Operator::Delete => "d",
83        }
84        .to_owned();
85
86        context
87            .map
88            .insert("vim_operator".to_string(), operator_context.to_string());
89    }
90}