@shikijs/core 1.15.2 → 1.16.1
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/dist/chunk-engines.d.mts +29 -1
- package/dist/index.d.mts +117 -78
- package/dist/index.mjs +1009 -922
- package/dist/types.d.mts +665 -5
- package/dist/wasm-inlined.d.mts +1 -0
- package/package.json +3 -2
- package/dist/chunk-tokens.d.mts +0 -1062
- package/dist/textmate.d.mts +0 -3
- package/dist/textmate.mjs +0 -3135
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { INITIAL, StackElementMetadata, Registry as Registry$1, Theme } from './textmate.mjs';
|
|
2
1
|
import { FontStyle } from './types.mjs';
|
|
2
|
+
import { INITIAL, EncodedTokenMetadata, Registry as Registry$1, Theme } from '@shikijs/vscode-textmate';
|
|
3
|
+
export { EncodedTokenMetadata as StackElementMetadata } from '@shikijs/vscode-textmate';
|
|
3
4
|
|
|
4
5
|
function toArray(x) {
|
|
5
6
|
return Array.isArray(x) ? x : [x];
|
|
@@ -121,6 +122,12 @@ function splitTokens(tokens, breakpoints) {
|
|
|
121
122
|
});
|
|
122
123
|
});
|
|
123
124
|
}
|
|
125
|
+
/**
|
|
126
|
+
* Normalize a getter to a promise.
|
|
127
|
+
*/
|
|
128
|
+
async function normalizeGetter(p) {
|
|
129
|
+
return Promise.resolve(typeof p === 'function' ? p() : p).then(r => r.default || r);
|
|
130
|
+
}
|
|
124
131
|
function resolveColorReplacements(theme, options) {
|
|
125
132
|
const replacements = typeof theme === 'string' ? {} : { ...theme.colorReplacements };
|
|
126
133
|
const themeName = typeof theme === 'string' ? theme : theme.name;
|
|
@@ -194,6 +201,248 @@ function createPositionConverter(code) {
|
|
|
194
201
|
};
|
|
195
202
|
}
|
|
196
203
|
|
|
204
|
+
class ShikiError extends Error {
|
|
205
|
+
constructor(message) {
|
|
206
|
+
super(message);
|
|
207
|
+
this.name = 'ShikiError';
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* A built-in transformer to add decorations to the highlighted code.
|
|
213
|
+
*/
|
|
214
|
+
function transformerDecorations() {
|
|
215
|
+
const map = new WeakMap();
|
|
216
|
+
function getContext(shiki) {
|
|
217
|
+
if (!map.has(shiki.meta)) {
|
|
218
|
+
const converter = createPositionConverter(shiki.source);
|
|
219
|
+
function normalizePosition(p) {
|
|
220
|
+
if (typeof p === 'number') {
|
|
221
|
+
if (p < 0 || p > shiki.source.length)
|
|
222
|
+
throw new ShikiError(`Invalid decoration offset: ${p}. Code length: ${shiki.source.length}`);
|
|
223
|
+
return {
|
|
224
|
+
...converter.indexToPos(p),
|
|
225
|
+
offset: p,
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
else {
|
|
229
|
+
const line = converter.lines[p.line];
|
|
230
|
+
if (line === undefined)
|
|
231
|
+
throw new ShikiError(`Invalid decoration position ${JSON.stringify(p)}. Lines length: ${converter.lines.length}`);
|
|
232
|
+
if (p.character < 0 || p.character > line.length)
|
|
233
|
+
throw new ShikiError(`Invalid decoration position ${JSON.stringify(p)}. Line ${p.line} length: ${line.length}`);
|
|
234
|
+
return {
|
|
235
|
+
...p,
|
|
236
|
+
offset: converter.posToIndex(p.line, p.character),
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
const decorations = (shiki.options.decorations || [])
|
|
241
|
+
.map((d) => ({
|
|
242
|
+
...d,
|
|
243
|
+
start: normalizePosition(d.start),
|
|
244
|
+
end: normalizePosition(d.end),
|
|
245
|
+
}));
|
|
246
|
+
verifyIntersections(decorations);
|
|
247
|
+
map.set(shiki.meta, {
|
|
248
|
+
decorations,
|
|
249
|
+
converter,
|
|
250
|
+
source: shiki.source,
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
return map.get(shiki.meta);
|
|
254
|
+
}
|
|
255
|
+
return {
|
|
256
|
+
name: 'shiki:decorations',
|
|
257
|
+
tokens(tokens) {
|
|
258
|
+
if (!this.options.decorations?.length)
|
|
259
|
+
return;
|
|
260
|
+
const ctx = getContext(this);
|
|
261
|
+
const breakpoints = ctx.decorations.flatMap(d => [d.start.offset, d.end.offset]);
|
|
262
|
+
const splitted = splitTokens(tokens, breakpoints);
|
|
263
|
+
return splitted;
|
|
264
|
+
},
|
|
265
|
+
code(codeEl) {
|
|
266
|
+
if (!this.options.decorations?.length)
|
|
267
|
+
return;
|
|
268
|
+
const ctx = getContext(this);
|
|
269
|
+
const lines = Array.from(codeEl.children).filter(i => i.type === 'element' && i.tagName === 'span');
|
|
270
|
+
if (lines.length !== ctx.converter.lines.length)
|
|
271
|
+
throw new ShikiError(`Number of lines in code element (${lines.length}) does not match the number of lines in the source (${ctx.converter.lines.length}). Failed to apply decorations.`);
|
|
272
|
+
function applyLineSection(line, start, end, decoration) {
|
|
273
|
+
const lineEl = lines[line];
|
|
274
|
+
let text = '';
|
|
275
|
+
let startIndex = -1;
|
|
276
|
+
let endIndex = -1;
|
|
277
|
+
if (start === 0)
|
|
278
|
+
startIndex = 0;
|
|
279
|
+
if (end === 0)
|
|
280
|
+
endIndex = 0;
|
|
281
|
+
if (end === Number.POSITIVE_INFINITY)
|
|
282
|
+
endIndex = lineEl.children.length;
|
|
283
|
+
if (startIndex === -1 || endIndex === -1) {
|
|
284
|
+
for (let i = 0; i < lineEl.children.length; i++) {
|
|
285
|
+
text += stringify$2(lineEl.children[i]);
|
|
286
|
+
if (startIndex === -1 && text.length === start)
|
|
287
|
+
startIndex = i + 1;
|
|
288
|
+
if (endIndex === -1 && text.length === end)
|
|
289
|
+
endIndex = i + 1;
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
if (startIndex === -1)
|
|
293
|
+
throw new ShikiError(`Failed to find start index for decoration ${JSON.stringify(decoration.start)}`);
|
|
294
|
+
if (endIndex === -1)
|
|
295
|
+
throw new ShikiError(`Failed to find end index for decoration ${JSON.stringify(decoration.end)}`);
|
|
296
|
+
const children = lineEl.children.slice(startIndex, endIndex);
|
|
297
|
+
// Full line decoration
|
|
298
|
+
if (!decoration.alwaysWrap && children.length === lineEl.children.length) {
|
|
299
|
+
applyDecoration(lineEl, decoration, 'line');
|
|
300
|
+
}
|
|
301
|
+
// Single token decoration
|
|
302
|
+
else if (!decoration.alwaysWrap && children.length === 1 && children[0].type === 'element') {
|
|
303
|
+
applyDecoration(children[0], decoration, 'token');
|
|
304
|
+
}
|
|
305
|
+
// Create a wrapper for the decoration
|
|
306
|
+
else {
|
|
307
|
+
const wrapper = {
|
|
308
|
+
type: 'element',
|
|
309
|
+
tagName: 'span',
|
|
310
|
+
properties: {},
|
|
311
|
+
children,
|
|
312
|
+
};
|
|
313
|
+
applyDecoration(wrapper, decoration, 'wrapper');
|
|
314
|
+
lineEl.children.splice(startIndex, children.length, wrapper);
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
function applyLine(line, decoration) {
|
|
318
|
+
lines[line] = applyDecoration(lines[line], decoration, 'line');
|
|
319
|
+
}
|
|
320
|
+
function applyDecoration(el, decoration, type) {
|
|
321
|
+
const properties = decoration.properties || {};
|
|
322
|
+
const transform = decoration.transform || (i => i);
|
|
323
|
+
el.tagName = decoration.tagName || 'span';
|
|
324
|
+
el.properties = {
|
|
325
|
+
...el.properties,
|
|
326
|
+
...properties,
|
|
327
|
+
class: el.properties.class,
|
|
328
|
+
};
|
|
329
|
+
if (decoration.properties?.class)
|
|
330
|
+
addClassToHast(el, decoration.properties.class);
|
|
331
|
+
el = transform(el, type) || el;
|
|
332
|
+
return el;
|
|
333
|
+
}
|
|
334
|
+
const lineApplies = [];
|
|
335
|
+
// Apply decorations in reverse order so the nested ones get applied first.
|
|
336
|
+
const sorted = ctx.decorations.sort((a, b) => b.start.offset - a.start.offset);
|
|
337
|
+
for (const decoration of sorted) {
|
|
338
|
+
const { start, end } = decoration;
|
|
339
|
+
if (start.line === end.line) {
|
|
340
|
+
applyLineSection(start.line, start.character, end.character, decoration);
|
|
341
|
+
}
|
|
342
|
+
else if (start.line < end.line) {
|
|
343
|
+
applyLineSection(start.line, start.character, Number.POSITIVE_INFINITY, decoration);
|
|
344
|
+
for (let i = start.line + 1; i < end.line; i++)
|
|
345
|
+
lineApplies.unshift(() => applyLine(i, decoration));
|
|
346
|
+
applyLineSection(end.line, 0, end.character, decoration);
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
lineApplies.forEach(i => i());
|
|
350
|
+
},
|
|
351
|
+
};
|
|
352
|
+
}
|
|
353
|
+
function verifyIntersections(items) {
|
|
354
|
+
for (let i = 0; i < items.length; i++) {
|
|
355
|
+
const foo = items[i];
|
|
356
|
+
if (foo.start.offset > foo.end.offset)
|
|
357
|
+
throw new ShikiError(`Invalid decoration range: ${JSON.stringify(foo.start)} - ${JSON.stringify(foo.end)}`);
|
|
358
|
+
for (let j = i + 1; j < items.length; j++) {
|
|
359
|
+
const bar = items[j];
|
|
360
|
+
const isFooHasBarStart = foo.start.offset < bar.start.offset && bar.start.offset < foo.end.offset;
|
|
361
|
+
const isFooHasBarEnd = foo.start.offset < bar.end.offset && bar.end.offset < foo.end.offset;
|
|
362
|
+
const isBarHasFooStart = bar.start.offset < foo.start.offset && foo.start.offset < bar.end.offset;
|
|
363
|
+
const isBarHasFooEnd = bar.start.offset < foo.end.offset && foo.end.offset < bar.end.offset;
|
|
364
|
+
if (isFooHasBarStart || isFooHasBarEnd || isBarHasFooStart || isBarHasFooEnd) {
|
|
365
|
+
if (isFooHasBarEnd && isFooHasBarEnd)
|
|
366
|
+
continue; // nested
|
|
367
|
+
if (isBarHasFooStart && isBarHasFooEnd)
|
|
368
|
+
continue; // nested
|
|
369
|
+
throw new ShikiError(`Decorations ${JSON.stringify(foo.start)} and ${JSON.stringify(bar.start)} intersect.`);
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
function stringify$2(el) {
|
|
375
|
+
if (el.type === 'text')
|
|
376
|
+
return el.value;
|
|
377
|
+
if (el.type === 'element')
|
|
378
|
+
return el.children.map(stringify$2).join('');
|
|
379
|
+
return '';
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
const builtInTransformers = [
|
|
383
|
+
/* @__PURE__ */ transformerDecorations(),
|
|
384
|
+
];
|
|
385
|
+
function getTransformers(options) {
|
|
386
|
+
return [
|
|
387
|
+
...options.transformers || [],
|
|
388
|
+
...builtInTransformers,
|
|
389
|
+
];
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
/**
|
|
393
|
+
* GrammarState is a special reference object that holds the state of a grammar.
|
|
394
|
+
*
|
|
395
|
+
* It's used to highlight code snippets that are part of the target language.
|
|
396
|
+
*/
|
|
397
|
+
class GrammarState {
|
|
398
|
+
_stack;
|
|
399
|
+
lang;
|
|
400
|
+
theme;
|
|
401
|
+
/**
|
|
402
|
+
* Static method to create a initial grammar state.
|
|
403
|
+
*/
|
|
404
|
+
static initial(lang, theme) {
|
|
405
|
+
return new GrammarState(INITIAL, lang, theme);
|
|
406
|
+
}
|
|
407
|
+
constructor(_stack, lang, theme) {
|
|
408
|
+
this._stack = _stack;
|
|
409
|
+
this.lang = lang;
|
|
410
|
+
this.theme = theme;
|
|
411
|
+
}
|
|
412
|
+
get scopes() {
|
|
413
|
+
return getScopes(this._stack);
|
|
414
|
+
}
|
|
415
|
+
toJSON() {
|
|
416
|
+
return {
|
|
417
|
+
lang: this.lang,
|
|
418
|
+
theme: this.theme,
|
|
419
|
+
scopes: this.scopes,
|
|
420
|
+
};
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
function getScopes(stack) {
|
|
424
|
+
const scopes = [];
|
|
425
|
+
const visited = new Set();
|
|
426
|
+
function pushScope(stack) {
|
|
427
|
+
if (visited.has(stack))
|
|
428
|
+
return;
|
|
429
|
+
visited.add(stack);
|
|
430
|
+
const name = stack?.nameScopesList?.scopeName;
|
|
431
|
+
if (name)
|
|
432
|
+
scopes.push(name);
|
|
433
|
+
if (stack.parent)
|
|
434
|
+
pushScope(stack.parent);
|
|
435
|
+
}
|
|
436
|
+
pushScope(stack);
|
|
437
|
+
return scopes;
|
|
438
|
+
}
|
|
439
|
+
function getGrammarStack(state) {
|
|
440
|
+
if (!(state instanceof GrammarState))
|
|
441
|
+
throw new ShikiError('Invalid grammar state');
|
|
442
|
+
// @ts-expect-error _stack is private
|
|
443
|
+
return state._stack;
|
|
444
|
+
}
|
|
445
|
+
|
|
197
446
|
// src/colors.ts
|
|
198
447
|
var namedColors = [
|
|
199
448
|
"black",
|
|
@@ -525,67 +774,9 @@ function dimColor(color) {
|
|
|
525
774
|
return color;
|
|
526
775
|
}
|
|
527
776
|
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
this.name = 'ShikiError';
|
|
532
|
-
}
|
|
533
|
-
}
|
|
534
|
-
|
|
535
|
-
/**
|
|
536
|
-
* GrammarState is a special reference object that holds the state of a grammar.
|
|
537
|
-
*
|
|
538
|
-
* It's used to highlight code snippets that are part of the target language.
|
|
539
|
-
*/
|
|
540
|
-
class GrammarState {
|
|
541
|
-
_stack;
|
|
542
|
-
lang;
|
|
543
|
-
theme;
|
|
544
|
-
/**
|
|
545
|
-
* Static method to create a initial grammar state.
|
|
546
|
-
*/
|
|
547
|
-
static initial(lang, theme) {
|
|
548
|
-
return new GrammarState(INITIAL, lang, theme);
|
|
549
|
-
}
|
|
550
|
-
constructor(_stack, lang, theme) {
|
|
551
|
-
this._stack = _stack;
|
|
552
|
-
this.lang = lang;
|
|
553
|
-
this.theme = theme;
|
|
554
|
-
}
|
|
555
|
-
get scopes() {
|
|
556
|
-
return getScopes(this._stack);
|
|
557
|
-
}
|
|
558
|
-
toJSON() {
|
|
559
|
-
return {
|
|
560
|
-
lang: this.lang,
|
|
561
|
-
theme: this.theme,
|
|
562
|
-
scopes: this.scopes,
|
|
563
|
-
};
|
|
564
|
-
}
|
|
565
|
-
}
|
|
566
|
-
function getScopes(stack) {
|
|
567
|
-
const scopes = [];
|
|
568
|
-
const visited = new Set();
|
|
569
|
-
function pushScope(stack) {
|
|
570
|
-
if (visited.has(stack))
|
|
571
|
-
return;
|
|
572
|
-
visited.add(stack);
|
|
573
|
-
const name = stack?.nameScopesList?.scopeName;
|
|
574
|
-
if (name)
|
|
575
|
-
scopes.push(name);
|
|
576
|
-
if (stack.parent)
|
|
577
|
-
pushScope(stack.parent);
|
|
578
|
-
}
|
|
579
|
-
pushScope(stack);
|
|
580
|
-
return scopes;
|
|
581
|
-
}
|
|
582
|
-
function getGrammarStack(state) {
|
|
583
|
-
if (!(state instanceof GrammarState))
|
|
584
|
-
throw new ShikiError('Invalid grammar state');
|
|
585
|
-
// @ts-expect-error _stack is private
|
|
586
|
-
return state._stack;
|
|
587
|
-
}
|
|
588
|
-
|
|
777
|
+
/* ---------------------------------------------------------
|
|
778
|
+
* Copyright (C) Microsoft Corporation. All rights reserved.
|
|
779
|
+
*-------------------------------------------------------- */
|
|
589
780
|
/**
|
|
590
781
|
* Code to tokens, with a simple theme.
|
|
591
782
|
*/
|
|
@@ -669,8 +860,8 @@ function _tokenizeWithTheme(code, grammar, theme, colorMap, options) {
|
|
|
669
860
|
if (startIndex === nextStartIndex)
|
|
670
861
|
continue;
|
|
671
862
|
const metadata = result.tokens[2 * j + 1];
|
|
672
|
-
const color = applyColorReplacements(colorMap[
|
|
673
|
-
const fontStyle =
|
|
863
|
+
const color = applyColorReplacements(colorMap[EncodedTokenMetadata.getForeground(metadata)], colorReplacements);
|
|
864
|
+
const fontStyle = EncodedTokenMetadata.getFontStyle(metadata);
|
|
674
865
|
const token = {
|
|
675
866
|
content: line.substring(startIndex, nextStartIndex),
|
|
676
867
|
offset: lineOffset + startIndex,
|
|
@@ -934,187 +1125,6 @@ function mergeToken(merged, variantsOrder, cssVariablePrefix, defaultColor) {
|
|
|
934
1125
|
return token;
|
|
935
1126
|
}
|
|
936
1127
|
|
|
937
|
-
/**
|
|
938
|
-
* A built-in transformer to add decorations to the highlighted code.
|
|
939
|
-
*/
|
|
940
|
-
function transformerDecorations() {
|
|
941
|
-
const map = new WeakMap();
|
|
942
|
-
function getContext(shiki) {
|
|
943
|
-
if (!map.has(shiki.meta)) {
|
|
944
|
-
const converter = createPositionConverter(shiki.source);
|
|
945
|
-
function normalizePosition(p) {
|
|
946
|
-
if (typeof p === 'number') {
|
|
947
|
-
if (p < 0 || p > shiki.source.length)
|
|
948
|
-
throw new ShikiError(`Invalid decoration offset: ${p}. Code length: ${shiki.source.length}`);
|
|
949
|
-
return {
|
|
950
|
-
...converter.indexToPos(p),
|
|
951
|
-
offset: p,
|
|
952
|
-
};
|
|
953
|
-
}
|
|
954
|
-
else {
|
|
955
|
-
const line = converter.lines[p.line];
|
|
956
|
-
if (line === undefined)
|
|
957
|
-
throw new ShikiError(`Invalid decoration position ${JSON.stringify(p)}. Lines length: ${converter.lines.length}`);
|
|
958
|
-
if (p.character < 0 || p.character > line.length)
|
|
959
|
-
throw new ShikiError(`Invalid decoration position ${JSON.stringify(p)}. Line ${p.line} length: ${line.length}`);
|
|
960
|
-
return {
|
|
961
|
-
...p,
|
|
962
|
-
offset: converter.posToIndex(p.line, p.character),
|
|
963
|
-
};
|
|
964
|
-
}
|
|
965
|
-
}
|
|
966
|
-
const decorations = (shiki.options.decorations || [])
|
|
967
|
-
.map((d) => ({
|
|
968
|
-
...d,
|
|
969
|
-
start: normalizePosition(d.start),
|
|
970
|
-
end: normalizePosition(d.end),
|
|
971
|
-
}));
|
|
972
|
-
verifyIntersections(decorations);
|
|
973
|
-
map.set(shiki.meta, {
|
|
974
|
-
decorations,
|
|
975
|
-
converter,
|
|
976
|
-
source: shiki.source,
|
|
977
|
-
});
|
|
978
|
-
}
|
|
979
|
-
return map.get(shiki.meta);
|
|
980
|
-
}
|
|
981
|
-
return {
|
|
982
|
-
name: 'shiki:decorations',
|
|
983
|
-
tokens(tokens) {
|
|
984
|
-
if (!this.options.decorations?.length)
|
|
985
|
-
return;
|
|
986
|
-
const ctx = getContext(this);
|
|
987
|
-
const breakpoints = ctx.decorations.flatMap(d => [d.start.offset, d.end.offset]);
|
|
988
|
-
const splitted = splitTokens(tokens, breakpoints);
|
|
989
|
-
return splitted;
|
|
990
|
-
},
|
|
991
|
-
code(codeEl) {
|
|
992
|
-
if (!this.options.decorations?.length)
|
|
993
|
-
return;
|
|
994
|
-
const ctx = getContext(this);
|
|
995
|
-
const lines = Array.from(codeEl.children).filter(i => i.type === 'element' && i.tagName === 'span');
|
|
996
|
-
if (lines.length !== ctx.converter.lines.length)
|
|
997
|
-
throw new ShikiError(`Number of lines in code element (${lines.length}) does not match the number of lines in the source (${ctx.converter.lines.length}). Failed to apply decorations.`);
|
|
998
|
-
function applyLineSection(line, start, end, decoration) {
|
|
999
|
-
const lineEl = lines[line];
|
|
1000
|
-
let text = '';
|
|
1001
|
-
let startIndex = -1;
|
|
1002
|
-
let endIndex = -1;
|
|
1003
|
-
if (start === 0)
|
|
1004
|
-
startIndex = 0;
|
|
1005
|
-
if (end === 0)
|
|
1006
|
-
endIndex = 0;
|
|
1007
|
-
if (end === Number.POSITIVE_INFINITY)
|
|
1008
|
-
endIndex = lineEl.children.length;
|
|
1009
|
-
if (startIndex === -1 || endIndex === -1) {
|
|
1010
|
-
for (let i = 0; i < lineEl.children.length; i++) {
|
|
1011
|
-
text += stringify$2(lineEl.children[i]);
|
|
1012
|
-
if (startIndex === -1 && text.length === start)
|
|
1013
|
-
startIndex = i + 1;
|
|
1014
|
-
if (endIndex === -1 && text.length === end)
|
|
1015
|
-
endIndex = i + 1;
|
|
1016
|
-
}
|
|
1017
|
-
}
|
|
1018
|
-
if (startIndex === -1)
|
|
1019
|
-
throw new ShikiError(`Failed to find start index for decoration ${JSON.stringify(decoration.start)}`);
|
|
1020
|
-
if (endIndex === -1)
|
|
1021
|
-
throw new ShikiError(`Failed to find end index for decoration ${JSON.stringify(decoration.end)}`);
|
|
1022
|
-
const children = lineEl.children.slice(startIndex, endIndex);
|
|
1023
|
-
// Full line decoration
|
|
1024
|
-
if (!decoration.alwaysWrap && children.length === lineEl.children.length) {
|
|
1025
|
-
applyDecoration(lineEl, decoration, 'line');
|
|
1026
|
-
}
|
|
1027
|
-
// Single token decoration
|
|
1028
|
-
else if (!decoration.alwaysWrap && children.length === 1 && children[0].type === 'element') {
|
|
1029
|
-
applyDecoration(children[0], decoration, 'token');
|
|
1030
|
-
}
|
|
1031
|
-
// Create a wrapper for the decoration
|
|
1032
|
-
else {
|
|
1033
|
-
const wrapper = {
|
|
1034
|
-
type: 'element',
|
|
1035
|
-
tagName: 'span',
|
|
1036
|
-
properties: {},
|
|
1037
|
-
children,
|
|
1038
|
-
};
|
|
1039
|
-
applyDecoration(wrapper, decoration, 'wrapper');
|
|
1040
|
-
lineEl.children.splice(startIndex, children.length, wrapper);
|
|
1041
|
-
}
|
|
1042
|
-
}
|
|
1043
|
-
function applyLine(line, decoration) {
|
|
1044
|
-
lines[line] = applyDecoration(lines[line], decoration, 'line');
|
|
1045
|
-
}
|
|
1046
|
-
function applyDecoration(el, decoration, type) {
|
|
1047
|
-
const properties = decoration.properties || {};
|
|
1048
|
-
const transform = decoration.transform || (i => i);
|
|
1049
|
-
el.tagName = decoration.tagName || 'span';
|
|
1050
|
-
el.properties = {
|
|
1051
|
-
...el.properties,
|
|
1052
|
-
...properties,
|
|
1053
|
-
class: el.properties.class,
|
|
1054
|
-
};
|
|
1055
|
-
if (decoration.properties?.class)
|
|
1056
|
-
addClassToHast(el, decoration.properties.class);
|
|
1057
|
-
el = transform(el, type) || el;
|
|
1058
|
-
return el;
|
|
1059
|
-
}
|
|
1060
|
-
const lineApplies = [];
|
|
1061
|
-
// Apply decorations in reverse order so the nested ones get applied first.
|
|
1062
|
-
const sorted = ctx.decorations.sort((a, b) => b.start.offset - a.start.offset);
|
|
1063
|
-
for (const decoration of sorted) {
|
|
1064
|
-
const { start, end } = decoration;
|
|
1065
|
-
if (start.line === end.line) {
|
|
1066
|
-
applyLineSection(start.line, start.character, end.character, decoration);
|
|
1067
|
-
}
|
|
1068
|
-
else if (start.line < end.line) {
|
|
1069
|
-
applyLineSection(start.line, start.character, Number.POSITIVE_INFINITY, decoration);
|
|
1070
|
-
for (let i = start.line + 1; i < end.line; i++)
|
|
1071
|
-
lineApplies.unshift(() => applyLine(i, decoration));
|
|
1072
|
-
applyLineSection(end.line, 0, end.character, decoration);
|
|
1073
|
-
}
|
|
1074
|
-
}
|
|
1075
|
-
lineApplies.forEach(i => i());
|
|
1076
|
-
},
|
|
1077
|
-
};
|
|
1078
|
-
}
|
|
1079
|
-
function verifyIntersections(items) {
|
|
1080
|
-
for (let i = 0; i < items.length; i++) {
|
|
1081
|
-
const foo = items[i];
|
|
1082
|
-
if (foo.start.offset > foo.end.offset)
|
|
1083
|
-
throw new ShikiError(`Invalid decoration range: ${JSON.stringify(foo.start)} - ${JSON.stringify(foo.end)}`);
|
|
1084
|
-
for (let j = i + 1; j < items.length; j++) {
|
|
1085
|
-
const bar = items[j];
|
|
1086
|
-
const isFooHasBarStart = foo.start.offset < bar.start.offset && bar.start.offset < foo.end.offset;
|
|
1087
|
-
const isFooHasBarEnd = foo.start.offset < bar.end.offset && bar.end.offset < foo.end.offset;
|
|
1088
|
-
const isBarHasFooStart = bar.start.offset < foo.start.offset && foo.start.offset < bar.end.offset;
|
|
1089
|
-
const isBarHasFooEnd = bar.start.offset < foo.end.offset && foo.end.offset < bar.end.offset;
|
|
1090
|
-
if (isFooHasBarStart || isFooHasBarEnd || isBarHasFooStart || isBarHasFooEnd) {
|
|
1091
|
-
if (isFooHasBarEnd && isFooHasBarEnd)
|
|
1092
|
-
continue; // nested
|
|
1093
|
-
if (isBarHasFooStart && isBarHasFooEnd)
|
|
1094
|
-
continue; // nested
|
|
1095
|
-
throw new ShikiError(`Decorations ${JSON.stringify(foo.start)} and ${JSON.stringify(bar.start)} intersect.`);
|
|
1096
|
-
}
|
|
1097
|
-
}
|
|
1098
|
-
}
|
|
1099
|
-
}
|
|
1100
|
-
function stringify$2(el) {
|
|
1101
|
-
if (el.type === 'text')
|
|
1102
|
-
return el.value;
|
|
1103
|
-
if (el.type === 'element')
|
|
1104
|
-
return el.children.map(stringify$2).join('');
|
|
1105
|
-
return '';
|
|
1106
|
-
}
|
|
1107
|
-
|
|
1108
|
-
const builtInTransformers = [
|
|
1109
|
-
/* @__PURE__ */ transformerDecorations(),
|
|
1110
|
-
];
|
|
1111
|
-
function getTransformers(options) {
|
|
1112
|
-
return [
|
|
1113
|
-
...options.transformers || [],
|
|
1114
|
-
...builtInTransformers,
|
|
1115
|
-
];
|
|
1116
|
-
}
|
|
1117
|
-
|
|
1118
1128
|
function codeToHast(internal, code, options, transformerContext = {
|
|
1119
1129
|
meta: {},
|
|
1120
1130
|
options,
|
|
@@ -4690,423 +4700,103 @@ function codeToHtml(internal, code, options) {
|
|
|
4690
4700
|
return result;
|
|
4691
4701
|
}
|
|
4692
4702
|
|
|
4693
|
-
|
|
4694
|
-
|
|
4695
|
-
*/
|
|
4696
|
-
const VSCODE_FALLBACK_EDITOR_FG = { light: '#333333', dark: '#bbbbbb' };
|
|
4697
|
-
const VSCODE_FALLBACK_EDITOR_BG = { light: '#fffffe', dark: '#1e1e1e' };
|
|
4698
|
-
const RESOLVED_KEY = '__shiki_resolved';
|
|
4699
|
-
/**
|
|
4700
|
-
* Normalize a textmate theme to shiki theme
|
|
4701
|
-
*/
|
|
4702
|
-
function normalizeTheme(rawTheme) {
|
|
4703
|
-
// @ts-expect-error private field
|
|
4704
|
-
if (rawTheme?.[RESOLVED_KEY])
|
|
4705
|
-
return rawTheme;
|
|
4706
|
-
const theme = {
|
|
4707
|
-
...rawTheme,
|
|
4708
|
-
};
|
|
4709
|
-
// Fallback settings
|
|
4710
|
-
if (theme.tokenColors && !theme.settings) {
|
|
4711
|
-
theme.settings = theme.tokenColors;
|
|
4712
|
-
delete theme.tokenColors;
|
|
4713
|
-
}
|
|
4714
|
-
theme.type ||= 'dark';
|
|
4715
|
-
theme.colorReplacements = { ...theme.colorReplacements };
|
|
4716
|
-
theme.settings ||= [];
|
|
4717
|
-
// Guess fg/bg colors
|
|
4718
|
-
let { bg, fg } = theme;
|
|
4719
|
-
if (!bg || !fg) {
|
|
4720
|
-
/**
|
|
4721
|
-
* First try:
|
|
4722
|
-
* Theme might contain a global `tokenColor` without `name` or `scope`
|
|
4723
|
-
* Used as default value for foreground/background
|
|
4724
|
-
*/
|
|
4725
|
-
const globalSetting = theme.settings
|
|
4726
|
-
? theme.settings.find((s) => !s.name && !s.scope)
|
|
4727
|
-
: undefined;
|
|
4728
|
-
if (globalSetting?.settings?.foreground)
|
|
4729
|
-
fg = globalSetting.settings.foreground;
|
|
4730
|
-
if (globalSetting?.settings?.background)
|
|
4731
|
-
bg = globalSetting.settings.background;
|
|
4732
|
-
/**
|
|
4733
|
-
* Second try:
|
|
4734
|
-
* If there's no global `tokenColor` without `name` or `scope`
|
|
4735
|
-
* Use `editor.foreground` and `editor.background`
|
|
4736
|
-
*/
|
|
4737
|
-
if (!fg && theme?.colors?.['editor.foreground'])
|
|
4738
|
-
fg = theme.colors['editor.foreground'];
|
|
4739
|
-
if (!bg && theme?.colors?.['editor.background'])
|
|
4740
|
-
bg = theme.colors['editor.background'];
|
|
4741
|
-
/**
|
|
4742
|
-
* Last try:
|
|
4743
|
-
* If there's no fg/bg color specified in theme, use default
|
|
4744
|
-
*/
|
|
4745
|
-
if (!fg)
|
|
4746
|
-
fg = theme.type === 'light' ? VSCODE_FALLBACK_EDITOR_FG.light : VSCODE_FALLBACK_EDITOR_FG.dark;
|
|
4747
|
-
if (!bg)
|
|
4748
|
-
bg = theme.type === 'light' ? VSCODE_FALLBACK_EDITOR_BG.light : VSCODE_FALLBACK_EDITOR_BG.dark;
|
|
4749
|
-
theme.fg = fg;
|
|
4750
|
-
theme.bg = bg;
|
|
4751
|
-
}
|
|
4752
|
-
// Push a no-scope setting with fallback colors
|
|
4753
|
-
if (!(theme.settings[0] && theme.settings[0].settings && !theme.settings[0].scope)) {
|
|
4754
|
-
theme.settings.unshift({
|
|
4755
|
-
settings: {
|
|
4756
|
-
foreground: theme.fg,
|
|
4757
|
-
background: theme.bg,
|
|
4758
|
-
},
|
|
4759
|
-
});
|
|
4760
|
-
}
|
|
4761
|
-
// Push non-hex colors to color replacements, as `vscode-textmate` doesn't support them
|
|
4762
|
-
let replacementCount = 0;
|
|
4763
|
-
const replacementMap = new Map();
|
|
4764
|
-
function getReplacementColor(value) {
|
|
4765
|
-
if (replacementMap.has(value))
|
|
4766
|
-
return replacementMap.get(value);
|
|
4767
|
-
replacementCount += 1;
|
|
4768
|
-
const hex = `#${replacementCount.toString(16).padStart(8, '0').toLowerCase()}`;
|
|
4769
|
-
if (theme.colorReplacements?.[`#${hex}`]) // already exists
|
|
4770
|
-
return getReplacementColor(value);
|
|
4771
|
-
replacementMap.set(value, hex);
|
|
4772
|
-
return hex;
|
|
4773
|
-
}
|
|
4774
|
-
theme.settings = theme.settings.map((setting) => {
|
|
4775
|
-
const replaceFg = setting.settings?.foreground && !setting.settings.foreground.startsWith('#');
|
|
4776
|
-
const replaceBg = setting.settings?.background && !setting.settings.background.startsWith('#');
|
|
4777
|
-
if (!replaceFg && !replaceBg)
|
|
4778
|
-
return setting;
|
|
4779
|
-
const clone = {
|
|
4780
|
-
...setting,
|
|
4781
|
-
settings: {
|
|
4782
|
-
...setting.settings,
|
|
4783
|
-
},
|
|
4784
|
-
};
|
|
4785
|
-
if (replaceFg) {
|
|
4786
|
-
const replacement = getReplacementColor(setting.settings.foreground);
|
|
4787
|
-
theme.colorReplacements[replacement] = setting.settings.foreground;
|
|
4788
|
-
clone.settings.foreground = replacement;
|
|
4789
|
-
}
|
|
4790
|
-
if (replaceBg) {
|
|
4791
|
-
const replacement = getReplacementColor(setting.settings.background);
|
|
4792
|
-
theme.colorReplacements[replacement] = setting.settings.background;
|
|
4793
|
-
clone.settings.background = replacement;
|
|
4794
|
-
}
|
|
4795
|
-
return clone;
|
|
4796
|
-
});
|
|
4797
|
-
for (const key of Object.keys(theme.colors || {})) {
|
|
4798
|
-
// Only patch for known keys
|
|
4799
|
-
if (key === 'editor.foreground' || key === 'editor.background' || key.startsWith('terminal.ansi')) {
|
|
4800
|
-
if (!theme.colors[key]?.startsWith('#')) {
|
|
4801
|
-
const replacement = getReplacementColor(theme.colors[key]);
|
|
4802
|
-
theme.colorReplacements[replacement] = theme.colors[key];
|
|
4803
|
-
theme.colors[key] = replacement;
|
|
4804
|
-
}
|
|
4805
|
-
}
|
|
4806
|
-
}
|
|
4807
|
-
Object.defineProperty(theme, RESOLVED_KEY, {
|
|
4808
|
-
enumerable: false,
|
|
4809
|
-
writable: false,
|
|
4810
|
-
value: true,
|
|
4811
|
-
});
|
|
4812
|
-
return theme;
|
|
4703
|
+
function getHeapMax() {
|
|
4704
|
+
return 2147483648;
|
|
4813
4705
|
}
|
|
4814
|
-
|
|
4815
|
-
|
|
4816
|
-
|
|
4817
|
-
|
|
4818
|
-
|
|
4819
|
-
|
|
4820
|
-
|
|
4821
|
-
|
|
4822
|
-
|
|
4823
|
-
|
|
4824
|
-
|
|
4825
|
-
|
|
4826
|
-
_loadedLanguagesCache = null;
|
|
4827
|
-
constructor(_resolver, _themes, _langs, _alias = {}) {
|
|
4828
|
-
super(_resolver);
|
|
4829
|
-
this._resolver = _resolver;
|
|
4830
|
-
this._themes = _themes;
|
|
4831
|
-
this._langs = _langs;
|
|
4832
|
-
this._alias = _alias;
|
|
4833
|
-
_themes.forEach(t => this.loadTheme(t));
|
|
4834
|
-
_langs.forEach(l => this.loadLanguage(l));
|
|
4706
|
+
function _emscripten_get_now() {
|
|
4707
|
+
return typeof performance !== 'undefined' ? performance.now() : Date.now();
|
|
4708
|
+
}
|
|
4709
|
+
const alignUp = (x, multiple) => x + ((multiple - (x % multiple)) % multiple);
|
|
4710
|
+
async function main(init) {
|
|
4711
|
+
let wasmMemory;
|
|
4712
|
+
let buffer;
|
|
4713
|
+
const binding = {};
|
|
4714
|
+
function updateGlobalBufferAndViews(buf) {
|
|
4715
|
+
buffer = buf;
|
|
4716
|
+
binding.HEAPU8 = new Uint8Array(buf);
|
|
4717
|
+
binding.HEAPU32 = new Uint32Array(buf);
|
|
4835
4718
|
}
|
|
4836
|
-
|
|
4837
|
-
|
|
4838
|
-
return this._resolvedThemes.get(theme);
|
|
4839
|
-
else
|
|
4840
|
-
return this.loadTheme(theme);
|
|
4719
|
+
function _emscripten_memcpy_big(dest, src, num) {
|
|
4720
|
+
binding.HEAPU8.copyWithin(dest, src, src + num);
|
|
4841
4721
|
}
|
|
4842
|
-
|
|
4843
|
-
|
|
4844
|
-
|
|
4845
|
-
|
|
4846
|
-
|
|
4847
|
-
this._loadedThemesCache = null;
|
|
4722
|
+
function emscripten_realloc_buffer(size) {
|
|
4723
|
+
try {
|
|
4724
|
+
wasmMemory.grow((size - buffer.byteLength + 65535) >>> 16);
|
|
4725
|
+
updateGlobalBufferAndViews(wasmMemory.buffer);
|
|
4726
|
+
return 1;
|
|
4848
4727
|
}
|
|
4849
|
-
|
|
4850
|
-
}
|
|
4851
|
-
getLoadedThemes() {
|
|
4852
|
-
if (!this._loadedThemesCache)
|
|
4853
|
-
this._loadedThemesCache = [...this._resolvedThemes.keys()];
|
|
4854
|
-
return this._loadedThemesCache;
|
|
4728
|
+
catch { }
|
|
4855
4729
|
}
|
|
4856
|
-
|
|
4857
|
-
|
|
4858
|
-
|
|
4859
|
-
|
|
4860
|
-
|
|
4861
|
-
|
|
4862
|
-
let
|
|
4863
|
-
|
|
4864
|
-
|
|
4865
|
-
|
|
4730
|
+
function _emscripten_resize_heap(requestedSize) {
|
|
4731
|
+
const oldSize = binding.HEAPU8.length;
|
|
4732
|
+
requestedSize = requestedSize >>> 0;
|
|
4733
|
+
const maxHeapSize = getHeapMax();
|
|
4734
|
+
if (requestedSize > maxHeapSize)
|
|
4735
|
+
return false;
|
|
4736
|
+
for (let cutDown = 1; cutDown <= 4; cutDown *= 2) {
|
|
4737
|
+
let overGrownHeapSize = oldSize * (1 + 0.2 / cutDown);
|
|
4738
|
+
overGrownHeapSize = Math.min(overGrownHeapSize, requestedSize + 100663296);
|
|
4739
|
+
const newSize = Math.min(maxHeapSize, alignUp(Math.max(requestedSize, overGrownHeapSize), 65536));
|
|
4740
|
+
const replacement = emscripten_realloc_buffer(newSize);
|
|
4741
|
+
if (replacement)
|
|
4742
|
+
return true;
|
|
4866
4743
|
}
|
|
4867
|
-
|
|
4868
|
-
this._syncRegistry.setTheme(textmateTheme);
|
|
4744
|
+
return false;
|
|
4869
4745
|
}
|
|
4870
|
-
|
|
4871
|
-
|
|
4872
|
-
|
|
4873
|
-
|
|
4874
|
-
|
|
4875
|
-
|
|
4876
|
-
|
|
4877
|
-
|
|
4746
|
+
const UTF8Decoder = typeof TextDecoder != 'undefined' ? new TextDecoder('utf8') : undefined;
|
|
4747
|
+
function UTF8ArrayToString(heapOrArray, idx, maxBytesToRead = 1024) {
|
|
4748
|
+
const endIdx = idx + maxBytesToRead;
|
|
4749
|
+
let endPtr = idx;
|
|
4750
|
+
while (heapOrArray[endPtr] && !(endPtr >= endIdx))
|
|
4751
|
+
++endPtr;
|
|
4752
|
+
if (endPtr - idx > 16 && heapOrArray.buffer && UTF8Decoder) {
|
|
4753
|
+
return UTF8Decoder.decode(heapOrArray.subarray(idx, endPtr));
|
|
4754
|
+
}
|
|
4755
|
+
let str = '';
|
|
4756
|
+
while (idx < endPtr) {
|
|
4757
|
+
let u0 = heapOrArray[idx++];
|
|
4758
|
+
if (!(u0 & 128)) {
|
|
4759
|
+
str += String.fromCharCode(u0);
|
|
4760
|
+
continue;
|
|
4761
|
+
}
|
|
4762
|
+
const u1 = heapOrArray[idx++] & 63;
|
|
4763
|
+
if ((u0 & 224) === 192) {
|
|
4764
|
+
str += String.fromCharCode(((u0 & 31) << 6) | u1);
|
|
4765
|
+
continue;
|
|
4766
|
+
}
|
|
4767
|
+
const u2 = heapOrArray[idx++] & 63;
|
|
4768
|
+
if ((u0 & 240) === 224) {
|
|
4769
|
+
u0 = ((u0 & 15) << 12) | (u1 << 6) | u2;
|
|
4770
|
+
}
|
|
4771
|
+
else {
|
|
4772
|
+
u0 = ((u0 & 7) << 18)
|
|
4773
|
+
| (u1 << 12)
|
|
4774
|
+
| (u2 << 6)
|
|
4775
|
+
| (heapOrArray[idx++] & 63);
|
|
4776
|
+
}
|
|
4777
|
+
if (u0 < 65536) {
|
|
4778
|
+
str += String.fromCharCode(u0);
|
|
4779
|
+
}
|
|
4780
|
+
else {
|
|
4781
|
+
const ch = u0 - 65536;
|
|
4782
|
+
str += String.fromCharCode(55296 | (ch >> 10), 56320 | (ch & 1023));
|
|
4878
4783
|
}
|
|
4879
4784
|
}
|
|
4880
|
-
return
|
|
4785
|
+
return str;
|
|
4881
4786
|
}
|
|
4882
|
-
|
|
4883
|
-
|
|
4884
|
-
|
|
4885
|
-
|
|
4886
|
-
|
|
4887
|
-
|
|
4888
|
-
|
|
4889
|
-
|
|
4890
|
-
|
|
4891
|
-
|
|
4892
|
-
|
|
4893
|
-
|
|
4894
|
-
|
|
4895
|
-
g.name = lang.name;
|
|
4896
|
-
this._resolvedGrammars.set(lang.name, g);
|
|
4897
|
-
if (lang.aliases) {
|
|
4898
|
-
lang.aliases.forEach((alias) => {
|
|
4899
|
-
this._alias[alias] = lang.name;
|
|
4900
|
-
});
|
|
4901
|
-
}
|
|
4902
|
-
// Reset cache
|
|
4903
|
-
this._loadedLanguagesCache = null;
|
|
4904
|
-
// If there is a language that embeds this language lazily, we need to reload it
|
|
4905
|
-
if (embeddedLazilyBy.size) {
|
|
4906
|
-
for (const e of embeddedLazilyBy) {
|
|
4907
|
-
this._resolvedGrammars.delete(e.name);
|
|
4908
|
-
// Reset cache
|
|
4909
|
-
this._loadedLanguagesCache = null;
|
|
4910
|
-
// @ts-expect-error clear cache
|
|
4911
|
-
this._syncRegistry?._injectionGrammars?.delete(e.scopeName);
|
|
4912
|
-
// @ts-expect-error clear cache
|
|
4913
|
-
this._syncRegistry?._grammars?.delete(e.scopeName);
|
|
4914
|
-
await this.loadLanguage(this._langMap.get(e.name));
|
|
4915
|
-
}
|
|
4916
|
-
}
|
|
4917
|
-
}
|
|
4918
|
-
async init() {
|
|
4919
|
-
this._themes.map(t => this.loadTheme(t));
|
|
4920
|
-
await this.loadLanguages(this._langs);
|
|
4921
|
-
}
|
|
4922
|
-
dispose() {
|
|
4923
|
-
super.dispose();
|
|
4924
|
-
this._resolvedThemes.clear();
|
|
4925
|
-
this._resolvedGrammars.clear();
|
|
4926
|
-
this._langMap.clear();
|
|
4927
|
-
this._langGraph.clear();
|
|
4928
|
-
this._loadedThemesCache = null;
|
|
4929
|
-
}
|
|
4930
|
-
async loadLanguages(langs) {
|
|
4931
|
-
for (const lang of langs)
|
|
4932
|
-
this.resolveEmbeddedLanguages(lang);
|
|
4933
|
-
const langsGraphArray = Array.from(this._langGraph.entries());
|
|
4934
|
-
const missingLangs = langsGraphArray.filter(([_, lang]) => !lang);
|
|
4935
|
-
if (missingLangs.length) {
|
|
4936
|
-
const dependents = langsGraphArray
|
|
4937
|
-
.filter(([_, lang]) => lang && lang.embeddedLangs?.some(l => missingLangs.map(([name]) => name).includes(l)))
|
|
4938
|
-
.filter(lang => !missingLangs.includes(lang));
|
|
4939
|
-
throw new ShikiError(`Missing languages ${missingLangs.map(([name]) => `\`${name}\``).join(', ')}, required by ${dependents.map(([name]) => `\`${name}\``).join(', ')}`);
|
|
4940
|
-
}
|
|
4941
|
-
for (const [_, lang] of langsGraphArray)
|
|
4942
|
-
this._resolver.addLanguage(lang);
|
|
4943
|
-
for (const [_, lang] of langsGraphArray)
|
|
4944
|
-
await this.loadLanguage(lang);
|
|
4945
|
-
}
|
|
4946
|
-
getLoadedLanguages() {
|
|
4947
|
-
if (!this._loadedLanguagesCache) {
|
|
4948
|
-
this._loadedLanguagesCache = [
|
|
4949
|
-
...new Set([...this._resolvedGrammars.keys(), ...Object.keys(this._alias)]),
|
|
4950
|
-
];
|
|
4951
|
-
}
|
|
4952
|
-
return this._loadedLanguagesCache;
|
|
4953
|
-
}
|
|
4954
|
-
resolveEmbeddedLanguages(lang) {
|
|
4955
|
-
this._langMap.set(lang.name, lang);
|
|
4956
|
-
this._langGraph.set(lang.name, lang);
|
|
4957
|
-
if (lang.embeddedLangs) {
|
|
4958
|
-
for (const embeddedLang of lang.embeddedLangs)
|
|
4959
|
-
this._langGraph.set(embeddedLang, this._langMap.get(embeddedLang));
|
|
4960
|
-
}
|
|
4961
|
-
}
|
|
4962
|
-
}
|
|
4963
|
-
|
|
4964
|
-
class Resolver {
|
|
4965
|
-
_langs = new Map();
|
|
4966
|
-
_scopeToLang = new Map();
|
|
4967
|
-
_injections = new Map();
|
|
4968
|
-
_onigLibPromise;
|
|
4969
|
-
constructor(onigLibPromise, langs) {
|
|
4970
|
-
this._onigLibPromise = onigLibPromise
|
|
4971
|
-
.then(engine => ({
|
|
4972
|
-
createOnigScanner: patterns => engine.createScanner(patterns),
|
|
4973
|
-
createOnigString: s => engine.createString(s),
|
|
4974
|
-
}));
|
|
4975
|
-
langs.forEach(i => this.addLanguage(i));
|
|
4976
|
-
}
|
|
4977
|
-
get onigLib() {
|
|
4978
|
-
return this._onigLibPromise;
|
|
4979
|
-
}
|
|
4980
|
-
getLangRegistration(langIdOrAlias) {
|
|
4981
|
-
return this._langs.get(langIdOrAlias);
|
|
4982
|
-
}
|
|
4983
|
-
async loadGrammar(scopeName) {
|
|
4984
|
-
return this._scopeToLang.get(scopeName);
|
|
4985
|
-
}
|
|
4986
|
-
addLanguage(l) {
|
|
4987
|
-
this._langs.set(l.name, l);
|
|
4988
|
-
if (l.aliases) {
|
|
4989
|
-
l.aliases.forEach((a) => {
|
|
4990
|
-
this._langs.set(a, l);
|
|
4991
|
-
});
|
|
4992
|
-
}
|
|
4993
|
-
this._scopeToLang.set(l.scopeName, l);
|
|
4994
|
-
if (l.injectTo) {
|
|
4995
|
-
l.injectTo.forEach((i) => {
|
|
4996
|
-
if (!this._injections.get(i))
|
|
4997
|
-
this._injections.set(i, []);
|
|
4998
|
-
this._injections.get(i).push(l.scopeName);
|
|
4999
|
-
});
|
|
5000
|
-
}
|
|
5001
|
-
}
|
|
5002
|
-
getInjections(scopeName) {
|
|
5003
|
-
const scopeParts = scopeName.split('.');
|
|
5004
|
-
let injections = [];
|
|
5005
|
-
for (let i = 1; i <= scopeParts.length; i++) {
|
|
5006
|
-
const subScopeName = scopeParts.slice(0, i).join('.');
|
|
5007
|
-
injections = [...injections, ...(this._injections.get(subScopeName) || [])];
|
|
5008
|
-
}
|
|
5009
|
-
return injections;
|
|
5010
|
-
}
|
|
5011
|
-
}
|
|
5012
|
-
|
|
5013
|
-
function getHeapMax() {
|
|
5014
|
-
return 2147483648;
|
|
5015
|
-
}
|
|
5016
|
-
function _emscripten_get_now() {
|
|
5017
|
-
return typeof performance !== 'undefined' ? performance.now() : Date.now();
|
|
5018
|
-
}
|
|
5019
|
-
const alignUp = (x, multiple) => x + ((multiple - (x % multiple)) % multiple);
|
|
5020
|
-
async function main(init) {
|
|
5021
|
-
let wasmMemory;
|
|
5022
|
-
let buffer;
|
|
5023
|
-
const binding = {};
|
|
5024
|
-
function updateGlobalBufferAndViews(buf) {
|
|
5025
|
-
buffer = buf;
|
|
5026
|
-
binding.HEAPU8 = new Uint8Array(buf);
|
|
5027
|
-
binding.HEAPU32 = new Uint32Array(buf);
|
|
5028
|
-
}
|
|
5029
|
-
function _emscripten_memcpy_big(dest, src, num) {
|
|
5030
|
-
binding.HEAPU8.copyWithin(dest, src, src + num);
|
|
5031
|
-
}
|
|
5032
|
-
function emscripten_realloc_buffer(size) {
|
|
5033
|
-
try {
|
|
5034
|
-
wasmMemory.grow((size - buffer.byteLength + 65535) >>> 16);
|
|
5035
|
-
updateGlobalBufferAndViews(wasmMemory.buffer);
|
|
5036
|
-
return 1;
|
|
5037
|
-
}
|
|
5038
|
-
catch { }
|
|
5039
|
-
}
|
|
5040
|
-
function _emscripten_resize_heap(requestedSize) {
|
|
5041
|
-
const oldSize = binding.HEAPU8.length;
|
|
5042
|
-
requestedSize = requestedSize >>> 0;
|
|
5043
|
-
const maxHeapSize = getHeapMax();
|
|
5044
|
-
if (requestedSize > maxHeapSize)
|
|
5045
|
-
return false;
|
|
5046
|
-
for (let cutDown = 1; cutDown <= 4; cutDown *= 2) {
|
|
5047
|
-
let overGrownHeapSize = oldSize * (1 + 0.2 / cutDown);
|
|
5048
|
-
overGrownHeapSize = Math.min(overGrownHeapSize, requestedSize + 100663296);
|
|
5049
|
-
const newSize = Math.min(maxHeapSize, alignUp(Math.max(requestedSize, overGrownHeapSize), 65536));
|
|
5050
|
-
const replacement = emscripten_realloc_buffer(newSize);
|
|
5051
|
-
if (replacement)
|
|
5052
|
-
return true;
|
|
5053
|
-
}
|
|
5054
|
-
return false;
|
|
5055
|
-
}
|
|
5056
|
-
const UTF8Decoder = typeof TextDecoder != 'undefined' ? new TextDecoder('utf8') : undefined;
|
|
5057
|
-
function UTF8ArrayToString(heapOrArray, idx, maxBytesToRead = 1024) {
|
|
5058
|
-
const endIdx = idx + maxBytesToRead;
|
|
5059
|
-
let endPtr = idx;
|
|
5060
|
-
while (heapOrArray[endPtr] && !(endPtr >= endIdx))
|
|
5061
|
-
++endPtr;
|
|
5062
|
-
if (endPtr - idx > 16 && heapOrArray.buffer && UTF8Decoder) {
|
|
5063
|
-
return UTF8Decoder.decode(heapOrArray.subarray(idx, endPtr));
|
|
5064
|
-
}
|
|
5065
|
-
let str = '';
|
|
5066
|
-
while (idx < endPtr) {
|
|
5067
|
-
let u0 = heapOrArray[idx++];
|
|
5068
|
-
if (!(u0 & 128)) {
|
|
5069
|
-
str += String.fromCharCode(u0);
|
|
5070
|
-
continue;
|
|
5071
|
-
}
|
|
5072
|
-
const u1 = heapOrArray[idx++] & 63;
|
|
5073
|
-
if ((u0 & 224) === 192) {
|
|
5074
|
-
str += String.fromCharCode(((u0 & 31) << 6) | u1);
|
|
5075
|
-
continue;
|
|
5076
|
-
}
|
|
5077
|
-
const u2 = heapOrArray[idx++] & 63;
|
|
5078
|
-
if ((u0 & 240) === 224) {
|
|
5079
|
-
u0 = ((u0 & 15) << 12) | (u1 << 6) | u2;
|
|
5080
|
-
}
|
|
5081
|
-
else {
|
|
5082
|
-
u0 = ((u0 & 7) << 18)
|
|
5083
|
-
| (u1 << 12)
|
|
5084
|
-
| (u2 << 6)
|
|
5085
|
-
| (heapOrArray[idx++] & 63);
|
|
5086
|
-
}
|
|
5087
|
-
if (u0 < 65536) {
|
|
5088
|
-
str += String.fromCharCode(u0);
|
|
5089
|
-
}
|
|
5090
|
-
else {
|
|
5091
|
-
const ch = u0 - 65536;
|
|
5092
|
-
str += String.fromCharCode(55296 | (ch >> 10), 56320 | (ch & 1023));
|
|
5093
|
-
}
|
|
5094
|
-
}
|
|
5095
|
-
return str;
|
|
5096
|
-
}
|
|
5097
|
-
function UTF8ToString(ptr, maxBytesToRead) {
|
|
5098
|
-
return ptr ? UTF8ArrayToString(binding.HEAPU8, ptr, maxBytesToRead) : '';
|
|
5099
|
-
}
|
|
5100
|
-
const asmLibraryArg = {
|
|
5101
|
-
emscripten_get_now: _emscripten_get_now,
|
|
5102
|
-
emscripten_memcpy_big: _emscripten_memcpy_big,
|
|
5103
|
-
emscripten_resize_heap: _emscripten_resize_heap,
|
|
5104
|
-
fd_write: () => 0,
|
|
5105
|
-
};
|
|
5106
|
-
async function createWasm() {
|
|
5107
|
-
const info = {
|
|
5108
|
-
env: asmLibraryArg,
|
|
5109
|
-
wasi_snapshot_preview1: asmLibraryArg,
|
|
4787
|
+
function UTF8ToString(ptr, maxBytesToRead) {
|
|
4788
|
+
return ptr ? UTF8ArrayToString(binding.HEAPU8, ptr, maxBytesToRead) : '';
|
|
4789
|
+
}
|
|
4790
|
+
const asmLibraryArg = {
|
|
4791
|
+
emscripten_get_now: _emscripten_get_now,
|
|
4792
|
+
emscripten_memcpy_big: _emscripten_memcpy_big,
|
|
4793
|
+
emscripten_resize_heap: _emscripten_resize_heap,
|
|
4794
|
+
fd_write: () => 0,
|
|
4795
|
+
};
|
|
4796
|
+
async function createWasm() {
|
|
4797
|
+
const info = {
|
|
4798
|
+
env: asmLibraryArg,
|
|
4799
|
+
wasi_snapshot_preview1: asmLibraryArg,
|
|
5110
4800
|
};
|
|
5111
4801
|
const exports = await init(info);
|
|
5112
4802
|
wasmMemory = exports.memory;
|
|
@@ -5241,284 +4931,599 @@ class UtfString {
|
|
|
5241
4931
|
this.utf16OffsetToUtf8 = utf16OffsetToUtf8;
|
|
5242
4932
|
this.utf8OffsetToUtf16 = utf8OffsetToUtf16;
|
|
5243
4933
|
}
|
|
5244
|
-
createString(onigBinding) {
|
|
5245
|
-
const result = onigBinding.omalloc(this.utf8Length);
|
|
5246
|
-
onigBinding.HEAPU8.set(this.utf8Value, result);
|
|
5247
|
-
return result;
|
|
4934
|
+
createString(onigBinding) {
|
|
4935
|
+
const result = onigBinding.omalloc(this.utf8Length);
|
|
4936
|
+
onigBinding.HEAPU8.set(this.utf8Value, result);
|
|
4937
|
+
return result;
|
|
4938
|
+
}
|
|
4939
|
+
}
|
|
4940
|
+
class OnigString {
|
|
4941
|
+
static LAST_ID = 0;
|
|
4942
|
+
static _sharedPtr = 0; // a pointer to a string of 10000 bytes
|
|
4943
|
+
static _sharedPtrInUse = false;
|
|
4944
|
+
id = (++OnigString.LAST_ID);
|
|
4945
|
+
_onigBinding;
|
|
4946
|
+
content;
|
|
4947
|
+
utf16Length;
|
|
4948
|
+
utf8Length;
|
|
4949
|
+
utf16OffsetToUtf8;
|
|
4950
|
+
utf8OffsetToUtf16;
|
|
4951
|
+
ptr;
|
|
4952
|
+
constructor(str) {
|
|
4953
|
+
if (!onigBinding)
|
|
4954
|
+
throw new ShikiError('Must invoke loadWasm first.');
|
|
4955
|
+
this._onigBinding = onigBinding;
|
|
4956
|
+
this.content = str;
|
|
4957
|
+
const utfString = new UtfString(str);
|
|
4958
|
+
this.utf16Length = utfString.utf16Length;
|
|
4959
|
+
this.utf8Length = utfString.utf8Length;
|
|
4960
|
+
this.utf16OffsetToUtf8 = utfString.utf16OffsetToUtf8;
|
|
4961
|
+
this.utf8OffsetToUtf16 = utfString.utf8OffsetToUtf16;
|
|
4962
|
+
if (this.utf8Length < 10000 && !OnigString._sharedPtrInUse) {
|
|
4963
|
+
if (!OnigString._sharedPtr)
|
|
4964
|
+
OnigString._sharedPtr = onigBinding.omalloc(10000);
|
|
4965
|
+
OnigString._sharedPtrInUse = true;
|
|
4966
|
+
onigBinding.HEAPU8.set(utfString.utf8Value, OnigString._sharedPtr);
|
|
4967
|
+
this.ptr = OnigString._sharedPtr;
|
|
4968
|
+
}
|
|
4969
|
+
else {
|
|
4970
|
+
this.ptr = utfString.createString(onigBinding);
|
|
4971
|
+
}
|
|
4972
|
+
}
|
|
4973
|
+
convertUtf8OffsetToUtf16(utf8Offset) {
|
|
4974
|
+
if (this.utf8OffsetToUtf16) {
|
|
4975
|
+
if (utf8Offset < 0)
|
|
4976
|
+
return 0;
|
|
4977
|
+
if (utf8Offset > this.utf8Length)
|
|
4978
|
+
return this.utf16Length;
|
|
4979
|
+
return this.utf8OffsetToUtf16[utf8Offset];
|
|
4980
|
+
}
|
|
4981
|
+
return utf8Offset;
|
|
4982
|
+
}
|
|
4983
|
+
convertUtf16OffsetToUtf8(utf16Offset) {
|
|
4984
|
+
if (this.utf16OffsetToUtf8) {
|
|
4985
|
+
if (utf16Offset < 0)
|
|
4986
|
+
return 0;
|
|
4987
|
+
if (utf16Offset > this.utf16Length)
|
|
4988
|
+
return this.utf8Length;
|
|
4989
|
+
return this.utf16OffsetToUtf8[utf16Offset];
|
|
4990
|
+
}
|
|
4991
|
+
return utf16Offset;
|
|
4992
|
+
}
|
|
4993
|
+
dispose() {
|
|
4994
|
+
if (this.ptr === OnigString._sharedPtr)
|
|
4995
|
+
OnigString._sharedPtrInUse = false;
|
|
4996
|
+
else
|
|
4997
|
+
this._onigBinding.ofree(this.ptr);
|
|
4998
|
+
}
|
|
4999
|
+
}
|
|
5000
|
+
class OnigScanner {
|
|
5001
|
+
_onigBinding;
|
|
5002
|
+
_ptr;
|
|
5003
|
+
constructor(patterns) {
|
|
5004
|
+
if (!onigBinding)
|
|
5005
|
+
throw new ShikiError('Must invoke loadWasm first.');
|
|
5006
|
+
const strPtrsArr = [];
|
|
5007
|
+
const strLenArr = [];
|
|
5008
|
+
for (let i = 0, len = patterns.length; i < len; i++) {
|
|
5009
|
+
const utfString = new UtfString(patterns[i]);
|
|
5010
|
+
strPtrsArr[i] = utfString.createString(onigBinding);
|
|
5011
|
+
strLenArr[i] = utfString.utf8Length;
|
|
5012
|
+
}
|
|
5013
|
+
const strPtrsPtr = onigBinding.omalloc(4 * patterns.length);
|
|
5014
|
+
onigBinding.HEAPU32.set(strPtrsArr, strPtrsPtr / 4);
|
|
5015
|
+
const strLenPtr = onigBinding.omalloc(4 * patterns.length);
|
|
5016
|
+
onigBinding.HEAPU32.set(strLenArr, strLenPtr / 4);
|
|
5017
|
+
const scannerPtr = onigBinding.createOnigScanner(strPtrsPtr, strLenPtr, patterns.length);
|
|
5018
|
+
for (let i = 0, len = patterns.length; i < len; i++)
|
|
5019
|
+
onigBinding.ofree(strPtrsArr[i]);
|
|
5020
|
+
onigBinding.ofree(strLenPtr);
|
|
5021
|
+
onigBinding.ofree(strPtrsPtr);
|
|
5022
|
+
if (scannerPtr === 0)
|
|
5023
|
+
throwLastOnigError(onigBinding);
|
|
5024
|
+
this._onigBinding = onigBinding;
|
|
5025
|
+
this._ptr = scannerPtr;
|
|
5026
|
+
}
|
|
5027
|
+
dispose() {
|
|
5028
|
+
this._onigBinding.freeOnigScanner(this._ptr);
|
|
5029
|
+
}
|
|
5030
|
+
findNextMatchSync(string, startPosition, arg) {
|
|
5031
|
+
// let debugCall = defaultDebugCall
|
|
5032
|
+
let options = 0 /* FindOption.None */;
|
|
5033
|
+
if (typeof arg === 'number') {
|
|
5034
|
+
// if (arg & FindOption.DebugCall)
|
|
5035
|
+
// debugCall = true
|
|
5036
|
+
options = arg;
|
|
5037
|
+
}
|
|
5038
|
+
if (typeof string === 'string') {
|
|
5039
|
+
string = new OnigString(string);
|
|
5040
|
+
const result = this._findNextMatchSync(string, startPosition, false, options);
|
|
5041
|
+
string.dispose();
|
|
5042
|
+
return result;
|
|
5043
|
+
}
|
|
5044
|
+
return this._findNextMatchSync(string, startPosition, false, options);
|
|
5045
|
+
}
|
|
5046
|
+
_findNextMatchSync(string, startPosition, debugCall, options) {
|
|
5047
|
+
const onigBinding = this._onigBinding;
|
|
5048
|
+
// let resultPtr: Pointer
|
|
5049
|
+
// if (debugCall)
|
|
5050
|
+
// resultPtr = onigBinding.findNextOnigScannerMatchDbg(this._ptr, string.id, string.ptr, string.utf8Length, string.convertUtf16OffsetToUtf8(startPosition), options)
|
|
5051
|
+
// else
|
|
5052
|
+
const resultPtr = onigBinding.findNextOnigScannerMatch(this._ptr, string.id, string.ptr, string.utf8Length, string.convertUtf16OffsetToUtf8(startPosition), options);
|
|
5053
|
+
if (resultPtr === 0) {
|
|
5054
|
+
// no match
|
|
5055
|
+
return null;
|
|
5056
|
+
}
|
|
5057
|
+
const HEAPU32 = onigBinding.HEAPU32;
|
|
5058
|
+
let offset = resultPtr / 4; // byte offset -> uint32 offset
|
|
5059
|
+
const index = HEAPU32[offset++];
|
|
5060
|
+
const count = HEAPU32[offset++];
|
|
5061
|
+
const captureIndices = [];
|
|
5062
|
+
for (let i = 0; i < count; i++) {
|
|
5063
|
+
const beg = string.convertUtf8OffsetToUtf16(HEAPU32[offset++]);
|
|
5064
|
+
const end = string.convertUtf8OffsetToUtf16(HEAPU32[offset++]);
|
|
5065
|
+
captureIndices[i] = {
|
|
5066
|
+
start: beg,
|
|
5067
|
+
end,
|
|
5068
|
+
length: end - beg,
|
|
5069
|
+
};
|
|
5070
|
+
}
|
|
5071
|
+
return {
|
|
5072
|
+
index,
|
|
5073
|
+
captureIndices,
|
|
5074
|
+
};
|
|
5075
|
+
}
|
|
5076
|
+
}
|
|
5077
|
+
function isInstantiatorOptionsObject(dataOrOptions) {
|
|
5078
|
+
return (typeof dataOrOptions.instantiator === 'function');
|
|
5079
|
+
}
|
|
5080
|
+
function isInstantiatorModule(dataOrOptions) {
|
|
5081
|
+
return (typeof dataOrOptions.default === 'function');
|
|
5082
|
+
}
|
|
5083
|
+
function isDataOptionsObject(dataOrOptions) {
|
|
5084
|
+
return (typeof dataOrOptions.data !== 'undefined');
|
|
5085
|
+
}
|
|
5086
|
+
function isResponse(dataOrOptions) {
|
|
5087
|
+
return (typeof Response !== 'undefined' && dataOrOptions instanceof Response);
|
|
5088
|
+
}
|
|
5089
|
+
function isArrayBuffer(data) {
|
|
5090
|
+
return (typeof ArrayBuffer !== 'undefined' && (data instanceof ArrayBuffer || ArrayBuffer.isView(data)))
|
|
5091
|
+
// eslint-disable-next-line node/prefer-global/buffer
|
|
5092
|
+
|| (typeof Buffer !== 'undefined' && Buffer.isBuffer?.(data))
|
|
5093
|
+
|| (typeof SharedArrayBuffer !== 'undefined' && data instanceof SharedArrayBuffer)
|
|
5094
|
+
|| (typeof Uint32Array !== 'undefined' && data instanceof Uint32Array);
|
|
5095
|
+
}
|
|
5096
|
+
let initPromise;
|
|
5097
|
+
function loadWasm(options) {
|
|
5098
|
+
if (initPromise)
|
|
5099
|
+
return initPromise;
|
|
5100
|
+
async function _load() {
|
|
5101
|
+
onigBinding = await main(async (info) => {
|
|
5102
|
+
let instance = options;
|
|
5103
|
+
instance = await instance;
|
|
5104
|
+
if (typeof instance === 'function')
|
|
5105
|
+
instance = await instance(info);
|
|
5106
|
+
if (typeof instance === 'function')
|
|
5107
|
+
instance = await instance(info);
|
|
5108
|
+
if (isInstantiatorOptionsObject(instance)) {
|
|
5109
|
+
instance = await instance.instantiator(info);
|
|
5110
|
+
}
|
|
5111
|
+
else if (isInstantiatorModule(instance)) {
|
|
5112
|
+
instance = await instance.default(info);
|
|
5113
|
+
}
|
|
5114
|
+
else {
|
|
5115
|
+
if (isDataOptionsObject(instance))
|
|
5116
|
+
instance = instance.data;
|
|
5117
|
+
if (isResponse(instance)) {
|
|
5118
|
+
if (typeof WebAssembly.instantiateStreaming === 'function')
|
|
5119
|
+
instance = await _makeResponseStreamingLoader(instance)(info);
|
|
5120
|
+
else
|
|
5121
|
+
instance = await _makeResponseNonStreamingLoader(instance)(info);
|
|
5122
|
+
}
|
|
5123
|
+
else if (isArrayBuffer(instance)) {
|
|
5124
|
+
instance = await _makeArrayBufferLoader(instance)(info);
|
|
5125
|
+
}
|
|
5126
|
+
// import("shiki/onig.wasm") returns `{ default: WebAssembly.Module }` on cloudflare workers
|
|
5127
|
+
// https://developers.cloudflare.com/workers/wrangler/bundling/
|
|
5128
|
+
else if (instance instanceof WebAssembly.Module) {
|
|
5129
|
+
instance = await _makeArrayBufferLoader(instance)(info);
|
|
5130
|
+
}
|
|
5131
|
+
else if ('default' in instance && instance.default instanceof WebAssembly.Module) {
|
|
5132
|
+
instance = await _makeArrayBufferLoader(instance.default)(info);
|
|
5133
|
+
}
|
|
5134
|
+
}
|
|
5135
|
+
if ('instance' in instance)
|
|
5136
|
+
instance = instance.instance;
|
|
5137
|
+
if ('exports' in instance)
|
|
5138
|
+
instance = instance.exports;
|
|
5139
|
+
return instance;
|
|
5140
|
+
});
|
|
5141
|
+
}
|
|
5142
|
+
initPromise = _load();
|
|
5143
|
+
return initPromise;
|
|
5144
|
+
}
|
|
5145
|
+
function _makeArrayBufferLoader(data) {
|
|
5146
|
+
return importObject => WebAssembly.instantiate(data, importObject);
|
|
5147
|
+
}
|
|
5148
|
+
function _makeResponseStreamingLoader(data) {
|
|
5149
|
+
return importObject => WebAssembly.instantiateStreaming(data, importObject);
|
|
5150
|
+
}
|
|
5151
|
+
function _makeResponseNonStreamingLoader(data) {
|
|
5152
|
+
return async (importObject) => {
|
|
5153
|
+
const arrayBuffer = await data.arrayBuffer();
|
|
5154
|
+
return WebAssembly.instantiate(arrayBuffer, importObject);
|
|
5155
|
+
};
|
|
5156
|
+
}
|
|
5157
|
+
// export function createOnigString(str: string) {
|
|
5158
|
+
// return new OnigString(str)
|
|
5159
|
+
// }
|
|
5160
|
+
// export function createOnigScanner(patterns: string[]) {
|
|
5161
|
+
// return new OnigScanner(patterns)
|
|
5162
|
+
// }
|
|
5163
|
+
// export function setDefaultDebugCall(_defaultDebugCall: boolean): void {
|
|
5164
|
+
// defaultDebugCall = _defaultDebugCall
|
|
5165
|
+
// }
|
|
5166
|
+
|
|
5167
|
+
async function createWasmOnigEngine(options) {
|
|
5168
|
+
if (options)
|
|
5169
|
+
await loadWasm(options);
|
|
5170
|
+
return {
|
|
5171
|
+
createScanner(patterns) {
|
|
5172
|
+
return new OnigScanner(patterns);
|
|
5173
|
+
},
|
|
5174
|
+
createString(s) {
|
|
5175
|
+
return new OnigString(s);
|
|
5176
|
+
},
|
|
5177
|
+
};
|
|
5178
|
+
}
|
|
5179
|
+
|
|
5180
|
+
/**
|
|
5181
|
+
* https://github.com/microsoft/vscode/blob/f7f05dee53fb33fe023db2e06e30a89d3094488f/src/vs/platform/theme/common/colorRegistry.ts#L258-L268
|
|
5182
|
+
*/
|
|
5183
|
+
const VSCODE_FALLBACK_EDITOR_FG = { light: '#333333', dark: '#bbbbbb' };
|
|
5184
|
+
const VSCODE_FALLBACK_EDITOR_BG = { light: '#fffffe', dark: '#1e1e1e' };
|
|
5185
|
+
const RESOLVED_KEY = '__shiki_resolved';
|
|
5186
|
+
/**
|
|
5187
|
+
* Normalize a textmate theme to shiki theme
|
|
5188
|
+
*/
|
|
5189
|
+
function normalizeTheme(rawTheme) {
|
|
5190
|
+
// @ts-expect-error private field
|
|
5191
|
+
if (rawTheme?.[RESOLVED_KEY])
|
|
5192
|
+
return rawTheme;
|
|
5193
|
+
const theme = {
|
|
5194
|
+
...rawTheme,
|
|
5195
|
+
};
|
|
5196
|
+
// Fallback settings
|
|
5197
|
+
if (theme.tokenColors && !theme.settings) {
|
|
5198
|
+
theme.settings = theme.tokenColors;
|
|
5199
|
+
delete theme.tokenColors;
|
|
5200
|
+
}
|
|
5201
|
+
theme.type ||= 'dark';
|
|
5202
|
+
theme.colorReplacements = { ...theme.colorReplacements };
|
|
5203
|
+
theme.settings ||= [];
|
|
5204
|
+
// Guess fg/bg colors
|
|
5205
|
+
let { bg, fg } = theme;
|
|
5206
|
+
if (!bg || !fg) {
|
|
5207
|
+
/**
|
|
5208
|
+
* First try:
|
|
5209
|
+
* Theme might contain a global `tokenColor` without `name` or `scope`
|
|
5210
|
+
* Used as default value for foreground/background
|
|
5211
|
+
*/
|
|
5212
|
+
const globalSetting = theme.settings
|
|
5213
|
+
? theme.settings.find((s) => !s.name && !s.scope)
|
|
5214
|
+
: undefined;
|
|
5215
|
+
if (globalSetting?.settings?.foreground)
|
|
5216
|
+
fg = globalSetting.settings.foreground;
|
|
5217
|
+
if (globalSetting?.settings?.background)
|
|
5218
|
+
bg = globalSetting.settings.background;
|
|
5219
|
+
/**
|
|
5220
|
+
* Second try:
|
|
5221
|
+
* If there's no global `tokenColor` without `name` or `scope`
|
|
5222
|
+
* Use `editor.foreground` and `editor.background`
|
|
5223
|
+
*/
|
|
5224
|
+
if (!fg && theme?.colors?.['editor.foreground'])
|
|
5225
|
+
fg = theme.colors['editor.foreground'];
|
|
5226
|
+
if (!bg && theme?.colors?.['editor.background'])
|
|
5227
|
+
bg = theme.colors['editor.background'];
|
|
5228
|
+
/**
|
|
5229
|
+
* Last try:
|
|
5230
|
+
* If there's no fg/bg color specified in theme, use default
|
|
5231
|
+
*/
|
|
5232
|
+
if (!fg)
|
|
5233
|
+
fg = theme.type === 'light' ? VSCODE_FALLBACK_EDITOR_FG.light : VSCODE_FALLBACK_EDITOR_FG.dark;
|
|
5234
|
+
if (!bg)
|
|
5235
|
+
bg = theme.type === 'light' ? VSCODE_FALLBACK_EDITOR_BG.light : VSCODE_FALLBACK_EDITOR_BG.dark;
|
|
5236
|
+
theme.fg = fg;
|
|
5237
|
+
theme.bg = bg;
|
|
5238
|
+
}
|
|
5239
|
+
// Push a no-scope setting with fallback colors
|
|
5240
|
+
if (!(theme.settings[0] && theme.settings[0].settings && !theme.settings[0].scope)) {
|
|
5241
|
+
theme.settings.unshift({
|
|
5242
|
+
settings: {
|
|
5243
|
+
foreground: theme.fg,
|
|
5244
|
+
background: theme.bg,
|
|
5245
|
+
},
|
|
5246
|
+
});
|
|
5247
|
+
}
|
|
5248
|
+
// Push non-hex colors to color replacements, as `vscode-textmate` doesn't support them
|
|
5249
|
+
let replacementCount = 0;
|
|
5250
|
+
const replacementMap = new Map();
|
|
5251
|
+
function getReplacementColor(value) {
|
|
5252
|
+
if (replacementMap.has(value))
|
|
5253
|
+
return replacementMap.get(value);
|
|
5254
|
+
replacementCount += 1;
|
|
5255
|
+
const hex = `#${replacementCount.toString(16).padStart(8, '0').toLowerCase()}`;
|
|
5256
|
+
if (theme.colorReplacements?.[`#${hex}`]) // already exists
|
|
5257
|
+
return getReplacementColor(value);
|
|
5258
|
+
replacementMap.set(value, hex);
|
|
5259
|
+
return hex;
|
|
5248
5260
|
}
|
|
5249
|
-
|
|
5250
|
-
|
|
5251
|
-
|
|
5252
|
-
|
|
5253
|
-
|
|
5254
|
-
|
|
5255
|
-
|
|
5256
|
-
|
|
5257
|
-
|
|
5258
|
-
|
|
5259
|
-
|
|
5260
|
-
|
|
5261
|
-
|
|
5262
|
-
|
|
5263
|
-
|
|
5264
|
-
throw new ShikiError('Must invoke loadWasm first.');
|
|
5265
|
-
this._onigBinding = onigBinding;
|
|
5266
|
-
this.content = str;
|
|
5267
|
-
const utfString = new UtfString(str);
|
|
5268
|
-
this.utf16Length = utfString.utf16Length;
|
|
5269
|
-
this.utf8Length = utfString.utf8Length;
|
|
5270
|
-
this.utf16OffsetToUtf8 = utfString.utf16OffsetToUtf8;
|
|
5271
|
-
this.utf8OffsetToUtf16 = utfString.utf8OffsetToUtf16;
|
|
5272
|
-
if (this.utf8Length < 10000 && !OnigString._sharedPtrInUse) {
|
|
5273
|
-
if (!OnigString._sharedPtr)
|
|
5274
|
-
OnigString._sharedPtr = onigBinding.omalloc(10000);
|
|
5275
|
-
OnigString._sharedPtrInUse = true;
|
|
5276
|
-
onigBinding.HEAPU8.set(utfString.utf8Value, OnigString._sharedPtr);
|
|
5277
|
-
this.ptr = OnigString._sharedPtr;
|
|
5261
|
+
theme.settings = theme.settings.map((setting) => {
|
|
5262
|
+
const replaceFg = setting.settings?.foreground && !setting.settings.foreground.startsWith('#');
|
|
5263
|
+
const replaceBg = setting.settings?.background && !setting.settings.background.startsWith('#');
|
|
5264
|
+
if (!replaceFg && !replaceBg)
|
|
5265
|
+
return setting;
|
|
5266
|
+
const clone = {
|
|
5267
|
+
...setting,
|
|
5268
|
+
settings: {
|
|
5269
|
+
...setting.settings,
|
|
5270
|
+
},
|
|
5271
|
+
};
|
|
5272
|
+
if (replaceFg) {
|
|
5273
|
+
const replacement = getReplacementColor(setting.settings.foreground);
|
|
5274
|
+
theme.colorReplacements[replacement] = setting.settings.foreground;
|
|
5275
|
+
clone.settings.foreground = replacement;
|
|
5278
5276
|
}
|
|
5279
|
-
|
|
5280
|
-
|
|
5277
|
+
if (replaceBg) {
|
|
5278
|
+
const replacement = getReplacementColor(setting.settings.background);
|
|
5279
|
+
theme.colorReplacements[replacement] = setting.settings.background;
|
|
5280
|
+
clone.settings.background = replacement;
|
|
5281
|
+
}
|
|
5282
|
+
return clone;
|
|
5283
|
+
});
|
|
5284
|
+
for (const key of Object.keys(theme.colors || {})) {
|
|
5285
|
+
// Only patch for known keys
|
|
5286
|
+
if (key === 'editor.foreground' || key === 'editor.background' || key.startsWith('terminal.ansi')) {
|
|
5287
|
+
if (!theme.colors[key]?.startsWith('#')) {
|
|
5288
|
+
const replacement = getReplacementColor(theme.colors[key]);
|
|
5289
|
+
theme.colorReplacements[replacement] = theme.colors[key];
|
|
5290
|
+
theme.colors[key] = replacement;
|
|
5291
|
+
}
|
|
5281
5292
|
}
|
|
5282
5293
|
}
|
|
5283
|
-
|
|
5284
|
-
|
|
5285
|
-
|
|
5286
|
-
|
|
5287
|
-
|
|
5288
|
-
|
|
5289
|
-
|
|
5294
|
+
Object.defineProperty(theme, RESOLVED_KEY, {
|
|
5295
|
+
enumerable: false,
|
|
5296
|
+
writable: false,
|
|
5297
|
+
value: true,
|
|
5298
|
+
});
|
|
5299
|
+
return theme;
|
|
5300
|
+
}
|
|
5301
|
+
|
|
5302
|
+
/**
|
|
5303
|
+
* Resolve
|
|
5304
|
+
*/
|
|
5305
|
+
async function resolveLangs(langs) {
|
|
5306
|
+
return Array.from(new Set((await Promise.all(langs
|
|
5307
|
+
.filter(l => !isSpecialLang(l))
|
|
5308
|
+
.map(async (lang) => await normalizeGetter(lang).then(r => Array.isArray(r) ? r : [r])))).flat()));
|
|
5309
|
+
}
|
|
5310
|
+
async function resolveThemes(themes) {
|
|
5311
|
+
const resolved = await Promise.all(themes.map(async (theme) => isSpecialTheme(theme)
|
|
5312
|
+
? null
|
|
5313
|
+
: normalizeTheme(await normalizeGetter(theme))));
|
|
5314
|
+
return resolved.filter(i => !!i);
|
|
5315
|
+
}
|
|
5316
|
+
|
|
5317
|
+
class Registry extends Registry$1 {
|
|
5318
|
+
_resolver;
|
|
5319
|
+
_themes;
|
|
5320
|
+
_langs;
|
|
5321
|
+
_alias;
|
|
5322
|
+
_resolvedThemes = new Map();
|
|
5323
|
+
_resolvedGrammars = new Map();
|
|
5324
|
+
_langMap = new Map();
|
|
5325
|
+
_langGraph = new Map();
|
|
5326
|
+
_textmateThemeCache = new WeakMap();
|
|
5327
|
+
_loadedThemesCache = null;
|
|
5328
|
+
_loadedLanguagesCache = null;
|
|
5329
|
+
constructor(_resolver, _themes, _langs, _alias = {}) {
|
|
5330
|
+
super(_resolver);
|
|
5331
|
+
this._resolver = _resolver;
|
|
5332
|
+
this._themes = _themes;
|
|
5333
|
+
this._langs = _langs;
|
|
5334
|
+
this._alias = _alias;
|
|
5335
|
+
this._themes.map(t => this.loadTheme(t));
|
|
5336
|
+
this.loadLanguages(this._langs);
|
|
5337
|
+
}
|
|
5338
|
+
getTheme(theme) {
|
|
5339
|
+
if (typeof theme === 'string')
|
|
5340
|
+
return this._resolvedThemes.get(theme);
|
|
5341
|
+
else
|
|
5342
|
+
return this.loadTheme(theme);
|
|
5343
|
+
}
|
|
5344
|
+
loadTheme(theme) {
|
|
5345
|
+
const _theme = normalizeTheme(theme);
|
|
5346
|
+
if (_theme.name) {
|
|
5347
|
+
this._resolvedThemes.set(_theme.name, _theme);
|
|
5348
|
+
// Reset cache
|
|
5349
|
+
this._loadedThemesCache = null;
|
|
5290
5350
|
}
|
|
5291
|
-
return
|
|
5351
|
+
return _theme;
|
|
5292
5352
|
}
|
|
5293
|
-
|
|
5294
|
-
if (this.
|
|
5295
|
-
|
|
5296
|
-
|
|
5297
|
-
|
|
5298
|
-
|
|
5299
|
-
|
|
5353
|
+
getLoadedThemes() {
|
|
5354
|
+
if (!this._loadedThemesCache)
|
|
5355
|
+
this._loadedThemesCache = [...this._resolvedThemes.keys()];
|
|
5356
|
+
return this._loadedThemesCache;
|
|
5357
|
+
}
|
|
5358
|
+
// Override and re-implement this method to cache the textmate themes as `TextMateTheme.createFromRawTheme`
|
|
5359
|
+
// is expensive. Themes can switch often especially for dual-theme support.
|
|
5360
|
+
//
|
|
5361
|
+
// The parent class also accepts `colorMap` as the second parameter, but since we don't use that,
|
|
5362
|
+
// we omit here so it's easier to cache the themes.
|
|
5363
|
+
setTheme(theme) {
|
|
5364
|
+
let textmateTheme = this._textmateThemeCache.get(theme);
|
|
5365
|
+
if (!textmateTheme) {
|
|
5366
|
+
textmateTheme = Theme.createFromRawTheme(theme);
|
|
5367
|
+
this._textmateThemeCache.set(theme, textmateTheme);
|
|
5300
5368
|
}
|
|
5301
|
-
|
|
5369
|
+
// @ts-expect-error Access private `_syncRegistry`, but should work in runtime
|
|
5370
|
+
this._syncRegistry.setTheme(textmateTheme);
|
|
5302
5371
|
}
|
|
5303
|
-
|
|
5304
|
-
if (this.
|
|
5305
|
-
|
|
5306
|
-
|
|
5307
|
-
|
|
5372
|
+
getGrammar(name) {
|
|
5373
|
+
if (this._alias[name]) {
|
|
5374
|
+
const resolved = new Set([name]);
|
|
5375
|
+
while (this._alias[name]) {
|
|
5376
|
+
name = this._alias[name];
|
|
5377
|
+
if (resolved.has(name))
|
|
5378
|
+
throw new ShikiError(`Circular alias \`${Array.from(resolved).join(' -> ')} -> ${name}\``);
|
|
5379
|
+
resolved.add(name);
|
|
5380
|
+
}
|
|
5381
|
+
}
|
|
5382
|
+
return this._resolvedGrammars.get(name);
|
|
5308
5383
|
}
|
|
5309
|
-
|
|
5310
|
-
|
|
5311
|
-
|
|
5312
|
-
|
|
5313
|
-
|
|
5314
|
-
|
|
5315
|
-
|
|
5316
|
-
|
|
5317
|
-
|
|
5318
|
-
|
|
5319
|
-
|
|
5320
|
-
|
|
5321
|
-
|
|
5384
|
+
loadLanguage(lang) {
|
|
5385
|
+
if (this.getGrammar(lang.name))
|
|
5386
|
+
return;
|
|
5387
|
+
const embeddedLazilyBy = new Set([...this._langMap.values()]
|
|
5388
|
+
.filter(i => i.embeddedLangsLazy?.includes(lang.name)));
|
|
5389
|
+
this._resolver.addLanguage(lang);
|
|
5390
|
+
const grammarConfig = {
|
|
5391
|
+
balancedBracketSelectors: lang.balancedBracketSelectors || ['*'],
|
|
5392
|
+
unbalancedBracketSelectors: lang.unbalancedBracketSelectors || [],
|
|
5393
|
+
};
|
|
5394
|
+
// @ts-expect-error Private members, set this to override the previous grammar (that can be a stub)
|
|
5395
|
+
this._syncRegistry._rawGrammars.set(lang.scopeName, lang);
|
|
5396
|
+
const g = this.loadGrammarWithConfiguration(lang.scopeName, 1, grammarConfig);
|
|
5397
|
+
g.name = lang.name;
|
|
5398
|
+
this._resolvedGrammars.set(lang.name, g);
|
|
5399
|
+
if (lang.aliases) {
|
|
5400
|
+
lang.aliases.forEach((alias) => {
|
|
5401
|
+
this._alias[alias] = lang.name;
|
|
5402
|
+
});
|
|
5403
|
+
}
|
|
5404
|
+
// Reset cache
|
|
5405
|
+
this._loadedLanguagesCache = null;
|
|
5406
|
+
// If there is a language that embeds this language lazily, we need to reload it
|
|
5407
|
+
if (embeddedLazilyBy.size) {
|
|
5408
|
+
for (const e of embeddedLazilyBy) {
|
|
5409
|
+
this._resolvedGrammars.delete(e.name);
|
|
5410
|
+
// Reset cache
|
|
5411
|
+
this._loadedLanguagesCache = null;
|
|
5412
|
+
// @ts-expect-error clear cache
|
|
5413
|
+
this._syncRegistry?._injectionGrammars?.delete(e.scopeName);
|
|
5414
|
+
// @ts-expect-error clear cache
|
|
5415
|
+
this._syncRegistry?._grammars?.delete(e.scopeName);
|
|
5416
|
+
this.loadLanguage(this._langMap.get(e.name));
|
|
5417
|
+
}
|
|
5322
5418
|
}
|
|
5323
|
-
const strPtrsPtr = onigBinding.omalloc(4 * patterns.length);
|
|
5324
|
-
onigBinding.HEAPU32.set(strPtrsArr, strPtrsPtr / 4);
|
|
5325
|
-
const strLenPtr = onigBinding.omalloc(4 * patterns.length);
|
|
5326
|
-
onigBinding.HEAPU32.set(strLenArr, strLenPtr / 4);
|
|
5327
|
-
const scannerPtr = onigBinding.createOnigScanner(strPtrsPtr, strLenPtr, patterns.length);
|
|
5328
|
-
for (let i = 0, len = patterns.length; i < len; i++)
|
|
5329
|
-
onigBinding.ofree(strPtrsArr[i]);
|
|
5330
|
-
onigBinding.ofree(strLenPtr);
|
|
5331
|
-
onigBinding.ofree(strPtrsPtr);
|
|
5332
|
-
if (scannerPtr === 0)
|
|
5333
|
-
throwLastOnigError(onigBinding);
|
|
5334
|
-
this._onigBinding = onigBinding;
|
|
5335
|
-
this._ptr = scannerPtr;
|
|
5336
5419
|
}
|
|
5337
5420
|
dispose() {
|
|
5338
|
-
|
|
5421
|
+
super.dispose();
|
|
5422
|
+
this._resolvedThemes.clear();
|
|
5423
|
+
this._resolvedGrammars.clear();
|
|
5424
|
+
this._langMap.clear();
|
|
5425
|
+
this._langGraph.clear();
|
|
5426
|
+
this._loadedThemesCache = null;
|
|
5339
5427
|
}
|
|
5340
|
-
|
|
5341
|
-
|
|
5342
|
-
|
|
5343
|
-
|
|
5344
|
-
|
|
5345
|
-
|
|
5346
|
-
|
|
5347
|
-
|
|
5348
|
-
|
|
5349
|
-
|
|
5350
|
-
const result = this._findNextMatchSync(string, startPosition, false, options);
|
|
5351
|
-
string.dispose();
|
|
5352
|
-
return result;
|
|
5428
|
+
loadLanguages(langs) {
|
|
5429
|
+
for (const lang of langs)
|
|
5430
|
+
this.resolveEmbeddedLanguages(lang);
|
|
5431
|
+
const langsGraphArray = Array.from(this._langGraph.entries());
|
|
5432
|
+
const missingLangs = langsGraphArray.filter(([_, lang]) => !lang);
|
|
5433
|
+
if (missingLangs.length) {
|
|
5434
|
+
const dependents = langsGraphArray
|
|
5435
|
+
.filter(([_, lang]) => lang && lang.embeddedLangs?.some(l => missingLangs.map(([name]) => name).includes(l)))
|
|
5436
|
+
.filter(lang => !missingLangs.includes(lang));
|
|
5437
|
+
throw new ShikiError(`Missing languages ${missingLangs.map(([name]) => `\`${name}\``).join(', ')}, required by ${dependents.map(([name]) => `\`${name}\``).join(', ')}`);
|
|
5353
5438
|
}
|
|
5354
|
-
|
|
5439
|
+
for (const [_, lang] of langsGraphArray)
|
|
5440
|
+
this._resolver.addLanguage(lang);
|
|
5441
|
+
for (const [_, lang] of langsGraphArray)
|
|
5442
|
+
this.loadLanguage(lang);
|
|
5355
5443
|
}
|
|
5356
|
-
|
|
5357
|
-
|
|
5358
|
-
|
|
5359
|
-
|
|
5360
|
-
|
|
5361
|
-
// else
|
|
5362
|
-
const resultPtr = onigBinding.findNextOnigScannerMatch(this._ptr, string.id, string.ptr, string.utf8Length, string.convertUtf16OffsetToUtf8(startPosition), options);
|
|
5363
|
-
if (resultPtr === 0) {
|
|
5364
|
-
// no match
|
|
5365
|
-
return null;
|
|
5366
|
-
}
|
|
5367
|
-
const HEAPU32 = onigBinding.HEAPU32;
|
|
5368
|
-
let offset = resultPtr / 4; // byte offset -> uint32 offset
|
|
5369
|
-
const index = HEAPU32[offset++];
|
|
5370
|
-
const count = HEAPU32[offset++];
|
|
5371
|
-
const captureIndices = [];
|
|
5372
|
-
for (let i = 0; i < count; i++) {
|
|
5373
|
-
const beg = string.convertUtf8OffsetToUtf16(HEAPU32[offset++]);
|
|
5374
|
-
const end = string.convertUtf8OffsetToUtf16(HEAPU32[offset++]);
|
|
5375
|
-
captureIndices[i] = {
|
|
5376
|
-
start: beg,
|
|
5377
|
-
end,
|
|
5378
|
-
length: end - beg,
|
|
5379
|
-
};
|
|
5444
|
+
getLoadedLanguages() {
|
|
5445
|
+
if (!this._loadedLanguagesCache) {
|
|
5446
|
+
this._loadedLanguagesCache = [
|
|
5447
|
+
...new Set([...this._resolvedGrammars.keys(), ...Object.keys(this._alias)]),
|
|
5448
|
+
];
|
|
5380
5449
|
}
|
|
5381
|
-
return
|
|
5382
|
-
index,
|
|
5383
|
-
captureIndices,
|
|
5384
|
-
};
|
|
5450
|
+
return this._loadedLanguagesCache;
|
|
5385
5451
|
}
|
|
5386
|
-
|
|
5387
|
-
|
|
5388
|
-
|
|
5389
|
-
|
|
5390
|
-
|
|
5391
|
-
|
|
5392
|
-
}
|
|
5393
|
-
function isDataOptionsObject(dataOrOptions) {
|
|
5394
|
-
return (typeof dataOrOptions.data !== 'undefined');
|
|
5395
|
-
}
|
|
5396
|
-
function isResponse(dataOrOptions) {
|
|
5397
|
-
return (typeof Response !== 'undefined' && dataOrOptions instanceof Response);
|
|
5398
|
-
}
|
|
5399
|
-
function isArrayBuffer(data) {
|
|
5400
|
-
return (typeof ArrayBuffer !== 'undefined' && (data instanceof ArrayBuffer || ArrayBuffer.isView(data)))
|
|
5401
|
-
// eslint-disable-next-line node/prefer-global/buffer
|
|
5402
|
-
|| (typeof Buffer !== 'undefined' && Buffer.isBuffer?.(data))
|
|
5403
|
-
|| (typeof SharedArrayBuffer !== 'undefined' && data instanceof SharedArrayBuffer)
|
|
5404
|
-
|| (typeof Uint32Array !== 'undefined' && data instanceof Uint32Array);
|
|
5405
|
-
}
|
|
5406
|
-
let initPromise;
|
|
5407
|
-
function loadWasm(options) {
|
|
5408
|
-
if (initPromise)
|
|
5409
|
-
return initPromise;
|
|
5410
|
-
async function _load() {
|
|
5411
|
-
onigBinding = await main(async (info) => {
|
|
5412
|
-
let instance = options;
|
|
5413
|
-
instance = await instance;
|
|
5414
|
-
if (typeof instance === 'function')
|
|
5415
|
-
instance = await instance(info);
|
|
5416
|
-
if (typeof instance === 'function')
|
|
5417
|
-
instance = await instance(info);
|
|
5418
|
-
if (isInstantiatorOptionsObject(instance)) {
|
|
5419
|
-
instance = await instance.instantiator(info);
|
|
5420
|
-
}
|
|
5421
|
-
else if (isInstantiatorModule(instance)) {
|
|
5422
|
-
instance = await instance.default(info);
|
|
5423
|
-
}
|
|
5424
|
-
else {
|
|
5425
|
-
if (isDataOptionsObject(instance))
|
|
5426
|
-
instance = instance.data;
|
|
5427
|
-
if (isResponse(instance)) {
|
|
5428
|
-
if (typeof WebAssembly.instantiateStreaming === 'function')
|
|
5429
|
-
instance = await _makeResponseStreamingLoader(instance)(info);
|
|
5430
|
-
else
|
|
5431
|
-
instance = await _makeResponseNonStreamingLoader(instance)(info);
|
|
5432
|
-
}
|
|
5433
|
-
else if (isArrayBuffer(instance)) {
|
|
5434
|
-
instance = await _makeArrayBufferLoader(instance)(info);
|
|
5435
|
-
}
|
|
5436
|
-
// import("shiki/onig.wasm") returns `{ default: WebAssembly.Module }` on cloudflare workers
|
|
5437
|
-
// https://developers.cloudflare.com/workers/wrangler/bundling/
|
|
5438
|
-
else if (instance instanceof WebAssembly.Module) {
|
|
5439
|
-
instance = await _makeArrayBufferLoader(instance)(info);
|
|
5440
|
-
}
|
|
5441
|
-
else if ('default' in instance && instance.default instanceof WebAssembly.Module) {
|
|
5442
|
-
instance = await _makeArrayBufferLoader(instance.default)(info);
|
|
5443
|
-
}
|
|
5444
|
-
}
|
|
5445
|
-
if ('instance' in instance)
|
|
5446
|
-
instance = instance.instance;
|
|
5447
|
-
if ('exports' in instance)
|
|
5448
|
-
instance = instance.exports;
|
|
5449
|
-
return instance;
|
|
5450
|
-
});
|
|
5452
|
+
resolveEmbeddedLanguages(lang) {
|
|
5453
|
+
this._langMap.set(lang.name, lang);
|
|
5454
|
+
this._langGraph.set(lang.name, lang);
|
|
5455
|
+
if (lang.embeddedLangs) {
|
|
5456
|
+
for (const embeddedLang of lang.embeddedLangs)
|
|
5457
|
+
this._langGraph.set(embeddedLang, this._langMap.get(embeddedLang));
|
|
5458
|
+
}
|
|
5451
5459
|
}
|
|
5452
|
-
initPromise = _load();
|
|
5453
|
-
return initPromise;
|
|
5454
|
-
}
|
|
5455
|
-
function _makeArrayBufferLoader(data) {
|
|
5456
|
-
return importObject => WebAssembly.instantiate(data, importObject);
|
|
5457
|
-
}
|
|
5458
|
-
function _makeResponseStreamingLoader(data) {
|
|
5459
|
-
return importObject => WebAssembly.instantiateStreaming(data, importObject);
|
|
5460
|
-
}
|
|
5461
|
-
function _makeResponseNonStreamingLoader(data) {
|
|
5462
|
-
return async (importObject) => {
|
|
5463
|
-
const arrayBuffer = await data.arrayBuffer();
|
|
5464
|
-
return WebAssembly.instantiate(arrayBuffer, importObject);
|
|
5465
|
-
};
|
|
5466
5460
|
}
|
|
5467
|
-
// export function createOnigString(str: string) {
|
|
5468
|
-
// return new OnigString(str)
|
|
5469
|
-
// }
|
|
5470
|
-
// export function createOnigScanner(patterns: string[]) {
|
|
5471
|
-
// return new OnigScanner(patterns)
|
|
5472
|
-
// }
|
|
5473
|
-
// export function setDefaultDebugCall(_defaultDebugCall: boolean): void {
|
|
5474
|
-
// defaultDebugCall = _defaultDebugCall
|
|
5475
|
-
// }
|
|
5476
5461
|
|
|
5477
|
-
|
|
5478
|
-
|
|
5479
|
-
|
|
5480
|
-
|
|
5481
|
-
|
|
5482
|
-
|
|
5483
|
-
|
|
5484
|
-
|
|
5485
|
-
|
|
5486
|
-
}
|
|
5487
|
-
|
|
5462
|
+
class Resolver {
|
|
5463
|
+
_langs = new Map();
|
|
5464
|
+
_scopeToLang = new Map();
|
|
5465
|
+
_injections = new Map();
|
|
5466
|
+
_onigLib;
|
|
5467
|
+
constructor(engine, langs) {
|
|
5468
|
+
this._onigLib = {
|
|
5469
|
+
createOnigScanner: patterns => engine.createScanner(patterns),
|
|
5470
|
+
createOnigString: s => engine.createString(s),
|
|
5471
|
+
};
|
|
5472
|
+
langs.forEach(i => this.addLanguage(i));
|
|
5473
|
+
}
|
|
5474
|
+
get onigLib() {
|
|
5475
|
+
return this._onigLib;
|
|
5476
|
+
}
|
|
5477
|
+
getLangRegistration(langIdOrAlias) {
|
|
5478
|
+
return this._langs.get(langIdOrAlias);
|
|
5479
|
+
}
|
|
5480
|
+
loadGrammar(scopeName) {
|
|
5481
|
+
return this._scopeToLang.get(scopeName);
|
|
5482
|
+
}
|
|
5483
|
+
addLanguage(l) {
|
|
5484
|
+
this._langs.set(l.name, l);
|
|
5485
|
+
if (l.aliases) {
|
|
5486
|
+
l.aliases.forEach((a) => {
|
|
5487
|
+
this._langs.set(a, l);
|
|
5488
|
+
});
|
|
5489
|
+
}
|
|
5490
|
+
this._scopeToLang.set(l.scopeName, l);
|
|
5491
|
+
if (l.injectTo) {
|
|
5492
|
+
l.injectTo.forEach((i) => {
|
|
5493
|
+
if (!this._injections.get(i))
|
|
5494
|
+
this._injections.set(i, []);
|
|
5495
|
+
this._injections.get(i).push(l.scopeName);
|
|
5496
|
+
});
|
|
5497
|
+
}
|
|
5498
|
+
}
|
|
5499
|
+
getInjections(scopeName) {
|
|
5500
|
+
const scopeParts = scopeName.split('.');
|
|
5501
|
+
let injections = [];
|
|
5502
|
+
for (let i = 1; i <= scopeParts.length; i++) {
|
|
5503
|
+
const subScopeName = scopeParts.slice(0, i).join('.');
|
|
5504
|
+
injections = [...injections, ...(this._injections.get(subScopeName) || [])];
|
|
5505
|
+
}
|
|
5506
|
+
return injections;
|
|
5507
|
+
}
|
|
5488
5508
|
}
|
|
5489
5509
|
|
|
5490
|
-
let _defaultWasmLoader;
|
|
5491
|
-
/**
|
|
5492
|
-
* Set the default wasm loader for `loadWasm`.
|
|
5493
|
-
* @internal
|
|
5494
|
-
*/
|
|
5495
|
-
function setDefaultWasmLoader(_loader) {
|
|
5496
|
-
_defaultWasmLoader = _loader;
|
|
5497
|
-
}
|
|
5498
5510
|
let instancesCount = 0;
|
|
5499
5511
|
/**
|
|
5500
5512
|
* Get the minimal shiki context for rendering.
|
|
5513
|
+
*
|
|
5514
|
+
* Synchronous version of `createShikiInternal`, which requires to provide the engine and all themes and languages upfront.
|
|
5501
5515
|
*/
|
|
5502
|
-
|
|
5516
|
+
function createShikiInternalSync(options) {
|
|
5503
5517
|
instancesCount += 1;
|
|
5504
5518
|
if (options.warnings !== false && instancesCount >= 10 && instancesCount % 10 === 0)
|
|
5505
5519
|
console.warn(`[Shiki] ${instancesCount} instances have been created. Shiki is supposed to be used as a singleton, consider refactoring your code to cache your highlighter instance; Or call \`highlighter.dispose()\` to release unused instances.`);
|
|
5506
5520
|
let isDisposed = false;
|
|
5507
|
-
|
|
5508
|
-
|
|
5509
|
-
|
|
5510
|
-
|
|
5511
|
-
|
|
5512
|
-
.filter(l => !isSpecialLang(l))
|
|
5513
|
-
.map(async (lang) => await normalizeGetter(lang).then(r => Array.isArray(r) ? r : [r])))).flat()));
|
|
5514
|
-
}
|
|
5515
|
-
const [themes, langs,] = await Promise.all([
|
|
5516
|
-
Promise.all((options.themes || []).map(normalizeGetter)).then(r => r.map(normalizeTheme)),
|
|
5517
|
-
resolveLangs(options.langs || []),
|
|
5518
|
-
]);
|
|
5519
|
-
const resolver = new Resolver(Promise.resolve(options.engine || createWasmOnigEngine(options.loadWasm || _defaultWasmLoader)), langs);
|
|
5521
|
+
if (!options.engine)
|
|
5522
|
+
throw new ShikiError('`engine` option is required for synchronous mode');
|
|
5523
|
+
const langs = (options.langs || []).flat(1);
|
|
5524
|
+
const themes = (options.themes || []).flat(1).map(normalizeTheme);
|
|
5525
|
+
const resolver = new Resolver(options.engine, langs);
|
|
5520
5526
|
const _registry = new Registry(resolver, themes, langs, options.langAlias);
|
|
5521
|
-
await _registry.init();
|
|
5522
5527
|
let _lastTheme;
|
|
5523
5528
|
function getLanguage(name) {
|
|
5524
5529
|
ensureNotDisposed();
|
|
@@ -5557,15 +5562,22 @@ async function createShikiInternal(options = {}) {
|
|
|
5557
5562
|
ensureNotDisposed();
|
|
5558
5563
|
return _registry.getLoadedLanguages();
|
|
5559
5564
|
}
|
|
5565
|
+
function loadLanguageSync(...langs) {
|
|
5566
|
+
ensureNotDisposed();
|
|
5567
|
+
_registry.loadLanguages(langs.flat(1));
|
|
5568
|
+
}
|
|
5560
5569
|
async function loadLanguage(...langs) {
|
|
5570
|
+
return loadLanguageSync(await resolveLangs(langs));
|
|
5571
|
+
}
|
|
5572
|
+
async function loadThemeSync(...themes) {
|
|
5561
5573
|
ensureNotDisposed();
|
|
5562
|
-
|
|
5574
|
+
for (const theme of themes.flat(1)) {
|
|
5575
|
+
_registry.loadTheme(theme);
|
|
5576
|
+
}
|
|
5563
5577
|
}
|
|
5564
5578
|
async function loadTheme(...themes) {
|
|
5565
5579
|
ensureNotDisposed();
|
|
5566
|
-
await
|
|
5567
|
-
? null
|
|
5568
|
-
: _registry.loadTheme(await normalizeGetter(theme))));
|
|
5580
|
+
return loadThemeSync(await resolveThemes(themes));
|
|
5569
5581
|
}
|
|
5570
5582
|
function ensureNotDisposed() {
|
|
5571
5583
|
if (isDisposed)
|
|
@@ -5585,11 +5597,39 @@ async function createShikiInternal(options = {}) {
|
|
|
5585
5597
|
getLoadedThemes,
|
|
5586
5598
|
getLoadedLanguages,
|
|
5587
5599
|
loadLanguage,
|
|
5600
|
+
loadLanguageSync,
|
|
5588
5601
|
loadTheme,
|
|
5602
|
+
loadThemeSync,
|
|
5589
5603
|
dispose,
|
|
5590
5604
|
[Symbol.dispose]: dispose,
|
|
5591
5605
|
};
|
|
5592
5606
|
}
|
|
5607
|
+
|
|
5608
|
+
let _defaultWasmLoader;
|
|
5609
|
+
/**
|
|
5610
|
+
* Set the default wasm loader for `loadWasm`.
|
|
5611
|
+
* @internal
|
|
5612
|
+
*/
|
|
5613
|
+
function setDefaultWasmLoader(_loader) {
|
|
5614
|
+
_defaultWasmLoader = _loader;
|
|
5615
|
+
}
|
|
5616
|
+
/**
|
|
5617
|
+
* Get the minimal shiki context for rendering.
|
|
5618
|
+
*/
|
|
5619
|
+
async function createShikiInternal(options = {}) {
|
|
5620
|
+
const [themes, langs, engine,] = await Promise.all([
|
|
5621
|
+
resolveThemes(options.themes || []),
|
|
5622
|
+
resolveLangs(options.langs || []),
|
|
5623
|
+
(options.engine || createWasmOnigEngine(options.loadWasm || _defaultWasmLoader)),
|
|
5624
|
+
]);
|
|
5625
|
+
return createShikiInternalSync({
|
|
5626
|
+
...options,
|
|
5627
|
+
loadWasm: undefined,
|
|
5628
|
+
themes,
|
|
5629
|
+
langs,
|
|
5630
|
+
engine,
|
|
5631
|
+
});
|
|
5632
|
+
}
|
|
5593
5633
|
/**
|
|
5594
5634
|
* @deprecated Use `createShikiInternal` instead.
|
|
5595
5635
|
*/
|
|
@@ -5602,7 +5642,7 @@ function getShikiInternal(options = {}) {
|
|
|
5602
5642
|
* Create a Shiki core highlighter instance, with no languages or themes bundled.
|
|
5603
5643
|
* Wasm and each language and theme must be loaded manually.
|
|
5604
5644
|
*
|
|
5605
|
-
* @see http://shiki.style/guide/
|
|
5645
|
+
* @see http://shiki.style/guide/bundles#fine-grained-bundle
|
|
5606
5646
|
*/
|
|
5607
5647
|
async function createHighlighterCore(options = {}) {
|
|
5608
5648
|
const internal = await createShikiInternal(options);
|
|
@@ -5617,6 +5657,27 @@ async function createHighlighterCore(options = {}) {
|
|
|
5617
5657
|
getInternalContext: () => internal,
|
|
5618
5658
|
};
|
|
5619
5659
|
}
|
|
5660
|
+
/**
|
|
5661
|
+
* Create a Shiki core highlighter instance, with no languages or themes bundled.
|
|
5662
|
+
* Wasm and each language and theme must be loaded manually.
|
|
5663
|
+
*
|
|
5664
|
+
* Synchronous version of `createHighlighterCore`, which requires to provide the engine and all themes and languages upfront.
|
|
5665
|
+
*
|
|
5666
|
+
* @see http://shiki.style/guide/bundles#fine-grained-bundle
|
|
5667
|
+
*/
|
|
5668
|
+
function createHighlighterCoreSync(options = {}) {
|
|
5669
|
+
const internal = createShikiInternalSync(options);
|
|
5670
|
+
return {
|
|
5671
|
+
getLastGrammarState: (code, options) => getLastGrammarState(internal, code, options),
|
|
5672
|
+
codeToTokensBase: (code, options) => codeToTokensBase(internal, code, options),
|
|
5673
|
+
codeToTokensWithThemes: (code, options) => codeToTokensWithThemes(internal, code, options),
|
|
5674
|
+
codeToTokens: (code, options) => codeToTokens(internal, code, options),
|
|
5675
|
+
codeToHast: (code, options) => codeToHast(internal, code, options),
|
|
5676
|
+
codeToHtml: (code, options) => codeToHtml(internal, code, options),
|
|
5677
|
+
...internal,
|
|
5678
|
+
getInternalContext: () => internal,
|
|
5679
|
+
};
|
|
5680
|
+
}
|
|
5620
5681
|
function makeSingletonHighlighterCore(createHighlighter) {
|
|
5621
5682
|
let _shiki;
|
|
5622
5683
|
async function getSingletonHighlighterCore(options = {}) {
|
|
@@ -5649,14 +5710,23 @@ function getHighlighterCore(options = {}) {
|
|
|
5649
5710
|
return createHighlighterCore(options);
|
|
5650
5711
|
}
|
|
5651
5712
|
|
|
5652
|
-
|
|
5653
|
-
|
|
5654
|
-
|
|
5655
|
-
|
|
5656
|
-
|
|
5657
|
-
|
|
5658
|
-
|
|
5659
|
-
|
|
5713
|
+
// Implementation
|
|
5714
|
+
function createdBundledHighlighter(arg1, arg2, arg3) {
|
|
5715
|
+
let bundledLanguages;
|
|
5716
|
+
let bundledThemes;
|
|
5717
|
+
let engine;
|
|
5718
|
+
if (arg2) {
|
|
5719
|
+
// TODO: next: console.warn('`createdBundledHighlighter` signature with `bundledLanguages` and `bundledThemes` is deprecated. Use the options object signature instead.')
|
|
5720
|
+
bundledLanguages = arg1;
|
|
5721
|
+
bundledThemes = arg2;
|
|
5722
|
+
engine = () => createWasmOnigEngine(arg3);
|
|
5723
|
+
}
|
|
5724
|
+
else {
|
|
5725
|
+
const options = arg1;
|
|
5726
|
+
bundledLanguages = options.langs;
|
|
5727
|
+
bundledThemes = options.themes;
|
|
5728
|
+
engine = options.engine;
|
|
5729
|
+
}
|
|
5660
5730
|
async function createHighlighter(options) {
|
|
5661
5731
|
function resolveLang(lang) {
|
|
5662
5732
|
if (typeof lang === 'string') {
|
|
@@ -5684,10 +5754,10 @@ function createdBundledHighlighter(bundledLanguages, bundledThemes, loadWasm) {
|
|
|
5684
5754
|
const langs = (options.langs ?? [])
|
|
5685
5755
|
.map(i => resolveLang(i));
|
|
5686
5756
|
const core = await createHighlighterCore({
|
|
5757
|
+
engine: engine(),
|
|
5687
5758
|
...options,
|
|
5688
5759
|
themes: _themes,
|
|
5689
5760
|
langs,
|
|
5690
|
-
loadWasm,
|
|
5691
5761
|
});
|
|
5692
5762
|
return {
|
|
5693
5763
|
...core,
|
|
@@ -5813,7 +5883,8 @@ function syntaxLowering(input, options = {}) {
|
|
|
5813
5883
|
const {
|
|
5814
5884
|
preserveFlags = false,
|
|
5815
5885
|
removePossessiveQuantifier = false,
|
|
5816
|
-
removeAtomicGroup = false
|
|
5886
|
+
removeAtomicGroup = false,
|
|
5887
|
+
convertHexDigitsShorthand = false
|
|
5817
5888
|
} = options;
|
|
5818
5889
|
let output = "";
|
|
5819
5890
|
const flags = /* @__PURE__ */ new Set();
|
|
@@ -5830,14 +5901,29 @@ function syntaxLowering(input, options = {}) {
|
|
|
5830
5901
|
const head = stack[0];
|
|
5831
5902
|
const wsEscape = freeSpacingGlobal || freeSpacingLocal.length;
|
|
5832
5903
|
if (char === "\\") {
|
|
5833
|
-
if (
|
|
5834
|
-
if (
|
|
5835
|
-
|
|
5836
|
-
|
|
5837
|
-
|
|
5904
|
+
if (convertHexDigitsShorthand) {
|
|
5905
|
+
if (input[i + 1] === "h") {
|
|
5906
|
+
const body = `0-9A-Fa-f`;
|
|
5907
|
+
if (head === "[") {
|
|
5908
|
+
output += body;
|
|
5909
|
+
} else {
|
|
5910
|
+
output += `[${body}]`;
|
|
5911
|
+
}
|
|
5912
|
+
i += 2;
|
|
5913
|
+
continue;
|
|
5914
|
+
}
|
|
5915
|
+
if (input[i + 1] === "H") {
|
|
5916
|
+
if (head === "[") {
|
|
5917
|
+
throw new RegExpConversionError(
|
|
5918
|
+
"Expending \\H in character class is not supported",
|
|
5919
|
+
{ pattern: input, converted: output, cursor: i }
|
|
5920
|
+
);
|
|
5921
|
+
} else {
|
|
5922
|
+
output += `[^0-9A-Fa-f]`;
|
|
5923
|
+
}
|
|
5924
|
+
i += 2;
|
|
5925
|
+
continue;
|
|
5838
5926
|
}
|
|
5839
|
-
i += 2;
|
|
5840
|
-
continue;
|
|
5841
5927
|
}
|
|
5842
5928
|
output += char + input[i + 1];
|
|
5843
5929
|
i += 2;
|
|
@@ -6068,6 +6154,7 @@ function onigurumaToRegexp(pattern, options = {}) {
|
|
|
6068
6154
|
} = syntaxLowering(pattern, {
|
|
6069
6155
|
removePossessiveQuantifier: true,
|
|
6070
6156
|
removeAtomicGroup: true,
|
|
6157
|
+
convertHexDigitsShorthand: true,
|
|
6071
6158
|
...options
|
|
6072
6159
|
});
|
|
6073
6160
|
return construct(converted, {
|
|
@@ -6199,4 +6286,4 @@ function createJavaScriptRegexEngine(options = {}) {
|
|
|
6199
6286
|
};
|
|
6200
6287
|
}
|
|
6201
6288
|
|
|
6202
|
-
export { FontStyle, ShikiError, addClassToHast, applyColorReplacements, codeToHast, codeToHtml, codeToTokens, codeToTokensBase, codeToTokensWithThemes, createHighlighterCore, createJavaScriptRegexEngine, createPositionConverter, createShikiInternal, createSingletonShorthands, createWasmOnigEngine, createdBundledHighlighter, getHighlighterCore, getShikiInternal, getSingletonHighlighterCore, getTokenStyleObject, toHtml as hastToHtml, isNoneTheme, isPlainLang, isSpecialLang, isSpecialTheme, loadWasm, makeSingletonHighlighter, makeSingletonHighlighterCore, normalizeTheme, resolveColorReplacements, setDefaultWasmLoader, splitLines, splitToken, splitTokens, stringifyTokenStyle, toArray, tokenizeAnsiWithTheme, tokenizeWithTheme, tokensToHast, transformerDecorations };
|
|
6289
|
+
export { FontStyle, ShikiError, addClassToHast, applyColorReplacements, codeToHast, codeToHtml, codeToTokens, codeToTokensBase, codeToTokensWithThemes, createHighlighterCore, createHighlighterCoreSync, createJavaScriptRegexEngine, createPositionConverter, createShikiInternal, createShikiInternalSync, createSingletonShorthands, createWasmOnigEngine, createdBundledHighlighter, getHighlighterCore, getShikiInternal, getSingletonHighlighterCore, getTokenStyleObject, toHtml as hastToHtml, isNoneTheme, isPlainLang, isSpecialLang, isSpecialTheme, loadWasm, makeSingletonHighlighter, makeSingletonHighlighterCore, normalizeGetter, normalizeTheme, resolveColorReplacements, setDefaultWasmLoader, splitLines, splitToken, splitTokens, stringifyTokenStyle, toArray, tokenizeAnsiWithTheme, tokenizeWithTheme, tokensToHast, transformerDecorations };
|