TOML highlighting !52
8 files changed, +64 −2
Layout: unified · split
Package.resolved +10 −1
| @@ -1,5 +1,5 @@ | |||
| 1 | { | 1 | { |
| 2 | "originHash" : "03b8c85ddc87e40eb8da5020efd09eeaa81aa04770e7ba4cb19fce3b7e5bcf77", | 2 | "originHash" : "99f611db4aa216eecc3254d58a7ad6ee060533c7f899b1a0d0f72c21a75f90a9", |
| 3 | "pins" : [ | 3 | "pins" : [ |
| 4 | { | 4 | { |
| 5 | "identity" : "grdb.swift", | 5 | "identity" : "grdb.swift", |
| @@ -154,6 +154,15 @@ | |||
| 154 | "version" : "0.24.7-1" | 154 | "version" : "0.24.7-1" |
| 155 | } | 155 | } |
| 156 | }, | 156 | }, |
| 157 | { | ||
| 158 | "identity" : "tree-sitter-toml", | ||
| 159 | "kind" : "remoteSourceControl", | ||
| 160 | "location" : "https://github.com/tree-sitter-grammars/tree-sitter-toml", | ||
| 161 | "state" : { | ||
| 162 | "revision" : "64b56832c2cffe41758f28e05c756a3a98d16f41", | ||
| 163 | "version" : "0.7.0" | ||
| 164 | } | ||
| 165 | }, | ||
| 157 | { | 166 | { |
| 158 | "identity" : "tree-sitter-yaml", | 167 | "identity" : "tree-sitter-yaml", |
| 159 | "kind" : "remoteSourceControl", | 168 | "kind" : "remoteSourceControl", |
Package.swift +2
| @@ -33,6 +33,7 @@ let package = Package( | |||
| 33 | .package(url: "https://github.com/tree-sitter/tree-sitter-ruby", exact: "0.23.1"), | 33 | .package(url: "https://github.com/tree-sitter/tree-sitter-ruby", exact: "0.23.1"), |
| 34 | .package(url: "https://github.com/tree-sitter/tree-sitter-rust", exact: "0.24.2"), | 34 | .package(url: "https://github.com/tree-sitter/tree-sitter-rust", exact: "0.24.2"), |
| 35 | .package(url: "https://github.com/6cdh/tree-sitter-scheme", exact: "0.24.7-1"), | 35 | .package(url: "https://github.com/6cdh/tree-sitter-scheme", exact: "0.24.7-1"), |
| 36 | .package(url: "https://github.com/tree-sitter-grammars/tree-sitter-toml", exact: "0.7.0"), | ||
| 36 | .package(url: "https://github.com/tree-sitter-grammars/tree-sitter-yaml", exact: "0.7.2") | 37 | .package(url: "https://github.com/tree-sitter-grammars/tree-sitter-yaml", exact: "0.7.2") |
| 37 | ], | 38 | ], |
| 38 | targets: [ | 39 | targets: [ |
| @@ -67,6 +68,7 @@ let package = Package( | |||
| 67 | .product(name: "TreeSitterRuby", package: "tree-sitter-ruby"), | 68 | .product(name: "TreeSitterRuby", package: "tree-sitter-ruby"), |
| 68 | .product(name: "TreeSitterRust", package: "tree-sitter-rust"), | 69 | .product(name: "TreeSitterRust", package: "tree-sitter-rust"), |
| 69 | .product(name: "TreeSitterScheme", package: "tree-sitter-scheme"), | 70 | .product(name: "TreeSitterScheme", package: "tree-sitter-scheme"), |
| 71 | .product(name: "TreeSitterTOML", package: "tree-sitter-toml"), | ||
| 70 | .product(name: "TreeSitterYAML", package: "tree-sitter-yaml") | 72 | .product(name: "TreeSitterYAML", package: "tree-sitter-yaml") |
| 71 | ] | 73 | ] |
| 72 | ), | 74 | ), |
Sources/OrgHighlight/Queries.swift +17
| @@ -2295,6 +2295,23 @@ enum HighlightQueries { | |||
| 2295 | (block_comment) | 2295 | (block_comment) |
| 2296 | (directive)] @comment | 2296 | (directive)] @comment |
| 2297 | """####, | 2297 | """####, |
| 2298 | "toml": ####""" | ||
| 2299 | ; TOML highlights for Orgstar: table names as types, keys as properties. The grammar's own | ||
| 2300 | ; query captures whole pairs as properties, which colors values too. | ||
| 2301 | (comment) @comment | ||
| 2302 | (string) @string | ||
| 2303 | (quoted_key) @string | ||
| 2304 | [(integer) (float)] @number | ||
| 2305 | (boolean) @constant | ||
| 2306 | [(offset_date_time) (local_date_time) (local_date) (local_time)] @string.special | ||
| 2307 | (table (bare_key) @type) | ||
| 2308 | (table (dotted_key (bare_key) @type)) | ||
| 2309 | (table_array_element (bare_key) @type) | ||
| 2310 | (table_array_element (dotted_key (bare_key) @type)) | ||
| 2311 | (pair (bare_key) @property) | ||
| 2312 | (pair (dotted_key (bare_key) @property)) | ||
| 2313 | "=" @operator | ||
| 2314 | """####, | ||
| 2298 | "yaml": ####""" | 2315 | "yaml": ####""" |
| 2299 | (boolean_scalar) @boolean | 2316 | (boolean_scalar) @boolean |
| 2300 | 2317 | ||
Sources/OrgHighlight/TreeSitterHighlighter.swift +3
| @@ -17,6 +17,7 @@ import TreeSitterR | |||
| 17 | import TreeSitterRuby | 17 | import TreeSitterRuby |
| 18 | import TreeSitterRust | 18 | import TreeSitterRust |
| 19 | import TreeSitterScheme | 19 | import TreeSitterScheme |
| 20 | import TreeSitterTOML | ||
| 20 | import TreeSitterYAML | 21 | import TreeSitterYAML |
| 21 | 22 | ||
| 22 | /// Src block highlighting with tree-sitter grammars and their own highlight queries. | 23 | /// Src block highlighting with tree-sitter grammars and their own highlight queries. |
| @@ -51,6 +52,7 @@ public final class TreeSitterHighlighter: CodeHighlighter, @unchecked Sendable { | |||
| 51 | case "ruby": "ruby" | 52 | case "ruby": "ruby" |
| 52 | case "json": "json" | 53 | case "json": "json" |
| 53 | case "yaml", "yml": "yaml" | 54 | case "yaml", "yml": "yaml" |
| 55 | case "toml", "conf-toml": "toml" | ||
| 54 | case "lua": "lua" | 56 | case "lua": "lua" |
| 55 | default: nil | 57 | default: nil |
| 56 | } | 58 | } |
| @@ -74,6 +76,7 @@ public final class TreeSitterHighlighter: CodeHighlighter, @unchecked Sendable { | |||
| 74 | case "ruby": tree_sitter_ruby() | 76 | case "ruby": tree_sitter_ruby() |
| 75 | case "rust": tree_sitter_rust() | 77 | case "rust": tree_sitter_rust() |
| 76 | case "scheme": tree_sitter_scheme() | 78 | case "scheme": tree_sitter_scheme() |
| 79 | case "toml": tree_sitter_toml() | ||
| 77 | case "yaml": tree_sitter_yaml() | 80 | case "yaml": tree_sitter_yaml() |
| 78 | default: nil | 81 | default: nil |
| 79 | } | 82 | } |
Sources/Orgstar/FileTypes.swift +1
| @@ -44,6 +44,7 @@ enum FileTypes { | |||
| 44 | case "rb": return "ruby" | 44 | case "rb": return "ruby" |
| 45 | case "json": return "json" | 45 | case "json": return "json" |
| 46 | case "yaml", "yml": return "yaml" | 46 | case "yaml", "yml": return "yaml" |
| 47 | case "toml": return "toml" | ||
| 47 | case "lua": return "lua" | 48 | case "lua": return "lua" |
| 48 | default: | 49 | default: |
| 49 | return ["zshrc", ".zshrc", "bashrc", ".bashrc", ".profile"].contains(url.lastPathComponent) ? "sh" : nil | 50 | return ["zshrc", ".zshrc", "bashrc", ".bashrc", ".profile"].contains(url.lastPathComponent) ? "sh" : nil |
Tests/OrgHighlightTests/HighlightTests.swift +11 −1
| @@ -17,7 +17,7 @@ struct HighlightTests { | |||
| 17 | } | 17 | } |
| 18 | 18 | ||
| 19 | @Test func everyGrammarLoads() { | 19 | @Test func everyGrammarLoads() { |
| 20 | for language in ["sh", "python", "emacs-lisp", "c", "cpp", "R", "js", "java", "scheme", "clojure", "haskell", "rust", "go", "ruby", "json", "yaml", "lua"] { | 20 | for language in ["sh", "python", "emacs-lisp", "c", "cpp", "R", "js", "java", "scheme", "clojure", "haskell", "rust", "go", "ruby", "json", "yaml", "lua", "toml"] { |
| 21 | #expect(!highlighter.highlights(language: language, code: "x").isEmpty || true, "\(language)") | 21 | #expect(!highlighter.highlights(language: language, code: "x").isEmpty || true, "\(language)") |
| 22 | let code = language == "json" ? "{\"a\": 1}" : "# comment\n" | 22 | let code = language == "json" ? "{\"a\": 1}" : "# comment\n" |
| 23 | _ = highlighter.highlights(language: language, code: code) | 23 | _ = highlighter.highlights(language: language, code: code) |
| @@ -39,6 +39,16 @@ struct HighlightTests { | |||
| 39 | #expect(lisp[";; c"] == .comment) | 39 | #expect(lisp[";; c"] == .comment) |
| 40 | } | 40 | } |
| 41 | 41 | ||
| 42 | @Test func toml() { | ||
| 43 | let found = categories("toml", "# settings\n[theme]\nfont-size = 13\nshow = true\nname = \"x\"\n") | ||
| 44 | #expect(found["# settings"] == .comment) | ||
| 45 | #expect(found["theme"] == .type) | ||
| 46 | #expect(found["font-size"] == .property) | ||
| 47 | #expect(found["13"] == .number) | ||
| 48 | #expect(found["true"] == .constant) | ||
| 49 | #expect(found["\"x\""] == .string) | ||
| 50 | } | ||
| 51 | |||
| 42 | @Test func unknownLanguagesGetNothing() { | 52 | @Test func unknownLanguagesGetNothing() { |
| 43 | #expect(highlighter.highlights(language: "cobol", code: "MOVE A TO B").isEmpty) | 53 | #expect(highlighter.highlights(language: "cobol", code: "MOVE A TO B").isEmpty) |
| 44 | } | 54 | } |
scripts/queries/toml.scm added +15
| @@ -0,0 +1,15 @@ | |||
| 1 | ; TOML highlights for Orgstar: table names as types, keys as properties. The grammar's own | ||
| 2 | ; query captures whole pairs as properties, which colors values too. | ||
| 3 | (comment) @comment | ||
| 4 | (string) @string | ||
| 5 | (quoted_key) @string | ||
| 6 | [(integer) (float)] @number | ||
| 7 | (boolean) @constant | ||
| 8 | [(offset_date_time) (local_date_time) (local_date) (local_time)] @string.special | ||
| 9 | (table (bare_key) @type) | ||
| 10 | (table (dotted_key (bare_key) @type)) | ||
| 11 | (table_array_element (bare_key) @type) | ||
| 12 | (table_array_element (dotted_key (bare_key) @type)) | ||
| 13 | (pair (bare_key) @property) | ||
| 14 | (pair (dotted_key (bare_key) @property)) | ||
| 15 | "=" @operator | ||
scripts/update-highlight-queries.sh +5
| @@ -25,6 +25,8 @@ QUERIES = { | |||
| 25 | "ruby": [("tree-sitter/tree-sitter-ruby", "v0.23.1", "queries/highlights.scm")], | 25 | "ruby": [("tree-sitter/tree-sitter-ruby", "v0.23.1", "queries/highlights.scm")], |
| 26 | "rust": [("tree-sitter/tree-sitter-rust", "v0.24.2", "queries/highlights.scm")], | 26 | "rust": [("tree-sitter/tree-sitter-rust", "v0.24.2", "queries/highlights.scm")], |
| 27 | "scheme": [("6cdh/tree-sitter-scheme", "v0.24.7-1", "queries/highlights.scm")], | 27 | "scheme": [("6cdh/tree-sitter-scheme", "v0.24.7-1", "queries/highlights.scm")], |
| 28 | # Orgstar's own query, in scripts/queries. | ||
| 29 | "toml": [("local", None, "scripts/queries/toml.scm")], | ||
| 28 | "yaml": [("tree-sitter-grammars/tree-sitter-yaml", "v0.7.2", "queries/highlights.scm")], | 30 | "yaml": [("tree-sitter-grammars/tree-sitter-yaml", "v0.7.2", "queries/highlights.scm")], |
| 29 | } | 31 | } |
| 30 | 32 | ||
| @@ -34,6 +36,9 @@ out = ["// Generated by scripts/update-highlight-queries.sh from the grammars' o | |||
| 34 | for language, files in sorted(QUERIES.items()): | 36 | for language, files in sorted(QUERIES.items()): |
| 35 | text = "" | 37 | text = "" |
| 36 | for repo, ref, path in files: | 38 | for repo, ref, path in files: |
| 39 | if repo == "local": | ||
| 40 | text += open(path, encoding="utf-8").read() + "\n" | ||
| 41 | continue | ||
| 37 | url = f"https://raw.githubusercontent.com/{repo}/{ref}/{path}" | 42 | url = f"https://raw.githubusercontent.com/{repo}/{ref}/{path}" |
| 38 | text += urllib.request.urlopen(url).read().decode("utf-8") + "\n" | 43 | text += urllib.request.urlopen(url).read().decode("utf-8") + "\n" |
| 39 | assert '"""####' not in text | 44 | assert '"""####' not in text |