From 7a31f23f3fd937585c61f9abb286624cac301e87 Mon Sep 17 00:00:00 2001 From: Nicolas BACQUEY Date: Thu, 9 Jan 2025 15:42:45 +0100 Subject: [PATCH] Identify comments with independent query files Instead of using ad hoc logic to identify comment nodes, this commit uses a separate query file. --- examples/client-app/src/main.rs | 1 + topiary-cli/src/io.rs | 78 +++++++++++++++++-- topiary-config/src/language.rs | 18 ++++- topiary-core/benches/benchmark.rs | 5 ++ topiary-core/src/comments.rs | 53 +++++++------ topiary-core/src/language.rs | 3 + topiary-core/src/lib.rs | 4 + topiary-core/src/tree_sitter.rs | 49 +++++++++++- topiary-core/tests/comment_tests.rs | 9 ++- topiary-playground/src/lib.rs | 1 + topiary-queries/queries/bash.comment.scm | 2 + topiary-queries/queries/css.comment.scm | 2 + topiary-queries/queries/nickel.comment.scm | 2 + topiary-queries/queries/ocaml.comment.scm | 2 + .../queries/ocaml_interface.comment.scm | 1 + topiary-queries/queries/ocamllex.comment.scm | 2 + topiary-queries/queries/rust.comment.scm | 5 ++ topiary-queries/queries/toml.comment.scm | 2 + .../queries/tree_sitter_query.comment.scm | 2 + topiary-queries/src/lib.rs | 55 +++++++++++++ 20 files changed, 256 insertions(+), 40 deletions(-) create mode 100644 topiary-queries/queries/bash.comment.scm create mode 100644 topiary-queries/queries/css.comment.scm create mode 100644 topiary-queries/queries/nickel.comment.scm create mode 100644 topiary-queries/queries/ocaml.comment.scm create mode 120000 topiary-queries/queries/ocaml_interface.comment.scm create mode 100644 topiary-queries/queries/ocamllex.comment.scm create mode 100644 topiary-queries/queries/rust.comment.scm create mode 100644 topiary-queries/queries/toml.comment.scm create mode 100644 topiary-queries/queries/tree_sitter_query.comment.scm diff --git a/examples/client-app/src/main.rs b/examples/client-app/src/main.rs index c4d624bc..a57f2c11 100644 --- a/examples/client-app/src/main.rs +++ b/examples/client-app/src/main.rs @@ -26,6 +26,7 @@ async fn main() { let language: Language = Language { name: "json".to_owned(), query: TopiaryQuery::new(&grammar, query).unwrap(), + comment_query: None, grammar, indent: None, }; diff --git a/topiary-cli/src/io.rs b/topiary-cli/src/io.rs index a01cdd7d..bee0f6e6 100644 --- a/topiary-cli/src/io.rs +++ b/topiary-cli/src/io.rs @@ -113,6 +113,7 @@ pub struct InputFile<'cfg> { source: InputSource, language: &'cfg topiary_config::language::Language, query: QuerySource, + comment_query: Option, } impl<'cfg> InputFile<'cfg> { @@ -125,9 +126,21 @@ impl<'cfg> InputFile<'cfg> { }; let query = TopiaryQuery::new(&grammar, &contents)?; + // Can't use `map` because of closures, async, and Result. + let comment_contents = match &self.comment_query { + Some(QuerySource::Path(query)) => Some(tokio::fs::read_to_string(query).await?), + Some(QuerySource::BuiltIn(contents)) => Some(contents.to_owned()), + None => None, + }; + let comment_query = match comment_contents { + Some(c) => Some(TopiaryQuery::new(&grammar, &c)?), + None => None, + }; + Ok(Language { name: self.language.name.clone(), query, + comment_query, grammar, indent: self.language().config.indent.clone(), }) @@ -178,9 +191,9 @@ impl<'cfg, 'i> Inputs<'cfg> { InputFrom::Stdin(language_name, query) => { vec![(|| { let language = config.get_language(&language_name)?; - let query_source: QuerySource = match query { + let (query, comment_query) = match query { // The user specified a query file - Some(p) => p, + Some(p) => (p, None), // The user did not specify a file, try the default locations None => to_query_from_language(language)?, }; @@ -188,7 +201,8 @@ impl<'cfg, 'i> Inputs<'cfg> { Ok(InputFile { source: InputSource::Stdin, language, - query: query_source, + query, + comment_query, }) })()] } @@ -197,12 +211,13 @@ impl<'cfg, 'i> Inputs<'cfg> { .into_iter() .map(|path| { let language = config.detect(&path)?; - let query: QuerySource = to_query_from_language(language)?; + let (query, comment_query) = to_query_from_language(language)?; Ok(InputFile { source: InputSource::Disk(path, None), language, query, + comment_query, }) }) .collect(), @@ -212,16 +227,21 @@ impl<'cfg, 'i> Inputs<'cfg> { } } -fn to_query_from_language(language: &topiary_config::language::Language) -> CLIResult { - let query: QuerySource = match language.find_query_file() { - Ok(p) => p.into(), +fn to_query_from_language( + language: &topiary_config::language::Language, +) -> CLIResult<(QuerySource, Option)> { + let query: (QuerySource, Option) = match language.find_query_file() { + Ok((path, comment_path)) => (path.into(), comment_path.map(|p| p.into())), // For some reason, Topiary could not find any // matching file in a default location. As a final attempt, try the // builtin ones. Store the error, return that if we // fail to find anything, because the builtin error might be unexpected. Err(e) => { log::warn!("No query files found in any of the expected locations. Falling back to compile-time included files."); - to_query(&language.name).map_err(|_| e)? + ( + to_query(&language.name).map_err(|_| e)?, + to_comment_query(&language.name)?, + ) } }; Ok(query) @@ -364,3 +384,45 @@ where )), } } + +fn to_comment_query(name: T) -> CLIResult> +where + T: AsRef + fmt::Display, +{ + match name.as_ref() { + #[cfg(feature = "bash")] + "bash" => Ok(Some(topiary_queries::bash_comment().into())), + + #[cfg(feature = "css")] + "css" => Ok(Some(topiary_queries::css_comment().into())), + + #[cfg(feature = "json")] + "json" => Ok(None), + + #[cfg(feature = "nickel")] + "nickel" => Ok(Some(topiary_queries::nickel_comment().into())), + + #[cfg(feature = "ocaml")] + "ocaml" => Ok(Some(topiary_queries::ocaml_comment().into())), + + #[cfg(feature = "ocaml_interface")] + "ocaml_interface" => Ok(Some(topiary_queries::ocaml_interface_comment().into())), + + #[cfg(feature = "ocamllex")] + "ocamllex" => Ok(Some(topiary_queries::ocamllex_comment().into())), + + #[cfg(feature = "rust")] + "rust" => Ok(Some(topiary_queries::rust_comment().into())), + + #[cfg(feature = "toml")] + "toml" => Ok(Some(topiary_queries::toml_comment().into())), + + #[cfg(feature = "tree_sitter_query")] + "tree_sitter_query" => Ok(Some(topiary_queries::tree_sitter_query_comment().into())), + + name => Err(TopiaryError::Bin( + format!("The specified language is unsupported: {}", name), + Some(CLIError::UnsupportedLanguage(name.to_string())), + )), + } +} diff --git a/topiary-config/src/language.rs b/topiary-config/src/language.rs index 297f62c5..daa4b80f 100644 --- a/topiary-config/src/language.rs +++ b/topiary-config/src/language.rs @@ -81,8 +81,10 @@ impl Language { } #[cfg(not(target_arch = "wasm32"))] - pub fn find_query_file(&self) -> TopiaryConfigResult { - let basename = PathBuf::from(self.name.as_str()).with_extension("scm"); + pub fn find_query_file(&self) -> TopiaryConfigResult<(PathBuf, Option)> { + let name = self.name.clone(); + let basename = PathBuf::from(&name).with_extension("scm"); // "clang.scm" + let comment_basename = PathBuf::from(&name).with_extension("comment.scm"); // "clang.comment.scm" #[rustfmt::skip] let potentials: [Option; 4] = [ @@ -92,12 +94,20 @@ impl Language { Some(PathBuf::from("../topiary-queries/queries")), ]; - potentials + let query_file = potentials .into_iter() .flatten() .map(|path| path.join(&basename)) .find(|path| path.exists()) - .ok_or_else(|| TopiaryConfigError::QueryFileNotFound(basename)) + .ok_or_else(|| TopiaryConfigError::QueryFileNotFound(basename))?; + + let comment_query_file = query_file.parent().unwrap().join(comment_basename); + + if comment_query_file.exists() { + Ok((query_file, Some(comment_query_file))) + } else { + Ok((query_file, None)) + } } #[cfg(not(target_arch = "wasm32"))] diff --git a/topiary-core/benches/benchmark.rs b/topiary-core/benches/benchmark.rs index f25b9b53..49fe55b8 100644 --- a/topiary-core/benches/benchmark.rs +++ b/topiary-core/benches/benchmark.rs @@ -7,6 +7,8 @@ use topiary_core::{formatter, Language, Operation, TopiaryQuery}; async fn format() { let input = fs::read_to_string("../topiary-cli/tests/samples/input/ocaml.ml").unwrap(); let query_content = fs::read_to_string("../topiary-queries/queries/ocaml.scm").unwrap(); + let comment_query_content = + fs::read_to_string("../topiary-queries/queries/ocaml.comment.scm").unwrap(); let ocaml = tree_sitter_ocaml::LANGUAGE_OCAML; let mut input = input.as_bytes(); @@ -15,6 +17,9 @@ async fn format() { let language: Language = Language { name: "ocaml".to_owned(), query: TopiaryQuery::new(&ocaml.clone().into(), &query_content).unwrap(), + comment_query: Some( + TopiaryQuery::new(&ocaml.clone().into(), &comment_query_content).unwrap(), + ), grammar: ocaml.into(), indent: None, }; diff --git a/topiary-core/src/comments.rs b/topiary-core/src/comments.rs index 82257583..b733c84e 100644 --- a/topiary-core/src/comments.rs +++ b/topiary-core/src/comments.rs @@ -1,3 +1,5 @@ +use std::collections::HashSet; + use topiary_tree_sitter_facade::{InputEdit, Language, Node, Tree}; use crate::{ @@ -63,11 +65,6 @@ impl Diff for InputSection { } } -// TODO: allow the users to manually identify comments. Maybe with a separate query file? -fn is_comment(node: &Node) -> bool { - node.is_extra() && node.kind().to_string().contains("comment") -} - fn into_edit(node: &Node<'_>) -> InputEdit { InputEdit::new( node.start_byte(), @@ -82,10 +79,11 @@ fn into_edit(node: &Node<'_>) -> InputEdit { fn find_comments( node: Node, input: &str, + comment_ids: &HashSet, comments: &mut Vec<(InputEdit, AnchoredComment)>, ) -> FormatterResult<()> { - if is_comment(&node) { - let commented = find_anchor(&node, input)?; + if comment_ids.contains(&node.id()) { + let commented = find_anchor(&node, input, comment_ids)?; // Build the corresponding InputEdit: // - If the comment is not alone on its line, return its bounds // - If the comment is alone on its line, return the bounds of all its line @@ -150,7 +148,7 @@ fn find_comments( } else { let mut walker = node.walk(); for child in node.children(&mut walker) { - find_comments(child, input, comments)?; + find_comments(child, input, comment_ids, comments)?; } Ok(()) } @@ -259,7 +257,10 @@ fn previous_disjoint_node<'tree>(starting_node: &'tree Node<'tree>) -> Option(starting_node: Node<'tree>) -> Option> { +fn next_non_comment_leaf<'tree>( + starting_node: Node<'tree>, + comment_ids: &HashSet, +) -> Option> { let mut node: Node<'tree> = starting_node; loop { // get the next leaf: @@ -275,7 +276,7 @@ fn next_non_comment_leaf<'tree>(starting_node: Node<'tree>) -> Option { node = sibling; - if is_comment(&node) { + if comment_ids.contains(&node.id()) { // get the following sibling continue; } else { @@ -287,14 +288,14 @@ fn next_non_comment_leaf<'tree>(starting_node: Node<'tree>) -> Option(starting_node: Node<'tree>) -> Option(starting_node: Node<'tree>) -> Option> { +fn previous_non_comment_leaf<'tree>( + starting_node: Node<'tree>, + comment_ids: &HashSet, +) -> Option> { let mut node: Node<'tree> = starting_node; loop { // get the previous leaf: @@ -320,7 +324,7 @@ fn previous_non_comment_leaf<'tree>(starting_node: Node<'tree>) -> Option { node = sibling; - if is_comment(&node) { + if comment_ids.contains(&node.id()) { // get the previous sibling continue; } else { @@ -338,14 +342,14 @@ fn previous_non_comment_leaf<'tree>(starting_node: Node<'tree>) -> Option(starting_node: Node<'tree>) -> Option(node: &'tree Node<'tree>, input: &str) -> FormatterResult { +fn find_anchor<'tree>( + node: &'tree Node<'tree>, + input: &str, + comment_ids: &HashSet, +) -> FormatterResult { let point = node.start_position(); let mut lines = input.lines(); let prefix = lines @@ -377,7 +385,7 @@ fn find_anchor<'tree>(node: &'tree Node<'tree>, input: &str) -> FormatterResult< ) })?; if prefix.trim_start() == "" { - if let Some(anchor) = next_non_comment_leaf(node.clone()) { + if let Some(anchor) = next_non_comment_leaf(node.clone(), comment_ids) { let prev = previous_disjoint_node(node); let next = next_disjoint_node(node); Ok(Commented::CommentedAfter { @@ -389,7 +397,7 @@ fn find_anchor<'tree>(node: &'tree Node<'tree>, input: &str) -> FormatterResult< .map(|prev| prev.end_position().row() + 1 < node.start_position().row()) .unwrap_or(false), }) - } else if let Some(anchor) = previous_non_comment_leaf(node.clone()) { + } else if let Some(anchor) = previous_non_comment_leaf(node.clone(), comment_ids) { Ok(Commented::CommentedBefore((&anchor).into())) } else { Err(FormatterError::CommentOrphaned( @@ -397,9 +405,9 @@ fn find_anchor<'tree>(node: &'tree Node<'tree>, input: &str) -> FormatterResult< )) } } else { - if let Some(anchor) = previous_non_comment_leaf(node.clone()) { + if let Some(anchor) = previous_non_comment_leaf(node.clone(), comment_ids) { Ok(Commented::CommentedBefore((&anchor).into())) - } else if let Some(anchor) = next_non_comment_leaf(node.clone()) { + } else if let Some(anchor) = next_non_comment_leaf(node.clone(), comment_ids) { let prev = previous_disjoint_node(node); let next = next_disjoint_node(node); Ok(Commented::CommentedAfter { @@ -445,6 +453,7 @@ pub struct SeparatedInput { pub fn extract_comments<'a>( tree: &'a Tree, input: &'a str, + comment_ids: HashSet, grammar: &Language, tolerate_parsing_errors: bool, ) -> FormatterResult { @@ -452,7 +461,7 @@ pub fn extract_comments<'a>( let mut anchored_comments: Vec = Vec::new(); let mut new_input: String = input.to_string(); let mut new_tree: Tree = tree.clone(); - find_comments(tree.root_node(), input, &mut anchors)?; + find_comments(tree.root_node(), input, &comment_ids, &mut anchors)?; anchors.sort_by_key(|(node, _)| node.start_byte()); let mut edits: Vec = Vec::new(); // for each (comment, anchor) pair in reverse order, we: diff --git a/topiary-core/src/language.rs b/topiary-core/src/language.rs index 1c903a47..bfacd81b 100644 --- a/topiary-core/src/language.rs +++ b/topiary-core/src/language.rs @@ -13,6 +13,9 @@ pub struct Language { /// The Query Topiary will use to get the formating captures, must be /// present. The topiary engine does not include any formatting queries. pub query: TopiaryQuery, + /// The Query Topiary will use to determine which nodes are comments. + /// When missing, ther ewill be no separate comment processing. + pub comment_query: Option, /// The tree-sitter Language. Topiary will use this Language for parsing. pub grammar: topiary_tree_sitter_facade::Language, /// The indentation string used for that particular language. Defaults to " " diff --git a/topiary-core/src/lib.rs b/topiary-core/src/lib.rs index df64ff20..d4d28d12 100644 --- a/topiary-core/src/lib.rs +++ b/topiary-core/src/lib.rs @@ -199,6 +199,7 @@ pub enum Operation { /// let language: Language = Language { /// name: "json".to_owned(), /// query: TopiaryQuery::new(&json.clone().into(), &query_content).unwrap(), +/// comment_query: None, /// grammar: json.into(), /// indent: None, /// }; @@ -240,6 +241,7 @@ pub fn formatter( let mut atoms = tree_sitter::apply_query( &content, &language.query, + &language.comment_query, &language.grammar, tolerate_parsing_errors, )?; @@ -395,6 +397,7 @@ mod tests { let language = Language { name: "json".to_owned(), query: TopiaryQuery::new(&grammar, query_content).unwrap(), + comment_query: None, grammar, indent: None, }; @@ -431,6 +434,7 @@ mod tests { let language = Language { name: "json".to_owned(), query: TopiaryQuery::new(&grammar, &query_content).unwrap(), + comment_query: None, grammar, indent: None, }; diff --git a/topiary-core/src/tree_sitter.rs b/topiary-core/src/tree_sitter.rs index 3a5ebacf..6d000704 100644 --- a/topiary-core/src/tree_sitter.rs +++ b/topiary-core/src/tree_sitter.rs @@ -7,7 +7,7 @@ use std::{collections::HashSet, fmt::Display}; use serde::Serialize; use topiary_tree_sitter_facade::{ - Node, Point, Query, QueryCapture, QueryCursor, QueryMatch, QueryPredicate, + Node, Point, Query, QueryCapture, QueryCursor, QueryMatch, QueryPredicate, Tree, }; use streaming_iterator::StreamingIterator; @@ -195,6 +195,30 @@ pub struct CoverageData { pub missing_patterns: Vec, } +/// Run a tree-sitter query to identify comments in the tree, then return their IDs +pub fn collect_comment_ids( + tree: &Tree, + input_content: &str, + query: &TopiaryQuery, +) -> HashSet { + let mut cursor = QueryCursor::new(); + let mut query_matches = + query + .query + .matches(&tree.root_node(), input_content.as_bytes(), &mut cursor); + let capture_names = query.query.capture_names(); + let mut ids = HashSet::new(); + #[allow(clippy::while_let_on_iterator)] // This is not a normal iterator + while let Some(query_match) = query_matches.next() { + for capture in query_match.captures() { + if capture.name(capture_names.as_slice()) == "comment" { + ids.insert(capture.node().id()); + } + } + } + ids +} + /// Applies a query to an input content and returns a collection of atoms. /// /// # Errors @@ -208,19 +232,36 @@ pub struct CoverageData { pub fn apply_query( input_content: &str, query: &TopiaryQuery, + comment_query: &Option, grammar: &topiary_tree_sitter_facade::Language, tolerate_parsing_errors: bool, ) -> FormatterResult { let tree = parse(input_content, grammar, tolerate_parsing_errors, None)?; - // Remove comments in a separate stream before applying queries + // Remove comments in a separate stream before applying queries, if applicable let SeparatedInput { input_string, input_tree, comments, - } = extract_comments(&tree, input_content, grammar, tolerate_parsing_errors)?; - let source = input_string.as_bytes(); + } = match comment_query { + Some(comment_query) => { + let comment_ids = collect_comment_ids(&tree, input_content, comment_query); + extract_comments( + &tree, + input_content, + comment_ids, + grammar, + tolerate_parsing_errors, + )? + } + None => SeparatedInput { + input_string: input_content.to_string(), + input_tree: tree, + comments: Vec::new(), + }, + }; let root = input_tree.root_node(); + let source = input_string.as_bytes(); for AnchoredComment { comment_text, diff --git a/topiary-core/tests/comment_tests.rs b/topiary-core/tests/comment_tests.rs index f28a2c83..c7945507 100644 --- a/topiary-core/tests/comment_tests.rs +++ b/topiary-core/tests/comment_tests.rs @@ -5,7 +5,8 @@ use topiary_core::{ SeparatedInput, }, common::{parse, InputSection}, - Position, + tree_sitter::collect_comment_ids, + Position, TopiaryQuery, }; const OCAML_WITH_COMMENTS: &str = r#"(* starting comment *) @@ -21,6 +22,8 @@ const OCAML_WITHOUT_COMMENTS: &str = r#"fun x -> body "#; +const OCAML_COMMENTS_QUERY: &str = "(comment) @comment"; + // The section corresponding to `fun` in the curated code const FUN_SECTION: InputSection = InputSection { start: Position { row: 1, column: 1 }, @@ -45,12 +48,14 @@ fn test_extract_comments() { let ocaml = tree_sitter_ocaml::LANGUAGE_OCAML; let tree = parse(input, &ocaml.into(), false, None).unwrap(); + let comment_query = TopiaryQuery::new(&ocaml.into(), OCAML_COMMENTS_QUERY).unwrap(); + let comment_ids = collect_comment_ids(&tree, input, &comment_query); let SeparatedInput { input_tree: _, input_string: new_input_string, mut comments, - } = extract_comments(&tree, input, &ocaml.into(), false).unwrap(); + } = extract_comments(&tree, input, comment_ids, &ocaml.into(), false).unwrap(); let mut expected_comments: Vec = vec![ AnchoredComment { diff --git a/topiary-playground/src/lib.rs b/topiary-playground/src/lib.rs index b74fcdff..7ab7547e 100644 --- a/topiary-playground/src/lib.rs +++ b/topiary-playground/src/lib.rs @@ -44,6 +44,7 @@ mod wasm_mod { let language = Language { name: language.name, query, + comment_query: None, grammar, indent: language.config.indent, }; diff --git a/topiary-queries/queries/bash.comment.scm b/topiary-queries/queries/bash.comment.scm new file mode 100644 index 00000000..b733adac --- /dev/null +++ b/topiary-queries/queries/bash.comment.scm @@ -0,0 +1,2 @@ +; Identify nodes for comment processing +(comment) @comment diff --git a/topiary-queries/queries/css.comment.scm b/topiary-queries/queries/css.comment.scm new file mode 100644 index 00000000..b733adac --- /dev/null +++ b/topiary-queries/queries/css.comment.scm @@ -0,0 +1,2 @@ +; Identify nodes for comment processing +(comment) @comment diff --git a/topiary-queries/queries/nickel.comment.scm b/topiary-queries/queries/nickel.comment.scm new file mode 100644 index 00000000..b733adac --- /dev/null +++ b/topiary-queries/queries/nickel.comment.scm @@ -0,0 +1,2 @@ +; Identify nodes for comment processing +(comment) @comment diff --git a/topiary-queries/queries/ocaml.comment.scm b/topiary-queries/queries/ocaml.comment.scm new file mode 100644 index 00000000..b733adac --- /dev/null +++ b/topiary-queries/queries/ocaml.comment.scm @@ -0,0 +1,2 @@ +; Identify nodes for comment processing +(comment) @comment diff --git a/topiary-queries/queries/ocaml_interface.comment.scm b/topiary-queries/queries/ocaml_interface.comment.scm new file mode 120000 index 00000000..8867762c --- /dev/null +++ b/topiary-queries/queries/ocaml_interface.comment.scm @@ -0,0 +1 @@ +ocaml.comment.scm \ No newline at end of file diff --git a/topiary-queries/queries/ocamllex.comment.scm b/topiary-queries/queries/ocamllex.comment.scm new file mode 100644 index 00000000..b733adac --- /dev/null +++ b/topiary-queries/queries/ocamllex.comment.scm @@ -0,0 +1,2 @@ +; Identify nodes for comment processing +(comment) @comment diff --git a/topiary-queries/queries/rust.comment.scm b/topiary-queries/queries/rust.comment.scm new file mode 100644 index 00000000..142d9f68 --- /dev/null +++ b/topiary-queries/queries/rust.comment.scm @@ -0,0 +1,5 @@ +; Identify nodes for comment processing +[ + (block_comment) + (line_comment) +] @comment diff --git a/topiary-queries/queries/toml.comment.scm b/topiary-queries/queries/toml.comment.scm new file mode 100644 index 00000000..b733adac --- /dev/null +++ b/topiary-queries/queries/toml.comment.scm @@ -0,0 +1,2 @@ +; Identify nodes for comment processing +(comment) @comment diff --git a/topiary-queries/queries/tree_sitter_query.comment.scm b/topiary-queries/queries/tree_sitter_query.comment.scm new file mode 100644 index 00000000..b733adac --- /dev/null +++ b/topiary-queries/queries/tree_sitter_query.comment.scm @@ -0,0 +1,2 @@ +; Identify nodes for comment processing +(comment) @comment diff --git a/topiary-queries/src/lib.rs b/topiary-queries/src/lib.rs index 20c886e6..cfb6f8a9 100644 --- a/topiary-queries/src/lib.rs +++ b/topiary-queries/src/lib.rs @@ -58,3 +58,58 @@ pub fn toml() -> &'static str { pub fn tree_sitter_query() -> &'static str { include_str!("../queries/tree_sitter_query.scm") } + +/// Returns the Topiary-compatible comment query file for Bash. +#[cfg(feature = "bash")] +pub fn bash_comment() -> &'static str { + include_str!("../queries/bash.comment.scm") +} + +/// Returns the Topiary-compatible comment query file for CSS. +#[cfg(feature = "css")] +pub fn css_comment() -> &'static str { + include_str!("../queries/css.comment.scm") +} + +/// Returns the Topiary-compatible comment query file for Nickel. +#[cfg(feature = "nickel")] +pub fn nickel_comment() -> &'static str { + include_str!("../queries/nickel.comment.scm") +} + +/// Returns the Topiary-compatible comment query file for Ocaml. +#[cfg(feature = "ocaml")] +pub fn ocaml_comment() -> &'static str { + include_str!("../queries/ocaml.comment.scm") +} + +/// Returns the Topiary-compatible comment query file for Ocaml Interface. +#[cfg(feature = "ocaml_interface")] +pub fn ocaml_interface_comment() -> &'static str { + include_str!("../queries/ocaml_interface.comment.scm") +} + +/// Returns the Topiary-compatible comment query file for Ocamllex. +#[cfg(feature = "ocamllex")] +pub fn ocamllex_comment() -> &'static str { + include_str!("../queries/ocamllex.comment.scm") +} + +/// Returns the Topiary-compatible query file for Rust. +#[cfg(feature = "rust")] +pub fn rust_comment() -> &'static str { + include_str!("../queries/rust.comment.scm") +} + +/// Returns the Topiary-compatible query file for Toml. +#[cfg(feature = "toml")] +pub fn toml_comment() -> &'static str { + include_str!("../queries/toml.comment.scm") +} + +/// Returns the Topiary-compatible query file for the +/// Tree-sitter query language. +#[cfg(feature = "tree_sitter_query")] +pub fn tree_sitter_query_comment() -> &'static str { + include_str!("../queries/tree_sitter_query.comment.scm") +}