From 9456104feb59eece9e2c3b6f98c3e5a7f634a7bb Mon Sep 17 00:00:00 2001 From: RubixDev Date: Sun, 24 Sep 2023 10:24:16 +0800 Subject: [PATCH] feat: add Ursa support closes #9 --- Cargo.toml | 2 +- examples/example_programs.toml | 39 +++++++ queries/ursa/highlights.scm | 101 ++++++++++++++++++ queries/ursa/locals.scm | 18 ++++ syntastica-js/src/index.ts | 1 + syntastica-macros/languages.toml | 16 +++ syntastica-parsers-git/Cargo.toml | 2 + syntastica-parsers-git/README.md | 1 + syntastica-parsers-gitdep/Cargo.toml | 7 ++ syntastica-parsers-gitdep/README.md | 1 + syntastica-parsers/Cargo.toml | 6 ++ syntastica-parsers/README.md | 1 + .../generated_queries/ursa/highlights.scm | 82 ++++++++++++++ .../ursa/highlights_crates_io.scm | 82 ++++++++++++++ .../generated_queries/ursa/injections.scm | 0 .../ursa/injections_crates_io.scm | 0 .../generated_queries/ursa/locals.scm | 10 ++ .../ursa/locals_crates_io.scm | 10 ++ syntastica-queries/src/lib.rs | 7 ++ xtask/src/add_lang.rs | 32 +----- 20 files changed, 386 insertions(+), 32 deletions(-) create mode 100644 queries/ursa/highlights.scm create mode 100644 queries/ursa/locals.scm create mode 100644 syntastica-queries/generated_queries/ursa/highlights.scm create mode 100644 syntastica-queries/generated_queries/ursa/highlights_crates_io.scm create mode 100644 syntastica-queries/generated_queries/ursa/injections.scm create mode 100644 syntastica-queries/generated_queries/ursa/injections_crates_io.scm create mode 100644 syntastica-queries/generated_queries/ursa/locals.scm create mode 100644 syntastica-queries/generated_queries/ursa/locals_crates_io.scm diff --git a/Cargo.toml b/Cargo.toml index 385703be..3f77fc5c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -52,7 +52,7 @@ once_cell = "1.18.0" rustc_version = "0.4.0" serde = "1.0.188" strum = "0.25.0" -tft = { version = "0.1.0", default-features = false } +tft = { version = "0.1.1", default-features = false } thiserror = "1.0.48" toml = "0.8.0" diff --git a/examples/example_programs.toml b/examples/example_programs.toml index b199f1c5..b71bab43 100644 --- a/examples/example_programs.toml +++ b/examples/example_programs.toml @@ -968,3 +968,42 @@ license.workspace = true repository.workspace = true description = "Modern and easy syntax highlighting using tree-sitter" ''' + +ursa = ''' +print("hello, woods!") + +let fac = null +fn fac(x) { + if x == 0 {1} else {x * fac(x - 1)} +} +fac(6) + +let sum = fn(l) { + let tot = 0 + let i = 0 + loop { + if i == l.length { return tot } + tot = tot + l[i] + i = i + 1 + } +} +sum([10, 30, 50, 5, 5]) + +let newAccums = fn() { + let tot = 0 + [ + fn(x) { + tot = tot + x + }, + fn(x) { + tot = tot + x + }, + ] +} +let accums = newAccums() +let accums2 = newAccums() +[ + [accums[0](1), accums[0](1), accums2[0](1)], + [accums[1](1), accums[1](1), accums2[1](1)], +] +''' diff --git a/queries/ursa/highlights.scm b/queries/ursa/highlights.scm new file mode 100644 index 00000000..c427af96 --- /dev/null +++ b/queries/ursa/highlights.scm @@ -0,0 +1,101 @@ +;; Forked from https://github.com/ursalang/tree-sitter-ursa/blob/main/queries/highlights.scm +;; Licensed under the ISC licence +; Special identifiers +;-------------------- +( + (identifier) @variable.builtin + (#match? @variable.builtin "^(pi)$") + (#is-not? local) +) + +( + (identifier) @function.builtin + (#eq? @function.builtin "print") + (#is-not? local) +) + +; Function definitions +;--------------------- +(named_fn + (identifier) @function +) + +(let + (identifier) @function + (lambda) +) + +; Function and calls +;------------------- +(call + function: (identifier) @function +) + +; (call +; (member_expression +; property: (property_identifier) @function.method)) +; Variables +;---------- +(identifier) @variable + +; Properties +;----------- +(property_identifier) @property + +; Literals +;--------- +[ + (bool) + (null) +] @constant.builtin + +(comment) @comment + +(string) @string + +(number) @number + +; Tokens +;------- +[ + ";" + "." + "," +] @punctuation.delimiter + +[ + "-" + "+" + "*" + "**" + "/" + "%" + "<" + "<=" + "=" + "==" + "!=" + ">" + ">=" +] @operator + +[ + "(" + ")" + "[" + "]" + "{" + "}" +] @punctuation.bracket + +[ + "break" + (continue) + "else" + "fn" + "if" + "let" + "loop" + "return" + "use" +] @keyword diff --git a/queries/ursa/locals.scm b/queries/ursa/locals.scm new file mode 100644 index 00000000..250f65a0 --- /dev/null +++ b/queries/ursa/locals.scm @@ -0,0 +1,18 @@ +;; Forked from https://github.com/ursalang/tree-sitter-ursa/blob/main/queries/locals.scm +;; Licensed under the ISC licence +; Scopes +;------- +[ + (block) + (lambda) +] @local.scope + +; Definitions +;------------ +(let + identifier: (identifier) @local.definition +) + +; References +;------------ +(identifier) @local.reference diff --git a/syntastica-js/src/index.ts b/syntastica-js/src/index.ts index 83acaf36..85f15d0f 100644 --- a/syntastica-js/src/index.ts +++ b/syntastica-js/src/index.ts @@ -201,6 +201,7 @@ export const LANGUAGES = [ 'toml', 'tsx', 'typescript', + 'ursa', 'verilog', 'wat', 'yaml', diff --git a/syntastica-macros/languages.toml b/syntastica-macros/languages.toml index 471ac9a8..2cd28e5e 100644 --- a/syntastica-macros/languages.toml +++ b/syntastica-macros/languages.toml @@ -693,6 +693,22 @@ nvim-like = true injections = true locals = true +[[languages]] +name = "ursa" +group = "all" +file-types = ["ursa"] +[languages.parser] +git = { url = "https://github.com/ursalang/tree-sitter-ursa", rev = "e15effeeff88df0e2c81a03f8e3098bdb6d749c4" } +external-scanner = { c = true, cpp = false } +ffi-func = "tree_sitter_ursa" +rust-func = "language" +package = "tree-sitter-ursa" +crates-io = "0.0.3" +[languages.queries] +nvim-like = false +injections = false +locals = true + [[languages]] name = "verilog" group = "all" diff --git a/syntastica-parsers-git/Cargo.toml b/syntastica-parsers-git/Cargo.toml index 67a81c09..38ecd84a 100644 --- a/syntastica-parsers-git/Cargo.toml +++ b/syntastica-parsers-git/Cargo.toml @@ -103,6 +103,7 @@ all = [ "ocaml_interface", "ql", "rush", + "ursa", "verilog", "wat", ] @@ -161,6 +162,7 @@ scss = [] toml = [] tsx = [] typescript = [] +ursa = [] verilog = [] wat = [] yaml = [] diff --git a/syntastica-parsers-git/README.md b/syntastica-parsers-git/README.md index 7ddafee6..4e75c85e 100644 --- a/syntastica-parsers-git/README.md +++ b/syntastica-parsers-git/README.md @@ -92,6 +92,7 @@ it will be reused the next time the build script is run. - [ocaml_interface](https://github.com/tree-sitter/tree-sitter-ocaml/tree/694c57718fd85d514f8b81176038e7a4cfabcaaf) - [ql](https://github.com/tree-sitter/tree-sitter-ql/tree/bd087020f0d8c183080ca615d38de0ec827aeeaf) - [rush](https://github.com/rush-rs/tree-sitter-rush/tree/20c04a0824dabcbf8119a84979cfb1c6f6c2155f) +- [ursa](https://github.com/ursalang/tree-sitter-ursa/tree/e15effeeff88df0e2c81a03f8e3098bdb6d749c4) - [verilog](https://github.com/tree-sitter/tree-sitter-verilog/tree/902031343056bc0b11f3e47b33f036a9cf59f58d) - [wat](https://github.com/wasm-lsp/tree-sitter-wasm/tree/2ca28a9f9d709847bf7a3de0942a84e912f59088) diff --git a/syntastica-parsers-gitdep/Cargo.toml b/syntastica-parsers-gitdep/Cargo.toml index 854b7017..3181f9b7 100644 --- a/syntastica-parsers-gitdep/Cargo.toml +++ b/syntastica-parsers-gitdep/Cargo.toml @@ -95,6 +95,7 @@ all = [ "ocaml_interface", "ql", "rush", + "ursa", "verilog", ] @@ -136,6 +137,7 @@ rust = ["dep:tree-sitter-rust"] scala = ["dep:tree-sitter-scala"] scss = ["dep:tree-sitter-scss"] toml = ["dep:tree-sitter-toml"] +ursa = ["dep:tree-sitter-ursa"] verilog = ["dep:tree-sitter-verilog"] yaml = ["dep:tree-sitter-yaml"] @@ -299,6 +301,11 @@ optional = true git = "https://github.com/Mathspy/tree-sitter-toml" rev = "ae4cdb5d27bf876a432b6c30b6a88f56c9b3e761" +[dependencies.tree-sitter-ursa] +optional = true +git = "https://github.com/ursalang/tree-sitter-ursa" +rev = "e15effeeff88df0e2c81a03f8e3098bdb6d749c4" + [dependencies.tree-sitter-verilog] optional = true git = "https://github.com/tree-sitter/tree-sitter-verilog" diff --git a/syntastica-parsers-gitdep/README.md b/syntastica-parsers-gitdep/README.md index 92b42c3a..0f9f7d11 100644 --- a/syntastica-parsers-gitdep/README.md +++ b/syntastica-parsers-gitdep/README.md @@ -73,6 +73,7 @@ for more information on all parser collections. - [ocaml_interface](https://github.com/tree-sitter/tree-sitter-ocaml/tree/694c57718fd85d514f8b81176038e7a4cfabcaaf) - [ql](https://github.com/tree-sitter/tree-sitter-ql/tree/bd087020f0d8c183080ca615d38de0ec827aeeaf) - [rush](https://github.com/rush-rs/tree-sitter-rush/tree/20c04a0824dabcbf8119a84979cfb1c6f6c2155f) +- [ursa](https://github.com/ursalang/tree-sitter-ursa/tree/e15effeeff88df0e2c81a03f8e3098bdb6d749c4) - [verilog](https://github.com/tree-sitter/tree-sitter-verilog/tree/902031343056bc0b11f3e47b33f036a9cf59f58d) - [wat](https://github.com/wasm-lsp/tree-sitter-wasm/tree/2ca28a9f9d709847bf7a3de0942a84e912f59088) (not supported by this collection) diff --git a/syntastica-parsers/Cargo.toml b/syntastica-parsers/Cargo.toml index a319757d..3da8253b 100644 --- a/syntastica-parsers/Cargo.toml +++ b/syntastica-parsers/Cargo.toml @@ -82,6 +82,7 @@ all = [ "ocaml", "ocaml_interface", "rush", + "ursa", ] ## Meant to be enabled when building docs @@ -113,6 +114,7 @@ rush = ["dep:tree-sitter-rush"] rust = ["dep:tree-sitter-rust"] scala = ["dep:tree-sitter-scala"] toml = ["dep:tree-sitter-toml"] +ursa = ["dep:tree-sitter-ursa"] [dependencies.tree-sitter-asm] optional = true @@ -205,3 +207,7 @@ version = "=0.20.1" [dependencies.tree-sitter-toml] optional = true version = "=0.20.0" + +[dependencies.tree-sitter-ursa] +optional = true +version = "=0.0.3" diff --git a/syntastica-parsers/README.md b/syntastica-parsers/README.md index 2889385b..80b5d3fa 100644 --- a/syntastica-parsers/README.md +++ b/syntastica-parsers/README.md @@ -73,6 +73,7 @@ for more information on all parser collections. - [ocaml_interface](https://docs.rs/tree-sitter-ocaml/0.20.4/) - [ql](https://github.com/tree-sitter/tree-sitter-ql) (not supported by this collection) - [rush](https://docs.rs/tree-sitter-rush/0.1.0/) +- [ursa](https://docs.rs/tree-sitter-ursa/0.0.3/) - [verilog](https://github.com/tree-sitter/tree-sitter-verilog) (not supported by this collection) - [wat](https://github.com/wasm-lsp/tree-sitter-wasm) (not supported by this collection) diff --git a/syntastica-queries/generated_queries/ursa/highlights.scm b/syntastica-queries/generated_queries/ursa/highlights.scm new file mode 100644 index 00000000..6f31d2a0 --- /dev/null +++ b/syntastica-queries/generated_queries/ursa/highlights.scm @@ -0,0 +1,82 @@ +( + (identifier) @variable.builtin + (#match? @variable.builtin "^(pi)$") + (#is-not? local) +) + +( + (identifier) @function.builtin + (#eq? @function.builtin "print") + (#is-not? local) +) + +(named_fn + (identifier) @function +) + +(let + (identifier) @function + (lambda) +) + +(call + function: (identifier) @function +) + +(identifier) @variable + +(property_identifier) @property + +[ + (bool) + (null) +] @constant.builtin + +(comment) @comment + +(string) @string + +(number) @number + +[ + ";" + "." + "," +] @punctuation.delimiter + +[ + "-" + "+" + "*" + "**" + "/" + "%" + "<" + "<=" + "=" + "==" + "!=" + ">" + ">=" +] @operator + +[ + "(" + ")" + "[" + "]" + "{" + "}" +] @punctuation.bracket + +[ + "break" + (continue) + "else" + "fn" + "if" + "let" + "loop" + "return" + "use" +] @keyword diff --git a/syntastica-queries/generated_queries/ursa/highlights_crates_io.scm b/syntastica-queries/generated_queries/ursa/highlights_crates_io.scm new file mode 100644 index 00000000..6f31d2a0 --- /dev/null +++ b/syntastica-queries/generated_queries/ursa/highlights_crates_io.scm @@ -0,0 +1,82 @@ +( + (identifier) @variable.builtin + (#match? @variable.builtin "^(pi)$") + (#is-not? local) +) + +( + (identifier) @function.builtin + (#eq? @function.builtin "print") + (#is-not? local) +) + +(named_fn + (identifier) @function +) + +(let + (identifier) @function + (lambda) +) + +(call + function: (identifier) @function +) + +(identifier) @variable + +(property_identifier) @property + +[ + (bool) + (null) +] @constant.builtin + +(comment) @comment + +(string) @string + +(number) @number + +[ + ";" + "." + "," +] @punctuation.delimiter + +[ + "-" + "+" + "*" + "**" + "/" + "%" + "<" + "<=" + "=" + "==" + "!=" + ">" + ">=" +] @operator + +[ + "(" + ")" + "[" + "]" + "{" + "}" +] @punctuation.bracket + +[ + "break" + (continue) + "else" + "fn" + "if" + "let" + "loop" + "return" + "use" +] @keyword diff --git a/syntastica-queries/generated_queries/ursa/injections.scm b/syntastica-queries/generated_queries/ursa/injections.scm new file mode 100644 index 00000000..e69de29b diff --git a/syntastica-queries/generated_queries/ursa/injections_crates_io.scm b/syntastica-queries/generated_queries/ursa/injections_crates_io.scm new file mode 100644 index 00000000..e69de29b diff --git a/syntastica-queries/generated_queries/ursa/locals.scm b/syntastica-queries/generated_queries/ursa/locals.scm new file mode 100644 index 00000000..62ef254f --- /dev/null +++ b/syntastica-queries/generated_queries/ursa/locals.scm @@ -0,0 +1,10 @@ +[ + (block) + (lambda) +] @local.scope + +(let + identifier: (identifier) @local.definition +) + +(identifier) @local.reference diff --git a/syntastica-queries/generated_queries/ursa/locals_crates_io.scm b/syntastica-queries/generated_queries/ursa/locals_crates_io.scm new file mode 100644 index 00000000..62ef254f --- /dev/null +++ b/syntastica-queries/generated_queries/ursa/locals_crates_io.scm @@ -0,0 +1,10 @@ +[ + (block) + (lambda) +] @local.scope + +(let + identifier: (identifier) @local.definition +) + +(identifier) @local.reference diff --git a/syntastica-queries/src/lib.rs b/syntastica-queries/src/lib.rs index 87a78fb7..0b48c948 100644 --- a/syntastica-queries/src/lib.rs +++ b/syntastica-queries/src/lib.rs @@ -296,6 +296,13 @@ pub const TYPESCRIPT_HIGHLIGHTS_CRATES_IO: &str = include_str!("../generated_que pub const TYPESCRIPT_INJECTIONS_CRATES_IO: &str = include_str!("../generated_queries/typescript/injections_crates_io.scm"); pub const TYPESCRIPT_LOCALS_CRATES_IO: &str = include_str!("../generated_queries/typescript/locals_crates_io.scm"); +pub const URSA_HIGHLIGHTS: &str = include_str!("../generated_queries/ursa/highlights.scm"); +pub const URSA_INJECTIONS: &str = include_str!("../generated_queries/ursa/injections.scm"); +pub const URSA_LOCALS: &str = include_str!("../generated_queries/ursa/locals.scm"); +pub const URSA_HIGHLIGHTS_CRATES_IO: &str = include_str!("../generated_queries/ursa/highlights_crates_io.scm"); +pub const URSA_INJECTIONS_CRATES_IO: &str = include_str!("../generated_queries/ursa/injections_crates_io.scm"); +pub const URSA_LOCALS_CRATES_IO: &str = include_str!("../generated_queries/ursa/locals_crates_io.scm"); + pub const VERILOG_HIGHLIGHTS: &str = include_str!("../generated_queries/verilog/highlights.scm"); pub const VERILOG_INJECTIONS: &str = include_str!("../generated_queries/verilog/injections.scm"); pub const VERILOG_LOCALS: &str = include_str!("../generated_queries/verilog/locals.scm"); diff --git a/xtask/src/add_lang.rs b/xtask/src/add_lang.rs index a1149fbf..87a84c8a 100644 --- a/xtask/src/add_lang.rs +++ b/xtask/src/add_lang.rs @@ -12,7 +12,6 @@ use crates_io_api::SyncClient; use fancy_regex::Regex; use once_cell::sync::Lazy; use semver::{Version, VersionReq}; -use serde_json::{Map, Value}; use toml::Table; pub fn run() -> Result<()> { @@ -36,10 +35,6 @@ pub fn run() -> Result<()> { }; println!("info: found revision '{rev}'"); - let file_extensions = content_url - .as_ref() - .and_then(|url| try_get_extensions(url)) - .unwrap_or_default(); let external_c = content_url.as_ref().map_or(false, |url| { reqwest::blocking::get(format!("{url}{path_in_url}/src/scanner.c")) .map_or(false, |response| response.status().is_success()) @@ -105,7 +100,7 @@ pub fn run() -> Result<()> { r###"[[languages]] name = "{name}" group = "{group}" -file-extensions = {file_extensions:?} +file-types = [] [languages.parser] git = {{ url = "{url}", rev = "{rev}"{path} }} external-scanner = {{ c = {external_c}, cpp = {external_cpp} }} @@ -192,31 +187,6 @@ pub fn url_to_content_url(url: &str, rev: &str) -> Option { } } -fn try_get_extensions(content_url: &str) -> Option> { - let json_str = reqwest::blocking::get(format!("{content_url}/package.json")) - .ok()? - .text() - .ok()?; - let json = serde_json::from_str::>(&json_str).ok()?; - let langs = json.get("tree-sitter")?.as_array()?; - let mut file_extensions = vec![]; - if langs.len() > 1 { - eprintln!("warning: 'package.json' contains information for multiple languages, all file extensions will be combined"); - } - for lang in langs { - let mut exts = lang - .get("file-types")? - .as_array()? - .iter() - .map(|val| val.as_str().map(ToOwned::to_owned)) - .collect::>>()?; - eprintln!("{}: {exts:?}", lang.get("scope")?); - file_extensions.append(&mut exts); - } - - Some(file_extensions) -} - fn try_get_package(content_url: &str) -> Option { let toml_str = reqwest::blocking::get(format!("{content_url}/Cargo.toml")) .ok()?