diff options
author | Kirawi | 2022-04-18 03:10:51 +0000 |
---|---|---|
committer | GitHub | 2022-04-18 03:10:51 +0000 |
commit | c2a40d9d5229c701fa1a6d0fb80ce4ba86e8dc0c (patch) | |
tree | b27da29863432ca7ee48c582f5aeb538d7a39ea1 /helix-loader | |
parent | be656c14e32243fc32ed68f9a3240301f2902df7 (diff) |
Add support for local language configuration (#1249)
* add local configuration
* move config loading to Application::new
* simplify find_root_impl
Diffstat (limited to 'helix-loader')
-rw-r--r-- | helix-loader/Cargo.toml | 2 | ||||
-rw-r--r-- | helix-loader/src/config.rs | 26 | ||||
-rw-r--r-- | helix-loader/src/grammar.rs | 2 | ||||
-rw-r--r-- | helix-loader/src/lib.rs | 53 |
4 files changed, 66 insertions, 17 deletions
diff --git a/helix-loader/Cargo.toml b/helix-loader/Cargo.toml index 21b37333..607d1a0a 100644 --- a/helix-loader/Cargo.toml +++ b/helix-loader/Cargo.toml @@ -18,6 +18,8 @@ tree-sitter = "0.20" libloading = "0.7" once_cell = "1.9" +log = "0.4" + # cloning/compiling tree-sitter grammars cc = { version = "1" } threadpool = { version = "1.0" } diff --git a/helix-loader/src/config.rs b/helix-loader/src/config.rs new file mode 100644 index 00000000..3d71baed --- /dev/null +++ b/helix-loader/src/config.rs @@ -0,0 +1,26 @@ +/// Default bultin-in languages.toml. +pub fn default_lang_config() -> toml::Value { + toml::from_slice(include_bytes!("../../languages.toml")) + .expect("Could not parse bultin-in languages.toml to valid toml") +} + +/// User configured languages.toml file, merged with the default config. +pub fn user_lang_config() -> Result<toml::Value, toml::de::Error> { + let config = crate::local_config_dirs() + .into_iter() + .chain([crate::config_dir()].into_iter()) + .map(|path| path.join("languages.toml")) + .filter_map(|file| { + std::fs::read(&file) + .map(|config| toml::from_slice(&config)) + .ok() + }) + .collect::<Result<Vec<_>, _>>()? + .into_iter() + .chain([default_lang_config()].into_iter()) + .fold(toml::Value::Table(toml::value::Table::default()), |a, b| { + crate::merge_toml_values(b, a) + }); + + Ok(config) +} diff --git a/helix-loader/src/grammar.rs b/helix-loader/src/grammar.rs index 7474713a..9d63a2be 100644 --- a/helix-loader/src/grammar.rs +++ b/helix-loader/src/grammar.rs @@ -92,7 +92,7 @@ pub fn build_grammars() -> Result<()> { // merged. The `grammar_selection` key of the config is then used to filter // down all grammars into a subset of the user's choosing. fn get_grammar_configs() -> Result<Vec<GrammarConfiguration>> { - let config: Configuration = crate::user_lang_config() + let config: Configuration = crate::config::user_lang_config() .context("Could not parse languages.toml")? .try_into()?; diff --git a/helix-loader/src/lib.rs b/helix-loader/src/lib.rs index a2c4d96f..de2951f8 100644 --- a/helix-loader/src/lib.rs +++ b/helix-loader/src/lib.rs @@ -1,3 +1,4 @@ +pub mod config; pub mod grammar; use etcetera::base_strategy::{choose_base_strategy, BaseStrategy}; @@ -36,6 +37,15 @@ pub fn config_dir() -> std::path::PathBuf { path } +pub fn local_config_dirs() -> Vec<std::path::PathBuf> { + let directories = find_root_impl(None, &[".helix".to_string()]) + .into_iter() + .map(|path| path.join(".helix")) + .collect(); + log::debug!("Located configuration folders: {:?}", directories); + directories +} + pub fn cache_dir() -> std::path::PathBuf { // TODO: allow env var override let strategy = choose_base_strategy().expect("Unable to find the config directory!"); @@ -56,25 +66,36 @@ pub fn log_file() -> std::path::PathBuf { cache_dir().join("helix.log") } -/// Default bultin-in languages.toml. -pub fn default_lang_config() -> toml::Value { - toml::from_slice(include_bytes!("../../languages.toml")) - .expect("Could not parse bultin-in languages.toml to valid toml") -} - -/// User configured languages.toml file, merged with the default config. -pub fn user_lang_config() -> Result<toml::Value, toml::de::Error> { - let def_lang_conf = default_lang_config(); - let data = std::fs::read(crate::config_dir().join("languages.toml")); - let user_lang_conf = match data { - Ok(raw) => { - let value = toml::from_slice(&raw)?; - merge_toml_values(def_lang_conf, value) +pub fn find_root_impl(root: Option<&str>, root_markers: &[String]) -> Vec<std::path::PathBuf> { + let current_dir = std::env::current_dir().expect("unable to determine current directory"); + let mut directories = Vec::new(); + + let root = match root { + Some(root) => { + let root = std::path::Path::new(root); + if root.is_absolute() { + root.to_path_buf() + } else { + current_dir.join(root) + } } - Err(_) => def_lang_conf, + None => current_dir, }; - Ok(user_lang_conf) + for ancestor in root.ancestors() { + // don't go higher than repo + if ancestor.join(".git").is_dir() { + // Use workspace if detected from marker + directories.push(ancestor.to_path_buf()); + break; + } else if root_markers + .iter() + .any(|marker| ancestor.join(marker).exists()) + { + directories.push(ancestor.to_path_buf()); + } + } + directories } // right overrides left |