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