aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGokul Soumya2022-03-15 08:04:22 +0000
committerGitHub2022-03-15 08:04:22 +0000
commit2b0835b295bbf57a171210be967e039a1bddf823 (patch)
treef9a61e0458d9015da85bacf1a1ad4e433b8db38c
parent0902ede7b1d4c7edb8b039235456d552aaf44679 (diff)
Refactor :set to parse by deserializing values (#1799)
* Refactor :set to parse by deserializing values * Implement serialize for idle_timeout config
-rw-r--r--helix-core/src/syntax.rs9
-rw-r--r--helix-term/src/commands/typed.rs34
-rw-r--r--helix-view/src/editor.rs22
3 files changed, 36 insertions, 29 deletions
diff --git a/helix-core/src/syntax.rs b/helix-core/src/syntax.rs
index 3b2d56d1..3fc91efc 100644
--- a/helix-core/src/syntax.rs
+++ b/helix-core/src/syntax.rs
@@ -216,14 +216,7 @@ impl FromStr for AutoPairConfig {
// only do bool parsing for runtime setting
fn from_str(s: &str) -> Result<Self, Self::Err> {
let enable: bool = s.parse()?;
-
- let enable = if enable {
- AutoPairConfig::Enable(true)
- } else {
- AutoPairConfig::Enable(false)
- };
-
- Ok(enable)
+ Ok(AutoPairConfig::Enable(enable))
}
}
diff --git a/helix-term/src/commands/typed.rs b/helix-term/src/commands/typed.rs
index 7866ff9d..0801b236 100644
--- a/helix-term/src/commands/typed.rs
+++ b/helix-term/src/commands/typed.rs
@@ -872,34 +872,32 @@ pub(super) fn goto_line_number(
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 setting(
cx: &mut compositor::Context,
args: &[Cow<str>],
_event: PromptEvent,
) -> anyhow::Result<()> {
- let runtime_config = &mut cx.editor.config;
-
if args.len() != 2 {
anyhow::bail!("Bad arguments. Usage: `:set key field`");
}
-
let (key, arg) = (&args[0].to_lowercase(), &args[1]);
- match key.as_ref() {
- "scrolloff" => runtime_config.scrolloff = arg.parse()?,
- "scroll-lines" => runtime_config.scroll_lines = arg.parse()?,
- "mouse" => runtime_config.mouse = arg.parse()?,
- "line-number" => runtime_config.line_number = arg.parse()?,
- "middle-click_paste" => runtime_config.middle_click_paste = arg.parse()?,
- "auto-pairs" => runtime_config.auto_pairs = arg.parse()?,
- "auto-completion" => runtime_config.auto_completion = arg.parse()?,
- "completion-trigger-len" => runtime_config.completion_trigger_len = arg.parse()?,
- "auto-info" => runtime_config.auto_info = arg.parse()?,
- "true-color" => runtime_config.true_color = arg.parse()?,
- "search.smart-case" => runtime_config.search.smart_case = arg.parse()?,
- "search.wrap-around" => runtime_config.search.wrap_around = arg.parse()?,
- _ => anyhow::bail!("Unknown key `{}`.", args[0]),
- }
+ let key_error = || anyhow::anyhow!("Unknown key `{key}`");
+ let field_error = |_| anyhow::anyhow!("Could not parse field `{arg}`");
+
+ let mut config = serde_json::to_value(&cx.editor.config).unwrap();
+ let pointer = format!("/{}", key.replace('.', "/"));
+ let value = config.pointer_mut(&pointer).ok_or_else(key_error)?;
+
+ *value = if value.is_string() {
+ // JSON strings require quotes, so we can't .parse() directly
+ serde_json::Value::String(arg.to_string())
+ } else {
+ arg.parse().map_err(field_error)?
+ };
+ cx.editor.config = serde_json::from_value(config).map_err(field_error)?;
Ok(())
}
diff --git a/helix-view/src/editor.rs b/helix-view/src/editor.rs
index 0eb61308..adf0cdf3 100644
--- a/helix-view/src/editor.rs
+++ b/helix-view/src/editor.rs
@@ -38,7 +38,7 @@ use helix_core::{
use helix_core::{Position, Selection};
use helix_dap as dap;
-use serde::{ser::SerializeMap, Deserialize, Deserializer, Serialize};
+use serde::{ser::SerializeMap, Deserialize, Deserializer, Serialize, Serializer};
fn deserialize_duration_millis<'de, D>(deserializer: D) -> Result<Duration, D::Error>
where
@@ -48,6 +48,18 @@ where
Ok(Duration::from_millis(millis))
}
+fn serialize_duration_millis<S>(duration: &Duration, serializer: S) -> Result<S::Ok, S::Error>
+where
+ S: Serializer,
+{
+ serializer.serialize_u64(
+ duration
+ .as_millis()
+ .try_into()
+ .map_err(|_| serde::ser::Error::custom("duration value overflowed u64"))?,
+ )
+}
+
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case", default, deny_unknown_fields)]
pub struct FilePickerConfig {
@@ -109,8 +121,12 @@ pub struct Config {
pub auto_pairs: AutoPairConfig,
/// Automatic auto-completion, automatically pop up without user trigger. Defaults to true.
pub auto_completion: bool,
- /// Time in milliseconds since last keypress before idle timers trigger. Used for autocompletion, set to 0 for instant. Defaults to 400ms.
- #[serde(skip_serializing, deserialize_with = "deserialize_duration_millis")]
+ /// Time in milliseconds since last keypress before idle timers trigger.
+ /// Used for autocompletion, set to 0 for instant. Defaults to 400ms.
+ #[serde(
+ serialize_with = "serialize_duration_millis",
+ deserialize_with = "deserialize_duration_millis"
+ )]
pub idle_timeout: Duration,
pub completion_trigger_len: u8,
/// Whether to display infoboxes. Defaults to true.