From 075a552430fa412dd72dfb1392d08eca7f9c3e45 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Thu, 17 Oct 2019 10:14:05 -0700 Subject: [PATCH] Tweak how highlight query paths are specified in package.json --- cli/src/loader.rs | 126 +++++++++++++++++++++++++++------------------- cli/src/main.rs | 10 +++- 2 files changed, 84 insertions(+), 52 deletions(-) diff --git a/cli/src/loader.rs b/cli/src/loader.rs index 8610eaaa..9b95faaf 100644 --- a/cli/src/loader.rs +++ b/cli/src/loader.rs @@ -28,9 +28,9 @@ pub struct LanguageConfiguration { pub injection_regex: Option, pub file_types: Vec, pub root_path: PathBuf, - pub highlights_filename: Option, - pub injections_filename: Option, - pub locals_filename: Option, + pub highlights_filenames: Option>, + pub injections_filenames: Option>, + pub locals_filenames: Option>, language_id: usize, highlight_config: OnceCell>, } @@ -343,6 +343,30 @@ impl Loader { &'a mut self, parser_path: &Path, ) -> Result<&[LanguageConfiguration]> { + #[derive(Deserialize)] + #[serde(untagged)] + enum PathsJSON { + Empty, + Single(String), + Multiple(Vec), + } + + impl Default for PathsJSON { + fn default() -> Self { + PathsJSON::Empty + } + } + + impl PathsJSON { + fn into_vec(self) -> Option> { + match self { + PathsJSON::Empty => None, + PathsJSON::Single(s) => Some(vec![s]), + PathsJSON::Multiple(s) => Some(s), + } + } + } + #[derive(Deserialize)] struct LanguageConfigurationJSON { #[serde(default)] @@ -356,9 +380,12 @@ impl Loader { first_line_regex: Option, #[serde(rename = "injection-regex")] injection_regex: Option, - highlights: Option, - injections: Option, - locals: Option, + #[serde(default)] + highlights: PathsJSON, + #[serde(default)] + injections: PathsJSON, + #[serde(default)] + locals: PathsJSON, } #[derive(Deserialize)] @@ -411,9 +438,9 @@ impl Loader { .injection_regex .and_then(|r| RegexBuilder::new(&r).multi_line(true).build().ok()), highlight_config: OnceCell::new(), - injections_filename: config_json.injections, - locals_filename: config_json.locals, - highlights_filename: config_json.highlights, + injections_filenames: config_json.injections.into_vec(), + locals_filenames: config_json.locals.into_vec(), + highlights_filenames: config_json.highlights.into_vec(), }; for file_type in &configuration.file_types { @@ -452,51 +479,48 @@ impl LanguageConfiguration { self.highlight_config .get_or_try_init(|| { let queries_path = self.root_path.join("queries"); + let read_queries = |paths: &Option>, default_path: &str| { + if let Some(paths) = paths.as_ref() { + let mut query = String::new(); + for path in paths { + let path = self.root_path.join(path); + query += &fs::read_to_string(&path).map_err(Error::wrap(|| { + format!("Failed to read query file {:?}", path) + }))?; + } + Ok(query) + } else { + let path = queries_path.join(default_path); + if path.exists() { + fs::read_to_string(&path).map_err(Error::wrap(|| { + format!("Failed to read query file {:?}", path) + })) + } else { + Ok(String::new()) + } + } + }; - let highlights_path = queries_path.join( - self.highlights_filename - .as_ref() - .map_or("highlights.scm", String::as_str), - ); - let injections_path = queries_path.join( - self.injections_filename - .as_ref() - .map_or("injections.scm", String::as_str), - ); - let locals_path = queries_path.join( - self.locals_filename - .as_ref() - .map_or("locals.scm", String::as_str), - ); + let highlights_query = read_queries(&self.highlights_filenames, "highlights.scm")?; + let injections_query = read_queries(&self.injections_filenames, "injections.scm")?; + let locals_query = read_queries(&self.locals_filenames, "locals.scm")?; - if !highlights_path.exists() { - return Ok(None); + if highlights_query.is_empty() { + Ok(None) + } else { + Ok(Some( + highlighter + .load_configuration( + language, + &highlights_query, + &injections_query, + &locals_query, + ) + .map_err(Error::wrap(|| { + format!("Failed to load queries in {:?}", self.root_path) + }))?, + )) } - - let highlights_query = fs::read_to_string(highlights_path)?; - let injections_query = if injections_path.exists() { - fs::read_to_string(injections_path)? - } else { - String::new() - }; - let locals_query = if locals_path.exists() { - fs::read_to_string(locals_path)? - } else { - String::new() - }; - - Ok(Some( - highlighter - .load_configuration( - language, - &highlights_query, - &injections_query, - &locals_query, - ) - .map_err(Error::wrap(|| { - format!("Failed to load queries in {:?}", queries_path) - }))?, - )) }) .map(Option::as_ref) } diff --git a/cli/src/main.rs b/cli/src/main.rs index 25ffe5f7..832cd92c 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -284,9 +284,17 @@ fn run() -> error::Result<()> { loader.find_all_languages(&config.parser_directories)?; for (configuration, language_path) in loader.get_all_language_configurations() { println!( - "scope: {}\nparser: {:?}\nfile_types: {:?}\ncontent_regex: {:?}\ninjection_regex: {:?}\n", + concat!( + "scope: {}\n", + "parser: {:?}\n", + "highlights: {:?}\n", + "file_types: {:?}\n", + "content_regex: {:?}\n", + "injection_regex: {:?}\n", + ), configuration.scope.as_ref().unwrap_or(&String::new()), language_path, + configuration.highlights_filenames, configuration.file_types, configuration.content_regex, configuration.injection_regex,