@@ -7,6 +7,7 @@ use super::*;
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};
12#[derive(Clone)]
13#[derive(Clone)]
@@ -1646,6 +1647,46 @@ fn set_option(
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-
1654+ cx: &mut compositor::Context,
1656+ event: PromptEvent,
1657+) -> anyhow::Result<()> {
1658+ if event != PromptEvent::Validate {
1662+ if args.len() != 1 {
1663+ anyhow::bail!("Bad arguments. Usage: `:toggle key`");
1665+ let key = &args[0].to_lowercase();
1667+ let key_error = || anyhow::anyhow!("Unknown key `{}`", key);
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)?;
1673+ if let Value::Bool(b) = *value {
1674+ *value = Value::Bool(!b);
1676+ anyhow::bail!("Key `{}` is not toggle-able", key)
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();
1686+ .send(ConfigEvent::Update(config))?;
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),
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),
2387 TypableCommand {
2435 TypableCommand {
2388 name: "get-option",
2436 name: "get-option",
2389 aliases: &["get"],
2437 aliases: &["get"],