on master help sign in
feat(commands): allows cycling option values at runtime (#4411)
commitd5707a4696af0c63ec350791501440e7d0adc036 authorAlex Vinyals <alevinval@gmail.com> dateMon 5 Jun 2023, 15:22 (3 years ago) parent2022e61
1 file changed+37−12
helix-term/src/commands/typed.rs+37−12
helix-term/src/commands/typed.rs+37−12
@@ -8,7 +8,6 @@ use super::*;
88use helix_core::{encoding, shellwords::Shellwords};
99use helix_view::document::DEFAULT_LANGUAGE_NAME;
1010use helix_view::editor::{Action, CloseError, ConfigEvent};
11−use serde_json::Value;
1211use ui::completers::{self, Completer};
1312
1413#[derive(Clone)]
@@ -1790,8 +1789,8 @@ fn toggle_option(
17901789 return Ok(());
17911790 }
17921791
1793− if args.len() != 1 {
1794− anyhow::bail!("Bad arguments. Usage: `:toggle key`");
1792+ if args.is_empty() {
1793+ anyhow::bail!("Bad arguments. Usage: `:toggle key [values]?`");
17951794 }
17961795 let key = &args[0].to_lowercase();
17971796
@@ -1801,22 +1800,48 @@ fn toggle_option(
18011800 let pointer = format!("/{}", key.replace('.', "/"));
18021801 let value = config.pointer_mut(&pointer).ok_or_else(key_error)?;
18031802
1804− let Value::Bool(old_value) = *value else {
1805− anyhow::bail!("Key `{}` is not toggle-able", key)
1803+ *value = match value.as_bool() {
1804+ Some(value) => {
1805+ ensure!(
1806+ args.len() == 1,
1807+ "Bad arguments. For boolean configurations use: `:toggle key`"
1808+ );
1809+ serde_json::Value::Bool(!value)
1810+ }
1811+ None => {
1812+ ensure!(
1813+ args.len() > 2,
1814+ "Bad arguments. For non-boolean configurations use: `:toggle key val1 val2 ...`",
1815+ );
1816+ ensure!(
1817+ value.is_string(),
1818+ "Bad configuration. Cannot cycle non-string configurations"
1819+ );
1820+
1821+ let value = value
1822+ .as_str()
1823+ .expect("programming error: should have been ensured before");
1824+
1825+ serde_json::Value::String(
1826+ args[1..]
1827+ .iter()
1828+ .skip_while(|e| *e != value)
1829+ .nth(1)
1830+ .unwrap_or_else(|| &args[1])
1831+ .to_string(),
1832+ )
1833+ }
18061834 };
18071835
1808− let new_value = !old_value;
1809− *value = Value::Bool(new_value);
1810− // This unwrap should never fail because we only replace one boolean value
1811− // with another, maintaining a valid json config
1812− let config = serde_json::from_value(config).unwrap();
1836+ let status = format!("'{key}' is now set to {value}");
1837+ let config = serde_json::from_value(config)
1838+ .map_err(|_| anyhow::anyhow!("Could not parse field: `{:?}`", &args))?;
18131839
18141840 cx.editor
18151841 .config_events
18161842 .0
18171843 .send(ConfigEvent::Update(config))?;
1818− cx.editor
1819− .set_status(format!("Option `{}` is now set to `{}`", key, new_value));
1844+ cx.editor.set_status(status);
18201845 Ok(())
18211846}
18221847