Skip to main content

nu_protocol/config/
reedline.rs

1use super::{config_update_string_enum, prelude::*};
2use crate as nu_protocol;
3use crate::{FromValue, engine::Closure};
4
5/// Definition of a parsed keybinding from the config object
6#[derive(Clone, Debug, FromValue, IntoValue, Serialize, Deserialize)]
7pub struct ParsedKeybinding {
8    pub name: Option<Value>,
9    pub modifier: Value,
10    pub keycode: Value,
11    pub event: Value,
12    pub mode: Value,
13}
14
15/// Definition of a parsed menu from the config object
16#[derive(Clone, Debug, FromValue, IntoValue, Serialize, Deserialize)]
17pub struct ParsedMenu {
18    pub name: Value,
19    pub marker: Value,
20    /// Legacy two-state input behavior. Required unless `input_mode` is set,
21    /// which supersedes it.
22    pub only_buffer_difference: Option<Value>,
23    /// Optional reedline `InputMode` ("diff" / "cursor_prefix" / "full_buffer").
24    /// Supersedes `only_buffer_difference` when set; absent keeps current behavior.
25    pub input_mode: Option<Value>,
26    /// Optional reedline `OutputMode` ("suggested_span" / "full_buffer" / "extend_to_end").
27    pub output_mode: Option<Value>,
28    pub style: Value,
29    pub r#type: Value,
30    pub source: Option<Closure>,
31}
32
33/// Definition of a Nushell CursorShape (to be mapped to crossterm::cursor::CursorShape)
34#[derive(Clone, Copy, Debug, Default, IntoValue, PartialEq, Eq, Serialize, Deserialize)]
35pub enum NuCursorShape {
36    Underscore,
37    Line,
38    Block,
39    BlinkUnderscore,
40    BlinkLine,
41    BlinkBlock,
42    #[default]
43    Inherit,
44}
45
46impl FromStr for NuCursorShape {
47    type Err = &'static str;
48
49    fn from_str(s: &str) -> Result<NuCursorShape, &'static str> {
50        match s.to_ascii_lowercase().as_str() {
51            "line" => Ok(NuCursorShape::Line),
52            "block" => Ok(NuCursorShape::Block),
53            "underscore" => Ok(NuCursorShape::Underscore),
54            "blink_line" => Ok(NuCursorShape::BlinkLine),
55            "blink_block" => Ok(NuCursorShape::BlinkBlock),
56            "blink_underscore" => Ok(NuCursorShape::BlinkUnderscore),
57            "inherit" => Ok(NuCursorShape::Inherit),
58            _ => Err(
59                "'line', 'block', 'underscore', 'blink_line', 'blink_block', 'blink_underscore' or 'inherit'",
60            ),
61        }
62    }
63}
64
65impl UpdateFromValue for NuCursorShape {
66    fn update(&mut self, value: &Value, path: &mut ConfigPath, errors: &mut ConfigErrors) {
67        config_update_string_enum(self, value, path, errors)
68    }
69}
70
71#[derive(Clone, Copy, Debug, Default, IntoValue, PartialEq, Eq, Serialize, Deserialize)]
72pub struct CursorShapeConfig {
73    pub emacs: NuCursorShape,
74    pub vi_insert: NuCursorShape,
75    pub vi_normal: NuCursorShape,
76    /// Only takes effect in builds with the `helix` feature.
77    pub helix_normal: NuCursorShape,
78    pub helix_select: NuCursorShape,
79    pub helix_insert: NuCursorShape,
80}
81
82impl UpdateFromValue for CursorShapeConfig {
83    fn update<'a>(
84        &mut self,
85        value: &'a Value,
86        path: &mut ConfigPath<'a>,
87        errors: &mut ConfigErrors,
88    ) {
89        let Value::Record { val: record, .. } = value else {
90            errors.type_mismatch(path, Type::record(), value);
91            return;
92        };
93
94        for (col, val) in record.iter() {
95            let path = &mut path.push(col);
96            match col.as_str() {
97                "vi_insert" => self.vi_insert.update(val, path, errors),
98                "vi_normal" => self.vi_normal.update(val, path, errors),
99                "emacs" => self.emacs.update(val, path, errors),
100                "helix_normal" => self.helix_normal.update(val, path, errors),
101                "helix_select" => self.helix_select.update(val, path, errors),
102                "helix_insert" => self.helix_insert.update(val, path, errors),
103                _ => errors.unknown_option(path, val),
104            }
105        }
106    }
107}
108
109#[derive(Clone, Copy, Debug, Default, IntoValue, PartialEq, Eq, Serialize, Deserialize)]
110pub enum EditBindings {
111    Vi,
112    #[default]
113    Emacs,
114    /// Only usable in builds with the `helix` feature; selecting it elsewhere
115    /// reports an error when the keybindings are constructed.
116    Helix,
117}
118
119impl FromStr for EditBindings {
120    type Err = &'static str;
121
122    fn from_str(s: &str) -> Result<Self, Self::Err> {
123        match s.to_ascii_lowercase().as_str() {
124            "vi" => Ok(Self::Vi),
125            "emacs" => Ok(Self::Emacs),
126            "helix" => Ok(Self::Helix),
127            _ => Err("'emacs', 'vi' or 'helix'"),
128        }
129    }
130}
131
132impl UpdateFromValue for EditBindings {
133    fn update(&mut self, value: &Value, path: &mut ConfigPath, errors: &mut ConfigErrors) {
134        config_update_string_enum(self, value, path, errors)
135    }
136}