@@ -4,6 +4,21 @@ import { LRUCache } from "./lruCache";
44import { fnv1a32 , resolveDiffThemeName , type DiffThemeName } from "./diffRendering" ;
55
66const CODE_FENCE_LANGUAGE_REGEX = / (?: ^ | \s ) l a n g u a g e - ( [ ^ \s ] + ) / ;
7+
8+ /**
9+ * Map VSCode language identifiers that don't match Shiki's bundled language names.
10+ * VSCode uses e.g. "typescriptreact" / "javascriptreact" while Shiki expects "tsx" / "jsx".
11+ */
12+ const VSCODE_TO_SHIKI_LANG : Record < string , string > = {
13+ typescriptreact : "tsx" ,
14+ javascriptreact : "jsx" ,
15+ } ;
16+
17+ /** Normalise a language identifier so Shiki can resolve it. */
18+ function normalizeLanguage ( language : string ) : string {
19+ return VSCODE_TO_SHIKI_LANG [ language ] ?? language ;
20+ }
21+
722const MAX_HIGHLIGHT_CACHE_ENTRIES = 500 ;
823const MAX_HIGHLIGHT_CACHE_MEMORY_BYTES = 50 * 1024 * 1024 ;
924const highlightedCodeCache = new LRUCache < string > (
@@ -61,24 +76,25 @@ export function setCachedHighlightedHtml(
6176}
6277
6378export function getHighlighterPromise ( language : string ) : Promise < DiffsHighlighter > {
64- const cached = highlighterPromiseCache . get ( language ) ;
79+ const normalized = normalizeLanguage ( language ) ;
80+ const cached = highlighterPromiseCache . get ( normalized ) ;
6581 if ( cached ) return cached ;
6682
6783 const promise = getSharedHighlighter ( {
6884 themes : [ resolveDiffThemeName ( "dark" ) , resolveDiffThemeName ( "light" ) ] ,
69- langs : [ language as SupportedLanguages ] ,
85+ langs : [ normalized as SupportedLanguages ] ,
7086 preferredHighlighter : "shiki-js" ,
7187 } ) . catch ( ( err ) => {
72- highlighterPromiseCache . delete ( language ) ;
73- if ( language === "text" ) {
88+ highlighterPromiseCache . delete ( normalized ) ;
89+ if ( normalized === "text" ) {
7490 // "text" itself failed — Shiki cannot initialize at all, surface the error
7591 throw err ;
7692 }
7793 // Language not supported by Shiki — fall back to "text"
7894 return getHighlighterPromise ( "text" ) ;
7995 } ) ;
8096
81- highlighterPromiseCache . set ( language , promise ) ;
97+ highlighterPromiseCache . set ( normalized , promise ) ;
8298 return promise ;
8399}
84100
@@ -88,12 +104,13 @@ export function renderHighlightedCodeHtml(
88104 language : string ,
89105 themeName : DiffThemeName ,
90106) : string {
107+ const normalized = normalizeLanguage ( language ) ;
91108 try {
92- return highlighter . codeToHtml ( code , { lang : language , theme : themeName } ) ;
109+ return highlighter . codeToHtml ( code , { lang : normalized , theme : themeName } ) ;
93110 } catch ( error ) {
94111 // Log highlighting failures for debugging while falling back to plain text
95112 console . warn (
96- `Code highlighting failed for language "${ language } ", falling back to plain text.` ,
113+ `Code highlighting failed for language "${ normalized } ", falling back to plain text.` ,
97114 error instanceof Error ? error . message : error ,
98115 ) ;
99116 return highlighter . codeToHtml ( code , { lang : "text" , theme : themeName } ) ;
0 commit comments