tree-sitter-validatetest 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +83 -0
- package/binding.gyp +27 -0
- package/bindings/node/binding.cc +20 -0
- package/bindings/node/index.js +11 -0
- package/grammar.js +259 -0
- package/package.json +65 -0
- package/queries/highlights.scm +85 -0
- package/queries/injections.scm +62 -0
- package/src/grammar.json +893 -0
- package/src/node-types.json +588 -0
- package/src/parser.c +7214 -0
- package/src/tree_sitter/alloc.h +54 -0
- package/src/tree_sitter/array.h +291 -0
- package/src/tree_sitter/parser.h +266 -0
package/README.md
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# tree-sitter-validatetest
|
|
2
|
+
|
|
3
|
+
GStreamer ValidateTest grammar for [tree-sitter](https://tree-sitter.github.io/).
|
|
4
|
+
|
|
5
|
+
This grammar parses [`.validatetest` files](https://gstreamer.freedesktop.org/documentation/gst-devtools/gst-validate-test-file.html) used for testing GStreamer pipelines. These files are executed by `gst-validate-1.0`, `ges-launch-1.0`, or any GStreamer tool that supports the validate test format.
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- Full support for GstStructure serialization format
|
|
10
|
+
- Comments (`# ...`)
|
|
11
|
+
- Variables (`$(variable_name)`)
|
|
12
|
+
- Expressions (`expr(...)`)
|
|
13
|
+
- Type casts (`(type)value`)
|
|
14
|
+
- Property paths (`element.pad::property`)
|
|
15
|
+
- Arrays with nested structures (`[...]`)
|
|
16
|
+
- GstValueArray (`<...>`)
|
|
17
|
+
- Value blocks (`{...}`)
|
|
18
|
+
|
|
19
|
+
## Installation
|
|
20
|
+
|
|
21
|
+
### Neovim (with nvim-treesitter)
|
|
22
|
+
|
|
23
|
+
Add the following to your neovim configuration (e.g., `lua/plugins/validatetest.lua` for LazyVim):
|
|
24
|
+
|
|
25
|
+
```lua
|
|
26
|
+
-- Register the filetype
|
|
27
|
+
vim.filetype.add({
|
|
28
|
+
extension = {
|
|
29
|
+
validatetest = "validatetest",
|
|
30
|
+
},
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
-- Register custom parser with nvim-treesitter
|
|
34
|
+
vim.api.nvim_create_autocmd("User", {
|
|
35
|
+
pattern = "TSUpdate",
|
|
36
|
+
callback = function()
|
|
37
|
+
require("nvim-treesitter.parsers").validatetest = {
|
|
38
|
+
install_info = {
|
|
39
|
+
url = "https://github.com/thiblahute/tree-sitter-validatetest",
|
|
40
|
+
files = { "src/parser.c" },
|
|
41
|
+
branch = "main",
|
|
42
|
+
},
|
|
43
|
+
}
|
|
44
|
+
end,
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
return {}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Then restart neovim and run `:TSInstall validatetest`.
|
|
51
|
+
|
|
52
|
+
### Rust
|
|
53
|
+
|
|
54
|
+
```toml
|
|
55
|
+
[dependencies]
|
|
56
|
+
tree-sitter-validatetest = "0.1"
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Node.js
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
npm install tree-sitter-validatetest
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Development
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
# Install dependencies
|
|
69
|
+
npm install
|
|
70
|
+
|
|
71
|
+
# Generate the parser
|
|
72
|
+
npx tree-sitter generate
|
|
73
|
+
|
|
74
|
+
# Run tests
|
|
75
|
+
npx tree-sitter test
|
|
76
|
+
|
|
77
|
+
# Parse a file
|
|
78
|
+
npx tree-sitter parse path/to/file.validatetest
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## License
|
|
82
|
+
|
|
83
|
+
MIT
|
package/binding.gyp
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"targets": [
|
|
3
|
+
{
|
|
4
|
+
"target_name": "tree_sitter_validatetest_binding",
|
|
5
|
+
"dependencies": [
|
|
6
|
+
"<!(node -p \"require('node-addon-api').targets\"):node_addon_api_except",
|
|
7
|
+
],
|
|
8
|
+
"include_dirs": [
|
|
9
|
+
"src",
|
|
10
|
+
],
|
|
11
|
+
"sources": [
|
|
12
|
+
"bindings/node/binding.cc",
|
|
13
|
+
"src/parser.c",
|
|
14
|
+
],
|
|
15
|
+
"conditions": [
|
|
16
|
+
["OS!='win'", {
|
|
17
|
+
"cflags_c": ["-std=c11"],
|
|
18
|
+
"cflags_cc": ["-std=c++17"]
|
|
19
|
+
}]
|
|
20
|
+
],
|
|
21
|
+
"xcode_settings": {
|
|
22
|
+
"CLANG_CXX_LANGUAGE_STANDARD": "c++17",
|
|
23
|
+
"GCC_C_LANGUAGE_STANDARD": "c11"
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
]
|
|
27
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
#include <napi.h>
|
|
2
|
+
|
|
3
|
+
typedef struct TSLanguage TSLanguage;
|
|
4
|
+
|
|
5
|
+
extern "C" TSLanguage *tree_sitter_validatetest();
|
|
6
|
+
|
|
7
|
+
// "tree-sitter", "currentABIVersion" heuristic
|
|
8
|
+
static Napi::Number CurrentABIVersion(const Napi::CallbackInfo& info) {
|
|
9
|
+
return Napi::Number::New(info.Env(), NAPI_VERSION);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
Napi::Object Init(Napi::Env env, Napi::Object exports) {
|
|
13
|
+
exports["name"] = Napi::String::New(env, "validatetest");
|
|
14
|
+
auto language = Napi::External<TSLanguage>::New(env, tree_sitter_validatetest());
|
|
15
|
+
exports["language"] = language;
|
|
16
|
+
exports["currentABIVersion"] = Napi::Function::New(env, CurrentABIVersion);
|
|
17
|
+
return exports;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
NODE_API_MODULE(tree_sitter_validatetest_binding, Init)
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
const root = require("path").join(__dirname, "..", "..");
|
|
2
|
+
|
|
3
|
+
module.exports =
|
|
4
|
+
typeof process.versions.bun === "string"
|
|
5
|
+
// Support `bun build --compile` by being statically analyzable enough to find the .node file at build-time
|
|
6
|
+
? require(`../../prebuilds/${process.platform}-${process.arch}/tree-sitter-validatetest.node`)
|
|
7
|
+
: require("node-gyp-build")(root);
|
|
8
|
+
|
|
9
|
+
try {
|
|
10
|
+
module.exports.nodeTypeInfo = require("../../src/node-types.json");
|
|
11
|
+
} catch (_) {}
|
package/grammar.js
ADDED
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file GStreamer ValidateTest grammar for tree-sitter
|
|
3
|
+
* @author Thibault Saunier
|
|
4
|
+
* @license MIT
|
|
5
|
+
*
|
|
6
|
+
* Grammar for .validatetest files used by gst-validate-1.0, ges-launch-1.0, etc.
|
|
7
|
+
* Based on GstStructure serialization format with additional constructs
|
|
8
|
+
* for variables, expressions, and comments.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/// <reference types="tree-sitter-cli/dsl" />
|
|
12
|
+
// @ts-check
|
|
13
|
+
|
|
14
|
+
module.exports = grammar({
|
|
15
|
+
name: "validatetest",
|
|
16
|
+
|
|
17
|
+
extras: ($) => [/\s/, $.line_continuation, $.comment],
|
|
18
|
+
|
|
19
|
+
conflicts: ($) => [
|
|
20
|
+
[$.array_structure],
|
|
21
|
+
[$.structure],
|
|
22
|
+
[$.structure, $.field_value],
|
|
23
|
+
[$.structure_name, $.array_value],
|
|
24
|
+
[$.structure_name, $.value],
|
|
25
|
+
[$.field_list],
|
|
26
|
+
],
|
|
27
|
+
|
|
28
|
+
rules: {
|
|
29
|
+
// A file is a sequence of structures (comments handled by extras)
|
|
30
|
+
source_file: ($) => repeat($.structure),
|
|
31
|
+
|
|
32
|
+
// Comments start with # and go to end of line
|
|
33
|
+
comment: ($) => seq("#", /.*/),
|
|
34
|
+
|
|
35
|
+
// Line continuation with backslash
|
|
36
|
+
line_continuation: ($) => seq("\\", /\r?\n/),
|
|
37
|
+
|
|
38
|
+
// A structure is: name, field=value, field=value, ...
|
|
39
|
+
// Can end with semicolon, newline, or EOF
|
|
40
|
+
structure: ($) =>
|
|
41
|
+
seq($.structure_name, optional(seq(",", $.field_list)), optional(";")),
|
|
42
|
+
|
|
43
|
+
// Structure name (action type) - can be identifier or variable
|
|
44
|
+
structure_name: ($) => choice($.identifier, $.variable),
|
|
45
|
+
|
|
46
|
+
// Comma-separated list of fields (allows trailing comma)
|
|
47
|
+
field_list: ($) => seq(sep1($.field, ","), optional(",")),
|
|
48
|
+
|
|
49
|
+
// A field is: name = value
|
|
50
|
+
field: ($) =>
|
|
51
|
+
seq(field("name", $.field_name), "=", field("value", $.field_value)),
|
|
52
|
+
|
|
53
|
+
// Field name can be a simple identifier or a property path
|
|
54
|
+
field_name: ($) => choice($.property_path, $.identifier),
|
|
55
|
+
|
|
56
|
+
// Property path: element.pad::property or element::property or element::parent::parent::property
|
|
57
|
+
property_path: ($) =>
|
|
58
|
+
seq(
|
|
59
|
+
$.identifier,
|
|
60
|
+
optional(seq(".", $.identifier)),
|
|
61
|
+
repeat1(seq("::", $.identifier)),
|
|
62
|
+
),
|
|
63
|
+
|
|
64
|
+
// Field value
|
|
65
|
+
field_value: ($) =>
|
|
66
|
+
choice(
|
|
67
|
+
$.typed_value,
|
|
68
|
+
$.value,
|
|
69
|
+
$.array,
|
|
70
|
+
$.angle_bracket_array,
|
|
71
|
+
$.nested_structure_block,
|
|
72
|
+
),
|
|
73
|
+
|
|
74
|
+
// Typed value: (type)value or (type)[array] or (type)<array>
|
|
75
|
+
typed_value: ($) =>
|
|
76
|
+
seq("(", field("type", $.type_name), ")", field("value", choice($.value, $.array, $.angle_bracket_array))),
|
|
77
|
+
|
|
78
|
+
// Type name for casts
|
|
79
|
+
type_name: ($) => /[a-zA-Z_][a-zA-Z0-9_]*/,
|
|
80
|
+
|
|
81
|
+
// A value can be many things
|
|
82
|
+
// Order matters: more specific patterns first, unquoted_string last as fallback
|
|
83
|
+
value: ($) =>
|
|
84
|
+
choice(
|
|
85
|
+
$.string,
|
|
86
|
+
$.hex_number,
|
|
87
|
+
$.fraction,
|
|
88
|
+
$.number,
|
|
89
|
+
$.boolean,
|
|
90
|
+
$.variable,
|
|
91
|
+
$.expression,
|
|
92
|
+
prec(2, $.flags),
|
|
93
|
+
prec(2, $.namespaced_identifier),
|
|
94
|
+
$.cli_argument,
|
|
95
|
+
$.unquoted_string,
|
|
96
|
+
),
|
|
97
|
+
|
|
98
|
+
// CLI arguments like -t, --videosink, +test-clip (used in args blocks)
|
|
99
|
+
cli_argument: ($) => /[-+][a-zA-Z][-a-zA-Z0-9_]*|--[a-zA-Z][-a-zA-Z0-9_]*/,
|
|
100
|
+
|
|
101
|
+
// Double-quoted string with escapes
|
|
102
|
+
// Expression and variable are matched first, then raw text
|
|
103
|
+
string: ($) =>
|
|
104
|
+
seq(
|
|
105
|
+
'"',
|
|
106
|
+
optional($.string_inner),
|
|
107
|
+
'"',
|
|
108
|
+
),
|
|
109
|
+
|
|
110
|
+
// Inner content of a string (used for injections)
|
|
111
|
+
string_inner: ($) =>
|
|
112
|
+
repeat1(
|
|
113
|
+
choice(
|
|
114
|
+
$.escape_sequence,
|
|
115
|
+
$.expression,
|
|
116
|
+
$.variable,
|
|
117
|
+
$.string_content,
|
|
118
|
+
"$", // Lone $ that's not part of $(...)
|
|
119
|
+
),
|
|
120
|
+
),
|
|
121
|
+
|
|
122
|
+
// String content that's not a special sequence
|
|
123
|
+
// Excludes: " (end), \ (escape), $ (variable start), e (expr start)
|
|
124
|
+
string_content: ($) => /[^"\\$e]+|e/,
|
|
125
|
+
|
|
126
|
+
// Escape sequences
|
|
127
|
+
escape_sequence: ($) => /\\./,
|
|
128
|
+
|
|
129
|
+
// Variable: $(name) or $(name.subfield)
|
|
130
|
+
variable: ($) => seq("$(", /[a-zA-Z_][a-zA-Z0-9_]*(\.[a-zA-Z0-9_]+)*/, ")"),
|
|
131
|
+
|
|
132
|
+
// Expression: expr(...)
|
|
133
|
+
// Handle nested parentheses by matching balanced content
|
|
134
|
+
expression: ($) => token(seq(
|
|
135
|
+
"expr(",
|
|
136
|
+
repeat(choice(
|
|
137
|
+
/[^()]+/, // Non-paren characters
|
|
138
|
+
seq("(", /[^()]*/, ")"), // One level of nested parens
|
|
139
|
+
)),
|
|
140
|
+
")"
|
|
141
|
+
)),
|
|
142
|
+
|
|
143
|
+
// Integer or float
|
|
144
|
+
number: ($) => {
|
|
145
|
+
const integer = /[+-]?[0-9]+/;
|
|
146
|
+
const float = /[+-]?[0-9]+\.[0-9]*/;
|
|
147
|
+
return choice(float, integer);
|
|
148
|
+
},
|
|
149
|
+
|
|
150
|
+
// Fraction: num/denom (e.g., 30/1 for framerate)
|
|
151
|
+
fraction: ($) => /[0-9]+\/[0-9]+/,
|
|
152
|
+
|
|
153
|
+
// Hexadecimal number
|
|
154
|
+
hex_number: ($) => /0x[0-9a-fA-F]+/,
|
|
155
|
+
|
|
156
|
+
// Boolean (true/false, yes/no, t/f - case insensitive)
|
|
157
|
+
// Note: 1/0 are parsed as numbers unless explicitly cast with (bool)
|
|
158
|
+
boolean: ($) => token(choice(
|
|
159
|
+
/[tT][rR][uU][eE]/,
|
|
160
|
+
/[fF][aA][lL][sS][eE]/,
|
|
161
|
+
/[yY][eE][sS]/,
|
|
162
|
+
/[nN][oO]/,
|
|
163
|
+
/[tT]/,
|
|
164
|
+
/[fF]/,
|
|
165
|
+
)),
|
|
166
|
+
|
|
167
|
+
// Flags: flag1+flag2+flag3
|
|
168
|
+
// Use token to match the whole flags expression as a single token
|
|
169
|
+
flags: ($) => token(seq(
|
|
170
|
+
/[a-zA-Z_][a-zA-Z0-9_-]*/,
|
|
171
|
+
repeat1(seq("+", /[a-zA-Z_][a-zA-Z0-9_-]*/))
|
|
172
|
+
)),
|
|
173
|
+
|
|
174
|
+
// Namespaced identifier: namespace::name
|
|
175
|
+
// Use token to match the whole namespaced identifier as a single token
|
|
176
|
+
namespaced_identifier: ($) => token(seq(
|
|
177
|
+
/[a-zA-Z_][a-zA-Z0-9_-]*/,
|
|
178
|
+
"::",
|
|
179
|
+
/[a-zA-Z_][a-zA-Z0-9_-]*/
|
|
180
|
+
)),
|
|
181
|
+
|
|
182
|
+
// Unquoted string (bare identifier or value)
|
|
183
|
+
// Using alias to make this distinct from identifier at parse level
|
|
184
|
+
unquoted_string: ($) => alias(/[a-zA-Z_][a-zA-Z0-9_\-.:/]*/, "unquoted_string"),
|
|
185
|
+
|
|
186
|
+
// Basic identifier (allows / for caps media types like video/x-raw)
|
|
187
|
+
identifier: ($) => /[a-zA-Z_][a-zA-Z0-9_\-/]*/,
|
|
188
|
+
|
|
189
|
+
// Array: [ item, item, ... ] or [ structure, structure, ... ]
|
|
190
|
+
// Allows trailing commas
|
|
191
|
+
// Uses repeat instead of sep1 because array_structure contains internal commas
|
|
192
|
+
array: ($) =>
|
|
193
|
+
seq(
|
|
194
|
+
"[",
|
|
195
|
+
repeat($.array_element),
|
|
196
|
+
"]",
|
|
197
|
+
),
|
|
198
|
+
|
|
199
|
+
// Array element: either a structure with fields or a simple value
|
|
200
|
+
// Uses array_value instead of field_value to avoid ambiguity with bare identifiers
|
|
201
|
+
array_element: ($) =>
|
|
202
|
+
choice(
|
|
203
|
+
seq($.array_structure, optional(",")),
|
|
204
|
+
seq($.array_value, optional(",")),
|
|
205
|
+
),
|
|
206
|
+
|
|
207
|
+
// Value types allowed directly in arrays (excludes bare identifiers to avoid ambiguity)
|
|
208
|
+
array_value: ($) =>
|
|
209
|
+
choice(
|
|
210
|
+
$.typed_value,
|
|
211
|
+
$.string,
|
|
212
|
+
$.hex_number,
|
|
213
|
+
$.fraction,
|
|
214
|
+
$.number,
|
|
215
|
+
$.boolean,
|
|
216
|
+
$.variable,
|
|
217
|
+
$.expression,
|
|
218
|
+
$.flags,
|
|
219
|
+
$.namespaced_identifier,
|
|
220
|
+
$.array,
|
|
221
|
+
$.angle_bracket_array,
|
|
222
|
+
$.nested_structure_block,
|
|
223
|
+
),
|
|
224
|
+
|
|
225
|
+
// GstValueArray: < item, item, ... > (angle bracket array, allows trailing comma)
|
|
226
|
+
angle_bracket_array: ($) =>
|
|
227
|
+
seq(
|
|
228
|
+
"<",
|
|
229
|
+
optional(seq(sep1($.field_value, ","), optional(","))),
|
|
230
|
+
">",
|
|
231
|
+
),
|
|
232
|
+
|
|
233
|
+
// Structure inside an array (without the trailing semicolon rules)
|
|
234
|
+
// Fields are optional - [video/x-raw] is a valid structure with no fields
|
|
235
|
+
array_structure: ($) =>
|
|
236
|
+
seq($.structure_name, optional(seq(",", $.field_list))),
|
|
237
|
+
|
|
238
|
+
// Nested structure block: { structure, structure, ... } or { "string", "string", ... }
|
|
239
|
+
// Note: strings, arrays, and other values are captured via field_value
|
|
240
|
+
// Allows trailing commas (comments are handled automatically via extras)
|
|
241
|
+
nested_structure_block: ($) =>
|
|
242
|
+
seq(
|
|
243
|
+
"{",
|
|
244
|
+
repeat(seq(choice($.structure, $.field_value), optional(","))),
|
|
245
|
+
"}",
|
|
246
|
+
),
|
|
247
|
+
},
|
|
248
|
+
});
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* Creates a rule to match one or more of the rule separated by the separator.
|
|
252
|
+
*
|
|
253
|
+
* @param {Rule} rule
|
|
254
|
+
* @param {Rule} sep
|
|
255
|
+
* @returns {SeqRule}
|
|
256
|
+
*/
|
|
257
|
+
function sep1(rule, sep) {
|
|
258
|
+
return seq(rule, repeat(seq(sep, rule)));
|
|
259
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "tree-sitter-validatetest",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "GStreamer ValidateTest grammar for tree-sitter",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "https://github.com/thiblahute/tree-sitter-validatetest"
|
|
8
|
+
},
|
|
9
|
+
"license": "MIT",
|
|
10
|
+
"author": "Thibault Saunier",
|
|
11
|
+
"main": "bindings/node",
|
|
12
|
+
"types": "bindings/node",
|
|
13
|
+
"keywords": [
|
|
14
|
+
"gstreamer",
|
|
15
|
+
"validate",
|
|
16
|
+
"validatetest",
|
|
17
|
+
"tree-sitter",
|
|
18
|
+
"parser"
|
|
19
|
+
],
|
|
20
|
+
"files": [
|
|
21
|
+
"grammar.js",
|
|
22
|
+
"binding.gyp",
|
|
23
|
+
"prebuilds/**",
|
|
24
|
+
"bindings/node/*",
|
|
25
|
+
"queries/*",
|
|
26
|
+
"src/**",
|
|
27
|
+
"*.wasm"
|
|
28
|
+
],
|
|
29
|
+
"dependencies": {
|
|
30
|
+
"node-addon-api": "^8.3.0",
|
|
31
|
+
"node-gyp-build": "^4.8.4"
|
|
32
|
+
},
|
|
33
|
+
"devDependencies": {
|
|
34
|
+
"tree-sitter-cli": "^0.24.0",
|
|
35
|
+
"prebuildify": "^6.0.1"
|
|
36
|
+
},
|
|
37
|
+
"peerDependencies": {
|
|
38
|
+
"tree-sitter": "^0.21.1"
|
|
39
|
+
},
|
|
40
|
+
"peerDependenciesMeta": {
|
|
41
|
+
"tree-sitter": {
|
|
42
|
+
"optional": true
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
"scripts": {
|
|
46
|
+
"build": "tree-sitter generate && node-gyp build",
|
|
47
|
+
"build-wasm": "tree-sitter build --wasm",
|
|
48
|
+
"install": "node-gyp-build",
|
|
49
|
+
"prestart": "tree-sitter build --wasm",
|
|
50
|
+
"start": "tree-sitter playground",
|
|
51
|
+
"test": "tree-sitter test",
|
|
52
|
+
"prebuildify": "prebuildify --napi --strip"
|
|
53
|
+
},
|
|
54
|
+
"tree-sitter": [
|
|
55
|
+
{
|
|
56
|
+
"scope": "source.validatetest",
|
|
57
|
+
"injection-regex": "^validatetest$",
|
|
58
|
+
"file-types": [
|
|
59
|
+
"validatetest"
|
|
60
|
+
],
|
|
61
|
+
"highlights": "queries/highlights.scm",
|
|
62
|
+
"injections": "queries/injections.scm"
|
|
63
|
+
}
|
|
64
|
+
]
|
|
65
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
; Highlights for GStreamer ValidateTest files
|
|
2
|
+
|
|
3
|
+
; Comments
|
|
4
|
+
(comment) @comment
|
|
5
|
+
|
|
6
|
+
; Structure/action names (function calls - actions are "called" with field arguments)
|
|
7
|
+
(structure_name
|
|
8
|
+
(identifier) @function.call)
|
|
9
|
+
|
|
10
|
+
(array_structure
|
|
11
|
+
(structure_name
|
|
12
|
+
(identifier) @function.call))
|
|
13
|
+
|
|
14
|
+
; Field names (parameters to the action call)
|
|
15
|
+
(field_name
|
|
16
|
+
(identifier) @parameter)
|
|
17
|
+
|
|
18
|
+
(field_name
|
|
19
|
+
(property_path
|
|
20
|
+
(identifier) @parameter))
|
|
21
|
+
|
|
22
|
+
; Type names in casts
|
|
23
|
+
(typed_value
|
|
24
|
+
(type_name) @type)
|
|
25
|
+
|
|
26
|
+
; Strings (quoted)
|
|
27
|
+
(string) @string
|
|
28
|
+
|
|
29
|
+
; Unquoted string values (use same as quoted strings)
|
|
30
|
+
(unquoted_string) @string
|
|
31
|
+
|
|
32
|
+
; Escape sequences within strings
|
|
33
|
+
(escape_sequence) @string.escape
|
|
34
|
+
|
|
35
|
+
; Numbers
|
|
36
|
+
(number) @number
|
|
37
|
+
(hex_number) @number
|
|
38
|
+
(fraction) @number
|
|
39
|
+
|
|
40
|
+
; Booleans
|
|
41
|
+
(boolean) @boolean
|
|
42
|
+
|
|
43
|
+
; Numbers inside (bool) or (boolean) typed values should be highlighted as booleans
|
|
44
|
+
((typed_value
|
|
45
|
+
type: (type_name) @_type
|
|
46
|
+
value: (value (number) @boolean))
|
|
47
|
+
(#eq? @_type "bool"))
|
|
48
|
+
|
|
49
|
+
((typed_value
|
|
50
|
+
type: (type_name) @_type
|
|
51
|
+
value: (value (number) @boolean))
|
|
52
|
+
(#eq? @_type "boolean"))
|
|
53
|
+
|
|
54
|
+
; Variables like $(foo)
|
|
55
|
+
(variable) @variable
|
|
56
|
+
|
|
57
|
+
; Expressions like expr(...)
|
|
58
|
+
(expression) @function.call
|
|
59
|
+
|
|
60
|
+
; Flags (like flush+accurate)
|
|
61
|
+
(flags) @constant
|
|
62
|
+
|
|
63
|
+
; Namespaced identifiers (like scenario::execution-error)
|
|
64
|
+
(namespaced_identifier) @module
|
|
65
|
+
|
|
66
|
+
; CLI arguments (like -t, --videosink)
|
|
67
|
+
(cli_argument) @attribute
|
|
68
|
+
|
|
69
|
+
; Operators and punctuation
|
|
70
|
+
"=" @operator
|
|
71
|
+
"::" @punctuation.delimiter
|
|
72
|
+
|
|
73
|
+
; Brackets and braces
|
|
74
|
+
"[" @punctuation.bracket
|
|
75
|
+
"]" @punctuation.bracket
|
|
76
|
+
"{" @punctuation.bracket
|
|
77
|
+
"}" @punctuation.bracket
|
|
78
|
+
"(" @punctuation.bracket
|
|
79
|
+
")" @punctuation.bracket
|
|
80
|
+
"<" @punctuation.bracket
|
|
81
|
+
">" @punctuation.bracket
|
|
82
|
+
|
|
83
|
+
; Separators
|
|
84
|
+
"," @punctuation.delimiter
|
|
85
|
+
";" @punctuation.delimiter
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
; Injections for GStreamer ValidateTest files
|
|
2
|
+
; Re-parse embedded GstStructure syntax within strings
|
|
3
|
+
|
|
4
|
+
; Strings in 'configs' field contain GstStructure syntax
|
|
5
|
+
((field
|
|
6
|
+
name: (field_name (identifier) @_field_name)
|
|
7
|
+
value: (field_value
|
|
8
|
+
(nested_structure_block
|
|
9
|
+
(field_value (value (string (string_inner) @injection.content))))))
|
|
10
|
+
(#eq? @_field_name "configs")
|
|
11
|
+
(#set! injection.language "validatetest")
|
|
12
|
+
(#set! injection.include-children))
|
|
13
|
+
|
|
14
|
+
; Strings in 'expected-issues' field contain GstStructure syntax
|
|
15
|
+
((field
|
|
16
|
+
name: (field_name (identifier) @_field_name)
|
|
17
|
+
value: (field_value
|
|
18
|
+
(nested_structure_block
|
|
19
|
+
(field_value (value (string (string_inner) @injection.content))))))
|
|
20
|
+
(#eq? @_field_name "expected-issues")
|
|
21
|
+
(#set! injection.language "validatetest")
|
|
22
|
+
(#set! injection.include-children))
|
|
23
|
+
|
|
24
|
+
; Typed GstCaps values contain GstStructure/caps syntax
|
|
25
|
+
((typed_value
|
|
26
|
+
type: (type_name) @_type
|
|
27
|
+
value: (value (string (string_inner) @injection.content)))
|
|
28
|
+
(#eq? @_type "GstCaps")
|
|
29
|
+
(#set! injection.language "validatetest")
|
|
30
|
+
(#set! injection.include-children))
|
|
31
|
+
|
|
32
|
+
; Typed caps values (lowercase alias) contain GstStructure/caps syntax
|
|
33
|
+
((typed_value
|
|
34
|
+
type: (type_name) @_type
|
|
35
|
+
value: (value (string (string_inner) @injection.content)))
|
|
36
|
+
(#eq? @_type "caps")
|
|
37
|
+
(#set! injection.language "validatetest")
|
|
38
|
+
(#set! injection.include-children))
|
|
39
|
+
|
|
40
|
+
; Typed GstStructure values contain GstStructure syntax
|
|
41
|
+
((typed_value
|
|
42
|
+
type: (type_name) @_type
|
|
43
|
+
value: (value (string (string_inner) @injection.content)))
|
|
44
|
+
(#eq? @_type "GstStructure")
|
|
45
|
+
(#set! injection.language "validatetest")
|
|
46
|
+
(#set! injection.include-children))
|
|
47
|
+
|
|
48
|
+
; Typed structure values (lowercase alias) contain GstStructure syntax
|
|
49
|
+
((typed_value
|
|
50
|
+
type: (type_name) @_type
|
|
51
|
+
value: (value (string (string_inner) @injection.content)))
|
|
52
|
+
(#eq? @_type "structure")
|
|
53
|
+
(#set! injection.language "validatetest")
|
|
54
|
+
(#set! injection.include-children))
|
|
55
|
+
|
|
56
|
+
; Field named 'caps' with string value contains caps syntax
|
|
57
|
+
((field
|
|
58
|
+
name: (field_name (identifier) @_field_name)
|
|
59
|
+
value: (field_value (value (string (string_inner) @injection.content))))
|
|
60
|
+
(#eq? @_field_name "caps")
|
|
61
|
+
(#set! injection.language "validatetest")
|
|
62
|
+
(#set! injection.include-children))
|