diff --git a/.gitmodules b/.gitmodules index 3cfb7b56e..f4d6456c3 100644 --- a/.gitmodules +++ b/.gitmodules @@ -82,6 +82,3 @@ path = helix-syntax/languages/tree-sitter-toml url = https://github.com/ikatyang/tree-sitter-toml shallow = true -[submodule "helix-syntax/nvim-treesitter"] - path = helix-syntax/nvim-treesitter - url = https://github.com/nvim-treesitter/nvim-treesitter diff --git a/Cargo.lock b/Cargo.lock index 8863337ef..c710d9242 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -486,7 +486,6 @@ version = "0.1.0" dependencies = [ "anyhow", "helix-syntax", - "log", "once_cell", "regex", "ropey", @@ -1227,9 +1226,9 @@ dependencies = [ [[package]] name = "tree-sitter" -version = "0.17.1" +version = "0.19.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d18dcb776d3affaba6db04d11d645946d34a69b3172e588af96ce9fecd20faac" +checksum = "1f41201fed3db3b520405a9c01c61773a250d4c3f43e9861c14b2bb232c981ab" dependencies = [ "cc", "regex", diff --git a/helix-core/Cargo.toml b/helix-core/Cargo.toml index 4b1566d71..4e07712b6 100644 --- a/helix-core/Cargo.toml +++ b/helix-core/Cargo.toml @@ -16,7 +16,7 @@ tendril = "0.4.2" unicode-segmentation = "1.6" unicode-width = "0.1" # slab = "0.4.2" -tree-sitter = "0.17" +tree-sitter = "0.19" once_cell = "1.4" regex = "1" diff --git a/helix-core/src/syntax.rs b/helix-core/src/syntax.rs index e108d030b..4c8901708 100644 --- a/helix-core/src/syntax.rs +++ b/helix-core/src/syntax.rs @@ -1,4 +1,4 @@ -use crate::{Change, Rope, RopeSlice, Transaction}; +use crate::{regex::Regex, Change, Rope, RopeSlice, Transaction}; pub use helix_syntax::{get_language, get_language_name, Lang}; use std::{ @@ -59,21 +59,53 @@ pub struct IndentationConfiguration { pub unit: String, } +fn read_query(language: &str, filename: &str) -> String { + static INHERITS_REGEX: Lazy = + Lazy::new(|| Regex::new(r";+\s*inherits\s*:?\s*([a-z_,()]+)\s*").unwrap()); + + let root = PathBuf::from(env!("CARGO_MANIFEST_DIR")); + + let path = root + .join("../runtime/queries") + .join(language) + .join(filename); + + let query = std::fs::read_to_string(&path).unwrap_or_default(); + + // TODO: the collect() is not ideal + let inherits = INHERITS_REGEX + .captures_iter(&query) + .flat_map(|captures| { + captures[1] + .split(',') + .map(str::to_owned) + .collect::>() + }) + .collect::>(); + + if inherits.is_empty() { + return query; + } + + let mut queries = inherits + .iter() + .map(|language| read_query(language, filename)) + .collect::>(); + + queries.push(query); + + queries.concat() +} + impl LanguageConfiguration { pub fn highlight_config(&self, scopes: &[String]) -> Option> { self.highlight_config .get_or_init(|| { - // let name = get_language_name(&self.language_id); + let language = get_language_name(self.language_id).to_ascii_lowercase(); - let root = PathBuf::from(env!("CARGO_MANIFEST_DIR")); + let highlights_query = read_query(&language, "highlights.scm"); - let highlights_query = - std::fs::read_to_string(root.join(&self.path).join("queries/highlights.scm")) - .unwrap_or_default(); - - let injections_query = - std::fs::read_to_string(root.join(&self.path).join("queries/injections.scm")) - .unwrap_or_default(); + let injections_query = read_query(&language, "injections.scm"); let locals_query = ""; diff --git a/helix-syntax/Cargo.toml b/helix-syntax/Cargo.toml index f145b6c0b..f00e2ba05 100644 --- a/helix-syntax/Cargo.toml +++ b/helix-syntax/Cargo.toml @@ -7,7 +7,7 @@ edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -tree-sitter = "0.17" +tree-sitter = "0.19" serde = { version = "1.0", features = ["derive"] } [build-dependencies] diff --git a/helix-syntax/languages/tree-sitter-bash b/helix-syntax/languages/tree-sitter-bash index 8ece09ca4..a8eb5cb57 160000 --- a/helix-syntax/languages/tree-sitter-bash +++ b/helix-syntax/languages/tree-sitter-bash @@ -1 +1 @@ -Subproject commit 8ece09ca4c0b5e59b124cd19fa92c76b1a9e9dd4 +Subproject commit a8eb5cb57c66f74c63ab950de081207cccf52017 diff --git a/helix-syntax/languages/tree-sitter-c b/helix-syntax/languages/tree-sitter-c index fa408bc9e..f05e279ae 160000 --- a/helix-syntax/languages/tree-sitter-c +++ b/helix-syntax/languages/tree-sitter-c @@ -1 +1 @@ -Subproject commit fa408bc9e77f4b770bd1db984ca00c901ddf95fc +Subproject commit f05e279aedde06a25801c3f2b2cc8ac17fac52ae diff --git a/helix-syntax/languages/tree-sitter-c-sharp b/helix-syntax/languages/tree-sitter-c-sharp index 21ec3c3de..53a65a908 160000 --- a/helix-syntax/languages/tree-sitter-c-sharp +++ b/helix-syntax/languages/tree-sitter-c-sharp @@ -1 +1 @@ -Subproject commit 21ec3c3deb4365085aa353fadbc6a616d7769f9f +Subproject commit 53a65a908167d6556e1fcdb67f1ee62aac101dda diff --git a/helix-syntax/languages/tree-sitter-cpp b/helix-syntax/languages/tree-sitter-cpp index 3bfe046f3..c61212414 160000 --- a/helix-syntax/languages/tree-sitter-cpp +++ b/helix-syntax/languages/tree-sitter-cpp @@ -1 +1 @@ -Subproject commit 3bfe046f3967fef92ebb33f8cd58c3ff373d5e56 +Subproject commit c61212414a3e95b5f7507f98e83de1d638044adc diff --git a/helix-syntax/languages/tree-sitter-css b/helix-syntax/languages/tree-sitter-css index e882c98b5..94e102309 160000 --- a/helix-syntax/languages/tree-sitter-css +++ b/helix-syntax/languages/tree-sitter-css @@ -1 +1 @@ -Subproject commit e882c98b5e62d864f7f9e4d855b19b6050c897a8 +Subproject commit 94e10230939e702b4fa3fa2cb5c3bc7173b95d07 diff --git a/helix-syntax/languages/tree-sitter-go b/helix-syntax/languages/tree-sitter-go index dadfd9c9a..2a83dfdd7 160000 --- a/helix-syntax/languages/tree-sitter-go +++ b/helix-syntax/languages/tree-sitter-go @@ -1 +1 @@ -Subproject commit dadfd9c9aab2630632e61cfce645c13c35aa092f +Subproject commit 2a83dfdd759a632651f852aa4dc0af2525fae5cd diff --git a/helix-syntax/languages/tree-sitter-html b/helix-syntax/languages/tree-sitter-html index 7f442e1c6..d93af487c 160000 --- a/helix-syntax/languages/tree-sitter-html +++ b/helix-syntax/languages/tree-sitter-html @@ -1 +1 @@ -Subproject commit 7f442e1c6163d450c69c75c7a621badc3a0ea98f +Subproject commit d93af487cc75120c89257195e6be46c999c6ba18 diff --git a/helix-syntax/languages/tree-sitter-java b/helix-syntax/languages/tree-sitter-java index 16c07a726..bd6186c24 160000 --- a/helix-syntax/languages/tree-sitter-java +++ b/helix-syntax/languages/tree-sitter-java @@ -1 +1 @@ -Subproject commit 16c07a726c34c9925b3e28716b2d6d60e3643252 +Subproject commit bd6186c24d5eb13b4623efac9d944dcc095c0dad diff --git a/helix-syntax/languages/tree-sitter-javascript b/helix-syntax/languages/tree-sitter-javascript index 452151f71..4a95461c4 160000 --- a/helix-syntax/languages/tree-sitter-javascript +++ b/helix-syntax/languages/tree-sitter-javascript @@ -1 +1 @@ -Subproject commit 452151f7192cc26b70fe4a7ec192a37d99854a6a +Subproject commit 4a95461c4761c624f2263725aca79eeaefd36cad diff --git a/helix-syntax/languages/tree-sitter-json b/helix-syntax/languages/tree-sitter-json index d3976b27d..65bceef69 160000 --- a/helix-syntax/languages/tree-sitter-json +++ b/helix-syntax/languages/tree-sitter-json @@ -1 +1 @@ -Subproject commit d3976b27df8622ed17bef6dd5e358b398e73c676 +Subproject commit 65bceef69c3b0f24c0b19ce67d79f57c96e90fcb diff --git a/helix-syntax/languages/tree-sitter-julia b/helix-syntax/languages/tree-sitter-julia index 6a0863f1c..0ba7a24b0 160000 --- a/helix-syntax/languages/tree-sitter-julia +++ b/helix-syntax/languages/tree-sitter-julia @@ -1 +1 @@ -Subproject commit 6a0863f1ce3fcf6f99dc0addb7886dcbd27c5a48 +Subproject commit 0ba7a24b062b671263ae08e707e9e94383b25bb7 diff --git a/helix-syntax/languages/tree-sitter-php b/helix-syntax/languages/tree-sitter-php index b0c0367d4..0d63eaf94 160000 --- a/helix-syntax/languages/tree-sitter-php +++ b/helix-syntax/languages/tree-sitter-php @@ -1 +1 @@ -Subproject commit b0c0367d4b7058921fdc4ba11e257441a64ab809 +Subproject commit 0d63eaf94e8d6c0694551b016c802787e61b3fb2 diff --git a/helix-syntax/languages/tree-sitter-python b/helix-syntax/languages/tree-sitter-python index 3196e2886..d6210ceab 160000 --- a/helix-syntax/languages/tree-sitter-python +++ b/helix-syntax/languages/tree-sitter-python @@ -1 +1 @@ -Subproject commit 3196e288650992bca2399dda15ac703c342a22bb +Subproject commit d6210ceab11e8d812d4ab59c07c81458ec6e5184 diff --git a/helix-syntax/languages/tree-sitter-ruby b/helix-syntax/languages/tree-sitter-ruby index 32cd5a04a..dfff673b4 160000 --- a/helix-syntax/languages/tree-sitter-ruby +++ b/helix-syntax/languages/tree-sitter-ruby @@ -1 +1 @@ -Subproject commit 32cd5a04adb4accb0c121f037ab59df3c3488228 +Subproject commit dfff673b41df7fadcbb609c6338f38da3cdd018e diff --git a/helix-syntax/languages/tree-sitter-rust b/helix-syntax/languages/tree-sitter-rust index 1be73c282..a360da0a2 160000 --- a/helix-syntax/languages/tree-sitter-rust +++ b/helix-syntax/languages/tree-sitter-rust @@ -1 +1 @@ -Subproject commit 1be73c282bb6d9fd2fbb55945b313f9527cad060 +Subproject commit a360da0a29a19c281d08295a35ecd0544d2da211 diff --git a/helix-syntax/languages/tree-sitter-scala b/helix-syntax/languages/tree-sitter-scala index 211bb726b..fb23ed9a9 160000 --- a/helix-syntax/languages/tree-sitter-scala +++ b/helix-syntax/languages/tree-sitter-scala @@ -1 +1 @@ -Subproject commit 211bb726bb5857f872247b600c7c1808e641a8d4 +Subproject commit fb23ed9a99da012d86b7a5059b9d8928607cce29 diff --git a/helix-syntax/languages/tree-sitter-toml b/helix-syntax/languages/tree-sitter-toml index 084da152d..7cff70bbc 160000 --- a/helix-syntax/languages/tree-sitter-toml +++ b/helix-syntax/languages/tree-sitter-toml @@ -1 +1 @@ -Subproject commit 084da152d85cb8c4bbbe0ab5f3f1f9e5bfb77d3c +Subproject commit 7cff70bbcbbc62001b465603ca1ea88edd668704 diff --git a/helix-syntax/languages/tree-sitter-typescript b/helix-syntax/languages/tree-sitter-typescript index 543cbe44f..3e897ea59 160000 --- a/helix-syntax/languages/tree-sitter-typescript +++ b/helix-syntax/languages/tree-sitter-typescript @@ -1 +1 @@ -Subproject commit 543cbe44f16189f7f1b739cf268d70f373d94b87 +Subproject commit 3e897ea5925f037cfae2e551f8e6b12eec2a201a diff --git a/helix-syntax/nvim-treesitter b/helix-syntax/nvim-treesitter deleted file mode 160000 index 1f00ecdfa..000000000 --- a/helix-syntax/nvim-treesitter +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 1f00ecdfa36ef5e43a4feaf189e8c2c003118c00 diff --git a/runtime/queries/c/highlights.scm b/runtime/queries/c/highlights.scm new file mode 100644 index 000000000..04d9a04f3 --- /dev/null +++ b/runtime/queries/c/highlights.scm @@ -0,0 +1,81 @@ +"break" @keyword +"case" @keyword +"const" @keyword +"continue" @keyword +"default" @keyword +"do" @keyword +"else" @keyword +"enum" @keyword +"extern" @keyword +"for" @keyword +"if" @keyword +"inline" @keyword +"return" @keyword +"sizeof" @keyword +"static" @keyword +"struct" @keyword +"switch" @keyword +"typedef" @keyword +"union" @keyword +"volatile" @keyword +"while" @keyword + +"#define" @keyword +"#elif" @keyword +"#else" @keyword +"#endif" @keyword +"#if" @keyword +"#ifdef" @keyword +"#ifndef" @keyword +"#include" @keyword +(preproc_directive) @keyword + +"--" @operator +"-" @operator +"-=" @operator +"->" @operator +"=" @operator +"!=" @operator +"*" @operator +"&" @operator +"&&" @operator +"+" @operator +"++" @operator +"+=" @operator +"<" @operator +"==" @operator +">" @operator +"||" @operator + +"." @delimiter +";" @delimiter + +(string_literal) @string +(system_lib_string) @string + +(null) @constant +(number_literal) @number +(char_literal) @number + +(call_expression + function: (identifier) @function) +(call_expression + function: (field_expression + field: (field_identifier) @function)) +(function_declarator + declarator: (identifier) @function) +(preproc_function_def + name: (identifier) @function.special) + +(field_identifier) @property +(statement_identifier) @label +(type_identifier) @type +(primitive_type) @type +(sized_type_specifier) @type + +((identifier) @constant + (#match? @constant "^[A-Z][A-Z\\d_]*$")) + +(identifier) @variable + +(comment) @comment diff --git a/runtime/queries/cpp/highlights.scm b/runtime/queries/cpp/highlights.scm new file mode 100644 index 000000000..3315fde05 --- /dev/null +++ b/runtime/queries/cpp/highlights.scm @@ -0,0 +1,68 @@ +; inherits: c + +; Functions + +(call_expression + function: (scoped_identifier + name: (identifier) @function)) + +(template_function + name: (identifier) @function) + +(template_method + name: (field_identifier) @function) + +(template_function + name: (scoped_identifier + name: (identifier) @function)) + +(function_declarator + declarator: (scoped_identifier + name: (identifier) @function)) + +(function_declarator + declarator: (scoped_identifier + name: (identifier) @function)) + +(function_declarator + declarator: (field_identifier) @function) + +; Types + +((namespace_identifier) @type + (#match? @type "^[A-Z]")) + +(auto) @type + +; Constants + +(this) @variable.builtin +(nullptr) @constant + +; Keywords + +"catch" @keyword +"class" @keyword +"constexpr" @keyword +"delete" @keyword +"explicit" @keyword +"final" @keyword +"friend" @keyword +"mutable" @keyword +"namespace" @keyword +"noexcept" @keyword +"new" @keyword +"override" @keyword +"private" @keyword +"protected" @keyword +"public" @keyword +"template" @keyword +"throw" @keyword +"try" @keyword +"typename" @keyword +"using" @keyword +"virtual" @keyword + +; Strings + +(raw_string_literal) @string diff --git a/runtime/queries/rust/highlights.scm b/runtime/queries/rust/highlights.scm new file mode 100644 index 000000000..196d483c2 --- /dev/null +++ b/runtime/queries/rust/highlights.scm @@ -0,0 +1,135 @@ +; Identifier conventions + +; Assume all-caps names are constants +((identifier) @constant + (#match? @constant "^[A-Z][A-Z\\d_]+$'")) + +; Assume that uppercase names in paths are types +((scoped_identifier + path: (identifier) @type) + (#match? @type "^[A-Z]")) +((scoped_identifier + path: (scoped_identifier + name: (identifier) @type)) + (#match? @type "^[A-Z]")) + +; Assume other uppercase names are enum constructors +((identifier) @constructor + (#match? @constructor "^[A-Z]")) + +; Function calls + +(call_expression + function: (identifier) @function) +(call_expression + function: (field_expression + field: (field_identifier) @function.method)) +(call_expression + function: (scoped_identifier + "::" + name: (identifier) @function)) + +(generic_function + function: (identifier) @function) +(generic_function + function: (scoped_identifier + name: (identifier) @function)) +(generic_function + function: (field_expression + field: (field_identifier) @function.method)) + +(macro_invocation + macro: (identifier) @function.macro + "!" @function.macro) + +; Function definitions + +(function_item (identifier) @function) +(function_signature_item (identifier) @function) + +; Other identifiers + +(type_identifier) @type +(primitive_type) @type.builtin +(field_identifier) @property + +(line_comment) @comment +(block_comment) @comment + +"(" @punctuation.bracket +")" @punctuation.bracket +"[" @punctuation.bracket +"]" @punctuation.bracket + +(type_arguments + "<" @punctuation.bracket + ">" @punctuation.bracket) +(type_parameters + "<" @punctuation.bracket + ">" @punctuation.bracket) + +"::" @punctuation.delimiter +"." @punctuation.delimiter +";" @punctuation.delimiter + +(parameter (identifier) @variable.parameter) + +(lifetime (identifier) @label) + +"break" @keyword +"const" @keyword +"continue" @keyword +"default" @keyword +"dyn" @keyword +"else" @keyword +"enum" @keyword +"extern" @keyword +"fn" @keyword +"for" @keyword +"if" @keyword +"impl" @keyword +"in" @keyword +"let" @keyword +"let" @keyword +"loop" @keyword +"macro_rules!" @keyword +"match" @keyword +"mod" @keyword +"move" @keyword +"pub" @keyword +"ref" @keyword +"return" @keyword +"static" @keyword +"struct" @keyword +"trait" @keyword +"type" @keyword +"union" @keyword +"unsafe" @keyword +"use" @keyword +"where" @keyword +"while" @keyword +(mutable_specifier) @keyword +(use_list (self) @keyword) +(scoped_use_list (self) @keyword) +(scoped_identifier (self) @keyword) +(super) @keyword + +(self) @variable.builtin + +(char_literal) @string +(string_literal) @string +(raw_string_literal) @string + +(boolean_literal) @constant.builtin +(integer_literal) @constant.builtin +(float_literal) @constant.builtin + +(escape_sequence) @escape + +(attribute_item) @attribute +(inner_attribute_item) @attribute + +"as" @operator +"*" @operator +"&" @operator +"'" @operator diff --git a/runtime/queries/rust/injections.scm b/runtime/queries/rust/injections.scm new file mode 100644 index 000000000..6035d4189 --- /dev/null +++ b/runtime/queries/rust/injections.scm @@ -0,0 +1,9 @@ +((macro_invocation + (token_tree) @injection.content) + (#set! injection.language "rust") + (#set! injection.include-children)) + +((macro_rule + (token_tree) @injection.content) + (#set! injection.language "rust") + (#set! injection.include-children))