diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..146b840 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,28 @@ +name: CI + +on: + push: + pull_request: + branches: + - main + workflow_dispatch: + +permissions: + contents: read + +jobs: + query_checks: + name: Query checks + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v6 + + - name: Set up ts_query_ls + run: curl -fL https://github.com/ribru17/ts_query_ls/releases/latest/download/ts_query_ls-x86_64-unknown-linux-gnu.tar.gz | tar -xz + + - name: Lint query files + run: ./ts_query_ls lint languages --config '{"language_retrieval_patterns":["languages/([^/]+)/[^/]+\\.scm$"]}' + + - name: Check Zed highlight captures + run: python3 scripts/lint_zed_captures.py diff --git a/extension.toml b/extension.toml index e18bfd9..ea444d6 100644 --- a/extension.toml +++ b/extension.toml @@ -1,6 +1,6 @@ id = "objectscript" name = "InterSystems ObjectScript" -version = "1.3.0" +version = "1.4.0" schema_version = 1 authors = ["Dave McCaldon ","Hannah Kimura "] description = "InterSystems IRIS ObjectScript Extension" @@ -8,17 +8,17 @@ repository = "https://github.com/intersystems/zed-objectscript" [grammars.objectscript_udl] repository = "https://github.com/intersystems/tree-sitter-objectscript" -commit = "bd68f926f0b3451421be3b60387d0dce901aebe7" +commit = "7aa01969d0fea2e75dc69f2be2244b13d8269d6f" path = "udl" [grammars.objectscript_core] repository = "https://github.com/intersystems/tree-sitter-objectscript" -commit = "bd68f926f0b3451421be3b60387d0dce901aebe7" +commit = "7aa01969d0fea2e75dc69f2be2244b13d8269d6f" path = "core" [grammars.objectscript] repository = "https://github.com/intersystems/tree-sitter-objectscript" -commit = "bd68f926f0b3451421be3b60387d0dce901aebe7" +commit = "7aa01969d0fea2e75dc69f2be2244b13d8269d6f" path = "objectscript" [grammars.xml] diff --git a/languages/objectscript/highlights.scm b/languages/objectscript/highlights.scm index 175f9b4..f854900 100644 --- a/languages/objectscript/highlights.scm +++ b/languages/objectscript/highlights.scm @@ -47,8 +47,6 @@ "#" "|" "||" - "/" - "/" "$$" ] @punctuation @@ -165,4 +163,4 @@ keyword: (_) @keyword (property_type) @type.builtin (index_property_type) @type.builtin -(identifier) @variable \ No newline at end of file +(identifier) @variable diff --git a/languages/objectscript_core/highlights.scm b/languages/objectscript_core/highlights.scm index 3b35c96..5d33712 100644 --- a/languages/objectscript_core/highlights.scm +++ b/languages/objectscript_core/highlights.scm @@ -47,8 +47,6 @@ "#" "|" "||" - "/" - "/" "$$" ] @punctuation @@ -121,4 +119,3 @@ keyword: (_) @keyword "##;" "$" ] @punctuation - diff --git a/languages/objectscript_udl/highlights.scm b/languages/objectscript_udl/highlights.scm index 3aca162..72de47a 100644 --- a/languages/objectscript_udl/highlights.scm +++ b/languages/objectscript_udl/highlights.scm @@ -22,7 +22,7 @@ (objectscript_identifier) @variable (method_arg) @variable.parameter -; I didn't include ( or ) in this, because they are often grouped +; I didn't include '(' or ')' in this, because they are often grouped ; as part of a sequence that gets turned into a single token, so they ; don't get matched, and one ends up getting colored differently than the other. [ @@ -47,9 +47,13 @@ "#" "|" "||" - "/" - "/" "$$" + "--" + ";" + "//" + "#;" + "##;" + "$" ] @punctuation [ @@ -68,13 +72,13 @@ "=" ">" ">=" - "@" + "@" "*" "**" "'" "'!" "'?" - "!" + "!" "?" ] @operator @@ -83,8 +87,6 @@ (json_number_literal) @number (json_null_literal) @string (bracket) @punctuation.bracket - -;; inherits: objectscript_expr (locktype) @variable (macro_arg) @variable @@ -113,16 +115,6 @@ keyword: (_) @keyword (tag) @tag -[ - "--" - ";" - "//" - "#;" - "##;" - "$" -] @punctuation - -;; inherits: objectscript_core ; ------------------ UDL ------------------- [ diff --git a/languages/objectscript_udl/injections.scm b/languages/objectscript_udl/injections.scm index e14e5a0..ff3f9e7 100644 --- a/languages/objectscript_udl/injections.scm +++ b/languages/objectscript_udl/injections.scm @@ -34,7 +34,7 @@ -; UDL injections +; UDL grammar injections ;; Keywords, one of type language = "python", none of type codemode ; External method body injection based on [ Language = ... ] (method_definition diff --git a/languages/xml/highlights.scm b/languages/xml/highlights.scm index c14be81..711c89b 100644 --- a/languages/xml/highlights.scm +++ b/languages/xml/highlights.scm @@ -105,7 +105,7 @@ (PubidLiteral) @string.special -(SystemLiteral (URI) @markup.link) +(SystemLiteral (URI) @link_uri) ;; Processing instructions @@ -154,15 +154,13 @@ ;; Text -(CharData) @markup +(CharData) @text (CDSect - (CDStart) @markup.heading - (CData) @markup.raw - "]]>" @markup.heading) + (CDStart) @punctuation.markup + (CData) @text.literal + "]]>" @punctuation.markup) ;; Misc (Comment) @comment - -(ERROR) @error \ No newline at end of file diff --git a/scripts/lint_zed_captures.py b/scripts/lint_zed_captures.py new file mode 100644 index 0000000..1ad9c66 --- /dev/null +++ b/scripts/lint_zed_captures.py @@ -0,0 +1,107 @@ +#!/usr/bin/env python3 + +"""Validate highlight captures against Zed's syntax capture names.""" + +from __future__ import annotations + +import re +import sys +from pathlib import Path + + +CAPTURE_PATTERN = re.compile(r"@([A-Za-z0-9_.-]+)") +ALLOWED_ZED_CAPTURES = { + "attribute", + "boolean", + "comment", + "comment.doc", + "constant", + "constructor", + "embedded", + "emphasis", + "emphasis.strong", + "enum", + "function", + "function.builtin", + "hint", + "keyword", + "label", + "link_text", + "link_uri", + "namespace", + "number", + "operator", + "predictive", + "preproc", + "primary", + "property", + "punctuation", + "punctuation.bracket", + "punctuation.delimiter", + "punctuation.list_marker", + "punctuation.markup", + "punctuation.special", + "selector", + "selector.pseudo", + "string", + "string.escape", + "string.regex", + "string.special", + "string.special.symbol", + "tag", + "text", + "text.literal", + "title", + "type", + "variable", + "variable.special", + "variant", +} + + +def is_allowed(capture: str) -> bool: + if capture.startswith("_"): + return True + + parts = capture.split(".") + for i in range(len(parts), 0, -1): + prefix = ".".join(parts[:i]) + if prefix in ALLOWED_ZED_CAPTURES: + return True + return False + + +def collect_highlight_files(root: Path) -> list[Path]: + return sorted(root.glob("languages/*/highlights.scm")) + + +def main() -> int: + root = Path.cwd() + highlight_files = collect_highlight_files(root) + if not highlight_files: + print("No highlights.scm files found under languages/*/") + return 1 + + failures: list[tuple[Path, int, str]] = [] + for highlight_file in highlight_files: + text = highlight_file.read_text(encoding="utf-8") + for line_number, line in enumerate(text.splitlines(), start=1): + for match in CAPTURE_PATTERN.finditer(line): + capture = match.group(1) + if not is_allowed(capture): + failures.append((highlight_file, line_number, capture)) + + if failures: + print("Unsupported highlight captures detected:") + for path, line_number, capture in failures: + relative_path = path.relative_to(root) + print(f"- {relative_path}:{line_number} uses @{capture}") + print("\nUse Zed capture names (or subscopes of them) for highlights.") + return 1 + + print("All highlight captures are compatible with Zed capture names.") + return 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/themes/tokyonight-day.json b/themes/tokyonight-day.json index fc1b702..4bd6830 100644 --- a/themes/tokyonight-day.json +++ b/themes/tokyonight-day.json @@ -230,6 +230,9 @@ "variable": { "color": "#3760bf" }, + "variable.special": { + "color": "#c64343" + }, "variable.builtin": { "color": "#f52a65" }, diff --git a/themes/tokyonight-light.json b/themes/tokyonight-light.json index 1e100ba..fddeb38 100644 --- a/themes/tokyonight-light.json +++ b/themes/tokyonight-light.json @@ -61,6 +61,12 @@ "variable": { "color": "#3760bf" }, + "variable.special": { + "color": "#bf3a4c" + }, + "variable.parameter": { + "color": "#8f5e15" + }, "constant": { "color": "#8f3f71" },