From 230ef1a77d22ff3565ba5998abb350586f3e7e91 Mon Sep 17 00:00:00 2001 From: Gokul Soumya Date: Sat, 12 Mar 2022 21:22:33 +0530 Subject: [PATCH] Refactor :set to parse by deserializing values --- helix-core/src/syntax.rs | 9 +-------- helix-term/src/commands/typed.rs | 34 +++++++++++++++----------------- helix-view/src/editor.rs | 2 +- 3 files changed, 18 insertions(+), 27 deletions(-) diff --git a/helix-core/src/syntax.rs b/helix-core/src/syntax.rs index 3b2d56d126407..3fc91efc88d28 100644 --- a/helix-core/src/syntax.rs +++ b/helix-core/src/syntax.rs @@ -216,14 +216,7 @@ impl FromStr for AutoPairConfig { // only do bool parsing for runtime setting fn from_str(s: &str) -> Result { let enable: bool = s.parse()?; - - let enable = if enable { - AutoPairConfig::Enable(true) - } else { - AutoPairConfig::Enable(false) - }; - - Ok(enable) + Ok(AutoPairConfig::Enable(enable)) } } diff --git a/helix-term/src/commands/typed.rs b/helix-term/src/commands/typed.rs index 3301d1486bd99..1f8a95da475be 100644 --- a/helix-term/src/commands/typed.rs +++ b/helix-term/src/commands/typed.rs @@ -852,34 +852,32 @@ pub(super) fn goto_line_number( Ok(()) } +/// Change config at runtime. Access nested values by dot syntax, for +/// example to disable smart case search, use `:set search.smart-case false`. fn setting( cx: &mut compositor::Context, args: &[Cow], _event: PromptEvent, ) -> anyhow::Result<()> { - let runtime_config = &mut cx.editor.config; - if args.len() != 2 { anyhow::bail!("Bad arguments. Usage: `:set key field`"); } - let (key, arg) = (&args[0].to_lowercase(), &args[1]); - match key.as_ref() { - "scrolloff" => runtime_config.scrolloff = arg.parse()?, - "scroll-lines" => runtime_config.scroll_lines = arg.parse()?, - "mouse" => runtime_config.mouse = arg.parse()?, - "line-number" => runtime_config.line_number = arg.parse()?, - "middle-click_paste" => runtime_config.middle_click_paste = arg.parse()?, - "auto-pairs" => runtime_config.auto_pairs = arg.parse()?, - "auto-completion" => runtime_config.auto_completion = arg.parse()?, - "completion-trigger-len" => runtime_config.completion_trigger_len = arg.parse()?, - "auto-info" => runtime_config.auto_info = arg.parse()?, - "true-color" => runtime_config.true_color = arg.parse()?, - "search.smart-case" => runtime_config.search.smart_case = arg.parse()?, - "search.wrap-around" => runtime_config.search.wrap_around = arg.parse()?, - _ => anyhow::bail!("Unknown key `{}`.", args[0]), - } + let key_error = || anyhow::anyhow!("Unknown key `{key}`"); + let field_error = |_| anyhow::anyhow!("Could not parse field `{arg}`"); + + let mut config = serde_json::to_value(&cx.editor.config).unwrap(); + let pointer = format!("/{}", key.replace(".", "/")); + let value = config.pointer_mut(&pointer).ok_or_else(key_error)?; + + *value = if value.is_string() { + // JSON strings require quotes, so we can't .parse() directly + serde_json::Value::String(arg.to_string()) + } else { + arg.parse().map_err(field_error)? + }; + cx.editor.config = serde_json::from_value(config).map_err(field_error)?; Ok(()) } diff --git a/helix-view/src/editor.rs b/helix-view/src/editor.rs index 0eb613087d80c..f0c262b8e995f 100644 --- a/helix-view/src/editor.rs +++ b/helix-view/src/editor.rs @@ -110,7 +110,7 @@ pub struct Config { /// Automatic auto-completion, automatically pop up without user trigger. Defaults to true. pub auto_completion: bool, /// Time in milliseconds since last keypress before idle timers trigger. Used for autocompletion, set to 0 for instant. Defaults to 400ms. - #[serde(skip_serializing, deserialize_with = "deserialize_duration_millis")] + #[serde(deserialize_with = "deserialize_duration_millis")] pub idle_timeout: Duration, pub completion_trigger_len: u8, /// Whether to display infoboxes. Defaults to true.