Skip to content

Commit 5d7ecde

Browse files
fix(textmate): grammer
1 parent bed8951 commit 5d7ecde

6 files changed

Lines changed: 306 additions & 43 deletions

File tree

packages/textmate/scripts/build.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { createHighlighterCore } from '@shikijs/core';
22
import { createOnigurumaEngine } from '@shikijs/engine-oniguruma';
33
import wasm from '@shikijs/engine-oniguruma/wasm-inlined';
44
import fs from 'node:fs/promises';
5-
import { grammars } from './grammar.ts';
5+
import { grammars } from './index.ts';
66

77
const dist = new URL('../dist/', import.meta.url);
88
await fs.mkdir(dist, { recursive: true });

packages/textmate/scripts/grammar.ts

Lines changed: 128 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
REG_IDENTIFIER,
88
RESERVED_KEYWORDS,
99
} from '@mirascript/constants';
10+
import { mirascriptDocLanguage, mirascriptLanguage, mirascriptTemplateLanguage } from './language.ts';
1011

1112
const SCOPE_SUFFIX = 'mira';
1213
const IDENTIFIER = REG_IDENTIFIER.source;
@@ -72,6 +73,11 @@ const classifiedKeywords = new Set([
7273
'type',
7374
]);
7475
const otherKeywords = KEYWORDS.filter((keyword) => !classifiedKeywords.has(keyword));
76+
const mirascriptFenceTags = alternatives([mirascriptLanguage.name, ...(mirascriptLanguage.aliases ?? [])]);
77+
const documentationMiraFenceBegin = String.raw`^(\s*\*\s?)(\x60{3,})\s*((?i:${mirascriptFenceTags}))?\s*$`;
78+
const documentationOtherFenceBegin = String.raw`^(\s*\*\s?)(\x60{3,})\s*(\S+)(?:\s+.*)?\s*$`;
79+
const documentationFenceEnd = String.raw`^(?:(\s*\*\s?)(\2\x60*)\s*$)|(?=\*/)`;
80+
const documentationMiraLine = String.raw`^(?!\s*\*\s*\x60{3,}\s*$)(?!.*\*/)(\s*\*\s?)`;
7581

