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