highlighter: Fix injection language highlight. (#931)
Still have a bit bug for highlight: <img width="1012" alt="image" src="https://github.com/user-attachments/assets/7ec39c85-c20c-4231-8752-b2a7a80f5570" />
This commit is contained in:
parent
c333fd7106
commit
79ff6ba9cc
11 changed files with 1180 additions and 280 deletions
101
Cargo.lock
generated
101
Cargo.lock
generated
|
|
@ -623,7 +623,7 @@ dependencies = [
|
|||
"bitflags 2.9.1",
|
||||
"cexpr",
|
||||
"clang-sys",
|
||||
"itertools 0.10.5",
|
||||
"itertools 0.12.1",
|
||||
"lazy_static",
|
||||
"lazycell",
|
||||
"log",
|
||||
|
|
@ -646,7 +646,7 @@ dependencies = [
|
|||
"bitflags 2.9.1",
|
||||
"cexpr",
|
||||
"clang-sys",
|
||||
"itertools 0.10.5",
|
||||
"itertools 0.13.0",
|
||||
"log",
|
||||
"prettyplease",
|
||||
"proc-macro2",
|
||||
|
|
@ -989,7 +989,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "eadd868a2ce9ca38de7eeafdcec9c7065ef89b42b32f0839278d55f35c54d1ff"
|
||||
dependencies = [
|
||||
"heck 0.4.1",
|
||||
"indexmap 2.7.1",
|
||||
"indexmap 2.9.0",
|
||||
"log",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
|
@ -1226,9 +1226,9 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "collections"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/zed-industries/zed.git#047a7f5d290448e026731123e912f8621c806031"
|
||||
source = "git+https://github.com/zed-industries/zed.git#ee2a3299815ea29770491b34592a448d95761cdb"
|
||||
dependencies = [
|
||||
"indexmap 2.7.1",
|
||||
"indexmap 2.9.0",
|
||||
"rustc-hash 2.1.0",
|
||||
"workspace-hack",
|
||||
]
|
||||
|
|
@ -1739,7 +1739,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "derive_refineable"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/zed-industries/zed.git#047a7f5d290448e026731123e912f8621c806031"
|
||||
source = "git+https://github.com/zed-industries/zed.git#ee2a3299815ea29770491b34592a448d95761cdb"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
|
@ -2313,6 +2313,15 @@ version = "1.3.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c"
|
||||
|
||||
[[package]]
|
||||
name = "ftree"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9ae0379499242d3b9355c5069b43b9417def8c9b09903b930db1fe49318dc9e9"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "funty"
|
||||
version = "2.0.0"
|
||||
|
|
@ -2777,7 +2786,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "gpui"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/zed-industries/zed.git#047a7f5d290448e026731123e912f8621c806031"
|
||||
source = "git+https://github.com/zed-industries/zed.git#ee2a3299815ea29770491b34592a448d95761cdb"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"as-raw-xcb-connection",
|
||||
|
|
@ -2879,6 +2888,7 @@ dependencies = [
|
|||
"gpui-component-macros",
|
||||
"html5ever 0.27.0",
|
||||
"image",
|
||||
"indexset",
|
||||
"indoc",
|
||||
"itertools 0.13.0",
|
||||
"markdown",
|
||||
|
|
@ -2909,10 +2919,10 @@ dependencies = [
|
|||
"tree-sitter-embedded-template",
|
||||
"tree-sitter-go",
|
||||
"tree-sitter-graphql",
|
||||
"tree-sitter-highlight",
|
||||
"tree-sitter-html",
|
||||
"tree-sitter-java",
|
||||
"tree-sitter-javascript",
|
||||
"tree-sitter-jsdoc",
|
||||
"tree-sitter-json",
|
||||
"tree-sitter-make",
|
||||
"tree-sitter-md",
|
||||
|
|
@ -2945,7 +2955,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "gpui_macros"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/zed-industries/zed.git#047a7f5d290448e026731123e912f8621c806031"
|
||||
source = "git+https://github.com/zed-industries/zed.git#ee2a3299815ea29770491b34592a448d95761cdb"
|
||||
dependencies = [
|
||||
"heck 0.5.0",
|
||||
"proc-macro2",
|
||||
|
|
@ -3024,7 +3034,7 @@ dependencies = [
|
|||
"futures-core",
|
||||
"futures-sink",
|
||||
"http",
|
||||
"indexmap 2.7.1",
|
||||
"indexmap 2.9.0",
|
||||
"slab",
|
||||
"tokio",
|
||||
"tokio-util",
|
||||
|
|
@ -3215,7 +3225,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "http_client"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/zed-industries/zed.git#047a7f5d290448e026731123e912f8621c806031"
|
||||
source = "git+https://github.com/zed-industries/zed.git#ee2a3299815ea29770491b34592a448d95761cdb"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bytes",
|
||||
|
|
@ -3232,7 +3242,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "http_client_tls"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/zed-industries/zed.git#047a7f5d290448e026731123e912f8621c806031"
|
||||
source = "git+https://github.com/zed-industries/zed.git#ee2a3299815ea29770491b34592a448d95761cdb"
|
||||
dependencies = [
|
||||
"rustls",
|
||||
"rustls-platform-verifier",
|
||||
|
|
@ -3415,15 +3425,24 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "2.7.1"
|
||||
version = "2.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8c9c992b02b5b4c94ea26e32fe5bccb7aa7d9f390ab5c1221ff895bc7ea8b652"
|
||||
checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e"
|
||||
dependencies = [
|
||||
"equivalent",
|
||||
"hashbrown 0.15.2",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "indexset"
|
||||
version = "0.12.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7d55bfb73496dd673d99571597bfe757c0b227339da7d842ef6159e211de1075"
|
||||
dependencies = [
|
||||
"ftree",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "indoc"
|
||||
version = "2.0.5"
|
||||
|
|
@ -3777,7 +3796,7 @@ dependencies = [
|
|||
"dashmap",
|
||||
"data-encoding",
|
||||
"getrandom 0.2.15",
|
||||
"indexmap 2.7.1",
|
||||
"indexmap 2.9.0",
|
||||
"itertools 0.10.5",
|
||||
"lazy_static",
|
||||
"lightningcss-derive",
|
||||
|
|
@ -4002,7 +4021,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "media"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/zed-industries/zed.git#047a7f5d290448e026731123e912f8621c806031"
|
||||
source = "git+https://github.com/zed-industries/zed.git#ee2a3299815ea29770491b34592a448d95761cdb"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bindgen 0.71.1",
|
||||
|
|
@ -4148,7 +4167,7 @@ dependencies = [
|
|||
"half",
|
||||
"hashbrown 0.15.2",
|
||||
"hexf-parse",
|
||||
"indexmap 2.7.1",
|
||||
"indexmap 2.9.0",
|
||||
"log",
|
||||
"num-traits",
|
||||
"once_cell",
|
||||
|
|
@ -4395,7 +4414,7 @@ version = "0.7.3"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56"
|
||||
dependencies = [
|
||||
"proc-macro-crate 1.3.1",
|
||||
"proc-macro-crate 3.2.0",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.101",
|
||||
|
|
@ -5719,7 +5738,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "refineable"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/zed-industries/zed.git#047a7f5d290448e026731123e912f8621c806031"
|
||||
source = "git+https://github.com/zed-industries/zed.git#ee2a3299815ea29770491b34592a448d95761cdb"
|
||||
dependencies = [
|
||||
"derive_refineable",
|
||||
"workspace-hack",
|
||||
|
|
@ -5829,7 +5848,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "reqwest_client"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/zed-industries/zed.git#047a7f5d290448e026731123e912f8621c806031"
|
||||
source = "git+https://github.com/zed-industries/zed.git#ee2a3299815ea29770491b34592a448d95761cdb"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bytes",
|
||||
|
|
@ -6267,7 +6286,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "3fbf2ae1b8bc8e02df939598064d22402220cd5bbcca1c76f7d6a310974d5615"
|
||||
dependencies = [
|
||||
"dyn-clone",
|
||||
"indexmap 2.7.1",
|
||||
"indexmap 2.9.0",
|
||||
"schemars_derive",
|
||||
"serde",
|
||||
"serde_json",
|
||||
|
|
@ -6378,7 +6397,7 @@ checksum = "d369a96f978623eb3dc28807c4852d6cc617fed53da5d3c400feff1ef34a714a"
|
|||
[[package]]
|
||||
name = "semantic_version"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/zed-industries/zed.git#047a7f5d290448e026731123e912f8621c806031"
|
||||
source = "git+https://github.com/zed-industries/zed.git#ee2a3299815ea29770491b34592a448d95761cdb"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"serde",
|
||||
|
|
@ -6437,7 +6456,7 @@ version = "1.0.140"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373"
|
||||
dependencies = [
|
||||
"indexmap 2.7.1",
|
||||
"indexmap 2.9.0",
|
||||
"itoa 1.0.11",
|
||||
"memchr",
|
||||
"ryu",
|
||||
|
|
@ -6450,7 +6469,7 @@ version = "0.2.4"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0e033097bf0d2b59a62b42c18ebbb797503839b26afdda2c4e1415cb6c813540"
|
||||
dependencies = [
|
||||
"indexmap 2.7.1",
|
||||
"indexmap 2.9.0",
|
||||
"itoa 1.0.11",
|
||||
"memchr",
|
||||
"ryu",
|
||||
|
|
@ -6495,7 +6514,7 @@ version = "0.9.34+deprecated"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47"
|
||||
dependencies = [
|
||||
"indexmap 2.7.1",
|
||||
"indexmap 2.9.0",
|
||||
"itoa 1.0.11",
|
||||
"ryu",
|
||||
"serde",
|
||||
|
|
@ -6876,7 +6895,7 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
|
|||
[[package]]
|
||||
name = "sum_tree"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/zed-industries/zed.git#047a7f5d290448e026731123e912f8621c806031"
|
||||
source = "git+https://github.com/zed-industries/zed.git#ee2a3299815ea29770491b34592a448d95761cdb"
|
||||
dependencies = [
|
||||
"arrayvec",
|
||||
"log",
|
||||
|
|
@ -7389,7 +7408,7 @@ version = "0.19.15"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421"
|
||||
dependencies = [
|
||||
"indexmap 2.7.1",
|
||||
"indexmap 2.9.0",
|
||||
"toml_datetime",
|
||||
"winnow 0.5.40",
|
||||
]
|
||||
|
|
@ -7400,7 +7419,7 @@ version = "0.20.7"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "70f427fce4d84c72b5b732388bf4a9f4531b53f74e2887e3ecb2481f68f66d81"
|
||||
dependencies = [
|
||||
"indexmap 2.7.1",
|
||||
"indexmap 2.9.0",
|
||||
"toml_datetime",
|
||||
"winnow 0.5.40",
|
||||
]
|
||||
|
|
@ -7411,7 +7430,7 @@ version = "0.22.22"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5"
|
||||
dependencies = [
|
||||
"indexmap 2.7.1",
|
||||
"indexmap 2.9.0",
|
||||
"serde",
|
||||
"serde_spanned",
|
||||
"toml_datetime",
|
||||
|
|
@ -7630,18 +7649,6 @@ dependencies = [
|
|||
"tree-sitter-language",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tree-sitter-highlight"
|
||||
version = "0.25.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ba3bdc761dfa6b50677cd1bb23b55571d3902c54671c952f7147da2642e15248"
|
||||
dependencies = [
|
||||
"regex",
|
||||
"streaming-iterator",
|
||||
"thiserror 2.0.12",
|
||||
"tree-sitter",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tree-sitter-html"
|
||||
version = "0.23.2"
|
||||
|
|
@ -7672,6 +7679,16 @@ dependencies = [
|
|||
"tree-sitter-language",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tree-sitter-jsdoc"
|
||||
version = "0.23.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a3862dfcb1038fc5e7812d7df14190afdeb7e1415288fd5f51f58395f8cb0faf"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"tree-sitter-language",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tree-sitter-json"
|
||||
version = "0.24.8"
|
||||
|
|
@ -8054,7 +8071,7 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
|
|||
[[package]]
|
||||
name = "util"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/zed-industries/zed.git#047a7f5d290448e026731123e912f8621c806031"
|
||||
source = "git+https://github.com/zed-industries/zed.git#ee2a3299815ea29770491b34592a448d95761cdb"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-fs 2.1.2",
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ fn init(cx: &mut App) {
|
|||
LanguageRegistry::global_mut(cx).register(
|
||||
"navi",
|
||||
&LanguageConfig::new(
|
||||
"navi",
|
||||
tree_sitter_navi::LANGUAGE.into(),
|
||||
vec![],
|
||||
tree_sitter_navi::HIGHLIGHTS_QUERY,
|
||||
|
|
@ -46,7 +47,7 @@ impl Lang {
|
|||
}
|
||||
}
|
||||
|
||||
const LANGUAGES: [(Lang, &'static str); 8] = [
|
||||
const LANGUAGES: [(Lang, &'static str); 9] = [
|
||||
(
|
||||
Lang::BuiltIn(Language::Rust),
|
||||
include_str!("./fixtures/test.rs"),
|
||||
|
|
@ -55,6 +56,10 @@ const LANGUAGES: [(Lang, &'static str); 8] = [
|
|||
Lang::BuiltIn(Language::JavaScript),
|
||||
include_str!("./fixtures/test.js"),
|
||||
),
|
||||
(
|
||||
Lang::BuiltIn(Language::TypeScript),
|
||||
include_str!("./fixtures/test.ts"),
|
||||
),
|
||||
(
|
||||
Lang::BuiltIn(Language::Go),
|
||||
include_str!("./fixtures/test.go"),
|
||||
|
|
|
|||
|
|
@ -1,76 +1,83 @@
|
|||
const fs = require("fs");
|
||||
|
||||
const getName = function () {
|
||||
return "John Doe";
|
||||
};
|
||||
|
||||
/**
|
||||
* A class representing a HelloWorld greeter with various utility methods
|
||||
* @class HelloWorld
|
||||
* @param {string} name - The name to use for greetings
|
||||
*/
|
||||
class HelloWorld {
|
||||
// Version number of the HelloWorld class
|
||||
static VERSION = '1.0.0';
|
||||
// Counter to track number of class instances
|
||||
static #instanceCount = 0;
|
||||
// Version number of the HelloWorld class
|
||||
static VERSION = "1.0.0";
|
||||
// Counter to track number of class instances
|
||||
static #instanceCount = 0;
|
||||
|
||||
// Private instance fields
|
||||
#name;
|
||||
#options;
|
||||
#createdAt;
|
||||
// Private instance fields
|
||||
#name;
|
||||
#options;
|
||||
#createdAt;
|
||||
|
||||
/**
|
||||
* Creates a new HelloWorld instance
|
||||
* @param {string} name - The name to use for greetings
|
||||
* @param {Object} options - Configuration options
|
||||
*/
|
||||
constructor(name = 'World', options = {}) {
|
||||
this.#name = name;
|
||||
this.#options = options;
|
||||
this.#createdAt = new Date();
|
||||
HelloWorld.#instanceCount++;
|
||||
/**
|
||||
* Creates a new HelloWorld instance
|
||||
* @param {string} name - The name to use for greetings
|
||||
* @param {Object} options - Configuration options
|
||||
*/
|
||||
constructor(name = "World", options = {}) {
|
||||
this.#name = name;
|
||||
this.#options = options;
|
||||
this.#createdAt = new Date();
|
||||
HelloWorld.#instanceCount++;
|
||||
}
|
||||
|
||||
static getInstanceCount() {
|
||||
return HelloWorld.#instanceCount;
|
||||
}
|
||||
|
||||
get name() {
|
||||
return this.#name;
|
||||
}
|
||||
|
||||
set name(value) {
|
||||
this.#name = value;
|
||||
}
|
||||
|
||||
async greet(...names) {
|
||||
try {
|
||||
for (const name of names) {
|
||||
await new Promise((resolve) => setTimeout(resolve, 100));
|
||||
console.log(`Hello, ${name}!`);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`Error: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
static getInstanceCount() {
|
||||
return HelloWorld.#instanceCount;
|
||||
}
|
||||
configure(options = {}) {
|
||||
Object.assign(this.#options, options);
|
||||
}
|
||||
|
||||
get name() {
|
||||
return this.#name;
|
||||
}
|
||||
*generateSequence(start = 0, end = 10) {
|
||||
for (let i = start; i <= end; i++) yield i;
|
||||
}
|
||||
|
||||
set name(value) {
|
||||
this.#name = value;
|
||||
}
|
||||
|
||||
async greet(...names) {
|
||||
try {
|
||||
for (const name of names) {
|
||||
await new Promise(resolve => setTimeout(resolve, 100));
|
||||
console.log(`Hello, ${name}!`);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`Error: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
configure(options = {}) {
|
||||
Object.assign(this.#options, options);
|
||||
}
|
||||
|
||||
*generateSequence(start = 0, end = 10) {
|
||||
for (let i = start; i <= end; i++) yield i;
|
||||
}
|
||||
|
||||
processNames(names) {
|
||||
return names
|
||||
.filter(name => name.length > 0)
|
||||
.map(name => name.toUpperCase())
|
||||
.sort();
|
||||
}
|
||||
processNames(names) {
|
||||
return names
|
||||
.filter((name) => name.length > 0)
|
||||
.map((name) => name.toUpperCase())
|
||||
.sort();
|
||||
}
|
||||
}
|
||||
|
||||
const greeter = new HelloWorld('JavaScript');
|
||||
const greeter = new HelloWorld("JavaScript");
|
||||
|
||||
(async () => {
|
||||
const uniqueNames = new Set(['Alice', 'Bob']);
|
||||
await greeter.greet(...uniqueNames);
|
||||
const uniqueNames = new Set(["Alice", "Bob"]);
|
||||
await greeter.greet(...uniqueNames);
|
||||
|
||||
for (const num of greeter.generateSequence(0, 5)) {
|
||||
console.log(num);
|
||||
}
|
||||
for (const num of greeter.generateSequence(0, 5)) {
|
||||
console.log(num);
|
||||
}
|
||||
})();
|
||||
|
|
|
|||
51
crates/story/examples/fixtures/test.ts
Normal file
51
crates/story/examples/fixtures/test.ts
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
import fs, { readFile } from "fs";
|
||||
|
||||
const VERSION = "1.0.0";
|
||||
|
||||
class HelloWorld {
|
||||
private name: string;
|
||||
private createdAt: Date;
|
||||
private options: Record<string, any>;
|
||||
|
||||
constructor(name: string) {
|
||||
this.name = name;
|
||||
this.createdAt = new Date();
|
||||
this.options = {};
|
||||
}
|
||||
|
||||
greet(names: string[]): void {
|
||||
for (const name of names) {
|
||||
console.log(`Hello, ${name}!`);
|
||||
}
|
||||
}
|
||||
|
||||
configure(cfg: { timeout: number; retries: number; debug: boolean }): void {
|
||||
this.options["timeout"] = cfg.timeout;
|
||||
this.options["retries"] = cfg.retries;
|
||||
this.options["debug"] = cfg.debug;
|
||||
}
|
||||
|
||||
generateReport(): string {
|
||||
return `
|
||||
HelloWorld Report
|
||||
=================
|
||||
Name: ${this.name}
|
||||
Created: ${this.createdAt.toISOString()}
|
||||
Options: ${JSON.stringify(this.options, null, 2)}
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
const timeout = 5000;
|
||||
|
||||
function main() {
|
||||
const greeter = new HelloWorld("TypeScript");
|
||||
greeter.configure({
|
||||
timeout: timeout,
|
||||
retries: 3,
|
||||
debug: true,
|
||||
});
|
||||
|
||||
greeter.greet(["Alice", "Bob"]);
|
||||
console.log(greeter.generateReport());
|
||||
}
|
||||
|
|
@ -57,6 +57,7 @@ minify-html = "0.15.0"
|
|||
chrono = "0.4.38"
|
||||
|
||||
# Code Editor
|
||||
indexset = "0.12.2"
|
||||
tree-sitter = "0.25.4"
|
||||
tree-sitter-bash = "0.23.3"
|
||||
tree-sitter-c = "0.24.1"
|
||||
|
|
@ -69,10 +70,10 @@ tree-sitter-elixir = "0.3"
|
|||
tree-sitter-embedded-template = "0.23.0"
|
||||
tree-sitter-go = "0.23.4"
|
||||
tree-sitter-graphql = "0.1.0"
|
||||
tree-sitter-highlight = "0.25.4"
|
||||
tree-sitter-html = "0.23.2"
|
||||
tree-sitter-java = "0.23.5"
|
||||
tree-sitter-javascript = "0.23.1"
|
||||
tree-sitter-jsdoc = "0.23.2"
|
||||
tree-sitter-json = "0.24.8"
|
||||
tree-sitter-make = "1.1.1"
|
||||
tree-sitter-md = { git = "https://github.com/tree-sitter-grammars/tree-sitter-markdown", tag = "v0.5.0" }
|
||||
|
|
|
|||
|
|
@ -1,17 +1,14 @@
|
|||
use super::HighlightTheme;
|
||||
use crate::highlighter::LanguageRegistry;
|
||||
use gpui::{App, HighlightStyle, SharedString};
|
||||
use indexset::BTreeMap;
|
||||
use std::{
|
||||
collections::{BTreeMap, HashMap},
|
||||
ops::Range,
|
||||
sync::Arc,
|
||||
collections::HashMap,
|
||||
ops::{Bound, Range},
|
||||
};
|
||||
use tree_sitter::{
|
||||
InputEdit, Node, Parser, Point, Query, QueryCursor, QueryMatch, StreamingIterator, Tree,
|
||||
};
|
||||
use tree_sitter_highlight::{HighlightConfiguration, Highlighter};
|
||||
|
||||
use crate::highlighter::LanguageRegistry;
|
||||
|
||||
use super::{HighlightTheme, Language};
|
||||
|
||||
/// A syntax highlighter that supports incremental parsing, multiline text,
|
||||
/// and caching of highlight results.
|
||||
|
|
@ -23,8 +20,6 @@ pub struct SyntaxHighlighter {
|
|||
parser: Parser,
|
||||
old_tree: Option<Tree>,
|
||||
text: SharedString,
|
||||
highlighter: Highlighter,
|
||||
config: Option<Arc<HighlightConfiguration>>,
|
||||
|
||||
locals_pattern_index: usize,
|
||||
highlights_pattern_index: usize,
|
||||
|
|
@ -43,7 +38,7 @@ pub struct SyntaxHighlighter {
|
|||
///
|
||||
/// - The `key` is the `start` of the range.
|
||||
/// -The `value` is a tuple of the range (in the entire text) and the highlight name.
|
||||
cache: BTreeMap<usize, (Range<usize>, String)>,
|
||||
cache: BTreeMap<usize, (Range<usize>, SharedString)>,
|
||||
}
|
||||
|
||||
impl SyntaxHighlighter {
|
||||
|
|
@ -60,10 +55,7 @@ impl SyntaxHighlighter {
|
|||
/// https://github.com/tree-sitter/tree-sitter/blob/v0.25.5/highlight/src/lib.rs#L336
|
||||
fn build_combined_injections_query(lang: &str, cx: &App) -> Option<Self> {
|
||||
let registry = LanguageRegistry::global(cx);
|
||||
let config = registry.language(&lang);
|
||||
let Some(config) = config else {
|
||||
return None;
|
||||
};
|
||||
let config = registry.language(&lang)?;
|
||||
|
||||
let mut parser = Parser::new();
|
||||
_ = parser.set_language(&config.language);
|
||||
|
|
@ -78,9 +70,12 @@ impl SyntaxHighlighter {
|
|||
|
||||
// Construct a single query by concatenating the three query strings, but record the
|
||||
// range of pattern indices that belong to each individual string.
|
||||
let Some(query) = Query::new(&config.language, &query_source).ok() else {
|
||||
return None;
|
||||
};
|
||||
let query = match Query::new(&config.language, &query_source) {
|
||||
Ok(query) => Some(query),
|
||||
Err(err) => {
|
||||
panic!("failed create Query for language {}, err: {}", lang, err);
|
||||
}
|
||||
}?;
|
||||
|
||||
let mut locals_pattern_index = 0;
|
||||
let mut highlights_pattern_index = 0;
|
||||
|
|
@ -176,8 +171,6 @@ impl SyntaxHighlighter {
|
|||
parser,
|
||||
old_tree: None,
|
||||
text: SharedString::new(""),
|
||||
highlighter: Highlighter::new(),
|
||||
config: None,
|
||||
cache: BTreeMap::new(),
|
||||
locals_pattern_index,
|
||||
highlights_pattern_index,
|
||||
|
|
@ -191,35 +184,6 @@ impl SyntaxHighlighter {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn set_language(&mut self, language: impl Into<SharedString>, cx: &App) {
|
||||
let language = language.into();
|
||||
|
||||
if self.language == language {
|
||||
return;
|
||||
}
|
||||
|
||||
// FIXME: use build_combined_injections_query to build the query.
|
||||
self.query = None;
|
||||
if let Some(language) = Language::from_str(&language) {
|
||||
self.query = Some(language.query());
|
||||
_ = self.parser.set_language(&language.config().language);
|
||||
} else {
|
||||
if let Some(config) = LanguageRegistry::global(cx).language(&language) {
|
||||
_ = self.parser.set_language(&config.language);
|
||||
if let Ok(query) = tree_sitter::Query::new(&config.language, &config.highlights) {
|
||||
self.query = Some(query);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.language = language;
|
||||
self.old_tree = None;
|
||||
self.text = SharedString::new("");
|
||||
self.highlighter = Highlighter::new();
|
||||
self.config = None;
|
||||
self.cache.clear();
|
||||
}
|
||||
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.text.is_empty()
|
||||
}
|
||||
|
|
@ -283,7 +247,7 @@ impl SyntaxHighlighter {
|
|||
&mut self,
|
||||
changed_ranges: Option<impl ExactSizeIterator<Item = tree_sitter::Range>>,
|
||||
changed_len: isize,
|
||||
_: &mut App,
|
||||
cx: &mut App,
|
||||
) {
|
||||
let Some(tree) = &self.old_tree else {
|
||||
return;
|
||||
|
|
@ -298,7 +262,6 @@ impl SyntaxHighlighter {
|
|||
let mut root_node = tree.root_node();
|
||||
|
||||
// Incremental parsing to only update changed ranges.
|
||||
let mut last_end = 0;
|
||||
if let Some(changed_ranges) = changed_ranges {
|
||||
let mut total_range = 0..0;
|
||||
for change_range in changed_ranges {
|
||||
|
|
@ -338,7 +301,7 @@ impl SyntaxHighlighter {
|
|||
});
|
||||
|
||||
// Apply changed_len to reorder the cache to move the range offset
|
||||
let mut old_cache: BTreeMap<usize, (Range<usize>, String)> = BTreeMap::new();
|
||||
let mut old_cache: BTreeMap<usize, (Range<usize>, SharedString)> = BTreeMap::new();
|
||||
std::mem::swap(&mut self.cache, &mut old_cache);
|
||||
|
||||
// NOTE: 10K lines, about 35ms
|
||||
|
|
@ -362,24 +325,19 @@ impl SyntaxHighlighter {
|
|||
|
||||
let mut matches = query_cursor.matches(&query, root_node, source);
|
||||
|
||||
// TODO: Merge duplicate ranges.
|
||||
|
||||
while let Some(m) = matches.next() {
|
||||
// Ref:
|
||||
// https://github.com/tree-sitter/tree-sitter/blob/460118b4c82318b083b4d527c9c750426730f9c0/highlight/src/lib.rs#L556
|
||||
let (language_name, content_node, _) = self.injection_for_match(None, query, m, source);
|
||||
if let Some(language_name) = language_name {
|
||||
if let Some(content_node) = content_node {
|
||||
if content_node.start_byte() < last_end {
|
||||
continue;
|
||||
}
|
||||
|
||||
let styles = self.handle_injection(&language_name, content_node, source);
|
||||
let styles = self.handle_injection(&language_name, content_node, source, cx);
|
||||
for (node_range, highlight_name) in styles {
|
||||
self.cache
|
||||
.insert(node_range.start, (node_range, highlight_name.to_string()));
|
||||
self.cache.insert(
|
||||
node_range.start,
|
||||
(node_range, highlight_name.to_string().into()),
|
||||
);
|
||||
}
|
||||
last_end = content_node.end_byte();
|
||||
}
|
||||
|
||||
continue;
|
||||
|
|
@ -387,23 +345,36 @@ impl SyntaxHighlighter {
|
|||
|
||||
for cap in m.captures {
|
||||
let node = cap.node;
|
||||
if node.start_byte() < last_end {
|
||||
|
||||
let Some(highlight_name) = query.capture_names().get(cap.index as usize) else {
|
||||
continue;
|
||||
}
|
||||
};
|
||||
|
||||
let highlight_name = query.capture_names()[cap.index as usize];
|
||||
let node_range: Range<usize> = node.start_byte()..node.end_byte();
|
||||
let highlight_name = SharedString::from(highlight_name.to_string());
|
||||
|
||||
self.cache.insert(
|
||||
node_range.start,
|
||||
(node_range.clone(), highlight_name.to_string()),
|
||||
);
|
||||
last_end = node_range.end;
|
||||
// Merge near range and same highlight name
|
||||
let last_item = self.cache.last_key_value().map(|kv| kv.1);
|
||||
let last_range = last_item.map(|(range, _)| range).unwrap_or(&(0..0));
|
||||
let last_highlight_name = last_item.map(|(_, name)| name.clone());
|
||||
|
||||
if last_range.end <= node_range.start
|
||||
&& last_highlight_name.as_ref() == Some(&highlight_name)
|
||||
{
|
||||
self.cache.insert(
|
||||
last_range.start,
|
||||
(last_range.start..node_range.end, highlight_name.clone()),
|
||||
);
|
||||
} else {
|
||||
self.cache
|
||||
.insert(node_range.start, (node_range, highlight_name.clone()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DO NOT REMOVE THIS PRINT, it's useful for debugging
|
||||
// for item in self.cache.iter() {
|
||||
// println!("---------- item: {:?}", item);
|
||||
// println!("item: {:?}", item);
|
||||
// }
|
||||
}
|
||||
|
||||
|
|
@ -413,6 +384,7 @@ impl SyntaxHighlighter {
|
|||
injection_language: &str,
|
||||
node: Node,
|
||||
source: &[u8],
|
||||
cx: &App,
|
||||
) -> Vec<(Range<usize>, String)> {
|
||||
let start_offset = node.start_byte();
|
||||
let end_offset = node.end_byte();
|
||||
|
|
@ -426,12 +398,11 @@ impl SyntaxHighlighter {
|
|||
if content.is_empty() {
|
||||
return cache;
|
||||
};
|
||||
let Some(lang) = super::Language::from_str(injection_language) else {
|
||||
let Some(config) = LanguageRegistry::global(cx).language(injection_language) else {
|
||||
return cache;
|
||||
};
|
||||
let lang_config = lang.config();
|
||||
let mut parser = Parser::new();
|
||||
if parser.set_language(&lang_config.language).is_err() {
|
||||
if parser.set_language(&config.language).is_err() {
|
||||
return cache;
|
||||
}
|
||||
let Some(tree) = parser.parse(content, None) else {
|
||||
|
|
@ -456,9 +427,10 @@ impl SyntaxHighlighter {
|
|||
break;
|
||||
}
|
||||
|
||||
let highlight_name = query.capture_names()[cap.index as usize];
|
||||
last_end = node_range.end;
|
||||
cache.push((node_range, highlight_name.to_string()));
|
||||
if let Some(highlight_name) = query.capture_names().get(cap.index as usize) {
|
||||
last_end = node_range.end;
|
||||
cache.push((node_range, highlight_name.to_string()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -549,7 +521,7 @@ impl SyntaxHighlighter {
|
|||
/// The argument `range` is the range of the line in the text.
|
||||
///
|
||||
/// Returns `range` is the range in the line.
|
||||
pub fn styles(
|
||||
pub(crate) fn styles(
|
||||
&self,
|
||||
range: &Range<usize>,
|
||||
theme: &HighlightTheme,
|
||||
|
|
@ -558,25 +530,42 @@ impl SyntaxHighlighter {
|
|||
let start_offset = range.start;
|
||||
let mut last_range = start_offset..start_offset;
|
||||
|
||||
// NOTE: the ranges in the cache may have duplicates, so we need to merge them.
|
||||
for (_, (node_range, name)) in self.cache.range(range.start..) {
|
||||
// TODO: If break, the `comment.doc` will not work.
|
||||
// Ref: https://github.com/longbridge/gpui-component/pull/904/commits/d8f886939d3b472f228c1ce72154a951e98f32c5
|
||||
if node_range.end > range.end {
|
||||
// NOTE: Iterate over the cache and print the range and style for each item.
|
||||
// for (_, (range, style)) in self.cache.iter() {
|
||||
// println!("-- range: {:?}, style: {:?}", range, style);
|
||||
// }
|
||||
|
||||
let mut cursor = self.cache.lower_bound(Bound::Included(&range.start));
|
||||
// Move to the previous item if the current item is not the start of the range.
|
||||
// This is for case like JsDoc, where token may contains multiple lines.
|
||||
if cursor.key() != Some(&range.start) {
|
||||
cursor.move_prev();
|
||||
}
|
||||
|
||||
while let Some((node_range, name)) = cursor.value() {
|
||||
// Break loop if the node_range is out of the range
|
||||
if node_range.start > range.end {
|
||||
break;
|
||||
}
|
||||
|
||||
// let range_in_line = node_range.start..node_range.end;
|
||||
let mut node_range = node_range.start.max(range.start)..node_range.end.min(range.end);
|
||||
// Avoid start larger than end
|
||||
if node_range.start > node_range.end {
|
||||
node_range.end = node_range.start;
|
||||
}
|
||||
|
||||
// Ensure every range is connected.
|
||||
if last_range.end < node_range.start {
|
||||
styles.push((last_range.end..node_range.start, HighlightStyle::default()));
|
||||
}
|
||||
|
||||
let style = theme.style(&name).unwrap_or_default();
|
||||
|
||||
styles.push((node_range.clone(), style));
|
||||
last_range = node_range.clone();
|
||||
styles.push((
|
||||
node_range.clone(),
|
||||
theme.style(name.as_ref()).unwrap_or_default(),
|
||||
));
|
||||
|
||||
cursor.move_next();
|
||||
}
|
||||
|
||||
// If the matched styles is empty, return a default range.
|
||||
|
|
@ -589,6 +578,179 @@ impl SyntaxHighlighter {
|
|||
styles.push((last_range.end..range.end, HighlightStyle::default()));
|
||||
}
|
||||
|
||||
let styles = unique_styles(styles);
|
||||
|
||||
// NOTE: DO NOT remove this comment, it is used for debugging.
|
||||
// for style in &result {
|
||||
// println!("---- style: {:?} - {:?}", style.0, style.1.color);
|
||||
// }
|
||||
// println!("--------------------------------");
|
||||
|
||||
styles
|
||||
}
|
||||
}
|
||||
|
||||
/// To merge intersection ranges
|
||||
///
|
||||
/// ```
|
||||
/// vec![
|
||||
/// (0..10, clean),
|
||||
/// (0..10, clean),
|
||||
/// (5..11, red),
|
||||
/// (10..15, green),
|
||||
/// (15..30, clean),
|
||||
/// (29..35, blue),
|
||||
/// (35..40, green),
|
||||
/// ];
|
||||
/// ```
|
||||
///
|
||||
/// to
|
||||
///
|
||||
/// ```
|
||||
/// vec![
|
||||
/// (0..5, clean),
|
||||
/// (5..10, red),
|
||||
/// (10..11, green),
|
||||
/// (11..15, green),
|
||||
/// (15..29, clean),
|
||||
/// (29..30, blue),
|
||||
/// (30..35, blue),
|
||||
/// (35..40, green),
|
||||
/// ];
|
||||
/// ```
|
||||
pub(crate) fn unique_styles(
|
||||
styles: Vec<(Range<usize>, HighlightStyle)>,
|
||||
) -> Vec<(Range<usize>, HighlightStyle)> {
|
||||
let mut result: Vec<(Range<usize>, HighlightStyle)> = vec![];
|
||||
let mut current_range: Option<(Range<usize>, HighlightStyle)> = None;
|
||||
|
||||
for (range, style) in styles.into_iter() {
|
||||
if range.is_empty() {
|
||||
continue;
|
||||
}
|
||||
|
||||
if let Some((last_range, last_style)) = current_range.as_mut() {
|
||||
if last_style.color == style.color && range.start <= last_range.end {
|
||||
// Merge overlapping or adjacent ranges with the same style
|
||||
last_range.end = last_range.end.max(range.end);
|
||||
} else if range.start < last_range.end {
|
||||
// Split overlapping ranges with different styles
|
||||
let overlap_start = range.start;
|
||||
let overlap_end = last_range.end.min(range.end);
|
||||
|
||||
if overlap_start > last_range.start {
|
||||
result.push((last_range.start..overlap_start, *last_style));
|
||||
}
|
||||
|
||||
result.push((overlap_start..overlap_end, style));
|
||||
|
||||
last_range.end = overlap_start;
|
||||
if overlap_end < range.end {
|
||||
current_range = Some((overlap_end..range.end, style));
|
||||
} else {
|
||||
current_range = None;
|
||||
}
|
||||
} else {
|
||||
// Push the completed range and start a new one
|
||||
result.push((last_range.clone(), *last_style));
|
||||
current_range = Some((range, style));
|
||||
}
|
||||
} else {
|
||||
current_range = Some((range, style));
|
||||
}
|
||||
}
|
||||
|
||||
if let Some((last_range, last_style)) = current_range {
|
||||
result.push((last_range, last_style));
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use gpui::Hsla;
|
||||
|
||||
use super::*;
|
||||
use crate::Colorize as _;
|
||||
|
||||
fn color_style(color: Hsla) -> HighlightStyle {
|
||||
let mut style = HighlightStyle::default();
|
||||
style.color = Some(color);
|
||||
style
|
||||
}
|
||||
|
||||
#[track_caller]
|
||||
fn assert_unique_styles(
|
||||
left: Vec<(Range<usize>, HighlightStyle)>,
|
||||
right: Vec<(Range<usize>, HighlightStyle)>,
|
||||
) {
|
||||
fn color_name(c: Option<Hsla>) -> String {
|
||||
match c {
|
||||
Some(c) => {
|
||||
if c == gpui::red() {
|
||||
"red".to_string()
|
||||
} else if c == gpui::green() {
|
||||
"green".to_string()
|
||||
} else if c == gpui::blue() {
|
||||
"blue".to_string()
|
||||
} else {
|
||||
c.to_hex()
|
||||
}
|
||||
}
|
||||
None => "clean".to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
let left = unique_styles(left);
|
||||
if left.len() != right.len() {
|
||||
println!("\n---------------------------------------------");
|
||||
for (range, style) in left.iter() {
|
||||
println!("({:?}, {})", range, color_name(style.color));
|
||||
}
|
||||
println!("---------------------------------------------");
|
||||
panic!("left {} styles, right {} styles", left.len(), right.len());
|
||||
}
|
||||
for (left, right) in left.into_iter().zip(right) {
|
||||
if left.1.color != right.1.color || left.0 != right.0 {
|
||||
panic!(
|
||||
"\n left: ({:?}, {})\nright: ({:?}, {})\n",
|
||||
left.0,
|
||||
color_name(left.1.color),
|
||||
right.0,
|
||||
color_name(right.1.color)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_unique_styles() {
|
||||
let red = color_style(gpui::red());
|
||||
let green = color_style(gpui::green());
|
||||
let blue = color_style(gpui::blue());
|
||||
let clean = HighlightStyle::default();
|
||||
|
||||
assert_unique_styles(
|
||||
vec![
|
||||
(0..10, clean),
|
||||
(0..10, clean),
|
||||
(5..11, red),
|
||||
(10..15, green),
|
||||
(15..30, clean),
|
||||
(29..35, blue),
|
||||
(35..40, green),
|
||||
],
|
||||
vec![
|
||||
(0..5, clean),
|
||||
(5..10, red),
|
||||
(10..11, green),
|
||||
(11..15, green),
|
||||
(15..29, clean),
|
||||
(29..30, blue),
|
||||
(30..35, blue),
|
||||
(35..40, green),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,39 +1,39 @@
|
|||
use gpui::SharedString;
|
||||
use tree_sitter::Query;
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, enum_iterator::Sequence)]
|
||||
pub enum Language {
|
||||
Json,
|
||||
Markdown,
|
||||
MarkdownInline,
|
||||
Toml,
|
||||
Yaml,
|
||||
Rust,
|
||||
Go,
|
||||
C,
|
||||
Cpp,
|
||||
JavaScript,
|
||||
Zig,
|
||||
Java,
|
||||
Python,
|
||||
Ruby,
|
||||
Bash,
|
||||
Html,
|
||||
Css,
|
||||
Swift,
|
||||
Scala,
|
||||
Sql,
|
||||
CSharp,
|
||||
GraphQL,
|
||||
Proto,
|
||||
Make,
|
||||
C,
|
||||
CMake,
|
||||
TypeScript,
|
||||
Tsx,
|
||||
CSharp,
|
||||
Cpp,
|
||||
Css,
|
||||
Diff,
|
||||
Ejs,
|
||||
Elixir,
|
||||
Erb,
|
||||
Ejs,
|
||||
Go,
|
||||
GraphQL,
|
||||
Html,
|
||||
Java,
|
||||
JavaScript,
|
||||
JsDoc,
|
||||
Json,
|
||||
Make,
|
||||
Markdown,
|
||||
MarkdownInline,
|
||||
Proto,
|
||||
Python,
|
||||
Ruby,
|
||||
Rust,
|
||||
Scala,
|
||||
Sql,
|
||||
Swift,
|
||||
Toml,
|
||||
Tsx,
|
||||
TypeScript,
|
||||
Yaml,
|
||||
Zig,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
|
|
@ -48,6 +48,7 @@ pub struct LanguageConfig {
|
|||
|
||||
impl LanguageConfig {
|
||||
pub fn new(
|
||||
name: impl Into<SharedString>,
|
||||
language: tree_sitter::Language,
|
||||
injection_languages: Vec<SharedString>,
|
||||
highlights: &str,
|
||||
|
|
@ -55,7 +56,7 @@ impl LanguageConfig {
|
|||
locals: &str,
|
||||
) -> Self {
|
||||
Self {
|
||||
name: language.name().unwrap_or_default().into(),
|
||||
name: name.into(),
|
||||
language,
|
||||
injection_languages,
|
||||
highlights: SharedString::from(highlights.to_string()),
|
||||
|
|
@ -77,73 +78,75 @@ impl Language {
|
|||
|
||||
pub fn name(&self) -> &'static str {
|
||||
match self {
|
||||
Self::Json => "json",
|
||||
Self::Markdown => "markdown",
|
||||
Self::MarkdownInline => "markdown_inline",
|
||||
Self::Toml => "toml",
|
||||
Self::Yaml => "yaml",
|
||||
Self::Rust => "rust",
|
||||
Self::Go => "go",
|
||||
Self::C => "c",
|
||||
Self::Cpp => "cpp",
|
||||
Self::JavaScript => "javascript",
|
||||
Self::Zig => "zig",
|
||||
Self::Java => "java",
|
||||
Self::Python => "python",
|
||||
Self::Ruby => "ruby",
|
||||
Self::Bash => "bash",
|
||||
Self::Html => "html",
|
||||
Self::Css => "css",
|
||||
Self::Swift => "swift",
|
||||
Self::Scala => "scala",
|
||||
Self::Sql => "sql",
|
||||
Self::CSharp => "csharp",
|
||||
Self::GraphQL => "graphql",
|
||||
Self::Proto => "proto",
|
||||
Self::Make => "make",
|
||||
Self::C => "c",
|
||||
Self::CMake => "cmake",
|
||||
Self::TypeScript => "typescript",
|
||||
Self::Tsx => "tsx",
|
||||
Self::CSharp => "csharp",
|
||||
Self::Cpp => "cpp",
|
||||
Self::Css => "css",
|
||||
Self::Diff => "diff",
|
||||
Self::Ejs => "ejs",
|
||||
Self::Elixir => "elixir",
|
||||
Self::Erb => "erb",
|
||||
Self::Ejs => "ejs",
|
||||
Self::Go => "go",
|
||||
Self::GraphQL => "graphql",
|
||||
Self::Html => "html",
|
||||
Self::Java => "java",
|
||||
Self::JavaScript => "javascript",
|
||||
Self::JsDoc => "jsdoc",
|
||||
Self::Json => "json",
|
||||
Self::Make => "make",
|
||||
Self::Markdown => "markdown",
|
||||
Self::MarkdownInline => "markdown_inline",
|
||||
Self::Proto => "proto",
|
||||
Self::Python => "python",
|
||||
Self::Ruby => "ruby",
|
||||
Self::Rust => "rust",
|
||||
Self::Scala => "scala",
|
||||
Self::Sql => "sql",
|
||||
Self::Swift => "swift",
|
||||
Self::Toml => "toml",
|
||||
Self::Tsx => "tsx",
|
||||
Self::TypeScript => "typescript",
|
||||
Self::Yaml => "yaml",
|
||||
Self::Zig => "zig",
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_str(s: &str) -> Option<Self> {
|
||||
match s {
|
||||
"json" | "jsonc" => Some(Self::Json),
|
||||
"markdown" | "md" | "mdx" => Some(Self::Markdown),
|
||||
"markdown_inline" | "markdown-inline" => Some(Self::MarkdownInline),
|
||||
"toml" => Some(Self::Toml),
|
||||
"yaml" | "yml" => Some(Self::Yaml),
|
||||
"rust" | "rs" => Some(Self::Rust),
|
||||
"go" => Some(Self::Go),
|
||||
"c" => Some(Self::C),
|
||||
"cpp" | "c++" => Some(Self::Cpp),
|
||||
"javascript" | "js" => Some(Self::JavaScript),
|
||||
"zig" => Some(Self::Zig),
|
||||
"java" => Some(Self::Java),
|
||||
"python" | "py" => Some(Self::Python),
|
||||
"ruby" | "rb" => Some(Self::Ruby),
|
||||
"bash" | "sh" => Some(Self::Bash),
|
||||
"html" => Some(Self::Html),
|
||||
"css" | "scss" => Some(Self::Css),
|
||||
"swift" => Some(Self::Swift),
|
||||
"scala" => Some(Self::Scala),
|
||||
"sql" => Some(Self::Sql),
|
||||
"csharp" | "cs" => Some(Self::CSharp),
|
||||
"graphql" => Some(Self::GraphQL),
|
||||
"proto" | "protobuf" => Some(Self::Proto),
|
||||
"make" | "makefile" => Some(Self::Make),
|
||||
"c" => Some(Self::C),
|
||||
"cmake" => Some(Self::CMake),
|
||||
"typescript" | "ts" => Some(Self::TypeScript),
|
||||
"tsx" => Some(Self::Tsx),
|
||||
"cpp" | "c++" => Some(Self::Cpp),
|
||||
"csharp" | "cs" => Some(Self::CSharp),
|
||||
"css" | "scss" => Some(Self::Css),
|
||||
"diff" => Some(Self::Diff),
|
||||
"ejs" => Some(Self::Ejs),
|
||||
"elixir" | "ex" => Some(Self::Elixir),
|
||||
"erb" => Some(Self::Erb),
|
||||
"ejs" => Some(Self::Ejs),
|
||||
"go" => Some(Self::Go),
|
||||
"graphql" => Some(Self::GraphQL),
|
||||
"html" => Some(Self::Html),
|
||||
"java" => Some(Self::Java),
|
||||
"javascript" | "js" => Some(Self::JavaScript),
|
||||
"jsdoc" => Some(Self::JsDoc),
|
||||
"json" | "jsonc" => Some(Self::Json),
|
||||
"make" | "makefile" => Some(Self::Make),
|
||||
"markdown" | "md" | "mdx" => Some(Self::Markdown),
|
||||
"markdown_inline" | "markdown-inline" => Some(Self::MarkdownInline),
|
||||
"proto" | "protobuf" => Some(Self::Proto),
|
||||
"python" | "py" => Some(Self::Python),
|
||||
"ruby" | "rb" => Some(Self::Ruby),
|
||||
"rust" | "rs" => Some(Self::Rust),
|
||||
"scala" => Some(Self::Scala),
|
||||
"sql" => Some(Self::Sql),
|
||||
"swift" => Some(Self::Swift),
|
||||
"toml" => Some(Self::Toml),
|
||||
"tsx" => Some(Self::Tsx),
|
||||
"typescript" | "ts" => Some(Self::TypeScript),
|
||||
"yaml" | "yml" => Some(Self::Yaml),
|
||||
"zig" => Some(Self::Zig),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
|
@ -155,6 +158,18 @@ impl Language {
|
|||
Self::MarkdownInline => vec![],
|
||||
Self::Html => vec!["javascript", "css"],
|
||||
Self::Rust => vec!["rust"],
|
||||
Self::JavaScript | Self::TypeScript => vec![
|
||||
"jsdoc",
|
||||
"json",
|
||||
"css",
|
||||
"html",
|
||||
"sql",
|
||||
"typescript",
|
||||
"javascript",
|
||||
"tsx",
|
||||
"yaml",
|
||||
"graphql",
|
||||
],
|
||||
_ => vec![],
|
||||
}
|
||||
.into_iter()
|
||||
|
|
@ -162,11 +177,6 @@ impl Language {
|
|||
.collect()
|
||||
}
|
||||
|
||||
pub(super) fn query(&self) -> Query {
|
||||
let config = self.config();
|
||||
Query::new(&config.language, &config.highlights).unwrap()
|
||||
}
|
||||
|
||||
/// Return the language info for the language.
|
||||
///
|
||||
/// (language, query, injection, locals)
|
||||
|
|
@ -210,7 +220,7 @@ impl Language {
|
|||
),
|
||||
Self::Go => (
|
||||
tree_sitter_go::LANGUAGE,
|
||||
tree_sitter_go::HIGHLIGHTS_QUERY,
|
||||
include_str!("languages/go/highlights.scm"),
|
||||
"",
|
||||
"",
|
||||
),
|
||||
|
|
@ -228,10 +238,16 @@ impl Language {
|
|||
),
|
||||
Self::JavaScript => (
|
||||
tree_sitter_javascript::LANGUAGE,
|
||||
tree_sitter_javascript::HIGHLIGHT_QUERY,
|
||||
tree_sitter_javascript::INJECTIONS_QUERY,
|
||||
include_str!("languages/javascript/highlights.scm"),
|
||||
include_str!("languages/javascript/injections.scm"),
|
||||
tree_sitter_javascript::LOCALS_QUERY,
|
||||
),
|
||||
Self::JsDoc => (
|
||||
tree_sitter_jsdoc::LANGUAGE,
|
||||
tree_sitter_jsdoc::HIGHLIGHTS_QUERY,
|
||||
"",
|
||||
"",
|
||||
),
|
||||
Self::Zig => (
|
||||
tree_sitter_zig::LANGUAGE,
|
||||
tree_sitter_zig::HIGHLIGHTS_QUERY,
|
||||
|
|
@ -299,8 +315,8 @@ impl Language {
|
|||
Self::CMake => (tree_sitter_cmake::LANGUAGE, "", "", ""),
|
||||
Self::TypeScript => (
|
||||
tree_sitter_typescript::LANGUAGE_TYPESCRIPT,
|
||||
tree_sitter_typescript::HIGHLIGHTS_QUERY,
|
||||
"",
|
||||
include_str!("languages/typescript/highlights.scm"),
|
||||
include_str!("languages/javascript/injections.scm"),
|
||||
tree_sitter_typescript::LOCALS_QUERY,
|
||||
),
|
||||
Self::Tsx => (
|
||||
|
|
@ -338,6 +354,7 @@ impl Language {
|
|||
let language = tree_sitter::Language::new(language);
|
||||
|
||||
LanguageConfig::new(
|
||||
self.name(),
|
||||
language,
|
||||
self.injection_languages(),
|
||||
query,
|
||||
|
|
|
|||
136
crates/ui/src/highlighter/languages/go/highlights.scm
Normal file
136
crates/ui/src/highlighter/languages/go/highlights.scm
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
; Function calls
|
||||
|
||||
(call_expression
|
||||
function: (identifier) @function)
|
||||
|
||||
(call_expression
|
||||
function: (identifier) @function.builtin
|
||||
(#match? @function.builtin "^(append|cap|close|complex|copy|delete|imag|len|make|new|panic|print|println|real|recover)$"))
|
||||
|
||||
(call_expression
|
||||
function: (selector_expression
|
||||
field: (field_identifier) @function.method))
|
||||
|
||||
; Function definitions
|
||||
|
||||
(function_declaration
|
||||
name: (identifier) @function)
|
||||
|
||||
(method_declaration
|
||||
name: (field_identifier) @function.method)
|
||||
(method_elem
|
||||
name: (field_identifier) @function.method)
|
||||
|
||||
; Identifiers
|
||||
(keyed_element
|
||||
.
|
||||
(literal_element
|
||||
(identifier) @variable.member))
|
||||
|
||||
(type_identifier) @type
|
||||
(field_identifier) @variable.member
|
||||
(identifier) @variable
|
||||
(package_identifier) @namespace
|
||||
|
||||
; Operators
|
||||
|
||||
[
|
||||
"--"
|
||||
"-"
|
||||
"-="
|
||||
":="
|
||||
"!"
|
||||
"!="
|
||||
"..."
|
||||
"*"
|
||||
"*"
|
||||
"*="
|
||||
"/"
|
||||
"/="
|
||||
"&"
|
||||
"&&"
|
||||
"&="
|
||||
"%"
|
||||
"%="
|
||||
"^"
|
||||
"^="
|
||||
"+"
|
||||
"++"
|
||||
"+="
|
||||
"<-"
|
||||
"<"
|
||||
"<<"
|
||||
"<<="
|
||||
"<="
|
||||
"="
|
||||
"=="
|
||||
">"
|
||||
">="
|
||||
">>"
|
||||
">>="
|
||||
"|"
|
||||
"|="
|
||||
"||"
|
||||
"~"
|
||||
] @operator
|
||||
|
||||
; Keywords
|
||||
|
||||
[
|
||||
"break"
|
||||
"case"
|
||||
"chan"
|
||||
"const"
|
||||
"continue"
|
||||
"default"
|
||||
"defer"
|
||||
"else"
|
||||
"fallthrough"
|
||||
"for"
|
||||
"func"
|
||||
"go"
|
||||
"goto"
|
||||
"if"
|
||||
"import"
|
||||
"interface"
|
||||
"map"
|
||||
"package"
|
||||
"range"
|
||||
"return"
|
||||
"select"
|
||||
"struct"
|
||||
"switch"
|
||||
"type"
|
||||
"var"
|
||||
] @keyword
|
||||
|
||||
; Literals
|
||||
|
||||
[
|
||||
(interpreted_string_literal)
|
||||
(raw_string_literal)
|
||||
(rune_literal)
|
||||
] @string
|
||||
|
||||
(escape_sequence) @string.escape
|
||||
|
||||
[
|
||||
(int_literal)
|
||||
(float_literal)
|
||||
(imaginary_literal)
|
||||
] @number
|
||||
|
||||
(const_spec
|
||||
name: (identifier) @constant)
|
||||
|
||||
[
|
||||
(true)
|
||||
(false)
|
||||
] @boolean
|
||||
|
||||
[
|
||||
(nil)
|
||||
(iota)
|
||||
] @constant.builtin
|
||||
|
||||
(comment) @comment
|
||||
207
crates/ui/src/highlighter/languages/javascript/highlights.scm
Normal file
207
crates/ui/src/highlighter/languages/javascript/highlights.scm
Normal file
|
|
@ -0,0 +1,207 @@
|
|||
; Variables
|
||||
;----------
|
||||
|
||||
(identifier) @variable
|
||||
|
||||
; Properties
|
||||
;-----------
|
||||
|
||||
(property_identifier) @property
|
||||
(shorthand_property_identifier) @property
|
||||
(shorthand_property_identifier_pattern) @property
|
||||
(private_property_identifier) @property
|
||||
|
||||
; Function and method definitions
|
||||
;--------------------------------
|
||||
|
||||
(function_expression
|
||||
name: (identifier) @function)
|
||||
(function_declaration
|
||||
name: (identifier) @function)
|
||||
(method_definition
|
||||
name: (property_identifier) @function.method)
|
||||
|
||||
(pair
|
||||
key: (property_identifier) @function.method
|
||||
value: [(function_expression) (arrow_function)])
|
||||
|
||||
(assignment_expression
|
||||
left: (member_expression
|
||||
property: (property_identifier) @function.method)
|
||||
right: [(function_expression) (arrow_function)])
|
||||
|
||||
(variable_declarator
|
||||
name: (identifier) @function
|
||||
value: [(function_expression) (arrow_function)])
|
||||
|
||||
(assignment_expression
|
||||
left: (identifier) @function
|
||||
right: [(function_expression) (arrow_function)])
|
||||
|
||||
; Function and method calls
|
||||
;--------------------------
|
||||
|
||||
(call_expression
|
||||
function: (identifier) @function)
|
||||
|
||||
(call_expression
|
||||
function: (member_expression
|
||||
property: (property_identifier) @function.method))
|
||||
|
||||
; Special identifiers
|
||||
;--------------------
|
||||
|
||||
((identifier) @type
|
||||
(#match? @type "^[A-Z]"))
|
||||
|
||||
([
|
||||
(identifier)
|
||||
(shorthand_property_identifier)
|
||||
(shorthand_property_identifier_pattern)
|
||||
] @constant
|
||||
(#match? @constant "^_*[A-Z_][A-Z\\d_]*$"))
|
||||
|
||||
((identifier) @variable.builtin
|
||||
(#match? @variable.builtin "^(arguments|module|console|window|document)$")
|
||||
(#is-not? local))
|
||||
|
||||
((identifier) @function.builtin
|
||||
(#eq? @function.builtin "require")
|
||||
(#is-not? local))
|
||||
|
||||
; Literals
|
||||
;---------
|
||||
|
||||
(this) @variable.builtin
|
||||
(super) @variable.builtin
|
||||
|
||||
[
|
||||
(true)
|
||||
(false)
|
||||
(null)
|
||||
(undefined)
|
||||
] @constant.builtin
|
||||
|
||||
(comment) @comment
|
||||
|
||||
[
|
||||
(string)
|
||||
(template_string)
|
||||
] @string
|
||||
|
||||
(regex) @string.special
|
||||
(number) @number
|
||||
|
||||
; Tokens
|
||||
;-------
|
||||
|
||||
[
|
||||
";"
|
||||
(optional_chain)
|
||||
"."
|
||||
","
|
||||
] @punctuation.delimiter
|
||||
|
||||
[
|
||||
"-"
|
||||
"--"
|
||||
"-="
|
||||
"+"
|
||||
"++"
|
||||
"+="
|
||||
"*"
|
||||
"*="
|
||||
"**"
|
||||
"**="
|
||||
"/"
|
||||
"/="
|
||||
"%"
|
||||
"%="
|
||||
"<"
|
||||
"<="
|
||||
"<<"
|
||||
"<<="
|
||||
"="
|
||||
"=="
|
||||
"==="
|
||||
"!"
|
||||
"!="
|
||||
"!=="
|
||||
"=>"
|
||||
">"
|
||||
">="
|
||||
">>"
|
||||
">>="
|
||||
">>>"
|
||||
">>>="
|
||||
"~"
|
||||
"^"
|
||||
"&"
|
||||
"|"
|
||||
"^="
|
||||
"&="
|
||||
"|="
|
||||
"&&"
|
||||
"||"
|
||||
"??"
|
||||
"&&="
|
||||
"||="
|
||||
"??="
|
||||
] @operator
|
||||
|
||||
[
|
||||
"("
|
||||
")"
|
||||
"["
|
||||
"]"
|
||||
"{"
|
||||
"}"
|
||||
] @punctuation.bracket
|
||||
|
||||
(template_substitution
|
||||
"${" @punctuation.special
|
||||
"}" @punctuation.special) @embedded
|
||||
|
||||
[
|
||||
"as"
|
||||
"async"
|
||||
"await"
|
||||
"break"
|
||||
"case"
|
||||
"catch"
|
||||
"class"
|
||||
"const"
|
||||
"continue"
|
||||
"debugger"
|
||||
"default"
|
||||
"delete"
|
||||
"do"
|
||||
"else"
|
||||
"export"
|
||||
"extends"
|
||||
"finally"
|
||||
"for"
|
||||
"from"
|
||||
"function"
|
||||
"get"
|
||||
"if"
|
||||
"import"
|
||||
"in"
|
||||
"instanceof"
|
||||
"let"
|
||||
"new"
|
||||
"of"
|
||||
"return"
|
||||
"set"
|
||||
"static"
|
||||
"switch"
|
||||
"target"
|
||||
"throw"
|
||||
"try"
|
||||
"typeof"
|
||||
"var"
|
||||
"void"
|
||||
"while"
|
||||
"with"
|
||||
"yield"
|
||||
] @keyword
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
(((comment) @_jsdoc_comment
|
||||
(#match? @_jsdoc_comment "(?s)^/[*][*][^*].*[*]/$")) @injection.content
|
||||
(#set! injection.language "jsdoc"))
|
||||
|
||||
((regex) @injection.content
|
||||
(#set! injection.language "regex"))
|
||||
|
||||
(call_expression
|
||||
function: (identifier) @_name (#eq? @_name "css")
|
||||
arguments: (template_string (string_fragment) @injection.content
|
||||
(#set! injection.language "css"))
|
||||
)
|
||||
|
||||
(call_expression
|
||||
function: (identifier) @_name (#eq? @_name "html")
|
||||
arguments: (template_string) @injection.content
|
||||
(#set! injection.language "html")
|
||||
)
|
||||
|
||||
(call_expression
|
||||
function: (identifier) @_name (#eq? @_name "js")
|
||||
arguments: (template_string (string_fragment) @injection.content
|
||||
(#set! injection.language "javascript"))
|
||||
)
|
||||
|
||||
(call_expression
|
||||
function: (identifier) @_name (#eq? @_name "json")
|
||||
arguments: (template_string (string_fragment) @injection.content
|
||||
(#set! injection.language "json"))
|
||||
)
|
||||
|
||||
(call_expression
|
||||
function: (identifier) @_name (#eq? @_name "sql")
|
||||
arguments: (template_string (string_fragment) @injection.content
|
||||
(#set! injection.language "sql"))
|
||||
)
|
||||
|
||||
(call_expression
|
||||
function: (identifier) @_name (#eq? @_name "ts")
|
||||
arguments: (template_string (string_fragment) @injection.content
|
||||
(#set! injection.language "typescript"))
|
||||
)
|
||||
|
||||
(call_expression
|
||||
function: (identifier) @_name (#match? @_name "^ya?ml$")
|
||||
arguments: (template_string (string_fragment) @injection.content
|
||||
(#set! injection.language "yaml"))
|
||||
)
|
||||
|
||||
(call_expression
|
||||
function: (identifier) @_name (#match? @_name "^g(raph)?ql$")
|
||||
arguments: (template_string (string_fragment) @injection.content
|
||||
(#set! injection.language "graphql"))
|
||||
)
|
||||
243
crates/ui/src/highlighter/languages/typescript/highlights.scm
Normal file
243
crates/ui/src/highlighter/languages/typescript/highlights.scm
Normal file
|
|
@ -0,0 +1,243 @@
|
|||
; Types
|
||||
; Variables
|
||||
;----------
|
||||
|
||||
(identifier) @variable
|
||||
|
||||
; Properties
|
||||
;-----------
|
||||
|
||||
(property_identifier) @property
|
||||
(shorthand_property_identifier) @property
|
||||
(shorthand_property_identifier_pattern) @property
|
||||
(private_property_identifier) @property
|
||||
|
||||
; Function and method definitions
|
||||
;--------------------------------
|
||||
|
||||
(function_expression
|
||||
name: (identifier) @function)
|
||||
(function_declaration
|
||||
name: (identifier) @function)
|
||||
(method_definition
|
||||
name: (property_identifier) @function.method)
|
||||
|
||||
(pair
|
||||
key: (property_identifier) @function.method
|
||||
value: [(function_expression) (arrow_function)])
|
||||
|
||||
(assignment_expression
|
||||
left: (member_expression
|
||||
property: (property_identifier) @function.method)
|
||||
right: [(function_expression) (arrow_function)])
|
||||
|
||||
(variable_declarator
|
||||
name: (identifier) @function
|
||||
value: [(function_expression) (arrow_function)])
|
||||
|
||||
(assignment_expression
|
||||
left: (identifier) @function
|
||||
right: [(function_expression) (arrow_function)])
|
||||
|
||||
; Function and method calls
|
||||
;--------------------------
|
||||
|
||||
(call_expression
|
||||
function: (identifier) @function)
|
||||
|
||||
(call_expression
|
||||
function: (member_expression
|
||||
property: (property_identifier) @function.method))
|
||||
|
||||
; Special identifiers
|
||||
;--------------------
|
||||
|
||||
((identifier) @type
|
||||
(#match? @type "^[A-Z]"))
|
||||
|
||||
([
|
||||
(identifier)
|
||||
(shorthand_property_identifier)
|
||||
(shorthand_property_identifier_pattern)
|
||||
] @constant
|
||||
(#match? @constant "^_*[A-Z_][A-Z\\d_]*$"))
|
||||
|
||||
((identifier) @variable.builtin
|
||||
(#match? @variable.builtin "^(arguments|module|console|window|document)$")
|
||||
(#is-not? local))
|
||||
|
||||
((identifier) @function.builtin
|
||||
(#eq? @function.builtin "require")
|
||||
(#is-not? local))
|
||||
|
||||
; Literals
|
||||
;---------
|
||||
|
||||
(this) @variable.builtin
|
||||
(super) @variable.builtin
|
||||
|
||||
[
|
||||
(true)
|
||||
(false)
|
||||
(null)
|
||||
(undefined)
|
||||
] @constant.builtin
|
||||
|
||||
(comment) @comment
|
||||
|
||||
[
|
||||
(string)
|
||||
(template_string)
|
||||
] @string
|
||||
|
||||
(regex) @string.special
|
||||
(number) @number
|
||||
|
||||
; Tokens
|
||||
;-------
|
||||
|
||||
[
|
||||
";"
|
||||
(optional_chain)
|
||||
"."
|
||||
","
|
||||
] @punctuation.delimiter
|
||||
|
||||
[
|
||||
"-"
|
||||
"--"
|
||||
"-="
|
||||
"+"
|
||||
"++"
|
||||
"+="
|
||||
"*"
|
||||
"*="
|
||||
"**"
|
||||
"**="
|
||||
"/"
|
||||
"/="
|
||||
"%"
|
||||
"%="
|
||||
"<"
|
||||
"<="
|
||||
"<<"
|
||||
"<<="
|
||||
"="
|
||||
"=="
|
||||
"==="
|
||||
"!"
|
||||
"!="
|
||||
"!=="
|
||||
"=>"
|
||||
">"
|
||||
">="
|
||||
">>"
|
||||
">>="
|
||||
">>>"
|
||||
">>>="
|
||||
"~"
|
||||
"^"
|
||||
"&"
|
||||
"|"
|
||||
"^="
|
||||
"&="
|
||||
"|="
|
||||
"&&"
|
||||
"||"
|
||||
"??"
|
||||
"&&="
|
||||
"||="
|
||||
"??="
|
||||
] @operator
|
||||
|
||||
[
|
||||
"("
|
||||
")"
|
||||
"["
|
||||
"]"
|
||||
"{"
|
||||
"}"
|
||||
] @punctuation.bracket
|
||||
|
||||
(template_substitution
|
||||
"${" @punctuation.special
|
||||
"}" @punctuation.special) @embedded
|
||||
|
||||
[
|
||||
"as"
|
||||
"async"
|
||||
"await"
|
||||
"break"
|
||||
"case"
|
||||
"catch"
|
||||
"class"
|
||||
"const"
|
||||
"continue"
|
||||
"debugger"
|
||||
"default"
|
||||
"delete"
|
||||
"do"
|
||||
"else"
|
||||
"export"
|
||||
"extends"
|
||||
"finally"
|
||||
"for"
|
||||
"from"
|
||||
"function"
|
||||
"get"
|
||||
"if"
|
||||
"import"
|
||||
"in"
|
||||
"instanceof"
|
||||
"let"
|
||||
"new"
|
||||
"of"
|
||||
"return"
|
||||
"set"
|
||||
"static"
|
||||
"switch"
|
||||
"target"
|
||||
"throw"
|
||||
"try"
|
||||
"typeof"
|
||||
"var"
|
||||
"void"
|
||||
"while"
|
||||
"with"
|
||||
"yield"
|
||||
] @keyword
|
||||
|
||||
|
||||
(type_identifier) @type
|
||||
(predefined_type) @type.builtin
|
||||
|
||||
((identifier) @type
|
||||
(#match? @type "^[A-Z]"))
|
||||
|
||||
(type_arguments
|
||||
"<" @punctuation.bracket
|
||||
">" @punctuation.bracket)
|
||||
|
||||
; Variables
|
||||
|
||||
(required_parameter (identifier) @variable.parameter)
|
||||
(optional_parameter (identifier) @variable.parameter)
|
||||
|
||||
; Keywords
|
||||
|
||||
[ "abstract"
|
||||
"declare"
|
||||
"enum"
|
||||
"export"
|
||||
"implements"
|
||||
"interface"
|
||||
"keyof"
|
||||
"namespace"
|
||||
"private"
|
||||
"protected"
|
||||
"public"
|
||||
"type"
|
||||
"readonly"
|
||||
"override"
|
||||
"satisfies"
|
||||
] @keyword
|
||||
Loading…
Reference in a new issue