diff --git a/helix-term/src/commands/typed.rs b/helix-term/src/commands/typed.rs index b0fd18a76b792..f0feea34d03ae 100644 --- a/helix-term/src/commands/typed.rs +++ b/helix-term/src/commands/typed.rs @@ -8,7 +8,6 @@ use super::*; use helix_core::encoding; use helix_view::document::DEFAULT_LANGUAGE_NAME; use helix_view::editor::{Action, CloseError, ConfigEvent}; -use serde_json::Value; use ui::completers::{self, Completer}; #[derive(Clone)] @@ -1660,8 +1659,8 @@ fn toggle_option( return Ok(()); } - if args.len() != 1 { - anyhow::bail!("Bad arguments. Usage: `:toggle key`"); + if args.is_empty() { + anyhow::bail!("Bad arguments. Usage: `:toggle key [values]?`"); } let key = &args[0].to_lowercase(); @@ -1671,15 +1670,40 @@ fn toggle_option( let pointer = format!("/{}", key.replace('.', "/")); let value = config.pointer_mut(&pointer).ok_or_else(key_error)?; - if let Value::Bool(b) = *value { - *value = Value::Bool(!b); + *value = if let Some(v) = value.as_bool() { + serde_json::Value::Bool(!v) } else { - anyhow::bail!("Key `{}` is not toggle-able", key) - } + if args.len() != 2 { + anyhow::bail!( + "Bad arguments. For non-boolean configurations use: `:toggle key val1,val2`" + ); + } - // This unwrap should never fail because we only replace one boolean value - // with another, maintaining a valid json config - let config = serde_json::from_value(config).unwrap(); + let arg = &args[1]; + let field_error = |_| anyhow::anyhow!("Could not parse field `{}`", arg); + + if let Some(v) = value.as_str() { + let arg = &args[1]; + let mut iter = arg.split(','); + let mut curr = iter.next(); + let first = curr; + while curr.is_some() { + if curr.unwrap() == v { + break; + } + curr = iter.next(); + } + if let Some(val) = iter.next().or(first) { + serde_json::Value::String(val.to_string()) + } else { + arg.parse().map_err(field_error)? + } + } else { + arg.parse().map_err(field_error)? + } + }; + let config = serde_json::from_value(config) + .map_err(|_| anyhow::anyhow!("Could not parse field: `{:?}`", &args))?; cx.editor .config_events