feat: add Zig syntax highlighting

This commit is contained in:
Valdemar Lorenzen
2026-10-15 11:53:49 +02:00
parent 08db1801eb
commit 2fd240aca8
6 changed files with 69 additions and 5 deletions
+37
View File
@@ -1658,6 +1658,43 @@ mod tests {
);
}
#[test]
fn zig_highlights_literals_builtins_and_predicate_matched_identifiers() {
let source = r#"const std = @import("std");
const MAX_COUNT: u32 = 42;
pub fn main() void {
const local = @as(u32, 7);
const value = Point;
const text =
\\first é
\\second
;
// note
}"#;
let cache = self::cache(source, "main.zig");
for (row, token, kind) in [
(0, "const", SyntaxKind::Keyword),
(0, "@import", SyntaxKind::Keyword),
(0, "\"std\"", SyntaxKind::String),
(1, "MAX_COUNT", SyntaxKind::Keyword),
(1, "u32", SyntaxKind::Type),
(1, "42", SyntaxKind::Number),
(2, "pub", SyntaxKind::Keyword),
(2, "fn", SyntaxKind::Keyword),
(2, "main", SyntaxKind::Function),
(2, "void", SyntaxKind::Type),
(3, "@as", SyntaxKind::Function),
(4, "Point", SyntaxKind::Type),
(6, "first é", SyntaxKind::String),
(7, "second", SyntaxKind::String),
(9, "note", SyntaxKind::Comment),
] {
assert_token(&cache, source, row, token, kind);
}
let local = source.lines().nth(3).unwrap().find("local").unwrap();
assert_eq!(kind_at(&cache, 3, local), None);
}
#[test]
fn filenames_shebang_save_as_and_tsx_use_actual_grammar_identity() {
let source = lines("\u{feff}#!/usr/bin/env python3\nreturn 42");
+18 -3
View File
@@ -74,6 +74,13 @@ static MD_HIGHLIGHTS: LazyLock<String> = LazyLock::new(|| {
.join("\n")
});
// Upstream's Lua patterns are regex-compatible; spell-check metadata is not a color.
static ZIG_HIGHLIGHTS: LazyLock<String> = LazyLock::new(|| {
tree_sitter_zig::HIGHLIGHTS_QUERY
.replace("#lua-match?", "#match?")
.replace(" @spell", "")
});
// The MIT-licensed upstream C++ crate bundles, but does not export, injections.scm.
// This minimal AST query uses its raw-string delimiter/content nodes:
// https://github.com/tree-sitter/tree-sitter-cpp/blob/v0.23.4/queries/injections.scm
@@ -111,7 +118,7 @@ fn spec(
}
}
static LANGUAGES: LazyLock<[LanguageSpec; 18]> = LazyLock::new(|| {
static LANGUAGES: LazyLock<[LanguageSpec; 19]> = LazyLock::new(|| {
[
spec(
super::RUST_ID,
@@ -257,6 +264,14 @@ static LANGUAGES: LazyLock<[LanguageSpec; 18]> = LazyLock::new(|| {
tree_sitter_md::INJECTION_QUERY_INLINE,
"",
),
spec(
"zig",
"Zig",
tree_sitter_zig::LANGUAGE.into(),
ZIG_HIGHLIGHTS.as_str(),
tree_sitter_zig::INJECTIONS_QUERY,
"",
),
]
});
@@ -349,6 +364,7 @@ fn detect_path(path: &Path) -> Option<&'static LanguageSpec> {
"cc" | "cpp" | "cxx" | "c++" | "hh" | "hpp" | "hxx" | "h++" | "ipp" | "inl"
| "tpp" => "C++",
"go" => "Go",
"zig" => "Zig",
_ => return None,
}
}
@@ -396,8 +412,6 @@ mod tests {
#[test]
fn selected_files_and_auxiliary_grammars_are_registered() {
assert_eq!(all().count(), 18);
assert!(all().all(|spec| !spec.highlights.is_empty()));
for (filename, language) in [
("main.rs", "Rust"),
("Gemfile", "Ruby"),
@@ -417,6 +431,7 @@ mod tests {
("main.cpp", "C++"),
("main.C", "C++"),
("main.go", "Go"),
("main.zig", "Zig"),
] {
assert_eq!(
detect(Some(Path::new(filename)), None).map(|spec| spec.name),