on master help sign in
Add :toggle-option command (#4085)
8b09b00A-Walrus
book/src/generated/typable-cmd.md+1
@@ -61,6 +61,7 @@
61| `:goto`, `:g` | Goto line number. |
61| `:goto`, `:g` | Goto line number. |
62| `:set-language`, `:lang` | Set the language of current buffer. |
62| `:set-language`, `:lang` | Set the language of current buffer. |
63| `:set-option`, `:set` | Set a config option at runtime.<br>For example to disable smart case search, use `:set search.smart-case false`. |
63| `:set-option`, `:set` | Set a config option at runtime.<br>For example to disable smart case search, use `:set search.smart-case false`. |
64+| `:toggle-option`, `:toggle` | Toggle a boolean config option at runtime.<br>For example to toggle smart case search, use `:toggle search.smart-case`. |
64| `:get-option`, `:get` | Get the current value of a config option. |
65| `:get-option`, `:get` | Get the current value of a config option. |
65| `:sort` | Sort ranges in selection. |
66| `:sort` | Sort ranges in selection. |
66| `:rsort` | Sort ranges in selection in reverse order. |
67| `:rsort` | Sort ranges in selection in reverse order. |
helix-term/src/commands/typed.rs+48
@@ -7,6 +7,7 @@ use super::*;
7
7
8use helix_core::encoding;
8use helix_core::encoding;
9use helix_view::editor::{Action, CloseError, ConfigEvent};
9use helix_view::editor::{Action, CloseError, ConfigEvent};
10+use serde_json::Value;
10use ui::completers::{self, Completer};
11use ui::completers::{self, Completer};
11
12
12#[derive(Clone)]
13#[derive(Clone)]
@@ -1646,6 +1647,46 @@ fn set_option(
1646 Ok(())
1647 Ok(())
1647}
1648}
1648
1649
1650+/// Toggle boolean config option at runtime. Access nested values by dot
1651+/// syntax, for example to toggle smart case search, use `:toggle search.smart-
1652+/// case`.
1653+fn toggle_option(
1654+ cx: &mut compositor::Context,
1655+ args: &[Cow<str>],
1656+ event: PromptEvent,
1657+) -> anyhow::Result<()> {
1658+ if event != PromptEvent::Validate {
1659+ return Ok(());
1660+ }
1661+
1662+ if args.len() != 1 {
1663+ anyhow::bail!("Bad arguments. Usage: `:toggle key`");
1664+ }
1665+ let key = &args[0].to_lowercase();
1666+
1667+ let key_error = || anyhow::anyhow!("Unknown key `{}`", key);
1668+
1669+ let mut config = serde_json::json!(&cx.editor.config().deref());
1670+ let pointer = format!("/{}", key.replace('.', "/"));
1671+ let value = config.pointer_mut(&pointer).ok_or_else(key_error)?;
1672+
1673+ if let Value::Bool(b) = *value {
1674+ *value = Value::Bool(!b);
1675+ } else {
1676+ anyhow::bail!("Key `{}` is not toggle-able", key)
1677+ }
1678+
1679+ // This unwrap should never fail because we only replace one boolean value
1680+ // with another, maintaining a valid json config
1681+ let config = serde_json::from_value(config).unwrap();
1682+
1683+ cx.editor
1684+ .config_events
1685+ .0
1686+ .send(ConfigEvent::Update(config))?;
1687+ Ok(())
1688+}
1689+
1649/// Change the language of the current buffer at runtime.
1690/// Change the language of the current buffer at runtime.
1650fn language(
1691fn language(
1651 cx: &mut compositor::Context,
1692 cx: &mut compositor::Context,
@@ -2384,6 +2425,13 @@ pub const TYPABLE_COMMAND_LIST: &[TypableCommand] = &[
2384 fun: set_option,
2425 fun: set_option,
2385 completer: Some(completers::setting),
2426 completer: Some(completers::setting),
2386 },
2427 },
2428+ TypableCommand {
2429+ name: "toggle-option",
2430+ aliases: &["toggle"],
2431+ doc: "Toggle a boolean config option at runtime.\nFor example to toggle smart case search, use `:toggle search.smart-case`.",
2432+ fun: toggle_option,
2433+ completer: Some(completers::setting),
2434+ },
2387 TypableCommand {
2435 TypableCommand {
2388 name: "get-option",
2436 name: "get-option",
2389 aliases: &["get"],
2437 aliases: &["get"],