Skip to content

Commit f35eda0

Browse files
committed
feat: Add a method to preload a language
1 parent 5005371 commit f35eda0

File tree

3 files changed

+40
-17
lines changed

3 files changed

+40
-17
lines changed

src/index.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import * as monaco from 'monaco-editor'
22
import { createEditor, registerEditorOpenHandler, registerTextModelContentProvider } from './monaco'
33
import { addVSCodeTheme } from './theme'
44
import { updateUserConfiguration, registerConfigurations, registerDefaultConfigurations, onConfigurationChanged, getConfiguration } from './configuration'
5-
import { getMonacoLanguage } from './languages'
5+
import { getMonacoLanguage, loadLanguage } from './languages'
66
import { updateKeybindings, updateEditorKeybindingsMode } from './keybindings'
77
import { getThemeData } from './theme/registry'
88
import type { IVSCodeTheme } from './theme/tools'
@@ -26,7 +26,8 @@ export {
2626

2727
getMonacoLanguage,
2828
registerTextModelContentProvider,
29-
registerEditorOpenHandler
29+
registerEditorOpenHandler,
30+
loadLanguage
3031
}
3132

3233
export type {

src/languages/index.ts

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import * as monaco from 'monaco-editor'
2-
import { createTextMateTokensProvider } from './textMate'
2+
import { getOrCreateTextMateTokensProvider } from './textMate'
33
import textMateLanguages from './extensions/languages.json'
44
import { languageLoader as monarchLanguageLoader } from './monarch'
55
import languageConfigurationLoader, { RawLanguageConfiguration } from './extensions/languageConfigurationLoader'
@@ -39,7 +39,7 @@ for (const languageId of languagesIds) {
3939

4040
monaco.languages.setTokenizationSupportFactory(languageId, {
4141
createTokenizationSupport: async () => {
42-
return createTextMateTokensProvider(languageId).catch(err => {
42+
return getOrCreateTextMateTokensProvider(languageId).catch(err => {
4343
const monarchLoader = monarchLanguageLoader[languageId]
4444
if (monarchLoader != null) {
4545
console.warn(`Failed to load TextMate grammar for language ${languageId}, fallback to monarch`, err)
@@ -70,22 +70,25 @@ function parseLanguageConfiguration (config: RawLanguageConfiguration): monaco.e
7070
}
7171
}
7272

73+
async function loadLanguageConfiguration (languageId: string) {
74+
const loader = languageConfigurationLoader[languageId]
75+
if (loader != null) {
76+
const configuration = await loader()
77+
monaco.extra.handleLanguageConfiguration(
78+
languageId,
79+
addCustomFoldingMarkers(parseLanguageConfiguration(configuration))
80+
)
81+
}
82+
}
83+
7384
languageService.onDidEncounterLanguage(async (languageId) => {
7485
if (languageId === 'plaintext') {
7586
return
7687
}
7788

78-
const loader = languageConfigurationLoader[languageId]
79-
if (loader != null) {
80-
loader().then((configuration) => {
81-
monaco.extra.handleLanguageConfiguration(
82-
languageId,
83-
addCustomFoldingMarkers(parseLanguageConfiguration(configuration))
84-
)
85-
}).catch(error => {
86-
console.error('Unable to load language configuration', error)
87-
})
88-
}
89+
loadLanguageConfiguration(languageId).catch(error => {
90+
console.error('Unable to load language configuration', error)
91+
})
8992
})
9093

9194
function getMonacoLanguage (languageOrModeId: string): string {
@@ -103,6 +106,14 @@ function getMonacoLanguage (languageOrModeId: string): string {
103106
return 'plaintext'
104107
}
105108

109+
async function loadLanguage (languageId: string): Promise<void> {
110+
await Promise.all([
111+
loadLanguageConfiguration(languageId),
112+
getOrCreateTextMateTokensProvider(languageId)
113+
])
114+
}
115+
106116
export {
107-
getMonacoLanguage
117+
getMonacoLanguage,
118+
loadLanguage
108119
}

src/languages/textMate/index.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ function getOrCreateGrammarFactory (): CGTMGrammarFactory {
3030
}
3131

3232
const languageService = monaco.extra.StandaloneServices.get(monaco.languages.ILanguageService)
33-
export async function createTextMateTokensProvider (languageId: string): Promise<monaco.languages.ITokenizationSupport> {
33+
async function createTextMateTokensProvider (languageId: string): Promise<monaco.languages.ITokenizationSupport> {
3434
const grammarFactory = getOrCreateGrammarFactory()
3535
const encodedLanguageId = languageService.languageIdCodec.encodeLanguageId(languageId)
3636
const { grammar, initialState, containsEmbeddedLanguages } = await grammarFactory.createGrammar(languageId, encodedLanguageId)
@@ -44,3 +44,14 @@ export async function createTextMateTokensProvider (languageId: string): Promise
4444
})
4545
return new CGTMTokenizationSupport(languageId, encodedLanguageId, tokenization, grammar)
4646
}
47+
48+
const tokenizationSupports = new Map<string, Promise<monaco.languages.ITokenizationSupport>>()
49+
50+
export function getOrCreateTextMateTokensProvider (languageId: string): Promise<monaco.languages.ITokenizationSupport> {
51+
let tokenizationSupportPromise = tokenizationSupports.get(languageId)
52+
if (tokenizationSupportPromise == null) {
53+
tokenizationSupportPromise = createTextMateTokensProvider(languageId)
54+
tokenizationSupports.set(languageId, tokenizationSupportPromise)
55+
}
56+
return tokenizationSupportPromise
57+
}

0 commit comments

Comments
 (0)