Skip to content

Commit

Permalink
plugin-ext: late textmate grammar activation
Browse files Browse the repository at this point in the history
There is a race condition when the layout is restored: if an editor was
opened, it will be restored and wait for some language activation event.
The issue with this was first seen with the builtin cpp extension: two
cpp grammars are contributed, but the first one is not the right one to
use on a cpp file. When an editor opened, the first bogus grammar is
loaded and activated, triggering bogus coloration.

This commit ensures that all grammars are more correctly contributed
before activating anything in the next event-loop tick.

Signed-off-by: Paul Maréchal <[email protected]>
  • Loading branch information
paul-marechal committed Apr 14, 2020
1 parent 37fa343 commit c5d3708
Showing 1 changed file with 23 additions and 12 deletions.
35 changes: 23 additions & 12 deletions packages/plugin-ext/src/main/browser/plugin-contribution-handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { ITokenTypeMap, IEmbeddedLanguagesMap, StandardTokenType } from 'vscode-
import { TextmateRegistry, getEncodedLanguageId, MonacoTextmateService, GrammarDefinition } from '@theia/monaco/lib/browser/textmate';
import { MenusContributionPointHandler } from './menus/menus-contribution-handler';
import { PluginViewRegistry } from './view/plugin-view-registry';
import { PluginContribution, IndentationRules, FoldingRules, ScopeMap, DeployedPlugin } from '../../common';
import { PluginContribution, IndentationRules, FoldingRules, ScopeMap, DeployedPlugin, GrammarsContribution } from '../../common';
import { PreferenceSchemaProvider } from '@theia/core/lib/browser';
import { PreferenceSchema, PreferenceSchemaProperties } from '@theia/core/lib/browser/preferences';
import { KeybindingsContributionPointHandler } from './keybindings/keybindings-contribution-handler';
Expand Down Expand Up @@ -162,6 +162,7 @@ export class PluginContributionHandler {

const grammars = contributions.grammars;
if (grammars && grammars.length) {
const grammarsWithLanguage: GrammarsContribution[] = [];
for (const grammar of grammars) {
if (grammar.injectTo) {
for (const injectScope of grammar.injectTo) {
Expand All @@ -178,6 +179,10 @@ export class PluginContributionHandler {
});
}
}
if (grammar.language) {
// processing is deferred.
grammarsWithLanguage.push(grammar);
}
pushContribution(`grammar.textmate.scope.${grammar.scope}`, () => this.grammarsRegistry.registerTextmateGrammarScope(grammar.scope, {
async getGrammarDefinition(): Promise<GrammarDefinition> {
return {
Expand All @@ -189,23 +194,29 @@ export class PluginContributionHandler {
getInjections: (scopeName: string) =>
this.injections.get(scopeName)!
}));

// load grammars on next tick to await registration of languages from all plugins in current tick
// see https://github.com/eclipse-theia/theia/issues/6907#issuecomment-578600243
}
// load grammars on next tick to await registration of languages from all plugins in current tick
// see https://github.com/eclipse-theia/theia/issues/6907#issuecomment-578600243
setTimeout(() => {
for (const grammar of grammarsWithLanguage) {
const language = grammar.language!;
pushContribution(`grammar.language.${language}.scope`, () => this.grammarsRegistry.mapLanguageIdToTextmateGrammar(language, grammar.scope));
pushContribution(`grammar.language.${language}.configuration`, () => this.grammarsRegistry.registerGrammarConfiguration(language, {
embeddedLanguages: this.convertEmbeddedLanguages(grammar.embeddedLanguages, logError),
tokenTypes: this.convertTokenTypes(grammar.tokenTypes)
}));
}
// activate grammars only once everything else is loaded.
// see https://github.com/eclipse-theia/theia-cpp-extensions/issues/100#issuecomment-610643866
setTimeout(() => {
const language = grammar.language;
if (language) {
pushContribution(`grammar.language.${language}.scope`, () => this.grammarsRegistry.mapLanguageIdToTextmateGrammar(language, grammar.scope));
pushContribution(`grammar.language.${language}.configuration`, () => this.grammarsRegistry.registerGrammarConfiguration(language, {
embeddedLanguages: this.convertEmbeddedLanguages(grammar.embeddedLanguages, logError),
tokenTypes: this.convertTokenTypes(grammar.tokenTypes)
}));
for (const grammar of grammarsWithLanguage) {
const language = grammar.language!;
pushContribution(`grammar.language.${language}.activation`,
() => this.monacoTextmateService.activateLanguage(language)
);
}
});
}
});
}

pushContribution('commands', () => this.registerCommands(contributions));
Expand Down

0 comments on commit c5d3708

Please sign in to comment.