diff options
author | A-Walrus | 2023-02-13 02:40:31 +0000 |
---|---|---|
committer | GitHub | 2023-02-13 02:40:31 +0000 |
commit | 8b09b0094285bb832ab88ac001b1fe631b10bfb1 (patch) | |
tree | b9d1fecbe35356c5624baf1412d9efb500592a0d | |
parent | 87518db1d12ea48a4d2fce7808e24852992b03ee (diff) |
Add :toggle-option command (#4085)
This command toggles the value of boolean options
-rw-r--r-- | book/src/generated/typable-cmd.md | 1 | ||||
-rw-r--r-- | helix-term/src/commands/typed.rs | 48 |
2 files changed, 49 insertions, 0 deletions
diff --git a/book/src/generated/typable-cmd.md b/book/src/generated/typable-cmd.md index 0ff501a3..7416ac32 100644 --- a/book/src/generated/typable-cmd.md +++ b/book/src/generated/typable-cmd.md @@ -61,6 +61,7 @@ | `:goto`, `:g` | Goto line number. | | `:set-language`, `:lang` | Set the language of current buffer. | | `:set-option`, `:set` | Set a config option at runtime.<br>For example to disable smart case search, use `:set search.smart-case false`. | +| `:toggle-option`, `:toggle` | Toggle a boolean config option at runtime.<br>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 0cc1b743..6b45b005 100644 --- a/helix-term/src/commands/typed.rs +++ b/helix-term/src/commands/typed.rs @@ -7,6 +7,7 @@ use super::*; use helix_core::encoding; use helix_view::editor::{Action, CloseError, ConfigEvent}; +use serde_json::Value; use ui::completers::{self, Completer}; #[derive(Clone)] @@ -1646,6 +1647,46 @@ fn set_option( Ok(()) } +/// Toggle boolean config option 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<str>], + 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::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)?; + + if let Value::Bool(b) = *value { + *value = Value::Bool(!b); + } else { + anyhow::bail!("Key `{}` is not toggle-able", key) + } + + // 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(); + + cx.editor + .config_events + .0 + .send(ConfigEvent::Update(config))?; + Ok(()) +} + /// Change the language of the current buffer at runtime. fn language( cx: &mut compositor::Context, @@ -2385,6 +2426,13 @@ pub const TYPABLE_COMMAND_LIST: &[TypableCommand] = &[ completer: Some(completers::setting), }, TypableCommand { + name: "toggle-option", + aliases: &["toggle"], + doc: "Toggle a boolean 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"], doc: "Get the current value of a config option.", |