floem_editor_core/
mode.rs

1use std::fmt::Write;
2
3use bitflags::bitflags;
4#[cfg(feature = "serde")]
5use serde::{Deserialize, Serialize};
6
7#[derive(Clone, Debug, PartialEq, Eq)]
8#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9pub enum MotionMode {
10    Delete { count: usize },
11    Yank { count: usize },
12    Indent,
13    Outdent,
14}
15
16impl MotionMode {
17    pub fn count(&self) -> usize {
18        match self {
19            MotionMode::Delete { count } => *count,
20            MotionMode::Yank { count } => *count,
21            MotionMode::Indent => 1,
22            MotionMode::Outdent => 1,
23        }
24    }
25}
26
27#[derive(Clone, PartialEq, Eq, Hash, Debug, Copy, Default, PartialOrd, Ord)]
28#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
29pub enum VisualMode {
30    #[default]
31    Normal,
32    Linewise,
33    Blockwise,
34}
35
36#[derive(Clone, PartialEq, Eq, Hash, Debug, Copy, PartialOrd, Ord)]
37pub enum Mode {
38    Normal,
39    Insert,
40    Visual(VisualMode),
41    Terminal,
42}
43
44bitflags! {
45    #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
46    pub struct Modes: u32 {
47        const NORMAL = 0x1;
48        const INSERT = 0x2;
49        const VISUAL = 0x4;
50        const TERMINAL = 0x8;
51    }
52}
53
54impl From<Mode> for Modes {
55    fn from(mode: Mode) -> Self {
56        match mode {
57            Mode::Normal => Self::NORMAL,
58            Mode::Insert => Self::INSERT,
59            Mode::Visual(_) => Self::VISUAL,
60            Mode::Terminal => Self::TERMINAL,
61        }
62    }
63}
64
65impl Modes {
66    pub fn parse(modes_str: &str) -> Self {
67        let mut this = Self::empty();
68
69        for c in modes_str.chars() {
70            match c {
71                'i' | 'I' => this.set(Self::INSERT, true),
72                'n' | 'N' => this.set(Self::NORMAL, true),
73                'v' | 'V' => this.set(Self::VISUAL, true),
74                't' | 'T' => this.set(Self::TERMINAL, true),
75                _ => {}
76            }
77        }
78
79        this
80    }
81}
82
83impl std::fmt::Display for Modes {
84    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
85        let bits = [
86            (Self::INSERT, 'i'),
87            (Self::NORMAL, 'n'),
88            (Self::VISUAL, 'v'),
89            (Self::TERMINAL, 't'),
90        ];
91        for (bit, chr) in bits {
92            if self.contains(bit) {
93                f.write_char(chr)?;
94            }
95        }
96
97        Ok(())
98    }
99}