Skip to main content

jiq/editor/
mode.rs

1use crate::editor::char_search::{SearchDirection, SearchType};
2
3/// Scope for text object operations (inner vs around)
4#[derive(Debug, Clone, Copy, PartialEq, Eq)]
5pub enum TextObjectScope {
6    /// Inner - select content inside delimiters (ci", di(, etc.)
7    Inner,
8    /// Around - select content including delimiters (ca", da(, etc.)
9    Around,
10}
11
12/// VIM editing modes for the input field
13#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
14pub enum EditorMode {
15    /// Insert mode - typing inserts characters
16    #[default]
17    Insert,
18    /// Normal mode - VIM navigation and commands
19    Normal,
20    /// Operator mode - waiting for motion after operator (d or c)
21    Operator(char),
22    /// CharSearch mode - waiting for target character after f/F/t/T
23    CharSearch(SearchDirection, SearchType),
24    /// OperatorCharSearch mode - waiting for target character after d/c + f/F/t/T
25    OperatorCharSearch(char, usize, SearchDirection, SearchType),
26    /// TextObject mode - waiting for text object target after operator + i/a
27    TextObject(char, TextObjectScope),
28}
29
30impl EditorMode {
31    fn char_search_display(dir: SearchDirection, st: SearchType) -> char {
32        match dir {
33            SearchDirection::Forward => match st {
34                SearchType::Find => 'f',
35                SearchType::Till => 't',
36            },
37            SearchDirection::Backward => match st {
38                SearchType::Find => 'F',
39                SearchType::Till => 'T',
40            },
41        }
42    }
43
44    /// Get the display string for the mode indicator
45    pub fn display(&self) -> String {
46        match self {
47            EditorMode::Insert => "INSERT".to_string(),
48            EditorMode::Normal => "NORMAL".to_string(),
49            EditorMode::Operator(op) => format!("OPERATOR({})", op),
50            EditorMode::CharSearch(dir, st) => {
51                format!("CHAR({})", Self::char_search_display(*dir, *st))
52            }
53            EditorMode::OperatorCharSearch(op, _, dir, st) => {
54                format!("{}{}…", op, Self::char_search_display(*dir, *st))
55            }
56            EditorMode::TextObject(op, scope) => {
57                let scope_char = match scope {
58                    TextObjectScope::Inner => 'i',
59                    TextObjectScope::Around => 'a',
60                };
61                format!("{}{}…", op, scope_char)
62            }
63        }
64    }
65}
66
67#[cfg(test)]
68#[path = "mode_tests.rs"]
69mod mode_tests;