Skip to content

Commit 9ff9425

Browse files
committed
feat: use textmate service override
remove monarch fallback
1 parent caac02d commit 9ff9425

File tree

8 files changed

+31
-338
lines changed

8 files changed

+31
-338
lines changed

src/languages/index.ts

Lines changed: 16 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
import * as monaco from 'monaco-editor'
2-
import { getOrCreateTextMateTokensProvider } from './textMate'
2+
import { setLanguages } from 'vscode/service-override/languages'
3+
import { setLanguageConfiguration } from 'vscode/service-override/languageConfiguration'
4+
import { StandaloneServices, ILanguageService } from 'vscode/services'
5+
import './textMate'
36
import textMateLanguages from './extensions/languages.json'
4-
import { languageLoader as monarchLanguageLoader } from './monarch'
5-
import languageConfigurationLoader, { RawLanguageConfiguration } from './extensions/languageConfigurationLoader'
7+
import languageConfigurationLoader from './extensions/languageConfigurationLoader'
68
import './snippets'
7-
import { addCustomFoldingMarkers } from '../hacks'
9+
import { addCustomFoldingMarkers, ILanguageConfiguration } from '../hacks'
810

911
const customAliases: Partial<Record<string, string[]>> = {
1012
csharp: ['c#'],
@@ -19,95 +21,27 @@ const customAliases: Partial<Record<string, string[]>> = {
1921
postgres: ['postgresql', 'postgres', 'pg', 'postgre']
2022
}
2123

24+
setLanguages(textMateLanguages.map(language => ({
25+
...language,
26+
configuration: languageConfigurationLoader[language.id] != null ? `./${language.id}-configuration.json` : undefined
27+
})))
28+
2229
for (const [languageId, aliases] of Object.entries(customAliases)) {
2330
monaco.languages.register({
2431
id: languageId,
2532
aliases
2633
})
2734
}
2835

29-
const languagesIds = Array.from(new Set([
30-
...Object.keys(monarchLanguageLoader),
31-
...textMateLanguages.map(rawLanguage => rawLanguage.id)
32-
]))
33-
3436
for (const textMateLanguage of textMateLanguages) {
35-
monaco.languages.register(textMateLanguage)
36-
}
37-
38-
for (const languageId of languagesIds) {
39-
monaco.languages.setTokenizationSupportFactory(languageId, {
40-
createTokenizationSupport: async () => {
41-
return getOrCreateTextMateTokensProvider(languageId).catch(async (error: Error) => {
42-
const monarchLoader = monarchLanguageLoader[languageId]
43-
if (monarchLoader != null) {
44-
monaco.errorHandler.onUnexpectedError(new Error(`Failed to load TextMate grammar for language ${languageId}, fallback to monarch`, {
45-
cause: error
46-
}))
47-
try {
48-
monaco.languages.setMonarchTokensProvider(languageId, (await monarchLoader()).language)
49-
} catch (error) {
50-
monaco.errorHandler.onUnexpectedError(new Error(`Failed to load Monarch grammar for language ${languageId}`, {
51-
cause: error as Error
52-
}))
53-
}
54-
} else {
55-
monaco.errorHandler.onUnexpectedError(new Error(`Failed to load TextMate grammar for language ${languageId} and no fallback monarch`, {
56-
cause: error
57-
}))
58-
}
59-
return null
60-
})
61-
}
62-
})
63-
}
64-
65-
/**
66-
* Type is wrong
67-
* see https://github.com/microsoft/vscode/blob/cfad2543487c4a8e8f53b4451dbccdc1c2036f41/src/vs/workbench/contrib/codeEditor/browser/languageConfigurationExtensionPoint.ts#L381
68-
*/
69-
function parseLanguageConfiguration (config: RawLanguageConfiguration): monaco.extra.ILanguageConfiguration {
70-
const markers = config.folding?.markers
71-
return {
72-
...config,
73-
folding: config.folding != null
74-
? {
75-
...config.folding,
76-
markers: (markers != null) ? { start: new RegExp(markers.start), end: new RegExp(markers.end) } : undefined
77-
}
78-
: undefined
37+
const configurationLoader = languageConfigurationLoader[textMateLanguage.id]
38+
if (configurationLoader != null) {
39+
setLanguageConfiguration(`/${textMateLanguage.id}-configuration.json`, async () => JSON.stringify(addCustomFoldingMarkers((await configurationLoader()) as ILanguageConfiguration)))
7940
}
8041
}
8142

82-
async function loadLanguageConfiguration (languageId: string) {
83-
const loader = languageConfigurationLoader[languageId]
84-
if (loader != null) {
85-
const configuration = await loader()
86-
monaco.extra.handleLanguageConfiguration(
87-
languageId,
88-
addCustomFoldingMarkers(parseLanguageConfiguration(configuration))
89-
)
90-
}
91-
}
92-
93-
setTimeout(() => {
94-
// In a timeout so the service can be overriden
95-
const languageService = monaco.extra.StandaloneServices.get(monaco.languages.ILanguageService)
96-
languageService.onDidEncounterLanguage(async (languageId) => {
97-
if (languageId === 'plaintext') {
98-
return
99-
}
100-
101-
loadLanguageConfiguration(languageId).catch(error => {
102-
monaco.errorHandler.onUnexpectedError(new Error(`Unable to load language configuration for language ${languageId}`, {
103-
cause: error
104-
}))
105-
})
106-
})
107-
})
108-
10943
function getMonacoLanguage (languageOrModeId: string): string {
110-
const languageService = monaco.extra.StandaloneServices.get(monaco.languages.ILanguageService)
44+
const languageService = StandaloneServices.get(ILanguageService)
11145
const modeId = languageService.getLanguageIdByLanguageName(languageOrModeId.toLowerCase())
11246
if (modeId != null) {
11347
return modeId
@@ -123,10 +57,7 @@ function getMonacoLanguage (languageOrModeId: string): string {
12357
}
12458

12559
async function loadLanguage (languageId: string): Promise<void> {
126-
await Promise.all([
127-
loadLanguageConfiguration(languageId),
128-
getOrCreateTextMateTokensProvider(languageId)
129-
])
60+
StandaloneServices.get(ILanguageService).createById(languageId)
13061
}
13162

13263
export {

src/languages/monarch/index.ts

Lines changed: 0 additions & 43 deletions
This file was deleted.

src/languages/monarch/stub-generator.ts

Lines changed: 0 additions & 15 deletions
This file was deleted.

src/languages/textMate/CGTMGrammarFactory.ts

Lines changed: 0 additions & 69 deletions
This file was deleted.

src/languages/textMate/CGTMTokenizationSupport.ts

Lines changed: 0 additions & 33 deletions
This file was deleted.

src/languages/textMate/index.ts

Lines changed: 5 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,63 +1,9 @@
1-
import * as monaco from 'monaco-editor'
2-
import onigFile from 'vscode-oniguruma/release/onig.wasm'
3-
import CGTMGrammarFactory from './CGTMGrammarFactory'
4-
import CGTMTokenizationSupport from './CGTMTokenizationSupport'
1+
import { setGrammars, ITMSyntaxExtensionPoint } from 'vscode/service-override/textmate'
52
import rawGrammars from '../extensions/grammars.json'
63
import grammarLoader from '../extensions/grammarLoader'
74
import './semanticTokens'
85

9-
function createGrammarFactory (): CGTMGrammarFactory {
10-
const languageService = monaco.extra.StandaloneServices.get(monaco.languages.ILanguageService)
11-
const parsedGrammars = (rawGrammars as unknown as Omit<monaco.extra.ITMSyntaxExtensionPoint, 'path'>[])
12-
.map(grammar => ({
13-
...monaco.extra.parseTextMateGrammar(grammar as monaco.extra.ITMSyntaxExtensionPoint, languageService),
14-
location: monaco.Uri.from({
15-
scheme: 'browser',
16-
path: grammar.scopeName + '.json'
17-
})
18-
}))
19-
20-
return new CGTMGrammarFactory(
21-
parsedGrammars,
22-
grammarLoader,
23-
onigFile
24-
)
25-
}
26-
27-
let textMateGrammarFactory: CGTMGrammarFactory | null = null
28-
function getOrCreateGrammarFactory (): CGTMGrammarFactory {
29-
if (textMateGrammarFactory == null) {
30-
textMateGrammarFactory = createGrammarFactory()
31-
}
32-
return textMateGrammarFactory
33-
}
34-
35-
async function createTextMateTokensProvider (languageId: string): Promise<monaco.languages.ITokenizationSupport | null> {
36-
const languageService = monaco.extra.StandaloneServices.get(monaco.languages.ILanguageService)
37-
const grammarFactory = getOrCreateGrammarFactory()
38-
const encodedLanguageId = languageService.languageIdCodec.encodeLanguageId(languageId)
39-
if (!grammarFactory.has(languageId)) {
40-
return null
41-
}
42-
const { grammar, initialState, containsEmbeddedLanguages } = await grammarFactory.createGrammar(languageId, encodedLanguageId)
43-
if (grammar == null) {
44-
return null
45-
}
46-
const tokenization = new monaco.extra.TMTokenization(grammar, initialState, containsEmbeddedLanguages)
47-
tokenization.onDidEncounterLanguage((encodedLanguageId) => {
48-
// Force monaco to load this language and trigger the global `onDidEncounterLanguage`
49-
languageService.createById(languageService.languageIdCodec.decodeLanguageId(encodedLanguageId))
50-
})
51-
return new CGTMTokenizationSupport(languageId, encodedLanguageId, tokenization, grammar)
52-
}
53-
54-
const tokenizationSupports = new Map<string, Promise<monaco.languages.ITokenizationSupport | null>>()
55-
56-
export function getOrCreateTextMateTokensProvider (languageId: string): Promise<monaco.languages.ITokenizationSupport | null> {
57-
let tokenizationSupportPromise = tokenizationSupports.get(languageId)
58-
if (tokenizationSupportPromise == null) {
59-
tokenizationSupportPromise = createTextMateTokensProvider(languageId)
60-
tokenizationSupports.set(languageId, tokenizationSupportPromise)
61-
}
62-
return tokenizationSupportPromise
63-
}
6+
setGrammars((rawGrammars as unknown as Omit<ITMSyntaxExtensionPoint, 'path'>[]).map(grammar => ({
7+
...grammar,
8+
path: grammar.scopeName + '.json'
9+
})), async (grammar) => JSON.stringify(await grammarLoader[grammar.scopeName]!()))

0 commit comments

Comments
 (0)