@stepcode/textmate 2.0.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 rolandoandrade
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,65 @@
1
+ # @stepcode/textmate
2
+
3
+ TextMate grammars for StepCode, generated from `@stepcode/profiles`. Keywords are profile data,
4
+ so the grammar is too: `es`, `en` and `pseint` ship ready-made, and any resolved profile can get
5
+ its own.
6
+
7
+ ```ts
8
+ import { createHighlighter } from 'shiki'
9
+ import { grammars } from '@stepcode/textmate'
10
+
11
+ const highlighter = await createHighlighter({ langs: [...grammars], themes: ['github-light'] })
12
+ highlighter.codeToHtml(source, { lang: 'stepcode', theme: 'github-light' })
13
+ ```
14
+
15
+ | Export | Fence / `lang` | Scope |
16
+ |---|---|---|
17
+ | `stepcode` | `stepcode` | `source.stepcode` (the `es` profile) |
18
+ | `stepcodeEn` | `stepcode-en` | `source.stepcode.en` |
19
+ | `stepcodePseint` | `stepcode-pseint` | `source.stepcode.pseint` |
20
+
21
+ The same three are available as JSON: `@stepcode/textmate/grammars/stepcode.json` and so on.
22
+
23
+ Astro (`astro.config.mjs`):
24
+
25
+ ```js
26
+ import { grammars } from '@stepcode/textmate'
27
+
28
+ export default defineConfig({
29
+ markdown: { shikiConfig: { langs: [...grammars] } },
30
+ })
31
+ ```
32
+
33
+ A custom profile:
34
+
35
+ ```ts
36
+ import { builtinProfiles, resolveProfile } from '@stepcode/profiles'
37
+ import { generateGrammar } from '@stepcode/textmate'
38
+
39
+ const grammar = generateGrammar(
40
+ resolveProfile({ id: 'clase', extends: 'es', keywords: { if: ['Cuando'] } }, builtinProfiles),
41
+ { name: 'stepcode-clase', scopeName: 'source.stepcode.clase' },
42
+ )
43
+ ```
44
+
45
+ ## Scopes
46
+
47
+ Control keywords `keyword.control`, definition keywords `storage.type`, `Por Referencia` /
48
+ `Por Valor` `storage.modifier`, input and output `keyword.other.io`, word operators
49
+ `keyword.operator.word`, booleans `constant.language.boolean`, types `support.type.primitive`,
50
+ builtins `support.function.builtin`, numbers `constant.numeric.{integer,real}`, strings
51
+ `string.quoted.{double,single}`, comments `comment.line`, symbol operators
52
+ `keyword.operator.{assignment,comparison,arithmetic}`, punctuation `punctuation.*`, subprogram
53
+ and program names `entity.name.function`, call names `entity.name.function.call`, names in a
54
+ `Definir` list `variable.other.definition`, other identifiers `variable.other`. Every scope ends
55
+ in `.stepcode`.
56
+
57
+ ## Limits
58
+
59
+ The grammar is line-based: a multi-word keyword split across lines is not matched. Accent
60
+ folding covers the Latin-1 marks (`á`, `è`, `ô`, `ü`, `ç`…). Calls and definitions are
61
+ heuristics (an identifier before `(`, the names after `Definir`); there are no folding markers.
62
+ A type or builtin spelling must contain a letter to be highlighted; symbolic spellings are
63
+ supported only for operators and for the word-operator keywords (`&`, `|`, `~`, `%`).
64
+
65
+ See `docs/superpowers/specs/2026-09-06-textmate-design.md` for the design.
@@ -0,0 +1,48 @@
1
+ import { ResolvedProfile } from "@stepcode/profiles";
2
+ //#region src/types.d.ts
3
+ /** A TextMate rule as vscode-textmate reads it. Structurally a Shiki `RawRule`. */
4
+ interface TextMateRule {
5
+ name?: string;
6
+ match?: string;
7
+ begin?: string;
8
+ end?: string;
9
+ captures?: Record<string, TextMateRule>;
10
+ beginCaptures?: Record<string, TextMateRule>;
11
+ endCaptures?: Record<string, TextMateRule>;
12
+ patterns?: TextMateRule[];
13
+ include?: string;
14
+ }
15
+ /** A TextMate grammar as Shiki and VS Code consume it. Structurally a Shiki `LanguageRegistration`. */
16
+ interface TextMateGrammar {
17
+ name: string;
18
+ scopeName: string;
19
+ displayName?: string;
20
+ aliases?: string[];
21
+ patterns: TextMateRule[];
22
+ repository: Record<string, TextMateRule>;
23
+ }
24
+ interface GenerateOptions {
25
+ /** Language id: the fence name in Markdown, the `lang` passed to Shiki. */
26
+ name: string;
27
+ /** `source.<...>`. */
28
+ scopeName: string;
29
+ displayName?: string;
30
+ aliases?: string[];
31
+ }
32
+ //#endregion
33
+ //#region src/generate.d.ts
34
+ /** Builds the full grammar (word, symbol and structural rules) for one resolved profile. */
35
+ declare function generateGrammar(profile: ResolvedProfile, options: GenerateOptions): TextMateGrammar;
36
+ //#endregion
37
+ //#region src/index.d.ts
38
+ declare const packageName = "@stepcode/textmate";
39
+ /** The `es` profile: fence ```stepcode, scope `source.stepcode`. */
40
+ declare const stepcode: TextMateGrammar;
41
+ /** The `en` profile: fence ```stepcode-en, scope `source.stepcode.en`. */
42
+ declare const stepcodeEn: TextMateGrammar;
43
+ /** The `pseint` profile: fence ```stepcode-pseint, scope `source.stepcode.pseint`. */
44
+ declare const stepcodePseint: TextMateGrammar;
45
+ /** All three, for `createHighlighter({ langs: [...grammars] })`. */
46
+ declare const grammars: readonly TextMateGrammar[];
47
+ //#endregion
48
+ export { type GenerateOptions, type TextMateGrammar, type TextMateRule, generateGrammar, grammars, packageName, stepcode, stepcodeEn, stepcodePseint };
package/dist/index.js ADDED
@@ -0,0 +1,448 @@
1
+ import { BUILTIN_KEYS, TYPE_KEYS, createNormalizer, profiles } from "@stepcode/profiles";
2
+ //#region src/regex.ts
3
+ /** Word boundaries as the lexer sees them: letters, digits and underscore form a word. */
4
+ const WORD_START = "(?<![\\p{L}\\p{N}_])";
5
+ const WORD_END = "(?![\\p{L}\\p{N}_])";
6
+ const IDENT = "[\\p{L}_][\\p{L}\\p{N}_]*";
7
+ /** What may separate the words of a multi-word spelling on one line. */
8
+ const WORD_GAP = "[ \\t]+";
9
+ const ACCENTS = {
10
+ a: "àáâãä",
11
+ e: "èéêë",
12
+ i: "ìíîï",
13
+ o: "òóôõö",
14
+ u: "ùúûü",
15
+ c: "ç",
16
+ y: "ýÿ"
17
+ };
18
+ /** Folds accents the way the profile normalizer does (ñ kept), without lowercasing. */
19
+ const foldAccentMarks = createNormalizer({
20
+ caseSensitive: true,
21
+ foldAccents: true
22
+ });
23
+ function escapeRegex(text) {
24
+ return text.replace(/[.*+?^${}()|[\]\\/]/g, "\\$&");
25
+ }
26
+ function accentClass(char) {
27
+ const lower = char.toLowerCase();
28
+ const marks = ACCENTS[lower];
29
+ if (marks === void 0 || char.length !== 1) return char;
30
+ return `[${char}${char === lower ? marks : marks.toUpperCase()}]`;
31
+ }
32
+ function isMultiWord(spelling) {
33
+ return /\s/.test(spelling.trim());
34
+ }
35
+ function hasLetter(spelling) {
36
+ return /\p{L}/u.test(spelling);
37
+ }
38
+ function expand(word, options) {
39
+ const escaped = escapeRegex(options.foldAccents ? foldAccentMarks(word) : word);
40
+ if (!options.foldAccents) return escaped;
41
+ let out = "";
42
+ for (let i = 0; i < escaped.length; i++) {
43
+ const char = escaped[i];
44
+ if (char === "\\") {
45
+ out += char + (escaped[i + 1] ?? "");
46
+ i++;
47
+ continue;
48
+ }
49
+ out += accentClass(char);
50
+ }
51
+ return out;
52
+ }
53
+ function wordPattern(spelling, options) {
54
+ return spelling.trim().split(/\s+/).map((word) => expand(word, options)).join(WORD_GAP);
55
+ }
56
+ const wordCount = (spelling) => spelling.trim().split(/\s+/).length;
57
+ /** Code-point comparison: deterministic across Node builds, unlike `localeCompare`. */
58
+ const compareCodePoints = (a, b) => a < b ? -1 : a > b ? 1 : 0;
59
+ function sortSpellings(spellings) {
60
+ return [...spellings].sort((a, b) => wordCount(b) - wordCount(a) || b.length - a.length || compareCodePoints(a, b));
61
+ }
62
+ function wordAlternation(spellings, options) {
63
+ return sortSpellings(spellings).map((spelling) => wordPattern(spelling, options)).join("|");
64
+ }
65
+ function caseFlag(options) {
66
+ return options.caseSensitive ? "" : "(?i)";
67
+ }
68
+ function wordRule(spellings, options) {
69
+ return `${caseFlag(options)}${WORD_START}(?:${wordAlternation(spellings, options)})${WORD_END}`;
70
+ }
71
+ function symbolAlternation(spellings) {
72
+ return [...spellings].sort((a, b) => b.length - a.length || compareCodePoints(a, b)).map(escapeRegex).join("|");
73
+ }
74
+ //#endregion
75
+ //#region src/scopes.ts
76
+ /** Shared by the `keyword-definition` family and the structural rules that capture its keywords. */
77
+ const DEFINITION_SCOPE = "storage.type.stepcode";
78
+ /** Word families in the order their rules appear in `patterns` (spec §4.4, §5). */
79
+ const WORD_FAMILIES = [
80
+ {
81
+ id: "keyword-control",
82
+ section: "keywords",
83
+ keys: [
84
+ "if",
85
+ "then",
86
+ "elseIf",
87
+ "else",
88
+ "endIf",
89
+ "switch",
90
+ "case",
91
+ "otherwise",
92
+ "endSwitch",
93
+ "while",
94
+ "do",
95
+ "endWhile",
96
+ "for",
97
+ "to",
98
+ "step",
99
+ "endFor",
100
+ "repeat",
101
+ "until",
102
+ "break",
103
+ "continue",
104
+ "return"
105
+ ],
106
+ scope: "keyword.control.stepcode"
107
+ },
108
+ {
109
+ id: "keyword-definition",
110
+ section: "keywords",
111
+ keys: [
112
+ "program",
113
+ "endProgram",
114
+ "define",
115
+ "as",
116
+ "constant",
117
+ "dimension",
118
+ "procedure",
119
+ "endProcedure",
120
+ "function",
121
+ "endFunction"
122
+ ],
123
+ scope: DEFINITION_SCOPE
124
+ },
125
+ {
126
+ id: "keyword-modifier",
127
+ section: "keywords",
128
+ keys: ["byRef", "byValue"],
129
+ scope: "storage.modifier.stepcode"
130
+ },
131
+ {
132
+ id: "keyword-io",
133
+ section: "keywords",
134
+ keys: [
135
+ "write",
136
+ "writeNoNewline",
137
+ "read",
138
+ "clearScreen",
139
+ "wait",
140
+ "waitKey"
141
+ ],
142
+ scope: "keyword.other.io.stepcode"
143
+ },
144
+ {
145
+ id: "keyword-operator",
146
+ section: "keywords",
147
+ keys: [
148
+ "and",
149
+ "or",
150
+ "not",
151
+ "mod",
152
+ "div"
153
+ ],
154
+ scope: "keyword.operator.word.stepcode"
155
+ },
156
+ {
157
+ id: "boolean",
158
+ section: "keywords",
159
+ keys: ["true", "false"],
160
+ scope: "constant.language.boolean.stepcode"
161
+ },
162
+ {
163
+ id: "type",
164
+ section: "types",
165
+ keys: TYPE_KEYS,
166
+ scope: "support.type.primitive.stepcode"
167
+ },
168
+ {
169
+ id: "builtin",
170
+ section: "builtins",
171
+ keys: BUILTIN_KEYS,
172
+ scope: "support.function.builtin.stepcode"
173
+ }
174
+ ];
175
+ const OPERATOR_FAMILIES = [
176
+ {
177
+ id: "operator-assignment",
178
+ keys: ["assign"],
179
+ scope: "keyword.operator.assignment.stepcode"
180
+ },
181
+ {
182
+ id: "operator-comparison",
183
+ keys: [
184
+ "equal",
185
+ "notEqual",
186
+ "lt",
187
+ "le",
188
+ "gt",
189
+ "ge"
190
+ ],
191
+ scope: "keyword.operator.comparison.stepcode"
192
+ },
193
+ {
194
+ id: "operator-arithmetic",
195
+ keys: [
196
+ "plus",
197
+ "minus",
198
+ "times",
199
+ "divide",
200
+ "power"
201
+ ],
202
+ scope: "keyword.operator.arithmetic.stepcode"
203
+ }
204
+ ];
205
+ const SCOPES = {
206
+ comment: "comment.line.stepcode",
207
+ stringDouble: "string.quoted.double.stepcode",
208
+ stringSingle: "string.quoted.single.stepcode",
209
+ integer: "constant.numeric.integer.stepcode",
210
+ real: "constant.numeric.real.stepcode",
211
+ parens: "punctuation.section.parens.stepcode",
212
+ brackets: "punctuation.section.brackets.stepcode",
213
+ separator: "punctuation.separator.stepcode",
214
+ terminator: "punctuation.terminator.stepcode",
215
+ subprogramName: "entity.name.function.stepcode",
216
+ callName: "entity.name.function.call.stepcode",
217
+ definedVariable: "variable.other.definition.stepcode",
218
+ identifier: "variable.other.stepcode",
219
+ assignment: "keyword.operator.assignment.stepcode"
220
+ };
221
+ /** Repository keys in the order they are tried (spec §4.4). Missing keys are skipped. */
222
+ const PATTERN_ORDER = [
223
+ "comment",
224
+ "string",
225
+ "subprogram",
226
+ "program",
227
+ "definition",
228
+ "multiword",
229
+ "keyword-control",
230
+ "keyword-definition",
231
+ "keyword-modifier",
232
+ "keyword-io",
233
+ "keyword-operator",
234
+ "boolean",
235
+ "type",
236
+ "builtin",
237
+ "number",
238
+ "call",
239
+ "operator-assignment",
240
+ "operator-comparison",
241
+ "operator-arithmetic",
242
+ "punctuation",
243
+ "identifier"
244
+ ];
245
+ //#endregion
246
+ //#region src/generate.ts
247
+ function wordOptions(profile) {
248
+ return {
249
+ caseSensitive: profile.options.caseSensitive,
250
+ foldAccents: profile.options.foldAccents
251
+ };
252
+ }
253
+ /** Letter-bearing spellings of some keys; symbols such as `&` belong to the operator rules. */
254
+ function spellingsOf(profile, section, keys) {
255
+ const table = profile[section];
256
+ return keys.flatMap((key) => table[key] ?? []).filter(hasLetter);
257
+ }
258
+ function wordFamilyRules(profile, repository) {
259
+ const options = wordOptions(profile);
260
+ const groups = [];
261
+ const captures = {};
262
+ for (const family of WORD_FAMILIES) {
263
+ const spellings = spellingsOf(profile, family.section, family.keys);
264
+ const multi = spellings.filter(isMultiWord);
265
+ const single = spellings.filter((spelling) => !isMultiWord(spelling));
266
+ if (multi.length > 0) {
267
+ groups.push(`(${wordAlternation(multi, options)})`);
268
+ captures[String(groups.length)] = { name: family.scope };
269
+ }
270
+ if (single.length > 0) repository[family.id] = {
271
+ name: family.scope,
272
+ match: wordRule(single, options)
273
+ };
274
+ }
275
+ if (groups.length > 0) repository.multiword = {
276
+ match: `${caseFlag(options)}${WORD_START}(?:${groups.join("|")})${WORD_END}`,
277
+ captures
278
+ };
279
+ }
280
+ /** Letterless keyword spellings (`&`, `%`) are symbols and read as arithmetic operators. */
281
+ function symbolSpellingsOf(profile) {
282
+ return WORD_FAMILIES.filter((family) => family.section === "keywords").flatMap((family) => family.keys.flatMap((key) => profile.keywords[key] ?? [])).filter((spelling) => !hasLetter(spelling));
283
+ }
284
+ function symbolRules(profile, repository) {
285
+ const comment = profile.operators.comment;
286
+ if (comment.length > 0) repository.comment = {
287
+ name: SCOPES.comment,
288
+ match: `(?:${symbolAlternation(comment)}).*$`
289
+ };
290
+ repository.string = { patterns: [{
291
+ name: SCOPES.stringDouble,
292
+ match: "\"[^\"]*(?:\"|$)"
293
+ }, {
294
+ name: SCOPES.stringSingle,
295
+ match: "'[^']*(?:'|$)"
296
+ }] };
297
+ repository.number = { patterns: [{
298
+ name: SCOPES.real,
299
+ match: `${WORD_START}\\d+\\.\\d+${WORD_END}`
300
+ }, {
301
+ name: SCOPES.integer,
302
+ match: `${WORD_START}\\d+${WORD_END}`
303
+ }] };
304
+ for (const family of OPERATOR_FAMILIES) {
305
+ const spellings = family.keys.flatMap((key) => profile.operators[key]);
306
+ if (family.id === "operator-arithmetic") spellings.push(...symbolSpellingsOf(profile));
307
+ if (spellings.length === 0) continue;
308
+ const letters = spellings.filter(hasLetter);
309
+ const symbols = spellings.filter((spelling) => !hasLetter(spelling));
310
+ const letterMatch = `${WORD_START}(?:${wordAlternation(letters, {
311
+ caseSensitive: true,
312
+ foldAccents: false
313
+ })})${WORD_END}`;
314
+ if (letters.length > 0 && symbols.length > 0) repository[family.id] = { patterns: [{
315
+ name: family.scope,
316
+ match: letterMatch
317
+ }, {
318
+ name: family.scope,
319
+ match: symbolAlternation(symbols)
320
+ }] };
321
+ else if (letters.length > 0) repository[family.id] = {
322
+ name: family.scope,
323
+ match: letterMatch
324
+ };
325
+ else repository[family.id] = {
326
+ name: family.scope,
327
+ match: symbolAlternation(symbols)
328
+ };
329
+ }
330
+ repository.punctuation = { patterns: [
331
+ {
332
+ name: SCOPES.parens,
333
+ match: "[()]"
334
+ },
335
+ {
336
+ name: SCOPES.brackets,
337
+ match: "[\\[\\]]"
338
+ },
339
+ {
340
+ name: SCOPES.separator,
341
+ match: "[,:]"
342
+ },
343
+ {
344
+ name: SCOPES.terminator,
345
+ match: ";"
346
+ }
347
+ ] };
348
+ repository.identifier = {
349
+ name: SCOPES.identifier,
350
+ match: `${WORD_START}${IDENT}${WORD_END}`
351
+ };
352
+ }
353
+ function structureRules(profile, repository) {
354
+ const options = wordOptions(profile);
355
+ const keyword = (keys) => spellingsOf(profile, "keywords", keys);
356
+ const head = (spellings) => `${caseFlag(options)}${WORD_START}(${wordAlternation(spellings, options)})${WORD_END}${WORD_GAP}`;
357
+ const subprogram = keyword(["function", "procedure"]);
358
+ if (subprogram.length > 0) {
359
+ const assign = profile.operators.assign;
360
+ if (assign.length > 0) repository.subprogram = {
361
+ match: `${head(subprogram)}(?:(${IDENT})[ \\t]*(${symbolAlternation(assign)})[ \\t]*)?(${IDENT})${WORD_END}`,
362
+ captures: {
363
+ "1": { name: DEFINITION_SCOPE },
364
+ "2": { name: SCOPES.definedVariable },
365
+ "3": { name: SCOPES.assignment },
366
+ "4": { name: SCOPES.subprogramName }
367
+ }
368
+ };
369
+ else repository.subprogram = {
370
+ match: `${head(subprogram)}(${IDENT})${WORD_END}`,
371
+ captures: {
372
+ "1": { name: DEFINITION_SCOPE },
373
+ "2": { name: SCOPES.subprogramName }
374
+ }
375
+ };
376
+ }
377
+ const program = keyword(["program"]);
378
+ if (program.length > 0) repository.program = {
379
+ match: `${head(program)}(${IDENT})${WORD_END}`,
380
+ captures: {
381
+ "1": { name: DEFINITION_SCOPE },
382
+ "2": { name: SCOPES.subprogramName }
383
+ }
384
+ };
385
+ const define = keyword(["define"]);
386
+ if (define.length > 0) repository.definition = {
387
+ match: `${head(define)}((?:${IDENT}[ \\t]*,[ \\t]*)*${IDENT})${WORD_END}`,
388
+ captures: {
389
+ "1": { name: DEFINITION_SCOPE },
390
+ "2": { patterns: [{
391
+ name: SCOPES.definedVariable,
392
+ match: IDENT
393
+ }, {
394
+ name: SCOPES.separator,
395
+ match: ","
396
+ }] }
397
+ }
398
+ };
399
+ repository.call = {
400
+ match: `${WORD_START}(${IDENT})(?=[ \\t]*\\()`,
401
+ captures: { "1": { name: SCOPES.callName } }
402
+ };
403
+ }
404
+ /** Builds the full grammar (word, symbol and structural rules) for one resolved profile. */
405
+ function generateGrammar(profile, options) {
406
+ const repository = {};
407
+ wordFamilyRules(profile, repository);
408
+ symbolRules(profile, repository);
409
+ structureRules(profile, repository);
410
+ const grammar = {
411
+ name: options.name,
412
+ scopeName: options.scopeName,
413
+ patterns: PATTERN_ORDER.filter((id) => id in repository).map((id) => ({ include: `#${id}` })),
414
+ repository
415
+ };
416
+ if (options.displayName !== void 0) grammar.displayName = options.displayName;
417
+ if (options.aliases !== void 0) grammar.aliases = [...options.aliases];
418
+ return grammar;
419
+ }
420
+ //#endregion
421
+ //#region src/index.ts
422
+ const packageName = "@stepcode/textmate";
423
+ /** The `es` profile: fence ```stepcode, scope `source.stepcode`. */
424
+ const stepcode = generateGrammar(profiles.es, {
425
+ name: "stepcode",
426
+ scopeName: "source.stepcode",
427
+ displayName: "StepCode"
428
+ });
429
+ /** The `en` profile: fence ```stepcode-en, scope `source.stepcode.en`. */
430
+ const stepcodeEn = generateGrammar(profiles.en, {
431
+ name: "stepcode-en",
432
+ scopeName: "source.stepcode.en",
433
+ displayName: "StepCode (English)"
434
+ });
435
+ /** The `pseint` profile: fence ```stepcode-pseint, scope `source.stepcode.pseint`. */
436
+ const stepcodePseint = generateGrammar(profiles.pseint, {
437
+ name: "stepcode-pseint",
438
+ scopeName: "source.stepcode.pseint",
439
+ displayName: "StepCode (PSeInt)"
440
+ });
441
+ /** All three, for `createHighlighter({ langs: [...grammars] })`. */
442
+ const grammars = [
443
+ stepcode,
444
+ stepcodeEn,
445
+ stepcodePseint
446
+ ];
447
+ //#endregion
448
+ export { generateGrammar, grammars, packageName, stepcode, stepcodeEn, stepcodePseint };
@@ -0,0 +1,221 @@
1
+ {
2
+ "name": "stepcode-en",
3
+ "scopeName": "source.stepcode.en",
4
+ "patterns": [
5
+ {
6
+ "include": "#comment"
7
+ },
8
+ {
9
+ "include": "#string"
10
+ },
11
+ {
12
+ "include": "#subprogram"
13
+ },
14
+ {
15
+ "include": "#program"
16
+ },
17
+ {
18
+ "include": "#definition"
19
+ },
20
+ {
21
+ "include": "#keyword-control"
22
+ },
23
+ {
24
+ "include": "#keyword-definition"
25
+ },
26
+ {
27
+ "include": "#keyword-modifier"
28
+ },
29
+ {
30
+ "include": "#keyword-io"
31
+ },
32
+ {
33
+ "include": "#keyword-operator"
34
+ },
35
+ {
36
+ "include": "#boolean"
37
+ },
38
+ {
39
+ "include": "#type"
40
+ },
41
+ {
42
+ "include": "#builtin"
43
+ },
44
+ {
45
+ "include": "#number"
46
+ },
47
+ {
48
+ "include": "#call"
49
+ },
50
+ {
51
+ "include": "#operator-assignment"
52
+ },
53
+ {
54
+ "include": "#operator-comparison"
55
+ },
56
+ {
57
+ "include": "#operator-arithmetic"
58
+ },
59
+ {
60
+ "include": "#punctuation"
61
+ },
62
+ {
63
+ "include": "#identifier"
64
+ }
65
+ ],
66
+ "repository": {
67
+ "keyword-control": {
68
+ "name": "keyword.control.stepcode",
69
+ "match": "(?i)(?<![\\p{L}\\p{N}_])(?:[EÈÉÊË]ndSw[iìíîï]t[cç]h|[OÒÓÔÕÖ]th[eèéêë]rw[iìíîï]s[eèéêë]|[CÇ][oòóôõö]nt[iìíîï]n[uùúûü][eèéêë]|[EÈÉÊË]ndWh[iìíîï]l[eèéêë]|[EÈÉÊË]ls[eèéêë][IÌÍÎÏ]f|[EÈÉÊË]ndF[oòóôõö]r|R[eèéêë]p[eèéêë][aàáâãä]t|R[eèéêë]t[uùúûü]rn|Sw[iìíîï]t[cç]h|Br[eèéêë][aàáâãä]k|[EÈÉÊË]nd[IÌÍÎÏ]f|[UÙÚÛÜ]nt[iìíîï]l|Wh[iìíîï]l[eèéêë]|[EÈÉÊË]ls[eèéêë]|St[eèéêë]p|Th[eèéêë]n|F[oòóôõö]r|D[oòóôõö]|[IÌÍÎÏ]f|T[oòóôõö])(?![\\p{L}\\p{N}_])"
70
+ },
71
+ "keyword-definition": {
72
+ "name": "storage.type.stepcode",
73
+ "match": "(?i)(?<![\\p{L}\\p{N}_])(?:[EÈÉÊË]ndPr[oòóôõö][cç][eèéêë]d[uùúûü]r[eèéêë]|[EÈÉÊË]ndF[uùúûü]n[cç]t[iìíîï][oòóôõö]n|[EÈÉÊË]ndPr[oòóôõö]gr[aàáâãä]m|D[iìíîï]m[eèéêë]ns[iìíîï][oòóôõö]n|Pr[oòóôõö][cç][eèéêë]d[uùúûü]r[eèéêë]|[CÇ][oòóôõö]nst[aàáâãä]nt|F[uùúûü]n[cç]t[iìíîï][oòóôõö]n|Pr[oòóôõö]gr[aàáâãä]m|D[eèéêë]f[iìíîï]n[eèéêë]|[AÀÁÂÃÄ]s)(?![\\p{L}\\p{N}_])"
74
+ },
75
+ "keyword-modifier": {
76
+ "name": "storage.modifier.stepcode",
77
+ "match": "(?i)(?<![\\p{L}\\p{N}_])(?:B[yýÿ]V[aàáâãä]l[uùúûü][eèéêë]|B[yýÿ]R[eèéêë]f)(?![\\p{L}\\p{N}_])"
78
+ },
79
+ "keyword-io": {
80
+ "name": "keyword.other.io.stepcode",
81
+ "match": "(?i)(?<![\\p{L}\\p{N}_])(?:Wr[iìíîï]t[eèéêë]N[oòóôõö]N[eèéêë]wl[iìíîï]n[eèéêë]|[CÇ]l[eèéêë][aàáâãä]rS[cç]r[eèéêë][eèéêë]n|W[aàáâãä][iìíîï]tK[eèéêë][yýÿ]|Pr[iìíîï]nt|Wr[iìíîï]t[eèéêë]|R[eèéêë][aàáâãä]d|W[aàáâãä][iìíîï]t)(?![\\p{L}\\p{N}_])"
82
+ },
83
+ "keyword-operator": {
84
+ "name": "keyword.operator.word.stepcode",
85
+ "match": "(?i)(?<![\\p{L}\\p{N}_])(?:[AÀÁÂÃÄ]nd|D[iìíîï]v|M[oòóôõö]d|N[oòóôõö]t|[OÒÓÔÕÖ]r)(?![\\p{L}\\p{N}_])"
86
+ },
87
+ "boolean": {
88
+ "name": "constant.language.boolean.stepcode",
89
+ "match": "(?i)(?<![\\p{L}\\p{N}_])(?:F[aàáâãä]ls[eèéêë]|Tr[uùúûü][eèéêë])(?![\\p{L}\\p{N}_])"
90
+ },
91
+ "type": {
92
+ "name": "support.type.primitive.stepcode",
93
+ "match": "(?i)(?<![\\p{L}\\p{N}_])(?:B[oòóôõö][oòóôõö]l[eèéêë][aàáâãä]n|[IÌÍÎÏ]nt[eèéêë]g[eèéêë]r|Str[iìíîï]ng|[CÇ]h[aàáâãä]r|R[eèéêë][aàáâãä]l|T[eèéêë]xt)(?![\\p{L}\\p{N}_])"
94
+ },
95
+ "builtin": {
96
+ "name": "support.function.builtin.stepcode",
97
+ "match": "(?i)(?<![\\p{L}\\p{N}_])(?:R[aàáâãä]nd[oòóôõö]mB[eèéêë]tw[eèéêë][eèéêë]n|S[uùúûü]bstr[iìíîï]ng|T[oòóôõö]N[uùúûü]mb[eèéêë]r|[CÇ][oòóôõö]n[cç][aàáâãä]t|L[eèéêë]ngth|R[aàáâãä]nd[oòóôõö]m|T[oòóôõö]T[eèéêë]xt|L[oòóôõö]w[eèéêë]r|R[oòóôõö][uùúûü]nd|Tr[uùúûü]n[cç]|[UÙÚÛÜ]pp[eèéêë]r|[AÀÁÂÃÄ][CÇ][oòóôõö]s|[AÀÁÂÃÄ]S[iìíîï]n|[AÀÁÂÃÄ]T[aàáâãä]n|Sqrt|[AÀÁÂÃÄ]bs|[CÇ][oòóôõö]s|[EÈÉÊË]xp|S[iìíîï]n|T[aàáâãä]n|Ln|P[IÌÍÎÏ])(?![\\p{L}\\p{N}_])"
98
+ },
99
+ "comment": {
100
+ "name": "comment.line.stepcode",
101
+ "match": "(?:\\/\\/).*$"
102
+ },
103
+ "string": {
104
+ "patterns": [
105
+ {
106
+ "name": "string.quoted.double.stepcode",
107
+ "match": "\"[^\"]*(?:\"|$)"
108
+ },
109
+ {
110
+ "name": "string.quoted.single.stepcode",
111
+ "match": "'[^']*(?:'|$)"
112
+ }
113
+ ]
114
+ },
115
+ "number": {
116
+ "patterns": [
117
+ {
118
+ "name": "constant.numeric.real.stepcode",
119
+ "match": "(?<![\\p{L}\\p{N}_])\\d+\\.\\d+(?![\\p{L}\\p{N}_])"
120
+ },
121
+ {
122
+ "name": "constant.numeric.integer.stepcode",
123
+ "match": "(?<![\\p{L}\\p{N}_])\\d+(?![\\p{L}\\p{N}_])"
124
+ }
125
+ ]
126
+ },
127
+ "operator-assignment": {
128
+ "name": "keyword.operator.assignment.stepcode",
129
+ "match": "<-|←"
130
+ },
131
+ "operator-comparison": {
132
+ "name": "keyword.operator.comparison.stepcode",
133
+ "match": "!=|<=|<>|>=|<|=|>|≠|≤|≥"
134
+ },
135
+ "operator-arithmetic": {
136
+ "name": "keyword.operator.arithmetic.stepcode",
137
+ "match": "\\*\\*|%|&|\\*|\\+|-|\\/|\\^|\\||~"
138
+ },
139
+ "punctuation": {
140
+ "patterns": [
141
+ {
142
+ "name": "punctuation.section.parens.stepcode",
143
+ "match": "[()]"
144
+ },
145
+ {
146
+ "name": "punctuation.section.brackets.stepcode",
147
+ "match": "[\\[\\]]"
148
+ },
149
+ {
150
+ "name": "punctuation.separator.stepcode",
151
+ "match": "[,:]"
152
+ },
153
+ {
154
+ "name": "punctuation.terminator.stepcode",
155
+ "match": ";"
156
+ }
157
+ ]
158
+ },
159
+ "identifier": {
160
+ "name": "variable.other.stepcode",
161
+ "match": "(?<![\\p{L}\\p{N}_])[\\p{L}_][\\p{L}\\p{N}_]*(?![\\p{L}\\p{N}_])"
162
+ },
163
+ "subprogram": {
164
+ "match": "(?i)(?<![\\p{L}\\p{N}_])(Pr[oòóôõö][cç][eèéêë]d[uùúûü]r[eèéêë]|F[uùúûü]n[cç]t[iìíîï][oòóôõö]n)(?![\\p{L}\\p{N}_])[ \\t]+(?:([\\p{L}_][\\p{L}\\p{N}_]*)[ \\t]*(<-|←)[ \\t]*)?([\\p{L}_][\\p{L}\\p{N}_]*)(?![\\p{L}\\p{N}_])",
165
+ "captures": {
166
+ "1": {
167
+ "name": "storage.type.stepcode"
168
+ },
169
+ "2": {
170
+ "name": "variable.other.definition.stepcode"
171
+ },
172
+ "3": {
173
+ "name": "keyword.operator.assignment.stepcode"
174
+ },
175
+ "4": {
176
+ "name": "entity.name.function.stepcode"
177
+ }
178
+ }
179
+ },
180
+ "program": {
181
+ "match": "(?i)(?<![\\p{L}\\p{N}_])(Pr[oòóôõö]gr[aàáâãä]m)(?![\\p{L}\\p{N}_])[ \\t]+([\\p{L}_][\\p{L}\\p{N}_]*)(?![\\p{L}\\p{N}_])",
182
+ "captures": {
183
+ "1": {
184
+ "name": "storage.type.stepcode"
185
+ },
186
+ "2": {
187
+ "name": "entity.name.function.stepcode"
188
+ }
189
+ }
190
+ },
191
+ "definition": {
192
+ "match": "(?i)(?<![\\p{L}\\p{N}_])(D[eèéêë]f[iìíîï]n[eèéêë])(?![\\p{L}\\p{N}_])[ \\t]+((?:[\\p{L}_][\\p{L}\\p{N}_]*[ \\t]*,[ \\t]*)*[\\p{L}_][\\p{L}\\p{N}_]*)(?![\\p{L}\\p{N}_])",
193
+ "captures": {
194
+ "1": {
195
+ "name": "storage.type.stepcode"
196
+ },
197
+ "2": {
198
+ "patterns": [
199
+ {
200
+ "name": "variable.other.definition.stepcode",
201
+ "match": "[\\p{L}_][\\p{L}\\p{N}_]*"
202
+ },
203
+ {
204
+ "name": "punctuation.separator.stepcode",
205
+ "match": ","
206
+ }
207
+ ]
208
+ }
209
+ }
210
+ },
211
+ "call": {
212
+ "match": "(?<![\\p{L}\\p{N}_])([\\p{L}_][\\p{L}\\p{N}_]*)(?=[ \\t]*\\()",
213
+ "captures": {
214
+ "1": {
215
+ "name": "entity.name.function.call.stepcode"
216
+ }
217
+ }
218
+ }
219
+ },
220
+ "displayName": "StepCode (English)"
221
+ }
@@ -0,0 +1,231 @@
1
+ {
2
+ "name": "stepcode-pseint",
3
+ "scopeName": "source.stepcode.pseint",
4
+ "patterns": [
5
+ {
6
+ "include": "#comment"
7
+ },
8
+ {
9
+ "include": "#string"
10
+ },
11
+ {
12
+ "include": "#subprogram"
13
+ },
14
+ {
15
+ "include": "#program"
16
+ },
17
+ {
18
+ "include": "#definition"
19
+ },
20
+ {
21
+ "include": "#multiword"
22
+ },
23
+ {
24
+ "include": "#keyword-control"
25
+ },
26
+ {
27
+ "include": "#keyword-definition"
28
+ },
29
+ {
30
+ "include": "#keyword-io"
31
+ },
32
+ {
33
+ "include": "#keyword-operator"
34
+ },
35
+ {
36
+ "include": "#boolean"
37
+ },
38
+ {
39
+ "include": "#type"
40
+ },
41
+ {
42
+ "include": "#builtin"
43
+ },
44
+ {
45
+ "include": "#number"
46
+ },
47
+ {
48
+ "include": "#call"
49
+ },
50
+ {
51
+ "include": "#operator-assignment"
52
+ },
53
+ {
54
+ "include": "#operator-comparison"
55
+ },
56
+ {
57
+ "include": "#operator-arithmetic"
58
+ },
59
+ {
60
+ "include": "#punctuation"
61
+ },
62
+ {
63
+ "include": "#identifier"
64
+ }
65
+ ],
66
+ "repository": {
67
+ "keyword-control": {
68
+ "name": "keyword.control.stepcode",
69
+ "match": "(?i)(?<![\\p{L}\\p{N}_])(?:F[iìíîï]nM[iìíîï][eèéêë]ntr[aàáâãä]s|[CÇ][oòóôõö]nt[iìíîï]n[uùúûü][aàáâãä]r|[EÈÉÊË]nt[oòóôõö]n[cç][eèéêë]s|F[iìíîï]nS[eèéêë]g[uùúûü]n|M[iìíîï][eèéêë]ntr[aàáâãä]s|R[eèéêë]t[oòóôõö]rn[aàáâãä]r|F[iìíîï]nP[aàáâãä]r[aàáâãä]|R[eèéêë]p[eèéêë]t[iìíîï]r|R[oòóôõö]mp[eèéêë]r|F[iìíîï]nS[iìíîï]|H[aàáâãä][cç][eèéêë]r|H[aàáâãä]st[aàáâãä]|S[eèéêë]g[uùúûü]n|P[aàáâãä]r[aàáâãä]|S[iìíîï]n[oòóôõö]|S[iìíîï])(?![\\p{L}\\p{N}_])"
70
+ },
71
+ "keyword-definition": {
72
+ "name": "storage.type.stepcode",
73
+ "match": "(?i)(?<![\\p{L}\\p{N}_])(?:F[iìíîï]nPr[oòóôõö][cç][eèéêë]d[iìíîï]m[iìíîï][eèéêë]nt[oòóôõö]|F[iìíîï]nS[uùúûü]b[AÀÁÂÃÄ]lg[oòóôõö]r[iìíîï]tm[oòóôõö]|F[iìíîï]nS[uùúûü]bPr[oòóôõö][cç][eèéêë]s[oòóôõö]|Pr[oòóôõö][cç][eèéêë]d[iìíîï]m[iìíîï][eèéêë]nt[oòóôõö]|F[iìíîï]n[AÀÁÂÃÄ]lg[oòóôõö]r[iìíîï]tm[oòóôõö]|S[uùúûü]b[AÀÁÂÃÄ]lg[oòóôõö]r[iìíîï]tm[oòóôõö]|F[iìíîï]nF[uùúûü]n[cç][iìíîï][oòóôõö]n|F[iìíîï]nPr[oòóôõö][cç][eèéêë]s[oòóôõö]|S[uùúûü]bPr[oòóôõö][cç][eèéêë]s[oòóôõö]|[AÀÁÂÃÄ]lg[oòóôõö]r[iìíîï]tm[oòóôõö]|[CÇ][oòóôõö]nst[aàáâãä]nt[eèéêë]|D[iìíîï]m[eèéêë]ns[iìíîï][oòóôõö]n|D[eèéêë]f[iìíîï]n[iìíîï]r|F[uùúûü]n[cç][iìíîï][oòóôõö]n|Pr[oòóôõö][cç][eèéêë]s[oòóôõö]|[CÇ][oòóôõö]m[oòóôõö])(?![\\p{L}\\p{N}_])"
74
+ },
75
+ "keyword-io": {
76
+ "name": "keyword.other.io.stepcode",
77
+ "match": "(?i)(?<![\\p{L}\\p{N}_])(?:[EÈÉÊË]s[cç]r[iìíîï]b[iìíîï]r|[IÌÍÎÏ]mpr[iìíîï]m[iìíîï]r|[EÈÉÊË]sp[eèéêë]r[aàáâãä]r|M[oòóôõö]str[aàáâãä]r|L[eèéêë][eèéêë]r)(?![\\p{L}\\p{N}_])"
78
+ },
79
+ "keyword-operator": {
80
+ "name": "keyword.operator.word.stepcode",
81
+ "match": "(?i)(?<![\\p{L}\\p{N}_])(?:D[IÌÍÎÏ]V|M[OÒÓÔÕÖ]D|N[oòóôõö]|[OÒÓÔÕÖ]|[YÝŸ])(?![\\p{L}\\p{N}_])"
82
+ },
83
+ "boolean": {
84
+ "name": "constant.language.boolean.stepcode",
85
+ "match": "(?i)(?<![\\p{L}\\p{N}_])(?:V[eèéêë]rd[aàáâãä]d[eèéêë]r[oòóôõö]|F[aàáâãä]ls[oòóôõö])(?![\\p{L}\\p{N}_])"
86
+ },
87
+ "type": {
88
+ "name": "support.type.primitive.stepcode",
89
+ "match": "(?i)(?<![\\p{L}\\p{N}_])(?:[CÇ][aàáâãä]r[aàáâãä][cç]t[eèéêë]r[eèéêë]s|[CÇ][aàáâãä]r[aàáâãä][cç]t[eèéêë]r|[CÇ][aàáâãä]d[eèéêë]n[aàáâãä]|[EÈÉÊË]nt[eèéêë]r[oòóôõö]|L[oòóôõö]g[iìíîï][cç][oòóôõö]|T[eèéêë]xt[oòóôõö]|R[eèéêë][aàáâãä]l)(?![\\p{L}\\p{N}_])"
90
+ },
91
+ "builtin": {
92
+ "name": "support.function.builtin.stepcode",
93
+ "match": "(?i)(?<![\\p{L}\\p{N}_])(?:[CÇ][oòóôõö]nv[eèéêë]rt[iìíîï]r[AÀÁÂÃÄ][CÇ][aàáâãä]d[eèéêë]n[aàáâãä]|[CÇ][oòóôõö]nv[eèéêë]rt[iìíîï]r[AÀÁÂÃÄ]N[uùúûü]m[eèéêë]r[oòóôõö]|[CÇ][oòóôõö]nv[eèéêë]rt[iìíîï]r[AÀÁÂÃÄ]T[eèéêë]xt[oòóôõö]|[CÇ][oòóôõö]n[cç][aàáâãä]t[eèéêë]n[aàáâãä]r|M[aàáâãä][yýÿ][uùúûü]s[cç][uùúûü]l[aàáâãä]s|M[iìíîï]n[uùúûü]s[cç][uùúûü]l[aàáâãä]s|[AÀÁÂÃÄ]l[eèéêë][aàáâãä]t[oòóôõö]r[iìíîï][oòóôõö]|R[eèéêë]d[oòóôõö]nd[eèéêë][aàáâãä]r|S[uùúûü]b[cç][aàáâãä]d[eèéêë]n[aàáâãä]|L[oòóôõö]ng[iìíîï]t[uùúûü]d|Tr[uùúûü]n[cç][aàáâãä]r|R[eèéêë]d[oòóôõö]n|Tr[uùúûü]n[cç]|[AÀÁÂÃÄ][CÇ][oòóôõö]s|[AÀÁÂÃÄ]S[eèéêë]n|[AÀÁÂÃÄ]T[aàáâãä]n|[AÀÁÂÃÄ]z[aàáâãä]r|R[aàáâãä][iìíîï]z|[AÀÁÂÃÄ]bs|[CÇ][oòóôõö]s|[EÈÉÊË]xp|S[eèéêë]n|T[aàáâãä]n|Ln|P[IÌÍÎÏ]|R[CÇ])(?![\\p{L}\\p{N}_])"
94
+ },
95
+ "multiword": {
96
+ "match": "(?i)(?<![\\p{L}\\p{N}_])(?:(D[eèéêë][ \\t]+[OÒÓÔÕÖ]tr[oòóôõö][ \\t]+M[oòóôõö]d[oòóôõö]|M[iìíîï][eèéêë]ntr[aàáâãä]s[ \\t]+Q[uùúûü][eèéêë]|H[aàáâãä]st[aàáâãä][ \\t]+Q[uùúûü][eèéêë]|[CÇ][oòóôõö]n[ \\t]+P[aàáâãä]s[oòóôõö]|S[iìíîï]n[oòóôõö][ \\t]+S[iìíîï])|(P[oòóôõö]r[ \\t]+R[eèéêë]f[eèéêë]r[eèéêë]n[cç][iìíîï][aàáâãä]|P[oòóôõö]r[ \\t]+V[aàáâãä]l[oòóôõö]r)|([EÈÉÊË]s[cç]r[iìíîï]b[iìíîï]r[ \\t]+S[iìíîï]n[ \\t]+S[aàáâãä]lt[aàáâãä]r|M[oòóôõö]str[aàáâãä]r[ \\t]+S[iìíîï]n[ \\t]+S[aàáâãä]lt[aàáâãä]r|L[iìíîï]mp[iìíîï][aàáâãä]r[ \\t]+P[aàáâãä]nt[aàáâãä]ll[aàáâãä]|B[oòóôõö]rr[aàáâãä]r[ \\t]+P[aàáâãä]nt[aàáâãä]ll[aàáâãä]|[EÈÉÊË]sp[eèéêë]r[aàáâãä]r[ \\t]+T[eèéêë][cç]l[aàáâãä]))(?![\\p{L}\\p{N}_])",
97
+ "captures": {
98
+ "1": {
99
+ "name": "keyword.control.stepcode"
100
+ },
101
+ "2": {
102
+ "name": "storage.modifier.stepcode"
103
+ },
104
+ "3": {
105
+ "name": "keyword.other.io.stepcode"
106
+ }
107
+ }
108
+ },
109
+ "comment": {
110
+ "name": "comment.line.stepcode",
111
+ "match": "(?:\\/\\/).*$"
112
+ },
113
+ "string": {
114
+ "patterns": [
115
+ {
116
+ "name": "string.quoted.double.stepcode",
117
+ "match": "\"[^\"]*(?:\"|$)"
118
+ },
119
+ {
120
+ "name": "string.quoted.single.stepcode",
121
+ "match": "'[^']*(?:'|$)"
122
+ }
123
+ ]
124
+ },
125
+ "number": {
126
+ "patterns": [
127
+ {
128
+ "name": "constant.numeric.real.stepcode",
129
+ "match": "(?<![\\p{L}\\p{N}_])\\d+\\.\\d+(?![\\p{L}\\p{N}_])"
130
+ },
131
+ {
132
+ "name": "constant.numeric.integer.stepcode",
133
+ "match": "(?<![\\p{L}\\p{N}_])\\d+(?![\\p{L}\\p{N}_])"
134
+ }
135
+ ]
136
+ },
137
+ "operator-assignment": {
138
+ "name": "keyword.operator.assignment.stepcode",
139
+ "match": "<-|←"
140
+ },
141
+ "operator-comparison": {
142
+ "name": "keyword.operator.comparison.stepcode",
143
+ "match": "!=|<=|<>|>=|<|=|>|≠|≤|≥"
144
+ },
145
+ "operator-arithmetic": {
146
+ "name": "keyword.operator.arithmetic.stepcode",
147
+ "match": "\\*\\*|%|&|\\*|\\+|-|\\/|\\^|\\||~"
148
+ },
149
+ "punctuation": {
150
+ "patterns": [
151
+ {
152
+ "name": "punctuation.section.parens.stepcode",
153
+ "match": "[()]"
154
+ },
155
+ {
156
+ "name": "punctuation.section.brackets.stepcode",
157
+ "match": "[\\[\\]]"
158
+ },
159
+ {
160
+ "name": "punctuation.separator.stepcode",
161
+ "match": "[,:]"
162
+ },
163
+ {
164
+ "name": "punctuation.terminator.stepcode",
165
+ "match": ";"
166
+ }
167
+ ]
168
+ },
169
+ "identifier": {
170
+ "name": "variable.other.stepcode",
171
+ "match": "(?<![\\p{L}\\p{N}_])[\\p{L}_][\\p{L}\\p{N}_]*(?![\\p{L}\\p{N}_])"
172
+ },
173
+ "subprogram": {
174
+ "match": "(?i)(?<![\\p{L}\\p{N}_])(Pr[oòóôõö][cç][eèéêë]d[iìíîï]m[iìíîï][eèéêë]nt[oòóôõö]|S[uùúûü]b[AÀÁÂÃÄ]lg[oòóôõö]r[iìíîï]tm[oòóôõö]|S[uùúûü]bPr[oòóôõö][cç][eèéêë]s[oòóôõö]|F[uùúûü]n[cç][iìíîï][oòóôõö]n)(?![\\p{L}\\p{N}_])[ \\t]+(?:([\\p{L}_][\\p{L}\\p{N}_]*)[ \\t]*(<-|←)[ \\t]*)?([\\p{L}_][\\p{L}\\p{N}_]*)(?![\\p{L}\\p{N}_])",
175
+ "captures": {
176
+ "1": {
177
+ "name": "storage.type.stepcode"
178
+ },
179
+ "2": {
180
+ "name": "variable.other.definition.stepcode"
181
+ },
182
+ "3": {
183
+ "name": "keyword.operator.assignment.stepcode"
184
+ },
185
+ "4": {
186
+ "name": "entity.name.function.stepcode"
187
+ }
188
+ }
189
+ },
190
+ "program": {
191
+ "match": "(?i)(?<![\\p{L}\\p{N}_])([AÀÁÂÃÄ]lg[oòóôõö]r[iìíîï]tm[oòóôõö]|Pr[oòóôõö][cç][eèéêë]s[oòóôõö])(?![\\p{L}\\p{N}_])[ \\t]+([\\p{L}_][\\p{L}\\p{N}_]*)(?![\\p{L}\\p{N}_])",
192
+ "captures": {
193
+ "1": {
194
+ "name": "storage.type.stepcode"
195
+ },
196
+ "2": {
197
+ "name": "entity.name.function.stepcode"
198
+ }
199
+ }
200
+ },
201
+ "definition": {
202
+ "match": "(?i)(?<![\\p{L}\\p{N}_])(D[eèéêë]f[iìíîï]n[iìíîï]r)(?![\\p{L}\\p{N}_])[ \\t]+((?:[\\p{L}_][\\p{L}\\p{N}_]*[ \\t]*,[ \\t]*)*[\\p{L}_][\\p{L}\\p{N}_]*)(?![\\p{L}\\p{N}_])",
203
+ "captures": {
204
+ "1": {
205
+ "name": "storage.type.stepcode"
206
+ },
207
+ "2": {
208
+ "patterns": [
209
+ {
210
+ "name": "variable.other.definition.stepcode",
211
+ "match": "[\\p{L}_][\\p{L}\\p{N}_]*"
212
+ },
213
+ {
214
+ "name": "punctuation.separator.stepcode",
215
+ "match": ","
216
+ }
217
+ ]
218
+ }
219
+ }
220
+ },
221
+ "call": {
222
+ "match": "(?<![\\p{L}\\p{N}_])([\\p{L}_][\\p{L}\\p{N}_]*)(?=[ \\t]*\\()",
223
+ "captures": {
224
+ "1": {
225
+ "name": "entity.name.function.call.stepcode"
226
+ }
227
+ }
228
+ }
229
+ },
230
+ "displayName": "StepCode (PSeInt)"
231
+ }
@@ -0,0 +1,231 @@
1
+ {
2
+ "name": "stepcode",
3
+ "scopeName": "source.stepcode",
4
+ "patterns": [
5
+ {
6
+ "include": "#comment"
7
+ },
8
+ {
9
+ "include": "#string"
10
+ },
11
+ {
12
+ "include": "#subprogram"
13
+ },
14
+ {
15
+ "include": "#program"
16
+ },
17
+ {
18
+ "include": "#definition"
19
+ },
20
+ {
21
+ "include": "#multiword"
22
+ },
23
+ {
24
+ "include": "#keyword-control"
25
+ },
26
+ {
27
+ "include": "#keyword-definition"
28
+ },
29
+ {
30
+ "include": "#keyword-io"
31
+ },
32
+ {
33
+ "include": "#keyword-operator"
34
+ },
35
+ {
36
+ "include": "#boolean"
37
+ },
38
+ {
39
+ "include": "#type"
40
+ },
41
+ {
42
+ "include": "#builtin"
43
+ },
44
+ {
45
+ "include": "#number"
46
+ },
47
+ {
48
+ "include": "#call"
49
+ },
50
+ {
51
+ "include": "#operator-assignment"
52
+ },
53
+ {
54
+ "include": "#operator-comparison"
55
+ },
56
+ {
57
+ "include": "#operator-arithmetic"
58
+ },
59
+ {
60
+ "include": "#punctuation"
61
+ },
62
+ {
63
+ "include": "#identifier"
64
+ }
65
+ ],
66
+ "repository": {
67
+ "keyword-control": {
68
+ "name": "keyword.control.stepcode",
69
+ "match": "(?i)(?<![\\p{L}\\p{N}_])(?:F[iìíîï]nM[iìíîï][eèéêë]ntr[aàáâãä]s|[CÇ][oòóôõö]nt[iìíîï]n[uùúûü][aàáâãä]r|[EÈÉÊË]nt[oòóôõö]n[cç][eèéêë]s|F[iìíîï]nS[eèéêë]g[uùúûü]n|M[iìíîï][eèéêë]ntr[aàáâãä]s|R[eèéêë]t[oòóôõö]rn[aàáâãä]r|F[iìíîï]nP[aàáâãä]r[aàáâãä]|R[eèéêë]p[eèéêë]t[iìíîï]r|R[oòóôõö]mp[eèéêë]r|F[iìíîï]nS[iìíîï]|H[aàáâãä][cç][eèéêë]r|H[aàáâãä]st[aàáâãä]|S[eèéêë]g[uùúûü]n|P[aàáâãä]r[aàáâãä]|S[iìíîï]n[oòóôõö]|S[iìíîï])(?![\\p{L}\\p{N}_])"
70
+ },
71
+ "keyword-definition": {
72
+ "name": "storage.type.stepcode",
73
+ "match": "(?i)(?<![\\p{L}\\p{N}_])(?:F[iìíîï]nPr[oòóôõö][cç][eèéêë]d[iìíîï]m[iìíîï][eèéêë]nt[oòóôõö]|F[iìíîï]nS[uùúûü]b[AÀÁÂÃÄ]lg[oòóôõö]r[iìíîï]tm[oòóôõö]|F[iìíîï]nS[uùúûü]bPr[oòóôõö][cç][eèéêë]s[oòóôõö]|Pr[oòóôõö][cç][eèéêë]d[iìíîï]m[iìíîï][eèéêë]nt[oòóôõö]|F[iìíîï]n[AÀÁÂÃÄ]lg[oòóôõö]r[iìíîï]tm[oòóôõö]|S[uùúûü]b[AÀÁÂÃÄ]lg[oòóôõö]r[iìíîï]tm[oòóôõö]|F[iìíîï]nF[uùúûü]n[cç][iìíîï][oòóôõö]n|F[iìíîï]nPr[oòóôõö][cç][eèéêë]s[oòóôõö]|S[uùúûü]bPr[oòóôõö][cç][eèéêë]s[oòóôõö]|[AÀÁÂÃÄ]lg[oòóôõö]r[iìíîï]tm[oòóôõö]|[CÇ][oòóôõö]nst[aàáâãä]nt[eèéêë]|D[iìíîï]m[eèéêë]ns[iìíîï][oòóôõö]n|D[eèéêë]f[iìíîï]n[iìíîï]r|F[uùúûü]n[cç][iìíîï][oòóôõö]n|Pr[oòóôõö][cç][eèéêë]s[oòóôõö]|[CÇ][oòóôõö]m[oòóôõö])(?![\\p{L}\\p{N}_])"
74
+ },
75
+ "keyword-io": {
76
+ "name": "keyword.other.io.stepcode",
77
+ "match": "(?i)(?<![\\p{L}\\p{N}_])(?:[EÈÉÊË]s[cç]r[iìíîï]b[iìíîï]r|[IÌÍÎÏ]mpr[iìíîï]m[iìíîï]r|[EÈÉÊË]sp[eèéêë]r[aàáâãä]r|M[oòóôõö]str[aàáâãä]r|L[eèéêë][eèéêë]r)(?![\\p{L}\\p{N}_])"
78
+ },
79
+ "keyword-operator": {
80
+ "name": "keyword.operator.word.stepcode",
81
+ "match": "(?i)(?<![\\p{L}\\p{N}_])(?:D[IÌÍÎÏ]V|M[OÒÓÔÕÖ]D|N[oòóôõö]|[OÒÓÔÕÖ]|[YÝŸ])(?![\\p{L}\\p{N}_])"
82
+ },
83
+ "boolean": {
84
+ "name": "constant.language.boolean.stepcode",
85
+ "match": "(?i)(?<![\\p{L}\\p{N}_])(?:V[eèéêë]rd[aàáâãä]d[eèéêë]r[oòóôõö]|F[aàáâãä]ls[oòóôõö])(?![\\p{L}\\p{N}_])"
86
+ },
87
+ "type": {
88
+ "name": "support.type.primitive.stepcode",
89
+ "match": "(?i)(?<![\\p{L}\\p{N}_])(?:[CÇ][aàáâãä]r[aàáâãä][cç]t[eèéêë]r[eèéêë]s|[CÇ][aàáâãä]r[aàáâãä][cç]t[eèéêë]r|[CÇ][aàáâãä]d[eèéêë]n[aàáâãä]|[EÈÉÊË]nt[eèéêë]r[oòóôõö]|L[oòóôõö]g[iìíîï][cç][oòóôõö]|T[eèéêë]xt[oòóôõö]|R[eèéêë][aàáâãä]l)(?![\\p{L}\\p{N}_])"
90
+ },
91
+ "builtin": {
92
+ "name": "support.function.builtin.stepcode",
93
+ "match": "(?i)(?<![\\p{L}\\p{N}_])(?:[CÇ][oòóôõö]nv[eèéêë]rt[iìíîï]r[AÀÁÂÃÄ][CÇ][aàáâãä]d[eèéêë]n[aàáâãä]|[CÇ][oòóôõö]nv[eèéêë]rt[iìíîï]r[AÀÁÂÃÄ]N[uùúûü]m[eèéêë]r[oòóôõö]|[CÇ][oòóôõö]nv[eèéêë]rt[iìíîï]r[AÀÁÂÃÄ]T[eèéêë]xt[oòóôõö]|[CÇ][oòóôõö]n[cç][aàáâãä]t[eèéêë]n[aàáâãä]r|M[aàáâãä][yýÿ][uùúûü]s[cç][uùúûü]l[aàáâãä]s|M[iìíîï]n[uùúûü]s[cç][uùúûü]l[aàáâãä]s|[AÀÁÂÃÄ]l[eèéêë][aàáâãä]t[oòóôõö]r[iìíîï][oòóôõö]|R[eèéêë]d[oòóôõö]nd[eèéêë][aàáâãä]r|S[uùúûü]b[cç][aàáâãä]d[eèéêë]n[aàáâãä]|L[oòóôõö]ng[iìíîï]t[uùúûü]d|Tr[uùúûü]n[cç][aàáâãä]r|R[eèéêë]d[oòóôõö]n|Tr[uùúûü]n[cç]|[AÀÁÂÃÄ][CÇ][oòóôõö]s|[AÀÁÂÃÄ]S[eèéêë]n|[AÀÁÂÃÄ]T[aàáâãä]n|[AÀÁÂÃÄ]z[aàáâãä]r|R[aàáâãä][iìíîï]z|[AÀÁÂÃÄ]bs|[CÇ][oòóôõö]s|[EÈÉÊË]xp|S[eèéêë]n|T[aàáâãä]n|Ln|P[IÌÍÎÏ]|R[CÇ])(?![\\p{L}\\p{N}_])"
94
+ },
95
+ "multiword": {
96
+ "match": "(?i)(?<![\\p{L}\\p{N}_])(?:(D[eèéêë][ \\t]+[OÒÓÔÕÖ]tr[oòóôõö][ \\t]+M[oòóôõö]d[oòóôõö]|M[iìíîï][eèéêë]ntr[aàáâãä]s[ \\t]+Q[uùúûü][eèéêë]|H[aàáâãä]st[aàáâãä][ \\t]+Q[uùúûü][eèéêë]|[CÇ][oòóôõö]n[ \\t]+P[aàáâãä]s[oòóôõö]|S[iìíîï]n[oòóôõö][ \\t]+S[iìíîï])|(P[oòóôõö]r[ \\t]+R[eèéêë]f[eèéêë]r[eèéêë]n[cç][iìíîï][aàáâãä]|P[oòóôõö]r[ \\t]+V[aàáâãä]l[oòóôõö]r)|([EÈÉÊË]s[cç]r[iìíîï]b[iìíîï]r[ \\t]+S[iìíîï]n[ \\t]+S[aàáâãä]lt[aàáâãä]r|M[oòóôõö]str[aàáâãä]r[ \\t]+S[iìíîï]n[ \\t]+S[aàáâãä]lt[aàáâãä]r|L[iìíîï]mp[iìíîï][aàáâãä]r[ \\t]+P[aàáâãä]nt[aàáâãä]ll[aàáâãä]|B[oòóôõö]rr[aàáâãä]r[ \\t]+P[aàáâãä]nt[aàáâãä]ll[aàáâãä]|[EÈÉÊË]sp[eèéêë]r[aàáâãä]r[ \\t]+T[eèéêë][cç]l[aàáâãä]))(?![\\p{L}\\p{N}_])",
97
+ "captures": {
98
+ "1": {
99
+ "name": "keyword.control.stepcode"
100
+ },
101
+ "2": {
102
+ "name": "storage.modifier.stepcode"
103
+ },
104
+ "3": {
105
+ "name": "keyword.other.io.stepcode"
106
+ }
107
+ }
108
+ },
109
+ "comment": {
110
+ "name": "comment.line.stepcode",
111
+ "match": "(?:\\/\\/).*$"
112
+ },
113
+ "string": {
114
+ "patterns": [
115
+ {
116
+ "name": "string.quoted.double.stepcode",
117
+ "match": "\"[^\"]*(?:\"|$)"
118
+ },
119
+ {
120
+ "name": "string.quoted.single.stepcode",
121
+ "match": "'[^']*(?:'|$)"
122
+ }
123
+ ]
124
+ },
125
+ "number": {
126
+ "patterns": [
127
+ {
128
+ "name": "constant.numeric.real.stepcode",
129
+ "match": "(?<![\\p{L}\\p{N}_])\\d+\\.\\d+(?![\\p{L}\\p{N}_])"
130
+ },
131
+ {
132
+ "name": "constant.numeric.integer.stepcode",
133
+ "match": "(?<![\\p{L}\\p{N}_])\\d+(?![\\p{L}\\p{N}_])"
134
+ }
135
+ ]
136
+ },
137
+ "operator-assignment": {
138
+ "name": "keyword.operator.assignment.stepcode",
139
+ "match": "<-|←"
140
+ },
141
+ "operator-comparison": {
142
+ "name": "keyword.operator.comparison.stepcode",
143
+ "match": "!=|<=|<>|>=|<|=|>|≠|≤|≥"
144
+ },
145
+ "operator-arithmetic": {
146
+ "name": "keyword.operator.arithmetic.stepcode",
147
+ "match": "\\*\\*|%|&|\\*|\\+|-|\\/|\\^|\\||~"
148
+ },
149
+ "punctuation": {
150
+ "patterns": [
151
+ {
152
+ "name": "punctuation.section.parens.stepcode",
153
+ "match": "[()]"
154
+ },
155
+ {
156
+ "name": "punctuation.section.brackets.stepcode",
157
+ "match": "[\\[\\]]"
158
+ },
159
+ {
160
+ "name": "punctuation.separator.stepcode",
161
+ "match": "[,:]"
162
+ },
163
+ {
164
+ "name": "punctuation.terminator.stepcode",
165
+ "match": ";"
166
+ }
167
+ ]
168
+ },
169
+ "identifier": {
170
+ "name": "variable.other.stepcode",
171
+ "match": "(?<![\\p{L}\\p{N}_])[\\p{L}_][\\p{L}\\p{N}_]*(?![\\p{L}\\p{N}_])"
172
+ },
173
+ "subprogram": {
174
+ "match": "(?i)(?<![\\p{L}\\p{N}_])(Pr[oòóôõö][cç][eèéêë]d[iìíîï]m[iìíîï][eèéêë]nt[oòóôõö]|S[uùúûü]b[AÀÁÂÃÄ]lg[oòóôõö]r[iìíîï]tm[oòóôõö]|S[uùúûü]bPr[oòóôõö][cç][eèéêë]s[oòóôõö]|F[uùúûü]n[cç][iìíîï][oòóôõö]n)(?![\\p{L}\\p{N}_])[ \\t]+(?:([\\p{L}_][\\p{L}\\p{N}_]*)[ \\t]*(<-|←)[ \\t]*)?([\\p{L}_][\\p{L}\\p{N}_]*)(?![\\p{L}\\p{N}_])",
175
+ "captures": {
176
+ "1": {
177
+ "name": "storage.type.stepcode"
178
+ },
179
+ "2": {
180
+ "name": "variable.other.definition.stepcode"
181
+ },
182
+ "3": {
183
+ "name": "keyword.operator.assignment.stepcode"
184
+ },
185
+ "4": {
186
+ "name": "entity.name.function.stepcode"
187
+ }
188
+ }
189
+ },
190
+ "program": {
191
+ "match": "(?i)(?<![\\p{L}\\p{N}_])([AÀÁÂÃÄ]lg[oòóôõö]r[iìíîï]tm[oòóôõö]|Pr[oòóôõö][cç][eèéêë]s[oòóôõö])(?![\\p{L}\\p{N}_])[ \\t]+([\\p{L}_][\\p{L}\\p{N}_]*)(?![\\p{L}\\p{N}_])",
192
+ "captures": {
193
+ "1": {
194
+ "name": "storage.type.stepcode"
195
+ },
196
+ "2": {
197
+ "name": "entity.name.function.stepcode"
198
+ }
199
+ }
200
+ },
201
+ "definition": {
202
+ "match": "(?i)(?<![\\p{L}\\p{N}_])(D[eèéêë]f[iìíîï]n[iìíîï]r)(?![\\p{L}\\p{N}_])[ \\t]+((?:[\\p{L}_][\\p{L}\\p{N}_]*[ \\t]*,[ \\t]*)*[\\p{L}_][\\p{L}\\p{N}_]*)(?![\\p{L}\\p{N}_])",
203
+ "captures": {
204
+ "1": {
205
+ "name": "storage.type.stepcode"
206
+ },
207
+ "2": {
208
+ "patterns": [
209
+ {
210
+ "name": "variable.other.definition.stepcode",
211
+ "match": "[\\p{L}_][\\p{L}\\p{N}_]*"
212
+ },
213
+ {
214
+ "name": "punctuation.separator.stepcode",
215
+ "match": ","
216
+ }
217
+ ]
218
+ }
219
+ }
220
+ },
221
+ "call": {
222
+ "match": "(?<![\\p{L}\\p{N}_])([\\p{L}_][\\p{L}\\p{N}_]*)(?=[ \\t]*\\()",
223
+ "captures": {
224
+ "1": {
225
+ "name": "entity.name.function.call.stepcode"
226
+ }
227
+ }
228
+ }
229
+ },
230
+ "displayName": "StepCode"
231
+ }
package/package.json ADDED
@@ -0,0 +1,45 @@
1
+ {
2
+ "name": "@stepcode/textmate",
3
+ "version": "2.0.0",
4
+ "description": "TextMate grammars for StepCode, generated from keyword profiles (Shiki, VS Code)",
5
+ "license": "MIT",
6
+ "author": "Rolando Andrade",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/RolandoAndrade/stepcode",
10
+ "directory": "packages/textmate"
11
+ },
12
+ "type": "module",
13
+ "sideEffects": false,
14
+ "files": [
15
+ "dist",
16
+ "grammars"
17
+ ],
18
+ "exports": {
19
+ ".": {
20
+ "types": "./dist/index.d.ts",
21
+ "default": "./dist/index.js"
22
+ },
23
+ "./grammars/*.json": "./grammars/*.json"
24
+ },
25
+ "publishConfig": {
26
+ "access": "public"
27
+ },
28
+ "dependencies": {
29
+ "@stepcode/profiles": "^2.0.0"
30
+ },
31
+ "devDependencies": {
32
+ "@types/node": "^24.13.3",
33
+ "shiki": "^4.4.3",
34
+ "stepcode": "^2.0.0",
35
+ "tsdown": "^0.22.14",
36
+ "typescript": "^7.0.2",
37
+ "vitest": "^4.1.11"
38
+ },
39
+ "scripts": {
40
+ "build": "tsdown",
41
+ "typecheck": "tsc --noEmit",
42
+ "test": "vitest run",
43
+ "generate": "vitest run --root ../.. test/grammars.test.ts -u"
44
+ }
45
+ }