diff --git a/book/src/generated/typable-cmd.md b/book/src/generated/typable-cmd.md index 66e6ac039c265..028f1457d7e65 100644 --- a/book/src/generated/typable-cmd.md +++ b/book/src/generated/typable-cmd.md @@ -60,6 +60,7 @@ | `:goto`, `:g` | Goto line number. | | `:set-language`, `:lang` | Set the language of current buffer. | | `:set-option`, `:set` | Set a config option at runtime.
For example to disable smart case search, use `:set search.smart-case false`. | +| `:toggle-option`, `:toggle` | Toggle a config option at runtime.
For example to toggle smart case search, use `:toggle search.smart-case`. | | `:get-option`, `:get` | Get the current value of a config option. | | `:sort` | Sort ranges in selection. | | `:rsort` | Sort ranges in selection in reverse order. | diff --git a/helix-term/src/commands/typed.rs b/helix-term/src/commands/typed.rs index ec7100a637405..d8c8cb3afae82 100644 --- a/helix-term/src/commands/typed.rs +++ b/helix-term/src/commands/typed.rs @@ -1479,6 +1479,42 @@ fn get_option( Ok(()) } +/// Change config at runtime. Access nested values by dot syntax, for +/// example to toggle smart case search, use `:toggle search.smart-case`. +fn toggle_option( + cx: &mut compositor::Context, + args: &[Cow], + event: PromptEvent, +) -> anyhow::Result<()> { + if event != PromptEvent::Validate { + return Ok(()); + } + + if args.len() != 1 { + anyhow::bail!("Bad arguments. Usage: `:toggle key`"); + } + + let key = &args[0].to_lowercase(); + + let key_error = || anyhow!("Unknown key `{}`", key); + + let mut config = serde_json::json!(&cx.editor.config().deref()); + let pointer = format!("/{}", key.replace('.', "/")); + let value = config.pointer_mut(&pointer).ok_or_else(key_error)?; + + *value = match value { + serde_json::Value::Bool(v) => serde_json::Value::Bool(!*v), + _ => anyhow::bail!("key {} must be a bool to be toggled", key), + }; + let config = serde_json::from_value(config)?; + + cx.editor + .config_events + .0 + .send(ConfigEvent::Update(config))?; + 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 set_option( @@ -2246,6 +2282,13 @@ pub const TYPABLE_COMMAND_LIST: &[TypableCommand] = &[ fun: set_option, completer: Some(completers::setting), }, + TypableCommand { + name: "toggle-option", + aliases: &["toggle"], + doc: "Toggle a config option at runtime.\nFor example to toggle smart case search, use `:toggle search.smart-case`.", + fun: toggle_option, + completer: Some(completers::setting), + }, TypableCommand { name: "get-option", aliases: &["get"],