7682
/**
7783
* Create interpolation rules for one exact dollar-sign width.
@@ -83,24 +89,24 @@ function interpolationPatterns(dollarCount: number) {
8389
name: `meta.interpolation.simple.${SCOPE_SUFFIX}`,
8490
match: `(${dollars})(${IDENTIFIER})`,
8591
captures: {
86-
1: { name: `punctuation.definition.interpolation.begin.${SCOPE_SUFFIX}` },
92+
1: { name: `punctuation.definition.template-expression.begin.${SCOPE_SUFFIX}` },
8793
2: { name: `variable.other.${SCOPE_SUFFIX}` },
8894
},
8995
},
9096
{
9197
name: `meta.interpolation.block.${SCOPE_SUFFIX}`,
9298
begin: String.raw`(${dollars}\{)`,
93-
beginCaptures: { 1: { name: `punctuation.definition.interpolation.begin.${SCOPE_SUFFIX}` } },
99+
beginCaptures: { 1: { name: `punctuation.definition.template-expression.begin.${SCOPE_SUFFIX}` } },
94100
end: String.raw`\}`,
95-
endCaptures: { 0: { name: `punctuation.definition.interpolation.end.${SCOPE_SUFFIX}` } },
101+
endCaptures: { 0: { name: `punctuation.definition.template-expression.end.${SCOPE_SUFFIX}` } },
96102
patterns: [{ include: '#braced-content' }],
97103
},
98104
{
99105
name: `meta.interpolation.expression.${SCOPE_SUFFIX}`,
100106
begin: String.raw`(${dollars}\()`,
101-
beginCaptures: { 1: { name: `punctuation.definition.interpolation.begin.${SCOPE_SUFFIX}` } },
107+
beginCaptures: { 1: { name: `punctuation.definition.template-expression.begin.${SCOPE_SUFFIX}` } },
102108
end: String.raw`\)`,
103-
endCaptures: { 0: { name: `punctuation.definition.interpolation.end.${SCOPE_SUFFIX}` } },
109+
endCaptures: { 0: { name: `punctuation.definition.template-expression.end.${SCOPE_SUFFIX}` } },
104110
patterns: [
105111
{
106112
begin: ':(?!:)',
@@ -209,19 +215,121 @@ function sourceRepository(): LanguageRegistration['repository'] {
209215
{ name: `comment.line.double-slash.${SCOPE_SUFFIX}`, match: '//.*$' },
210216
{
211217
name: `comment.block.documentation.${SCOPE_SUFFIX}`,
212-
begin: String.raw`/\*\*(?!/)`,
218+
begin: String.raw`/\*\*`,
213219
end: String.raw`\*/`,
220+
},
221+
{ name: `comment.block.${SCOPE_SUFFIX}`, begin: String.raw`/\*`, end: String.raw`\*/` },
222+
],
223+
},
224+
documentation: {
225+
patterns: [
226+
{ include: '#documentation-mirascript-fence' },
227+
{ include: '#documentation-other-fence' },
228+
{ include: '#documentation-line' },
229+
{ include: '#documentation-fragment' },
230+
],
231+
},
232+
'documentation-inline': {
233+
patterns: [
234+
{
235+
name: `storage.type.class.documentation.${SCOPE_SUFFIX}`,
236+
match: String.raw`@(param|returns)\b`,
237+
},
238+
{
239+
name: `markup.bold.documentation.${SCOPE_SUFFIX}`,
240+
match: String.raw`\*\*[^*]+\*\*`,
241+
},
242+
{ name: `markup.italic.documentation.${SCOPE_SUFFIX}`, match: String.raw`\*[^*]+\*` },
243+
{ name: `constant.character.escape.documentation.${SCOPE_SUFFIX}`, match: String.raw`\\\*` },
244+
],
245+
},
246+
'documentation-line': {
247+
patterns: [
248+
{
249+
match: String.raw`^(?!\s*\*/)(\s*\*\s?)(.*?)(?=\*/|$)`,
250+
captures: {
251+
1: { name: `comment.block.documentation.${SCOPE_SUFFIX}` },
252+
2: {
253+
name: `meta.documentation.inline.${SCOPE_SUFFIX}`,
254+
patterns: [{ include: '#documentation-inline' }],
255+
},
256+
},
257+
},
258+
],
259+
},
260+
'documentation-fragment': {
261+
patterns: [
262+
{
263+
match: String.raw`(?!\*/)(.+?)(?=\*/|$)`,
264+
captures: {
265+
1: {
266+
name: `meta.documentation.inline.${SCOPE_SUFFIX}`,
267+
patterns: [{ include: '#documentation-inline' }],
268+
},
269+
},
270+
},
271+
],
272+
},
273+
'documentation-mirascript-fence': {
274+
patterns: [
275+
{
276+
name: `markup.fenced_code.block.${SCOPE_SUFFIX}`,
277+
begin: documentationMiraFenceBegin,
278+
beginCaptures: {
279+
1: { name: `comment.block.documentation.${SCOPE_SUFFIX}` },
280+
2: { name: `punctuation.definition.markdown.${SCOPE_SUFFIX}` },
281+
3: { name: `fenced_code.block.language.${SCOPE_SUFFIX}` },
282+
},
283+
end: documentationFenceEnd,
284+
endCaptures: {
285+
1: { name: `comment.block.documentation.${SCOPE_SUFFIX}` },
286+
2: { name: `punctuation.definition.markdown.${SCOPE_SUFFIX}` },
287+
},
214288
patterns: [
215289
{
216-
name: `storage.type.class.documentation.${SCOPE_SUFFIX}`,
217-
match: String.raw`@(param|returns)\b`,
290+
name: `meta.embedded.block.${SCOPE_SUFFIX}`,
291+
contentName: `source.${SCOPE_SUFFIX}`,
292+
begin: documentationMiraLine,
293+
beginCaptures: {
294+
1: { name: `comment.block.documentation.${SCOPE_SUFFIX}` },
295+
},
296+
while: documentationMiraLine,
297+
whileCaptures: {
298+
1: { name: `comment.block.documentation.${SCOPE_SUFFIX}` },
299+
},
300+
patterns: [{ include: '#source' }],
301+
},
302+
{
303+
name: `comment.block.documentation.${SCOPE_SUFFIX}`,
304+
match: String.raw`^(?!\s*\*/)(\s*\*\s?)`,
305+
},
306+
],
307+
},
308+
],
309+
},
310+
'documentation-other-fence': {
311+
patterns: [
312+
{
313+
name: `markup.fenced_code.block.${SCOPE_SUFFIX}`,
314+
contentName: `markup.raw.block.${SCOPE_SUFFIX}`,
315+
begin: documentationOtherFenceBegin,
316+
beginCaptures: {
317+
1: { name: `comment.block.documentation.${SCOPE_SUFFIX}` },
318+
2: { name: `punctuation.definition.markdown.${SCOPE_SUFFIX}` },
319+
3: { name: `fenced_code.block.language.${SCOPE_SUFFIX}` },
320+
},
321+
end: documentationFenceEnd,
322+
endCaptures: {
323+
1: { name: `comment.block.documentation.${SCOPE_SUFFIX}` },
324+
2: { name: `punctuation.definition.markdown.${SCOPE_SUFFIX}` },
325+
},
326+
patterns: [
327+
{
328+
name: `comment.block.documentation.${SCOPE_SUFFIX}`,
329+
match: String.raw`^(?!\s*\*/)(\s*\*\s?)`,
218330
},
219-
{ name: `markup.bold.documentation.${SCOPE_SUFFIX}`, match: String.raw`\*\*[^*]+\*\*` },
220-
{ name: `markup.italic.documentation.${SCOPE_SUFFIX}`, match: String.raw`\*[^*]+\*` },
221-
{ name: `constant.character.escape.documentation.${SCOPE_SUFFIX}`, match: String.raw`\\\*` },
222331
],
223332
},
224-
{ name: `comment.block.${SCOPE_SUFFIX}`, begin: String.raw`/\*`, end: String.raw`\*/` },
225333
],
226334
},
227335
'format-content': {
@@ -503,11 +611,14 @@ function sourceRepository(): LanguageRegistration['repository'] {
503611
*/
504612
export function createMiraScriptGrammar(): LanguageRegistration {
505613
return {
506-
name: 'mirascript',
507-
aliases: ['MiraScript', 'mira', 'Mira'],
508-
scopeName: 'source.mira',
614+
...mirascriptLanguage,
509615
patterns: [{ include: '#source' }],
510616
repository: sourceRepository(),
617+
injections: {
618+
'L:comment.block.documentation.mira -markup.fenced_code.block.mira -meta.documentation.inline.mira': {
619+
patterns: [{ include: '#documentation' }],
620+
},
621+
},
511622
};
512623
}
513624

@@ -516,9 +627,7 @@ export function createMiraScriptGrammar(): LanguageRegistration {
516627
*/
517628
export function createMiraScriptTemplateGrammar(): LanguageRegistration {
518629
return {
519-
name: 'mirascript-template',
520-
aliases: ['MiraScript-Template', 'miratpl', 'MiraTpl'],
521-
scopeName: 'text.miratpl',
630+
...mirascriptTemplateLanguage,
522631
patterns: [
523632
...interpolationPatterns(1),
524633
{ name: 'string.unquoted.template.mira', match: '[^$]+' },
@@ -533,8 +642,7 @@ export function createMiraScriptTemplateGrammar(): LanguageRegistration {
533642
*/
534643
export function createMiraScriptDocGrammar(): LanguageRegistration {
535644
return {
536-
name: 'mirascript-doc',
537-
scopeName: 'source.mira.doc',
645+
...mirascriptDocLanguage,
538646
patterns: [{ include: '#doc' }],
539647
repository: {
540648
doc: {
@@ -906,9 +1014,3 @@ export function createMiraScriptDocGrammar(): LanguageRegistration {
9061014
},
9071015
};
9081016
}
909-
910-
export const grammars: LanguageRegistration[] = [
911-
createMiraScriptGrammar(),
912-
createMiraScriptTemplateGrammar(),
913-
createMiraScriptDocGrammar(),
914-
];

packages/textmate/scripts/index.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import type { LanguageRegistration } from '@shikijs/types';
2+
import { createMiraScriptDocGrammar, createMiraScriptGrammar, createMiraScriptTemplateGrammar } from './grammar.ts';
3+
4+
export const mirascript = createMiraScriptGrammar();
5+
export const mirascriptTemplate = createMiraScriptTemplateGrammar();
6+
export const mirascriptDoc = createMiraScriptDocGrammar();
7+
8+
export const grammars: LanguageRegistration[] = [mirascript, mirascriptTemplate, mirascriptDoc];
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import type { LanguageRegistration } from '@shikijs/types';
2+
3+
/** Shared TextMate language metadata. */
4+
export type LanguageMetadata = Pick<LanguageRegistration, 'name' | 'aliases' | 'scopeName'>;
5+
6+
export const mirascriptLanguage = {
7+
name: 'mirascript',
8+
aliases: ['MiraScript', 'mira', 'Mira'],
9+
scopeName: 'source.mira',
10+
} satisfies LanguageMetadata;
11+
12+
export const mirascriptTemplateLanguage = {
13+
name: 'mirascript-template',
14+
aliases: ['MiraScript-Template', 'miratpl', 'MiraTpl'],
15+
scopeName: 'text.miratpl',
16+
} satisfies LanguageMetadata;
17+
18+
export const mirascriptDocLanguage = {
19+
name: 'mirascript-doc',
20+
scopeName: 'source.mira.doc',
21+
} satisfies LanguageMetadata;

packages/textmate/test/fixtures/valid.mira

Lines changed: 0 additions & 11 deletions
This file was deleted.

0 commit comments

Comments
 (0)