1import "@t3tools/client-runtime/assembly-highlighting";
2import {
3 getSharedHighlighter,
4 setCustomExtension,
5 type DiffsHighlighter,
6 type HighlighterTypes,
7 type SupportedLanguages,
8} from "@pierre/diffs";
9
10import { DIFF_THEME_NAMES } from "./diffRendering";
11
12// Highlights has no lexer for these dialects, so they use their base language's.
13setCustomExtension("luau", "lua");
14setCustomExtension("xsl", "xml");
15setCustomExtension("xslt", "xml");
16
17/**
18 * Highlights' hand-written WASM lexers tokenize large files 10-40x faster than
19 * Shiki and never backtrack like Shiki's JS regex engine. Only one highlighter
20 * type can be active per thread, so every creation site must pass this value.
21 */
22export const PREFERRED_HIGHLIGHTER: HighlighterTypes = "highlights";
23
24const highlighterPromiseCache = new Map<string, Promise<DiffsHighlighter>>();
25
26export function getSyntaxHighlighterPromise(language: string): Promise<DiffsHighlighter> {
27 const cached = highlighterPromiseCache.get(language);
28 if (cached) return cached;
29
30 const promise = getSharedHighlighter({
31 // Both palettes, so switching appearance never needs a new highlighter.
32 themes: Object.values(DIFF_THEME_NAMES),
33 langs: [language as SupportedLanguages],
34 preferredHighlighter: PREFERRED_HIGHLIGHTER,
35 }).catch((error) => {
36 if (language === "text") {
37 highlighterPromiseCache.delete(language);
38 throw error;
39 }
40 return getSyntaxHighlighterPromise("text");
41 });
42 highlighterPromiseCache.set(language, promise);
43 return promise;
44}