1use super::{config_update_string_enum, prelude::*};
2use crate as nu_protocol;
3use crate::engine::Closure;
4
5#[derive(Clone, Copy, Debug, Default, IntoValue, PartialEq, Eq, Serialize, Deserialize)]
6pub enum CompletionAlgorithm {
7 #[default]
8 Prefix,
9 Fuzzy,
10}
11
12impl FromStr for CompletionAlgorithm {
13 type Err = &'static str;
14
15 fn from_str(s: &str) -> Result<Self, Self::Err> {
16 match s.to_ascii_lowercase().as_str() {
17 "prefix" => Ok(Self::Prefix),
18 "fuzzy" => Ok(Self::Fuzzy),
19 _ => Err("'prefix' or 'fuzzy'"),
20 }
21 }
22}
23
24impl UpdateFromValue for CompletionAlgorithm {
25 fn update(&mut self, value: &Value, path: &mut ConfigPath, errors: &mut ConfigErrors) {
26 config_update_string_enum(self, value, path, errors)
27 }
28}
29
30#[derive(Clone, Copy, Debug, Default, IntoValue, PartialEq, Eq, Serialize, Deserialize)]
31pub enum CompletionSort {
32 #[default]
33 Smart,
34 Alphabetical,
35}
36
37impl FromStr for CompletionSort {
38 type Err = &'static str;
39
40 fn from_str(s: &str) -> Result<Self, Self::Err> {
41 match s.to_ascii_lowercase().as_str() {
42 "smart" => Ok(Self::Smart),
43 "alphabetical" => Ok(Self::Alphabetical),
44 _ => Err("'smart' or 'alphabetical'"),
45 }
46 }
47}
48
49impl UpdateFromValue for CompletionSort {
50 fn update(&mut self, value: &Value, path: &mut ConfigPath, errors: &mut ConfigErrors) {
51 config_update_string_enum(self, value, path, errors)
52 }
53}
54
55#[derive(Clone, Debug, IntoValue, Serialize, Deserialize)]
56pub struct ExternalCompleterConfig {
57 pub enable: bool,
58 pub max_results: i64,
59 pub completer: Option<Closure>,
60}
61
62impl Default for ExternalCompleterConfig {
63 fn default() -> Self {
64 Self {
65 enable: true,
66 max_results: 100,
67 completer: None,
68 }
69 }
70}
71
72impl UpdateFromValue for ExternalCompleterConfig {
73 fn update<'a>(
74 &mut self,
75 value: &'a Value,
76 path: &mut ConfigPath<'a>,
77 errors: &mut ConfigErrors,
78 ) {
79 let Value::Record { val: record, .. } = value else {
80 errors.type_mismatch(path, Type::record(), value);
81 return;
82 };
83
84 for (col, val) in record.iter() {
85 let path = &mut path.push(col);
86 match col.as_str() {
87 "completer" => match val {
88 Value::Nothing { .. } => self.completer = None,
89 Value::Closure { val, .. } => self.completer = Some(val.as_ref().clone()),
90 _ => errors.type_mismatch(path, Type::custom("closure or nothing"), val),
91 },
92 "max_results" => self.max_results.update(val, path, errors),
93 "enable" => self.enable.update(val, path, errors),
94 _ => errors.unknown_option(path, val),
95 }
96 }
97 }
98}
99
100#[derive(Clone, Debug, IntoValue, Serialize, Deserialize)]
101pub struct CompletionConfig {
102 pub sort: CompletionSort,
103 pub case_sensitive: bool,
104 pub quick: bool,
105 pub partial: bool,
106 pub algorithm: CompletionAlgorithm,
107 pub external: ExternalCompleterConfig,
108 pub use_ls_colors: bool,
109}
110
111impl Default for CompletionConfig {
112 fn default() -> Self {
113 Self {
114 sort: CompletionSort::default(),
115 case_sensitive: false,
116 quick: true,
117 partial: true,
118 algorithm: CompletionAlgorithm::default(),
119 external: ExternalCompleterConfig::default(),
120 use_ls_colors: true,
121 }
122 }
123}
124
125impl UpdateFromValue for CompletionConfig {
126 fn update<'a>(
127 &mut self,
128 value: &'a Value,
129 path: &mut ConfigPath<'a>,
130 errors: &mut ConfigErrors,
131 ) {
132 let Value::Record { val: record, .. } = value else {
133 errors.type_mismatch(path, Type::record(), value);
134 return;
135 };
136
137 for (col, val) in record.iter() {
138 let path = &mut path.push(col);
139 match col.as_str() {
140 "sort" => self.sort.update(val, path, errors),
141 "quick" => self.quick.update(val, path, errors),
142 "partial" => self.partial.update(val, path, errors),
143 "algorithm" => self.algorithm.update(val, path, errors),
144 "case_sensitive" => self.case_sensitive.update(val, path, errors),
145 "external" => self.external.update(val, path, errors),
146 "use_ls_colors" => self.use_ls_colors.update(val, path, errors),
147 _ => errors.unknown_option(path, val),
148 }
149 }
150 }
151}