nvim_rs/
uioptions.rs

1//! Options for UI implementations
2//!
3//! This should be used with the manually implemented
4//! [`ui_attach`](crate::neovim::Neovim::ui_attach)
5use rmpv::Value;
6
7pub enum UiOption {
8  Rgb(bool),
9  Override(bool),
10  ExtCmdline(bool),
11  ExtHlstate(bool),
12  ExtLinegrid(bool),
13  ExtMessages(bool),
14  ExtMultigrid(bool),
15  ExtPopupmenu(bool),
16  ExtTabline(bool),
17  ExtTermcolors(bool),
18  TermName(String),
19  TermColors(u64),
20  TermBackground(String),
21  StdinFd(u64),
22  StdinTty(bool),
23  StdoutTty(bool),
24  ExtWildmenu(bool),
25}
26
27impl UiOption {
28  fn to_value(&self) -> (Value, Value) {
29    let name_value = self.to_name_value();
30    (name_value.0.into(), name_value.1)
31  }
32
33  fn to_name_value(&self) -> (&'static str, Value) {
34    match self {
35      Self::Rgb(val) => ("rgb", (*val).into()),
36      Self::Override(val) => ("override", (*val).into()),
37      Self::ExtCmdline(val) => ("ext_cmdline", (*val).into()),
38      Self::ExtHlstate(val) => ("ext_hlstate", (*val).into()),
39      Self::ExtLinegrid(val) => ("ext_linegrid", (*val).into()),
40      Self::ExtMessages(val) => ("ext_messages", (*val).into()),
41      Self::ExtMultigrid(val) => ("ext_multigrid", (*val).into()),
42      Self::ExtPopupmenu(val) => ("ext_popupmenu", (*val).into()),
43      Self::ExtTabline(val) => ("ext_tabline", (*val).into()),
44      Self::ExtTermcolors(val) => ("ext_termcolors", (*val).into()),
45      Self::TermName(val) => ("term_name", val.as_str().into()),
46      Self::TermColors(val) => ("term_colors", (*val).into()),
47      Self::TermBackground(val) => ("term_background", val.as_str().into()),
48      Self::StdinFd(val) => ("stdin_fd", (*val).into()),
49      Self::StdinTty(val) => ("stdin_tty", (*val).into()),
50      Self::StdoutTty(val) => ("stdout_tty", (*val).into()),
51      Self::ExtWildmenu(val) => ("ext_wildmenu", (*val).into()),
52    }
53  }
54}
55
56#[derive(Default)]
57pub struct UiAttachOptions {
58  options: Vec<(&'static str, UiOption)>,
59}
60
61macro_rules! ui_opt_setters {
62  ($( $opt:ident as $set:ident($type:ty) );+ ;) => {
63    impl UiAttachOptions {
64      $(
65        pub fn $set(&mut self, val: $type) -> &mut Self {
66          self.set_option(UiOption::$opt(val.into()));
67          self
68        }
69      )+
70    }
71  }
72}
73
74ui_opt_setters! (
75
76  Rgb as set_rgb(bool);
77  Override as set_override(bool);
78  ExtCmdline as set_cmdline_external(bool);
79  ExtHlstate as set_hlstate_external(bool);
80  ExtLinegrid as set_linegrid_external(bool);
81  ExtMessages as set_messages_externa(bool);
82  ExtMultigrid as set_multigrid_external(bool);
83  ExtPopupmenu as set_popupmenu_external(bool);
84  ExtTabline as set_tabline_external(bool);
85  ExtTermcolors as set_termcolors_external(bool);
86  TermName as set_term_name(&str);
87  TermColors as set_term_colors(u64);
88  TermBackground as set_term_background(&str);
89  StdinFd as set_stdin_fd(u64);
90  StdinTty as set_stdin_tty(bool);
91  StdoutTty as set_stdout_tty(bool);
92  ExtWildmenu as set_wildmenu_external(bool);
93);
94
95impl UiAttachOptions {
96  #[must_use]
97  pub fn new() -> UiAttachOptions {
98    UiAttachOptions {
99      options: Vec::new(),
100    }
101  }
102
103  fn set_option(&mut self, option: UiOption) {
104    let name = option.to_name_value();
105    let position = self.options.iter().position(|o| o.0 == name.0);
106
107    if let Some(position) = position {
108      self.options[position].1 = option;
109    } else {
110      self.options.push((name.0, option));
111    }
112  }
113
114  #[must_use]
115  pub fn to_value_map(&self) -> Value {
116    let map = self.options.iter().map(|o| o.1.to_value()).collect();
117    Value::Map(map)
118  }
119}
120
121#[cfg(test)]
122mod tests {
123  use super::*;
124
125  #[test]
126  fn test_ui_options() {
127    let value_map = UiAttachOptions::new()
128      .set_rgb(true)
129      .set_rgb(false)
130      .set_popupmenu_external(true)
131      .to_value_map();
132
133    assert_eq!(
134      Value::Map(vec![
135        ("rgb".into(), false.into()),
136        ("ext_popupmenu".into(), true.into()),
137      ]),
138      value_map
139    );
140  }
141}