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}