Skip to main content

tmprl_core/
mode.rs

1//! Editing modes.
2
3use std::fmt;
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
6pub enum Mode {
7    #[default]
8    Normal,
9    Insert,
10    Visual,
11    VisualLine,
12    /// The `:` command line.
13    Command,
14}
15
16impl Mode {
17    /// Shown in the statusline. Uppercase, like vim's.
18    pub fn label(self) -> &'static str {
19        match self {
20            Mode::Normal => "NORMAL",
21            Mode::Insert => "INSERT",
22            Mode::Visual => "VISUAL",
23            Mode::VisualLine => "V-LINE",
24            Mode::Command => "COMMAND",
25        }
26    }
27
28    /// Whether a leading digit starts a count rather than being literal input.
29    pub fn takes_counts(self) -> bool {
30        matches!(self, Mode::Normal | Mode::Visual | Mode::VisualLine)
31    }
32
33    /// Whether unmatched keys should be inserted as text.
34    pub fn is_text_entry(self) -> bool {
35        matches!(self, Mode::Insert | Mode::Command)
36    }
37
38    pub fn is_visual(self) -> bool {
39        matches!(self, Mode::Visual | Mode::VisualLine)
40    }
41}
42
43impl fmt::Display for Mode {
44    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
45        f.write_str(self.label())
46    }
47}
48
49#[cfg(test)]
50mod tests {
51    use super::*;
52
53    #[test]
54    fn only_normal_and_visual_take_counts() {
55        assert!(Mode::Normal.takes_counts());
56        assert!(Mode::Visual.takes_counts());
57        assert!(Mode::VisualLine.takes_counts());
58        assert!(!Mode::Insert.takes_counts());
59        assert!(!Mode::Command.takes_counts());
60    }
61
62    #[test]
63    fn text_entry_modes_are_not_count_modes() {
64        for m in [
65            Mode::Normal,
66            Mode::Insert,
67            Mode::Visual,
68            Mode::VisualLine,
69            Mode::Command,
70        ] {
71            assert!(
72                !(m.takes_counts() && m.is_text_entry()),
73                "{m} cannot be both"
74            );
75        }
76    }
77}