1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
use super::prelude::*;
use crate as nu_protocol;
use std::collections::HashMap;
/// Definition of a parsed hook from the config object
#[derive(Clone, Debug, IntoValue, PartialEq, Serialize, Deserialize)]
pub struct Hooks {
pub pre_prompt: Vec<Value>,
pub pre_execution: Vec<Value>,
pub env_change: HashMap<String, Vec<Value>>,
pub display_output: Option<Value>,
pub command_not_found: Option<Value>,
}
impl Hooks {
pub fn new() -> Self {
Self {
pre_prompt: Vec::new(),
pre_execution: Vec::new(),
env_change: HashMap::new(),
display_output: Some(Value::string(
"if (term size).columns >= 100 { table -e } else { table }",
Span::unknown(),
)),
command_not_found: None,
}
}
}
impl Default for Hooks {
fn default() -> Self {
Self::new()
}
}
impl UpdateFromValue for Hooks {
fn update<'a>(
&mut self,
value: &'a Value,
path: &mut ConfigPath<'a>,
errors: &mut ConfigErrors,
) {
let Value::Record { val: record, .. } = value else {
errors.type_mismatch(path, Type::record(), value);
return;
};
for (col, val) in record.iter() {
let path = &mut path.push(col);
match col.as_str() {
"pre_prompt" => {
if let Ok(hooks) = val.as_list() {
self.pre_prompt = hooks.into()
} else {
errors.type_mismatch(path, Type::list(Type::Any), val);
}
}
"pre_execution" => {
if let Ok(hooks) = val.as_list() {
self.pre_execution = hooks.into()
} else {
errors.type_mismatch(path, Type::list(Type::Any), val);
}
}
"env_change" => {
if let Ok(record) = val.as_record() {
self.env_change = record
.iter()
.map(|(key, val)| {
let old = self.env_change.remove(key).unwrap_or_default();
let new = if let Ok(hooks) = val.as_list() {
hooks.into()
} else {
errors.type_mismatch(
&path.push(key),
Type::list(Type::Any),
val,
);
old
};
(key.as_str().into(), new)
})
.collect();
} else {
errors.type_mismatch(path, Type::record(), val);
}
}
"display_output" => {
self.display_output = if val.is_nothing() {
None
} else {
Some(val.clone())
}
}
"command_not_found" => {
self.command_not_found = if val.is_nothing() {
None
} else {
Some(val.clone())
}
}
_ => errors.unknown_option(path, val),
}
}
}
}