on master help sign in
Refactor 'helix-loader::merge_toml_values' to use a 'merge-depth' instead of 'merge_toplevel_arrays' (#3080)
235237dPhilipp Mildenberger
helix-loader/src/config.rs+17−1
@@ -19,7 +19,23 @@ pub fn user_lang_config() -> Result<toml::Value, toml::de::Error> {
19 .into_iter()
19 .into_iter()
20 .chain([default_lang_config()].into_iter())
20 .chain([default_lang_config()].into_iter())
21 .fold(toml::Value::Table(toml::value::Table::default()), |a, b| {
21 .fold(toml::Value::Table(toml::value::Table::default()), |a, b| {
22+ // combines for example
23+ // b:
24+ // [[language]]
25+ // name = "toml"
26+ // language-server = { command = "taplo", args = ["lsp", "stdio"] }
27+ //
28+ // a:
29+ // [[language]]
30+ // language-server = { command = "/usr/bin/taplo" }
31+ //
32+ // into:
33+ // [[language]]
34+ // name = "toml"
35+ // language-server = { command = "/usr/bin/taplo" }
36+ //
37+ // thus it overrides the third depth-level of b with values of a if they exist, but otherwise merges their values
22− crate::merge_toml_values(b, a, true)
38+ crate::merge_toml_values(b, a, 3)
23 });
39 });
24
40
25 Ok(config)
41 Ok(config)
helix-loader/src/lib.rs+18−18
@@ -113,11 +113,7 @@ pub fn find_root_impl(root: Option<&str>, root_markers: &[String]) -> Vec<std::p
113/// documents that use a top-level array of values like the `languages.toml`,
113/// documents that use a top-level array of values like the `languages.toml`,
114/// where one usually wants to override or add to the array instead of
114/// where one usually wants to override or add to the array instead of
115/// replacing it altogether.
115/// replacing it altogether.
116−pub fn merge_toml_values(
116+pub fn merge_toml_values(left: toml::Value, right: toml::Value, merge_depth: usize) -> toml::Value {
117− left: toml::Value,
118− right: toml::Value,
119− merge_toplevel_arrays: bool,
120−) -> toml::Value {
121 use toml::Value;
117 use toml::Value;
122
118
123 fn get_name(v: &Value) -> Option<&str> {
119 fn get_name(v: &Value) -> Option<&str> {
@@ -131,7 +127,7 @@ pub fn merge_toml_values(
131 // that you can specify a sub-set of languages in an overriding
127 // that you can specify a sub-set of languages in an overriding
132 // `languages.toml` but that nested arrays like Language Server
128 // `languages.toml` but that nested arrays like Language Server
133 // arguments are replaced instead of merged.
129 // arguments are replaced instead of merged.
134− if merge_toplevel_arrays {
130+ if merge_depth > 0 {
135 left_items.reserve(right_items.len());
131 left_items.reserve(right_items.len());
136 for rvalue in right_items {
132 for rvalue in right_items {
137 let lvalue = get_name(&rvalue)
133 let lvalue = get_name(&rvalue)
@@ -140,7 +136,7 @@ pub fn merge_toml_values(
140 })
136 })
141 .map(|lpos| left_items.remove(lpos));
137 .map(|lpos| left_items.remove(lpos));
142 let mvalue = match lvalue {
138 let mvalue = match lvalue {
143− Some(lvalue) => merge_toml_values(lvalue, rvalue, false),
139+ Some(lvalue) => merge_toml_values(lvalue, rvalue, merge_depth - 1),
144 None => rvalue,
140 None => rvalue,
145 };
141 };
146 left_items.push(mvalue);
142 left_items.push(mvalue);
@@ -151,18 +147,22 @@ pub fn merge_toml_values(
151 }
147 }
152 }
148 }
153 (Value::Table(mut left_map), Value::Table(right_map)) => {
149 (Value::Table(mut left_map), Value::Table(right_map)) => {
150+ if merge_depth > 0 {
154− for (rname, rvalue) in right_map {
151+ for (rname, rvalue) in right_map {
155− match left_map.remove(&rname) {
152+ match left_map.remove(&rname) {
156− Some(lvalue) => {
153+ Some(lvalue) => {
157− let merged_value = merge_toml_values(lvalue, rvalue, merge_toplevel_arrays);
154+ let merged_value = merge_toml_values(lvalue, rvalue, merge_depth - 1);
158− left_map.insert(rname, merged_value);
155+ left_map.insert(rname, merged_value);
159− }
156+ }
160− None => {
157+ None => {
161− left_map.insert(rname, rvalue);
158+ left_map.insert(rname, rvalue);
159+ }
162 }
160 }
163 }
161 }
162+ Value::Table(left_map)
163+ } else {
164+ Value::Table(right_map)
164 }
165 }
165− Value::Table(left_map)
166 }
166 }
167 // Catch everything else we didn't handle, and use the right value
167 // Catch everything else we didn't handle, and use the right value
168 (_, value) => value,
168 (_, value) => value,
@@ -187,7 +187,7 @@ mod merge_toml_tests {
187 .expect("Couldn't parse built-in languages config");
187 .expect("Couldn't parse built-in languages config");
188 let user: Value = toml::from_str(USER).unwrap();
188 let user: Value = toml::from_str(USER).unwrap();
189
189
190− let merged = merge_toml_values(base, user, true);
190+ let merged = merge_toml_values(base, user, 3);
191 let languages = merged.get("language").unwrap().as_array().unwrap();
191 let languages = merged.get("language").unwrap().as_array().unwrap();
192 let nix = languages
192 let nix = languages
193 .iter()
193 .iter()
@@ -220,7 +220,7 @@ mod merge_toml_tests {
220 .expect("Couldn't parse built-in languages config");
220 .expect("Couldn't parse built-in languages config");
221 let user: Value = toml::from_str(USER).unwrap();
221 let user: Value = toml::from_str(USER).unwrap();
222
222
223− let merged = merge_toml_values(base, user, true);
223+ let merged = merge_toml_values(base, user, 3);
224 let languages = merged.get("language").unwrap().as_array().unwrap();
224 let languages = merged.get("language").unwrap().as_array().unwrap();
225 let ts = languages
225 let ts = languages
226 .iter()
226 .iter()