From a424ef4e209c0483385acedffd2331534f0ce906 Mon Sep 17 00:00:00 2001 From: Omnikar Date: Mon, 8 Nov 2021 21:07:54 -0500 Subject: [PATCH] Use default `languages.toml` if user's is invalid (#994) --- helix-core/src/syntax.rs | 3 ++- helix-term/src/application.rs | 28 ++++++++++++++++++++-------- 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/helix-core/src/syntax.rs b/helix-core/src/syntax.rs index a5dd0c59..142265a8 100644 --- a/helix-core/src/syntax.rs +++ b/helix-core/src/syntax.rs @@ -40,13 +40,14 @@ where } #[derive(Debug, Serialize, Deserialize)] +#[serde(deny_unknown_fields)] pub struct Configuration { pub language: Vec, } // largely based on tree-sitter/cli/src/loader.rs #[derive(Debug, Serialize, Deserialize)] -#[serde(rename_all = "kebab-case")] +#[serde(rename_all = "kebab-case", deny_unknown_fields)] pub struct LanguageConfiguration { #[serde(rename = "name")] pub language_id: String, diff --git a/helix-term/src/application.rs b/helix-term/src/application.rs index 6037148f..f1884199 100644 --- a/helix-term/src/application.rs +++ b/helix-term/src/application.rs @@ -60,14 +60,19 @@ impl Application { std::sync::Arc::new(theme::Loader::new(&conf_dir, &helix_core::runtime_dir())); // load default and user config, and merge both - let def_lang_conf: toml::Value = toml::from_slice(include_bytes!("../../languages.toml")) - .expect("Could not parse built-in languages.toml, something must be very wrong"); - let user_lang_conf: Option = std::fs::read(conf_dir.join("languages.toml")) + let builtin_err_msg = + "Could not parse built-in languages.toml, something must be very wrong"; + let def_lang_conf: toml::Value = + toml::from_slice(include_bytes!("../../languages.toml")).expect(builtin_err_msg); + let def_syn_loader_conf: helix_core::syntax::Configuration = + def_lang_conf.clone().try_into().expect(builtin_err_msg); + let user_lang_conf = std::fs::read(conf_dir.join("languages.toml")) .ok() - .map(|raw| toml::from_slice(&raw).expect("Could not parse user languages.toml")); + .map(|raw| toml::from_slice(&raw)); let lang_conf = match user_lang_conf { - Some(value) => merge_toml_values(def_lang_conf, value), - None => def_lang_conf, + Some(Ok(value)) => Ok(merge_toml_values(def_lang_conf, value)), + Some(err @ Err(_)) => err, + None => Ok(def_lang_conf), }; let theme = if let Some(theme) = &config.theme { @@ -83,8 +88,15 @@ impl Application { }; let syn_loader_conf: helix_core::syntax::Configuration = lang_conf - .try_into() - .expect("Could not parse merged (built-in + user) languages.toml"); + .and_then(|conf| conf.try_into()) + .unwrap_or_else(|err| { + eprintln!("Bad language config: {}", err); + eprintln!("Press to continue with default language config"); + use std::io::Read; + // This waits for an enter press. + let _ = std::io::stdin().read(&mut []); + def_syn_loader_conf + }); let syn_loader = std::sync::Arc::new(syntax::Loader::new(syn_loader_conf)); let mut editor = Editor::new(