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}