11import { createHighlighter } from "shiki" ;
2+ import { createJavaScriptRegexEngine } from "shiki/engine/javascript" ;
23
34import { processAST , type SyntaxLine } from "./processAST" ;
45
56import type { _getAST } from "./lang" ;
6- import type { codeToHast } from "shiki" ;
7+ import type { BundledLanguage , codeToHast } from "shiki" ;
78
89type DePromise < T > = T extends Promise < infer U > ? DePromise < U > : T ;
910
@@ -22,49 +23,107 @@ export type DiffHighlighter = {
2223 getHighlighterEngine : ( ) => DePromise < ReturnType < typeof createHighlighter > > | null ;
2324} ;
2425
25- let internal : DePromise < ReturnType < typeof createHighlighter > > | null = null ;
26-
27- const getDefaultHighlighter = async ( ) =>
28- await createHighlighter ( {
29- themes : [ "github-light" , "github-dark" ] ,
30- langs : [
31- "cpp" ,
32- "java" ,
33- "javascript" ,
34- "css" ,
35- "c#" ,
36- "c" ,
37- "c++" ,
38- "vue" ,
39- "vue-html" ,
40- "astro" ,
41- "bash" ,
42- "make" ,
43- "markdown" ,
44- "makefile" ,
45- "bat" ,
46- "cmake" ,
47- "cmd" ,
48- "csv" ,
49- "docker" ,
50- "dockerfile" ,
51- "go" ,
52- "python" ,
53- "html" ,
54- "jsx" ,
55- "tsx" ,
56- "typescript" ,
57- "sql" ,
58- "xml" ,
59- "sass" ,
60- "ssh-config" ,
61- "kotlin" ,
62- "json" ,
63- "swift" ,
64- "txt" ,
65- "diff" ,
66- ] ,
67- } ) ;
26+ const jsEngine = createJavaScriptRegexEngine ( { forgiving : true } ) ;
27+
28+ let provider : DePromise < ReturnType < typeof createHighlighter > > | null = null ;
29+
30+ let defaultInternal : DePromise < ReturnType < typeof createHighlighter > > | null = null ;
31+
32+ let customInternal : DePromise < ReturnType < typeof createHighlighter > > | null = null ;
33+
34+ let customInternalLangs : BundledLanguage [ ] | null = null ;
35+
36+ const getDefaultHighlighter = async ( ) => {
37+ let i = defaultInternal ;
38+
39+ if ( ! i ) {
40+ i = await createHighlighter ( {
41+ themes : [ "github-light" , "github-dark" ] ,
42+ langs : [
43+ "cpp" ,
44+ "java" ,
45+ "javascript" ,
46+ "css" ,
47+ "c#" ,
48+ "c" ,
49+ "c++" ,
50+ "vue" ,
51+ "vue-html" ,
52+ "astro" ,
53+ "bash" ,
54+ "make" ,
55+ "markdown" ,
56+ "makefile" ,
57+ "bat" ,
58+ "cmake" ,
59+ "cmd" ,
60+ "csv" ,
61+ "docker" ,
62+ "dockerfile" ,
63+ "go" ,
64+ "python" ,
65+ "html" ,
66+ "jsx" ,
67+ "tsx" ,
68+ "typescript" ,
69+ "sql" ,
70+ "xml" ,
71+ "sass" ,
72+ "ssh-config" ,
73+ "kotlin" ,
74+ "json" ,
75+ "swift" ,
76+ "txt" ,
77+ "diff" ,
78+ ] ,
79+ engine : jsEngine ,
80+ } ) ;
81+
82+ defaultInternal = i ;
83+ }
84+
85+ provider = i ;
86+
87+ return i ;
88+ } ;
89+
90+ const getHighlighter = async ( langs ?: BundledLanguage [ ] ) => {
91+ if ( Array . isArray ( langs ) && langs . length > 0 ) {
92+ let i = customInternal ;
93+
94+ if ( ! i ) {
95+ i = await createHighlighter ( {
96+ themes : [ "github-light" , "github-dark" ] ,
97+ langs,
98+ engine : jsEngine ,
99+ } ) ;
100+
101+ customInternal = i ;
102+
103+ customInternalLangs = langs ;
104+ } else {
105+ if ( __DEV__ ) {
106+ if ( customInternalLangs ) {
107+ if ( customInternalLangs . length < langs . length ) {
108+ console . warn (
109+ "@git-diff-view/shiki: custom langs has been set, but the new langs is different from the old one, please check your code"
110+ ) ;
111+ } else if ( ! customInternalLangs . sort ( ) . join ( "," ) . startsWith ( langs . sort ( ) . join ( "," ) ) ) {
112+ console . warn (
113+ "@git-diff-view/shiki: custom langs has been set, but the new langs is not a subset of the old one, please check your code"
114+ ) ;
115+ }
116+ }
117+ }
118+ }
119+
120+ provider = i ;
121+
122+ return i ;
123+ } else {
124+ return await getDefaultHighlighter ( ) ;
125+ }
126+ } ;
68127
69128const instance = { name : "shiki" } ;
70129
@@ -110,7 +169,7 @@ Object.defineProperty(instance, "getAST", {
110169 }
111170
112171 try {
113- return internal ?. codeToHast ( raw , {
172+ return ( provider || customInternal || defaultInternal ) ?. codeToHast ( raw , {
114173 lang : lang ,
115174 themes : {
116175 dark : "github-dark" ,
@@ -139,13 +198,13 @@ Object.defineProperty(instance, "processAST", {
139198
140199Object . defineProperty ( instance , "hasRegisteredCurrentLang" , {
141200 value : ( lang : string ) => {
142- return internal ?. getLanguage ( lang ) !== undefined ;
201+ return ( provider || customInternal || defaultInternal ) ?. getLanguage ( lang ) !== undefined ;
143202 } ,
144203} ) ;
145204
146205Object . defineProperty ( instance , "getHighlighterEngine" , {
147206 value : ( ) => {
148- return internal ;
207+ return provider || customInternal || defaultInternal ;
149208 } ,
150209} ) ;
151210
@@ -168,15 +227,17 @@ const highlighter: DiffHighlighter = instance as DiffHighlighter;
168227 * ```
169228 */
170229export const highlighterReady = new Promise < DiffHighlighter > ( ( r ) => {
171- if ( internal ) {
172- r ( highlighter ) ;
173- } else {
174- getDefaultHighlighter ( )
175- . then ( ( i ) => {
176- internal = i ;
177- } )
178- . then ( ( ) => r ( highlighter ) ) ;
179- }
230+ getDefaultHighlighter ( ) . then ( ( ) => r ( highlighter ) ) ;
231+ } ) . then ( ( r ) => {
232+ const proxy = new Proxy ( r , {
233+ get ( target , prop , receiver ) {
234+ if ( typeof prop === "string" && prop !== "then" ) {
235+ console . warn ( "@git-diff-view/shiki: highlighterReady is deprecated, please use getDiffViewHighlighter instead" ) ;
236+ }
237+ return Reflect . get ( target , prop , receiver ) ;
238+ } ,
239+ } ) ;
240+ return proxy ;
180241} ) ;
181242
182243/**
@@ -192,7 +253,17 @@ export const highlighterReady = new Promise<DiffHighlighter>((r) => {
192253 * }
193254 * ```
194255 */
195- export const getDiffViewHighlighter = ( ) => highlighterReady ;
256+ export const getDiffViewHighlighter = async ( langs ?: BundledLanguage [ ] ) => {
257+ if ( Array . isArray ( langs ) && langs . length > 0 ) {
258+ await getHighlighter ( langs ) ;
259+
260+ return highlighter ;
261+ } else {
262+ await getDefaultHighlighter ( ) ;
263+
264+ return highlighter ;
265+ }
266+ } ;
196267
197268export { processAST } from "./processAST" ;
198269
0 commit comments