vne-language 0.1.0 → 0.2.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/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "vne-language",
3
3
  "displayName": "vne-language",
4
4
  "description": "Syntax highlighting for .vne scenario files",
5
- "version": "0.1.0",
5
+ "version": "0.2.0",
6
6
  "main": "./src/extension.js",
7
7
  "scripts": {
8
8
  "package:vsix": "vsce package",
@@ -5,13 +5,194 @@
5
5
  root.VneCommandTokens = factory();
6
6
  }
7
7
  })(typeof globalThis !== "undefined" ? globalThis : this, function () {
8
- const TOKEN_TYPES = ["keyword", "function"];
8
+ const TOKEN_TYPES = ["keyword", "function", "number"];
9
9
 
10
10
  const escapeRegExp = (value) => String(value).replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
11
11
 
12
12
  const actionLiterals = (entry) =>
13
13
  Object.values((entry && entry.actions) || {}).filter((value) => typeof value === "string" && value.length > 0);
14
14
 
15
+ const enumLiterals = (arg) => {
16
+ if (!arg || arg.kind !== "enum" || !arg.values || typeof arg.values !== "object") return [];
17
+
18
+ return Object.values(arg.values).filter((value) => typeof value === "string" && value.length > 0);
19
+ };
20
+
21
+ const collectEnumLiteralsFromEntry = (entry) => {
22
+ const literals = new Set();
23
+
24
+ for (const arg of entry.args || []) {
25
+ for (const value of enumLiterals(arg)) literals.add(value);
26
+ }
27
+
28
+ for (const specs of Object.values(entry.argsByAction || {})) {
29
+ for (const arg of specs || []) {
30
+ for (const value of enumLiterals(arg)) literals.add(value);
31
+ }
32
+ }
33
+
34
+ for (const value of actionLiterals(entry)) literals.add(value);
35
+
36
+ return [...literals].sort((a, b) => b.length - a.length);
37
+ };
38
+
39
+ const isDelimitedToken = (token) => {
40
+ if (!token || !token.text) return false;
41
+ const open = token.text[0];
42
+ return open === "{" || open === '"' || open === "'";
43
+ };
44
+
45
+ const matchesArg = (spec, token) => {
46
+ if (!spec || !token) return false;
47
+
48
+ if (spec.kind === "id") {
49
+ if (spec.delimited) return isDelimitedToken(token);
50
+ return true;
51
+ }
52
+
53
+ if (spec.kind === "number") return /^-?\d+(?:\.\d+)?$/.test(token.text);
54
+
55
+ if (spec.kind === "enum") return enumLiterals(spec).includes(token.text);
56
+
57
+ return false;
58
+ };
59
+
60
+ /**
61
+ * Read `{…}`, `"…"`, or `'…'` as a single token (continues after the closer).
62
+ * @returns {{ text: string, start: number, end: number } | null}
63
+ */
64
+ const readDelimitedToken = (line, from, end = line.length) => {
65
+ const open = line[from];
66
+ if (from >= end) return null;
67
+
68
+ if (open === "{") {
69
+ let depth = 1;
70
+ let index = from + 1;
71
+
72
+ while (index < end && depth > 0) {
73
+ const ch = line[index];
74
+ if (ch === "{") depth += 1;
75
+ else if (ch === "}") depth -= 1;
76
+ index += 1;
77
+ }
78
+
79
+ return { text: line.slice(from, index), start: from, end: index };
80
+ }
81
+
82
+ if (open === '"' || open === "'") {
83
+ let index = from + 1;
84
+
85
+ while (index < end) {
86
+ const ch = line[index];
87
+ if (ch === "\\") {
88
+ index += 2;
89
+ continue;
90
+ }
91
+ if (ch === open) {
92
+ index += 1;
93
+ break;
94
+ }
95
+ index += 1;
96
+ }
97
+
98
+ return { text: line.slice(from, index), start: from, end: index };
99
+ }
100
+
101
+ return null;
102
+ };
103
+
104
+ /**
105
+ * Read next positional token (stops before `|` or `key:`; `{…}` / quotes are one token).
106
+ * @param {string[]} [extraLiterals] longest-first operator/enum literals (e.g. `===`, `++`)
107
+ * @param {number} [end]
108
+ * @returns {{ text: string, start: number, end: number } | null}
109
+ */
110
+ const nextPositionalToken = (line, from, extraLiterals = [], end = line.length) => {
111
+ let index = from;
112
+
113
+ while (index < end && /\s/.test(line[index])) index += 1;
114
+
115
+ if (index >= end) return null;
116
+
117
+ const ch = line[index];
118
+ if (ch === "|") return null;
119
+
120
+ if (ch === "{" || ch === '"' || ch === "'") {
121
+ return readDelimitedToken(line, index, end);
122
+ }
123
+
124
+ if (/^[a-zA-Z0-9_-]+:/.test(line.slice(index))) return null;
125
+
126
+ const rest = line.slice(index, end);
127
+
128
+ for (const literal of extraLiterals) {
129
+ if (rest.startsWith(literal)) {
130
+ const after = rest.slice(literal.length);
131
+ // Prefer operator match when next char is boundary (space/end/brace) or literal is word-like id
132
+ if (after === "" || /^\s/.test(after) || /^[{|"']/.test(after) || /^[a-zA-Z0-9_-]+:/.test(after)) {
133
+ return { text: literal, start: index, end: index + literal.length };
134
+ }
135
+ }
136
+ }
137
+
138
+ const numberMatch = /^-?\d+(?:\.\d+)?/.exec(rest);
139
+ if (numberMatch) {
140
+ return { text: numberMatch[0], start: index, end: index + numberMatch[0].length };
141
+ }
142
+
143
+ const idMatch = /^[a-zA-Z0-9_/-]+/.exec(rest);
144
+ if (!idMatch) return null;
145
+
146
+ return { text: idMatch[0], start: index, end: index + idMatch[0].length };
147
+ };
148
+
149
+ const collectPositionalTokens = (line, from, end = line.length, extraLiterals = []) => {
150
+ const tokens = [];
151
+ let cursor = from;
152
+
153
+ while (cursor < end) {
154
+ const token = nextPositionalToken(line, cursor, extraLiterals, end);
155
+ if (!token || token.start >= end) break;
156
+ tokens.push(token);
157
+ cursor = token.end;
158
+ }
159
+
160
+ return tokens;
161
+ };
162
+
163
+ const pushArgRanges = (ranges, lineIndex, tokens, specs) => {
164
+ const argSpecs = Array.isArray(specs) ? specs : [];
165
+ let tokenIndex = 0;
166
+
167
+ for (const spec of argSpecs) {
168
+ if (!spec) continue;
169
+
170
+ if (tokenIndex >= tokens.length) {
171
+ if (spec.optional) continue;
172
+ break;
173
+ }
174
+
175
+ const token = tokens[tokenIndex];
176
+
177
+ if (matchesArg(spec, token)) {
178
+ if (spec.kind === "id") {
179
+ ranges.push({ line: lineIndex, start: token.start, length: token.text.length, type: "function" });
180
+ } else if (spec.kind === "number") {
181
+ ranges.push({ line: lineIndex, start: token.start, length: token.text.length, type: "number" });
182
+ } else if (spec.kind === "enum") {
183
+ ranges.push({ line: lineIndex, start: token.start, length: token.text.length, type: "keyword" });
184
+ }
185
+
186
+ tokenIndex += 1;
187
+ continue;
188
+ }
189
+
190
+ if (spec.optional) continue;
191
+
192
+ break;
193
+ }
194
+ };
195
+
15
196
  /**
16
197
  * Collect semantic token ranges for document text.
17
198
  * @returns {{ line: number, start: number, length: number, type: string }[]}
@@ -32,38 +213,42 @@
32
213
  const lead = line.slice(trimmedStart);
33
214
  if (lead.startsWith("//") || lead.startsWith("#")) continue;
34
215
 
35
- const execMatch = /^(\s*)([%$])\s+([a-zA-Z0-9_.-]+)(?:\s+([a-zA-Z0-9_-]+))?/.exec(line);
216
+ const pipeIndex = line.indexOf("|");
217
+ const execEnd = pipeIndex === -1 ? line.length : pipeIndex;
218
+ const execMatch = /^(\s*)([%$])\s+([a-zA-Z0-9_.-]+)/.exec(line.slice(0, execEnd));
36
219
 
37
220
  if (execMatch) {
38
221
  const prefix = execMatch[2];
39
222
  const commandName = execMatch[3];
40
- const action = execMatch[4];
41
223
  const dict = prefix === "$" ? modules : blocks;
42
224
  const entry = dict[commandName];
43
- const actions = actionLiterals(entry);
44
225
 
45
- if (entry && action && actions.includes(action)) {
46
- const nameOffset = line.indexOf(commandName, execMatch[1].length);
47
- const actionOffset = line.indexOf(action, nameOffset + commandName.length);
226
+ if (entry) {
227
+ const commandStart = line.indexOf(commandName, trimmedStart);
228
+ const extraLiterals = collectEnumLiteralsFromEntry(entry);
229
+ const tokens = collectPositionalTokens(line, commandStart + commandName.length, execEnd, extraLiterals);
230
+ const actions = actionLiterals(entry);
231
+ const first = tokens[0];
232
+ const hasAction = Boolean(first && actions.includes(first.text));
48
233
 
49
- if (actionOffset !== -1) {
50
- ranges.push({ line: lineIndex, start: actionOffset, length: action.length, type: "keyword" });
51
- }
52
-
53
- if (actionOffset !== -1) {
54
- const afterAction = line.slice(actionOffset + action.length);
55
- const idMatch = /^\s+([a-zA-Z0-9_/-]+)/.exec(afterAction);
234
+ if (hasAction) {
235
+ ranges.push({
236
+ line: lineIndex,
237
+ start: first.start,
238
+ length: first.text.length,
239
+ type: "keyword",
240
+ });
56
241
 
57
- if (idMatch) {
58
- const idOffset = actionOffset + action.length + afterAction.indexOf(idMatch[1]);
59
- ranges.push({ line: lineIndex, start: idOffset, length: idMatch[1].length, type: "function" });
60
- }
242
+ const specs =
243
+ (entry.argsByAction && entry.argsByAction[first.text]) ||
244
+ (actions.length ? [{ kind: "id" }] : []);
245
+ pushArgRanges(ranges, lineIndex, tokens.slice(1), specs);
246
+ } else if (Array.isArray(entry.args) && entry.args.length) {
247
+ pushArgRanges(ranges, lineIndex, tokens, entry.args);
61
248
  }
62
249
  }
63
250
  }
64
251
 
65
- const pipeIndex = line.indexOf("|");
66
-
67
252
  if (pipeIndex !== -1 && lineKeywords.length) {
68
253
  const rest = line.slice(pipeIndex + 1);
69
254
 
@@ -113,7 +298,12 @@
113
298
  TOKEN_TYPES,
114
299
  actionLiterals,
115
300
  collectCommandTokenRanges,
301
+ collectPositionalTokens,
116
302
  encodeSemanticTokenData,
303
+ enumLiterals,
117
304
  escapeRegExp,
305
+ isDelimitedToken,
306
+ nextPositionalToken,
307
+ readDelimitedToken,
118
308
  };
119
309
  });
@@ -42,10 +42,20 @@ const findContractPackageDirs = (gameRoot) => {
42
42
 
43
43
  const importModule = async (filePath) => import(pathToFileURL(filePath).href);
44
44
 
45
+ /**
46
+ * @param {unknown} keywords
47
+ * @returns {string[]}
48
+ */
49
+ const collectLineKeywords = (keywords) => {
50
+ if (!keywords || typeof keywords !== "object") return [];
51
+
52
+ return Object.values(keywords).filter((value) => typeof value === "string" && value.length > 0);
53
+ };
54
+
45
55
  /**
46
56
  * Load and merge SCENARIO_COMMANDS from contracts in node_modules of the game package.
47
57
  *
48
- * Imports only `dist/commands.js` when present (not the full package entry), so we do not
58
+ * Imports only `dist/commands.js` / `dist/const.js` when present (not the full package entry), so we do not
49
59
  * pull every contract's side-effect graph into the editor/extension host.
50
60
  *
51
61
  * @param {string} gameRoot
@@ -56,34 +66,31 @@ const loadCommandsFromNodeModules = async (gameRoot) => {
56
66
 
57
67
  const packageDirs = findContractPackageDirs(gameRoot);
58
68
  const manifests = [];
59
- let lineKeywords = [];
69
+ const lineKeywords = [];
60
70
 
61
- for (const [shortName, packageDir] of packageDirs) {
71
+ for (const [, packageDir] of packageDirs) {
62
72
  const commandsPath = path.join(packageDir, "dist", "commands.js");
73
+ const constPath = path.join(packageDir, "dist", "const.js");
63
74
 
64
- if (!fs.existsSync(commandsPath)) continue;
75
+ if (fs.existsSync(commandsPath)) {
76
+ try {
77
+ const mod = await importModule(commandsPath);
65
78
 
66
- try {
67
- const mod = await importModule(commandsPath);
68
-
69
- if (mod.SCENARIO_COMMANDS) manifests.push(mod.SCENARIO_COMMANDS);
70
-
71
- if (shortName === "contracts.core.scenario") {
72
- const constPath = path.join(packageDir, "dist", "const.js");
79
+ if (mod.SCENARIO_COMMANDS) manifests.push(mod.SCENARIO_COMMANDS);
80
+ } catch {
81
+ // Skip unreadable / incompatible packages.
82
+ }
83
+ }
73
84
 
74
- if (fs.existsSync(constPath)) {
75
- const consts = await importModule(constPath);
76
- const keywords = consts.LINE_KEYWORDS || consts.CONSTANTS?.LINE_KEYWORDS;
85
+ if (fs.existsSync(constPath)) {
86
+ try {
87
+ const consts = await importModule(constPath);
88
+ const keywords = consts.LINE_KEYWORDS || consts.CONSTANTS?.LINE_KEYWORDS;
77
89
 
78
- if (keywords && typeof keywords === "object") {
79
- lineKeywords = Object.values(keywords).filter(
80
- (value) => typeof value === "string" && value.length > 0,
81
- );
82
- }
83
- }
90
+ lineKeywords.push(...collectLineKeywords(keywords));
91
+ } catch {
92
+ // Skip unreadable / incompatible packages.
84
93
  }
85
- } catch {
86
- // Skip unreadable / incompatible packages.
87
94
  }
88
95
  }
89
96
 
@@ -92,7 +99,7 @@ const loadCommandsFromNodeModules = async (gameRoot) => {
92
99
  return {
93
100
  modules: merged.modules,
94
101
  blocks: merged.blocks,
95
- lineKeywords,
102
+ lineKeywords: [...new Set(lineKeywords)],
96
103
  };
97
104
  };
98
105
 
@@ -22,6 +22,11 @@ const main = async () => {
22
22
 
23
23
  assert(commands.modules.stack, "expected stack module from contracts");
24
24
  assert(commands.modules.scenario, "expected scenario module from contracts");
25
+ assert(commands.modules.save, "expected save module from contracts");
26
+ assert(commands.modules["bl.bg"], "expected bl.bg module from layer contracts");
27
+ assert(commands.modules["audio.music"], "expected audio.music module from contracts");
28
+ assert(commands.blocks.qte, "expected qte block from contracts");
29
+ assert(commands.blocks.choose, "expected choose block from contracts");
25
30
  assert(
26
31
  Object.values(commands.modules.stack.actions || {}).includes("jump"),
27
32
  "expected stack jump action",
@@ -30,10 +35,51 @@ const main = async () => {
30
35
  Object.values(commands.modules.scenario.actions || {}).includes("goto"),
31
36
  "expected scenario goto action",
32
37
  );
38
+ assert(
39
+ Object.values(commands.modules.save.actions || {}).includes("key"),
40
+ "expected save key action",
41
+ );
42
+ assert(
43
+ Object.values(commands.modules["bl.bg"].actions || {}).includes("show"),
44
+ "expected bl.bg show action",
45
+ );
46
+ assert(
47
+ Object.values(commands.modules["audio.music"].actions || {}).includes("play"),
48
+ "expected audio.music play action",
49
+ );
50
+ assert(commands.modules["text.meet"], "expected text.meet module from contracts");
51
+ assert(commands.modules["ul.sprite"], "expected ul.sprite module from layer contracts");
52
+ assert(
53
+ Array.isArray(commands.modules["text.meet"].args) && commands.modules["text.meet"].args[0]?.kind === "id",
54
+ "expected text.meet args id slot",
55
+ );
56
+ assert(
57
+ Array.isArray(commands.modules["ul.sprite"].argsByAction?.show) &&
58
+ commands.modules["ul.sprite"].argsByAction.show.some((arg) => arg.kind === "enum"),
59
+ "expected ul.sprite show position enum slot",
60
+ );
33
61
  assert(commands.lineKeywords.includes("async"), "expected LINE_KEYWORDS from scenario contract");
62
+ assert(commands.lineKeywords.includes("extend"), "expected LINE_KEYWORDS from text contract");
63
+ assert(commands.lineKeywords.includes("global"), "expected LINE_KEYWORDS from vars contract");
64
+ assert(commands.lineKeywords.includes("dangerous"), "expected LINE_KEYWORDS from layer animation contract");
65
+ assert(commands.lineKeywords.includes("qte-fallback"), "expected LINE_KEYWORDS from qte contract");
34
66
 
35
67
  const ranges = collectCommandTokenRanges(
36
- [' $ stack jump testsCanvas', ' "hi" | async global', ' $ scenario goto loop'].join("\n"),
68
+ [
69
+ " $ stack jump testsCanvas",
70
+ ' "hi" | async global',
71
+ " $ scenario goto loop",
72
+ " $ save key autosave",
73
+ " $ bl.bg show forest",
74
+ " $ audio.music play theme",
75
+ " $ text.meet alice",
76
+ " $ ul.sprite show co center",
77
+ " $ flag quest unset",
78
+ " $ counter gold += 2",
79
+ " $ bl.bg show {castle/surgery_room} opacity 500 | async",
80
+ " $ ul.sprite show co left {co/default} opacity 500",
81
+ " $ ul.sprite hide co opacity 300",
82
+ ].join("\n"),
37
83
  commands,
38
84
  );
39
85
 
@@ -53,6 +99,78 @@ const main = async () => {
53
99
  ranges.some((range) => range.type === "keyword" && range.line === 2),
54
100
  "expected keyword token on scenario goto",
55
101
  );
102
+ assert(
103
+ ranges.some((range) => range.type === "keyword" && range.line === 3),
104
+ "expected keyword token on save key",
105
+ );
106
+ assert(
107
+ ranges.some((range) => range.type === "keyword" && range.line === 4),
108
+ "expected keyword token on bl.bg show",
109
+ );
110
+ assert(
111
+ ranges.some((range) => range.type === "keyword" && range.line === 5),
112
+ "expected keyword token on audio.music play",
113
+ );
114
+ assert(
115
+ ranges.some((range) => range.type === "function" && range.line === 6),
116
+ "expected function token for text.meet speaker",
117
+ );
118
+ assert(
119
+ ranges.some((range) => range.type === "keyword" && range.line === 7 && range.length === "show".length),
120
+ "expected keyword token on ul.sprite show",
121
+ );
122
+ assert(
123
+ ranges.some((range) => range.type === "function" && range.line === 7),
124
+ "expected function token for sprite name",
125
+ );
126
+ assert(
127
+ ranges.some((range) => range.type === "keyword" && range.line === 7 && range.length === "center".length),
128
+ "expected keyword token for sprite position",
129
+ );
130
+ assert(
131
+ ranges.some((range) => range.type === "function" && range.line === 8),
132
+ "expected function token for flag name",
133
+ );
134
+ assert(
135
+ ranges.some((range) => range.type === "keyword" && range.line === 8 && range.length === "unset".length),
136
+ "expected keyword token for flag unset",
137
+ );
138
+ assert(
139
+ ranges.some((range) => range.type === "function" && range.line === 9),
140
+ "expected function token for counter name",
141
+ );
142
+ assert(
143
+ ranges.some((range) => range.type === "keyword" && range.line === 9 && range.length === "+=".length),
144
+ "expected keyword token for counter +=",
145
+ );
146
+ assert(
147
+ ranges.some((range) => range.type === "function" && range.line === 10 && range.length === "{castle/surgery_room}".length),
148
+ "expected function token for braced bg media ref",
149
+ );
150
+ assert(
151
+ ranges.some((range) => range.type === "keyword" && range.line === 10 && range.length === "opacity".length),
152
+ "expected keyword token for bg opacity transition",
153
+ );
154
+ assert(
155
+ ranges.some((range) => range.type === "number" && range.line === 10 && range.length === "500".length),
156
+ "expected number token for bg duration",
157
+ );
158
+ assert(
159
+ ranges.some((range) => range.type === "function" && range.line === 11 && range.length === "{co/default}".length),
160
+ "expected function token for braced sprite variation",
161
+ );
162
+ assert(
163
+ ranges.some((range) => range.type === "keyword" && range.line === 11 && range.length === "opacity".length),
164
+ "expected keyword token for sprite show opacity",
165
+ );
166
+ assert(
167
+ ranges.some((range) => range.type === "keyword" && range.line === 12 && range.length === "opacity".length),
168
+ "expected keyword token for sprite hide opacity",
169
+ );
170
+ assert(
171
+ ranges.some((range) => range.type === "number" && range.line === 12 && range.length === "300".length),
172
+ "expected number token for sprite hide duration",
173
+ );
56
174
 
57
175
  console.log("ok", {
58
176
  gameRoot,
@@ -61,157 +61,9 @@
61
61
  "name": "variable.other",
62
62
  "match": "(?<=\\s)[a-zA-Z0-9_-]+:(?=\\s|$)"
63
63
  },
64
- {
65
- "name": "variable.other",
66
- "match": "(?<=\\b(counter|flag)\\s+)[a-zA-Z0-9_-]+"
67
- },
68
64
  {
69
65
  "name": "keyword.other",
70
66
  "match": "(?<=^\\s*)[a-zA-Z0-9_-]+(?=\\s+\")"
71
- },
72
- {
73
- "name": "keyword.control",
74
- "match": "(?<=\\b(bl|ml|fl|ul)\\.sprite\\s)(show|hide|change|move)\\b"
75
- },
76
- {
77
- "name": "keyword.control",
78
- "match": "(?<=\\b(bl|ml|fl|ul)\\.bg\\s)(show|hide|change)\\b"
79
- },
80
- {
81
- "name": "keyword.control",
82
- "match": "(?<=\\b(bl|ml|fl|ul)\\.video\\s)(show|hide|change)\\b"
83
- },
84
- {
85
- "name": "keyword.control",
86
- "match": "(?<=\\b(bl|ml|fl|ul)\\.text\\s)(show|hide|change|move)\\b"
87
- },
88
- {
89
- "name": "keyword.control",
90
- "match": "(?<=\\b(bl|ml|fl|ul)\\.filter\\s)(set|unset)\\b"
91
- },
92
- {
93
- "name": "keyword.control",
94
- "match": "(?<=\\b(bl|ml|fl|ul)\\.clip\\s)(set|unset)\\b"
95
- },
96
- {
97
- "name": "keyword.control",
98
- "match": "(?<=\\b(bl|ml|fl|ul)\\.mask\\s)(set|unset|change)\\b"
99
- },
100
- {
101
- "name": "keyword.control",
102
- "match": "(?<=\\b(bl|ml|fl|ul)\\.scale\\s)(set|unset)\\b"
103
- },
104
- {
105
- "name": "keyword.control",
106
- "match": "(?<=\\b(bl|ml|fl|ul)\\.animation\\s)(set|unset)\\b"
107
- },
108
- {
109
- "name": "keyword.control",
110
- "match": "(?<=\\baudio\\.(music|sound|ambient|voice)\\s)(play|stop|pause|resume|volume)\\b"
111
- },
112
- {
113
- "name": "keyword.control",
114
- "match": "(?<=\\bvideo\\s)play\\b"
115
- },
116
- {
117
- "name": "keyword.control",
118
- "match": "(?<=\\binterface\\s)(show|hide|view)\\b"
119
- },
120
- {
121
- "name": "keyword.control",
122
- "match": "(?<=\\bsave\\s)key\\b"
123
- },
124
- {
125
- "name": "keyword.control",
126
- "match": "(?<=\\bflag\\s+[a-zA-Z0-9_-]+\\s)(set|unset)\\b"
127
- },
128
- {
129
- "name": "keyword.control",
130
- "match": "(?<=\\btime\\s+)(add|set)\\b"
131
- },
132
- {
133
- "name": "keyword.control",
134
- "match": "(?<=\\bdate\\s+)(add|set)\\b"
135
- },
136
- {
137
- "name": "keyword.control",
138
- "match": "(?<=\\btext\\.wall\\s+)(clear|start|end)\\b"
139
- },
140
- {
141
- "name": "keyword.control",
142
- "match": "(?<=\\btext\\.meet\\s+)[a-zA-Z0-9_-]+"
143
- },
144
- {
145
- "name": "keyword.control",
146
- "match": "(?<=\\bcomment\\s+)hide\\b"
147
- },
148
- {
149
- "name": "keyword.control",
150
- "match": "(?<=\\bachievement\\s+)unlock\\b"
151
- },
152
- {
153
- "name": "keyword.control",
154
- "match": "(?<=\\bwallet\\s+[a-zA-Z0-9_-]+\\s)(add|set|reset)\\b"
155
- },
156
- {
157
- "name": "keyword.control",
158
- "match": "(?<=\\bcredits\\s+)(show|hide)\\b"
159
- },
160
- {
161
- "name": "entity.name.function",
162
- "match": "(?<=\\bachievement\\s+unlock\\s+)[a-zA-Z0-9_-]+"
163
- },
164
- {
165
- "name": "entity.name.function",
166
- "match": "(?<=\\bwallet\\s+)[a-zA-Z0-9_-]+(?=\\s+(add|set|reset))"
167
- },
168
- {
169
- "name": "entity.name.type",
170
- "match": "(?<=\\binterface\\s+view\\s+)[a-zA-Z0-9_-]+"
171
- },
172
- {
173
- "name": "entity.name.function",
174
- "match": "(?<=\\b(bl|ml|fl|ul)\\.bg\\sshow\\s\\{[^}]*\\}\\s)[a-zA-Z0-9_-]+"
175
- },
176
- {
177
- "name": "entity.name.function",
178
- "match": "(?<=\\b(bl|ml|fl|ul)\\.bg\\shide\\s)[a-zA-Z0-9_-]+"
179
- },
180
- {
181
- "name": "entity.name.function",
182
- "match": "(?<=\\b(bl|ml|fl|ul)\\.sprite\\sshow\\s)[a-zA-Z0-9_-]+"
183
- },
184
- {
185
- "name": "entity.name.function",
186
- "match": "(?<=\\b(bl|ml|fl|ul)\\.sprite\\s(hide|change|move)\\s)[a-zA-Z0-9_-]+"
187
- },
188
- {
189
- "name": "entity.name.function",
190
- "match": "(?<=\\b(bl|ml|fl|ul)\\.video\\s(show|change)\\s)[a-zA-Z0-9_{}/-]+"
191
- },
192
- {
193
- "name": "entity.name.function",
194
- "match": "(?<=\\b(bl|ml|fl|ul)\\.text\\s(show|hide|change|move)\\s)[a-zA-Z0-9_-]+"
195
- },
196
- {
197
- "name": "entity.name.function",
198
- "match": "(?<=\\b(bl|ml|fl|ul)\\.filter\\sset\\s)[a-zA-Z0-9_-]+"
199
- },
200
- {
201
- "name": "entity.name.function",
202
- "match": "(?<=\\b(bl|ml|fl|ul)\\.clip\\sset\\s)[a-zA-Z0-9_-]+"
203
- },
204
- {
205
- "name": "entity.name.function",
206
- "match": "(?<=\\b(bl|ml|fl|ul)\\.mask\\sset\\s)[a-zA-Z0-9_-]+"
207
- },
208
- {
209
- "name": "entity.name.function",
210
- "match": "(?<=\\b(bl|ml|fl|ul)\\.animation\\sset\\s)[a-zA-Z0-9_-]+"
211
- },
212
- {
213
- "name": "keyword.other",
214
- "match": "(?<=\\b(bl|ml|fl|ul)\\.sprite\\s(show|hide|change|move)\\s[a-zA-Z0-9_-]+\\s)[a-zA-Z0-9_-]+"
215
67
  }
216
68
  ],
217
69
  "repository": {},
package/syntaxes/vne.json CHANGED
@@ -61,161 +61,9 @@
61
61
  "name": "variable.other",
62
62
  "match": "(?<=\\s)[a-zA-Z0-9_-]+:(?=\\s|$)"
63
63
  },
64
- {
65
- "name": "variable.other",
66
- "match": "(?<=\\b(counter|flag)\\s+)[a-zA-Z0-9_-]+"
67
- },
68
64
  {
69
65
  "name": "keyword.other",
70
66
  "match": "(?<=^\\s*)[a-zA-Z0-9_-]+(?=\\s+\")"
71
- },
72
- {
73
- "name": "keyword.control",
74
- "match": "(?<=\\b(bl|ml|fl|ul)\\.sprite\\s)(show|hide|change|move)\\b"
75
- },
76
- {
77
- "name": "keyword.control",
78
- "match": "(?<=\\b(bl|ml|fl|ul)\\.bg\\s)(show|hide|change)\\b"
79
- },
80
- {
81
- "name": "keyword.control",
82
- "match": "(?<=\\b(bl|ml|fl|ul)\\.video\\s)(show|hide|change)\\b"
83
- },
84
- {
85
- "name": "keyword.control",
86
- "match": "(?<=\\b(bl|ml|fl|ul)\\.text\\s)(show|hide|change|move)\\b"
87
- },
88
- {
89
- "name": "keyword.control",
90
- "match": "(?<=\\b(bl|ml|fl|ul)\\.filter\\s)(set|unset)\\b"
91
- },
92
- {
93
- "name": "keyword.control",
94
- "match": "(?<=\\b(bl|ml|fl|ul)\\.clip\\s)(set|unset)\\b"
95
- },
96
- {
97
- "name": "keyword.control",
98
- "match": "(?<=\\b(bl|ml|fl|ul)\\.mask\\s)(set|unset|change)\\b"
99
- },
100
- {
101
- "name": "keyword.control",
102
- "match": "(?<=\\b(bl|ml|fl|ul)\\.scale\\s)(set|unset)\\b"
103
- },
104
- {
105
- "name": "keyword.control",
106
- "match": "(?<=\\b(bl|ml|fl|ul)\\.animation\\s)(set|unset)\\b"
107
- },
108
- {
109
- "name": "keyword.control",
110
- "match": "(?<=\\baudio\\.(music|sound|ambient|voice)\\s)(play|stop|pause|resume|volume)\\b"
111
- },
112
- {
113
- "name": "keyword.control",
114
- "match": "(?<=\\bvideo\\s)play\\b"
115
- },
116
- {
117
- "name": "keyword.control",
118
- "match": "(?<=\\binterface\\s)(show|hide|view)\\b"
119
- },
120
- {
121
- "name": "keyword.control",
122
- "match": "(?<=\\bsave\\s)key\\b"
123
- },
124
- {
125
- "name": "keyword.control",
126
- "match": "(?<=\\bflag\\s+[a-zA-Z0-9_-]+\\s)(set|unset)\\b"
127
- },
128
- {
129
- "name": "keyword.control",
130
- "match": "(?<=\\btime\\s+)(add|set)\\b"
131
- },
132
- {
133
- "name": "keyword.control",
134
- "match": "(?<=\\bdate\\s+)(add|set)\\b"
135
- },
136
- {
137
- "name": "keyword.control",
138
- "match": "(?<=\\btext\\.wall\\s+)(clear|start|end)\\b"
139
- },
140
- {
141
- "name": "keyword.control",
142
- "match": "(?<=\\btext\\.meet\\s+)[a-zA-Z0-9_-]+"
143
- },
144
- {
145
- "name": "keyword.control",
146
- "match": "(?<=\\bcomment\\s+)hide\\b"
147
- },
148
- {
149
- "name": "keyword.control",
150
- "match": "(?<=\\bachievement\\s+)unlock\\b"
151
- },
152
- {
153
- "name": "keyword.control",
154
- "match": "(?<=\\bwallet\\s+[a-zA-Z0-9_-]+\\s)(add|set|reset)\\b"
155
- },
156
- {
157
- "name": "keyword.control",
158
- "match": "(?<=\\bcredits\\s+)(show|hide)\\b"
159
- },
160
- {
161
- "name": "entity.name.function",
162
- "match": "(?<=\\bachievement\\s+unlock\\s+)[a-zA-Z0-9_-]+"
163
- },
164
- {
165
- "name": "entity.name.function",
166
- "match": "(?<=\\bwallet\\s+)[a-zA-Z0-9_-]+(?=\\s+(add|set|reset))"
167
- },
168
- {
169
- "name": "entity.name.type",
170
- "match": "(?<=\\binterface\\s+view\\s+)[a-zA-Z0-9_-]+"
171
- },
172
- {
173
- "name": "entity.name.function",
174
- "match": "(?<=\\b(bl|ml|fl|ul)\\.bg\\sshow\\s\\{[^}]*\\}\\s)[a-zA-Z0-9_-]+"
175
- },
176
- {
177
- "name": "entity.name.function",
178
- "match": "(?<=\\b(bl|ml|fl|ul)\\.bg\\shide\\s)[a-zA-Z0-9_-]+"
179
- },
180
- {
181
- "name": "entity.name.function",
182
- "match": "(?<=\\b(bl|ml|fl|ul)\\.sprite\\sshow\\s)[a-zA-Z0-9_-]+"
183
- },
184
- {
185
- "name": "entity.name.function",
186
- "match": "(?<=\\b(bl|ml|fl|ul)\\.sprite\\s(hide|change|move)\\s)[a-zA-Z0-9_-]+"
187
- },
188
- {
189
- "name": "entity.name.function",
190
- "match": "(?<=\\b(bl|ml|fl|ul)\\.video\\s(show|change)\\s)[a-zA-Z0-9_{}/-]+"
191
- },
192
- {
193
- "name": "entity.name.function",
194
- "match": "(?<=\\b(bl|ml|fl|ul)\\.text\\s(show|hide|change|move)\\s)[a-zA-Z0-9_-]+"
195
- },
196
- {
197
- "name": "entity.name.function",
198
- "match": "(?<=\\b(bl|ml|fl|ul)\\.filter\\sset\\s)[a-zA-Z0-9_-]+"
199
- },
200
- {
201
- "name": "entity.name.function",
202
- "match": "(?<=\\b(bl|ml|fl|ul)\\.clip\\sset\\s)[a-zA-Z0-9_-]+"
203
- },
204
- {
205
- "name": "entity.name.function",
206
- "match": "(?<=\\b(bl|ml|fl|ul)\\.mask\\sset\\s)[a-zA-Z0-9_-]+"
207
- },
208
- {
209
- "name": "entity.name.function",
210
- "match": "(?<=\\b(bl|ml|fl|ul)\\.animation\\sset\\s)[a-zA-Z0-9_-]+"
211
- },
212
- {
213
- "name": "keyword.other",
214
- "match": "(?<=\\b(bl|ml|fl|ul)\\.sprite\\s(show|hide|change|move)\\s[a-zA-Z0-9_-]+\\s)[a-zA-Z0-9_-]+"
215
- },
216
- {
217
- "name": "keyword.control",
218
- "match": "(?<=\\s\\|\\s.*)(global|skip-if-possible|async|extend|autonext|dangerous)(?=\\s|$)"
219
67
  }
220
68
  ],
221
69
  "repository": {},
Binary file
Binary file