tree-sitter-sh 0.13.0 → 0.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/Cargo.toml ADDED
@@ -0,0 +1,35 @@
1
+ [package]
2
+ name = "tree-sitter-sh"
3
+ version = "0.15.0"
4
+ edition = "2024"
5
+ description = "Tree-sitter grammar for POSIX sh."
6
+ readme = "README.md"
7
+ repository = "https://github.com/konomanoasa/tree-sitter-sh"
8
+ license = "MIT"
9
+ keywords = ["incremental", "parsing", "sh", "tree-sitter"]
10
+ categories = ["parser-implementations", "parsing", "text-editors"]
11
+ build = "bindings/rust/build.rs"
12
+ include = [
13
+ "/LICENSE",
14
+ "/README.md",
15
+ "/bindings/rust/*.rs",
16
+ "/grammar.js",
17
+ "/queries/*.scm",
18
+ "/src/*.c",
19
+ "/src/*.h",
20
+ "/src/*.json",
21
+ "/src/tree_sitter/*.h",
22
+ "/tree-sitter.json",
23
+ ]
24
+
25
+ [lib]
26
+ path = "bindings/rust/lib.rs"
27
+
28
+ [dependencies]
29
+ tree-sitter-language = "0.1.8"
30
+
31
+ [dev-dependencies]
32
+ tree-sitter = "0.27.0"
33
+
34
+ [build-dependencies]
35
+ cc = "1.4.6"
@@ -0,0 +1,9 @@
1
+ fn main() {
2
+ println!("cargo::rerun-if-changed=src");
3
+
4
+ cc::Build::new()
5
+ .std("c17")
6
+ .include("src")
7
+ .files(["src/parser.c", "src/scanner.c"])
8
+ .compile("tree-sitter-sh");
9
+ }
@@ -0,0 +1,56 @@
1
+ //! POSIX.1-2024 Shell Command Language support for Tree-sitter.
2
+ //!
3
+ //! ```
4
+ //! let mut parser = tree_sitter::Parser::new();
5
+ //! parser.set_language(&tree_sitter_sh::LANGUAGE.into()).unwrap();
6
+ //! let tree = parser.parse("echo hello\n", None).unwrap();
7
+ //! assert!(!tree.root_node().has_error());
8
+ //! ```
9
+
10
+ use tree_sitter_language::LanguageFn;
11
+
12
+ unsafe extern "C" {
13
+ fn tree_sitter_sh() -> *const ();
14
+ }
15
+
16
+ /// Grammar entry point for `tree_sitter::Parser::set_language`.
17
+ pub const LANGUAGE: LanguageFn = unsafe { LanguageFn::from_raw(tree_sitter_sh) };
18
+
19
+ /// Public node types and fields in Tree-sitter's JSON format.
20
+ pub const NODE_TYPES: &str = include_str!("../../src/node-types.json");
21
+
22
+ /// Highlight query using standard Tree-sitter and Neovim captures.
23
+ pub const HIGHLIGHTS_QUERY: &str = include_str!("../../queries/highlights.scm");
24
+
25
+ #[cfg(test)]
26
+ mod tests {
27
+ use tree_sitter::{Parser, Query, QueryCursor, StreamingIterator};
28
+
29
+ #[test]
30
+ fn parses_quoted_here_document_and_highlights_its_terminator() {
31
+ let source = "cat <<'EOF'\n$HOME\nEOF\n";
32
+ let language = super::LANGUAGE.into();
33
+ let mut parser = Parser::new();
34
+ parser.set_language(&language).unwrap();
35
+ let tree = parser.parse(source, None).unwrap();
36
+ let root = tree.root_node();
37
+ assert_eq!(root.kind(), "program");
38
+ assert_eq!(root.byte_range(), 0..source.len());
39
+ assert!(!root.has_error(), "{}", root.to_sexp());
40
+
41
+ let query = Query::new(&language, super::HIGHLIGHTS_QUERY).unwrap();
42
+ let mut cursor = QueryCursor::new();
43
+ let mut captures = cursor.captures(&query, root, source.as_bytes());
44
+ let mut terminators = 0;
45
+ while let Some((matched, index)) = captures.next() {
46
+ let capture = matched.captures()[*index];
47
+ if capture.node.kind() == "here_document_end_text" {
48
+ assert_eq!(query.capture_names()[capture.index as usize], "label");
49
+ assert_eq!(capture.node.byte_range(), 18..21);
50
+ assert_eq!(capture.node.utf8_text(source.as_bytes()).unwrap(), "EOF");
51
+ terminators += 1;
52
+ }
53
+ }
54
+ assert_eq!(terminators, 1);
55
+ }
56
+ }