nvim_gtk/
mode.rs

1use std::collections::HashMap;
2use neovim_lib::Value;
3
4#[derive(Clone, PartialEq)]
5pub enum NvimMode {
6    Normal,
7    Insert,
8    Other,
9}
10
11pub struct Mode {
12    mode: NvimMode,
13    idx: usize,
14    info: Option<Vec<ModeInfo>>,
15}
16
17impl Mode {
18    pub fn new() -> Self {
19        Mode {
20            mode: NvimMode::Normal,
21            idx: 0,
22            info: None,
23        }
24    }
25
26    pub fn is(&self, mode: &NvimMode) -> bool {
27        self.mode == *mode
28    }
29
30    pub fn mode_info(&self) -> Option<&ModeInfo> {
31        self.info.as_ref().and_then(|i| i.get(self.idx))
32    }
33
34    pub fn update(&mut self, mode: &str, idx: usize) {
35        match mode {
36            "normal" => self.mode = NvimMode::Normal,
37            "insert" => self.mode = NvimMode::Insert,
38            _ => self.mode = NvimMode::Other,
39        }
40
41        self.idx = idx;
42    }
43
44    pub fn set_info(&mut self, cursor_style_enabled: bool, info: Vec<ModeInfo>) {
45        self.info = if cursor_style_enabled {
46            Some(info)
47        } else {
48            None
49        };
50    }
51}
52
53
54#[derive(Debug, PartialEq, Clone)]
55pub enum CursorShape {
56    Block,
57    Horizontal,
58    Vertical,
59    Unknown,
60}
61
62impl CursorShape {
63    fn new(shape_code: &Value) -> Result<CursorShape, String> {
64        let str_code = shape_code
65            .as_str()
66            .ok_or_else(|| "Can't convert cursor shape to string".to_owned())?;
67
68        Ok(match str_code {
69            "block" => CursorShape::Block,
70            "horizontal" => CursorShape::Horizontal,
71            "vertical" => CursorShape::Vertical,
72            _ => {
73                error!("Unknown cursor_shape {}", str_code);
74                CursorShape::Unknown
75            }
76        })
77    }
78}
79
80#[derive(Debug, PartialEq, Clone)]
81pub struct ModeInfo {
82    cursor_shape: Option<CursorShape>,
83    cell_percentage: Option<u64>,
84    pub blinkwait: Option<u32>,
85}
86
87impl ModeInfo {
88    pub fn new(mode_info_map: &HashMap<String, Value>) -> Result<Self, String> {
89        let cursor_shape = if let Some(shape) = mode_info_map.get("cursor_shape") {
90            Some(CursorShape::new(shape)?)
91        } else {
92            None
93        };
94
95        Ok(ModeInfo {
96            cursor_shape,
97            cell_percentage: mode_info_map.get("cell_percentage").and_then(|cp| cp.as_u64()),
98            blinkwait: mode_info_map.get("blinkwait").and_then(|cp| cp.as_u64()).map(|v| v as u32),
99        })
100    }
101
102    pub fn cursor_shape(&self) -> Option<&CursorShape> {
103        self.cursor_shape.as_ref()
104    }
105
106    pub fn cell_percentage(&self) -> u64 {
107        self.cell_percentage.unwrap_or(0)
108    }
109}