Skip to content

Commit

Permalink
[vscode] support onLanguage activation event
Browse files Browse the repository at this point in the history
Signed-off-by: Anton Kosyakov <[email protected]>
  • Loading branch information
akosyakov committed Jul 2, 2019
1 parent 39a48a8 commit cf111db
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 22 deletions.
54 changes: 33 additions & 21 deletions packages/monaco/src/browser/textmate/monaco-textmate-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

import { injectable, inject, named } from 'inversify';
import { Registry, IOnigLib, IRawGrammar, parseRawGrammar } from 'vscode-textmate';
import { ILogger, ContributionProvider } from '@theia/core';
import { ILogger, ContributionProvider, Emitter } from '@theia/core';
import { FrontendApplicationContribution, isBasicWasmSupported } from '@theia/core/lib/browser';
import { ThemeService } from '@theia/core/lib/browser/theming';
import { LanguageGrammarDefinitionContribution, getEncodedLanguageId } from './textmate-contribution';
Expand All @@ -30,6 +30,14 @@ export type OnigasmPromise = Promise<IOnigLib>;
@injectable()
export class MonacoTextmateService implements FrontendApplicationContribution {

protected readonly _activatedLanguages = new Set<string>();
get activatedLanguages(): ReadonlySet<string> {
return this._activatedLanguages;
}

protected readonly onDidActivateLanguageEmitter = new Emitter<string>();
readonly onDidActivateLanguage = this.onDidActivateLanguageEmitter.event;

protected grammarRegistry: Registry;

@inject(ContributionProvider) @named(LanguageGrammarDefinitionContribution)
Expand Down Expand Up @@ -97,35 +105,39 @@ export class MonacoTextmateService implements FrontendApplicationContribution {
}
});

const registered = new Set<string>();
for (const { id } of monaco.languages.getLanguages()) {
if (!registered.has(id)) {
monaco.languages.onLanguage(id, () => this.activateLanguage(id));
registered.add(id);
}
monaco.languages.onLanguage(id, () => this.activateLanguage(id));
}
}

async activateLanguage(languageId: string) {
const scopeName = this.textmateRegistry.getScope(languageId);
if (!scopeName) {
return;
}
const provider = this.textmateRegistry.getProvider(scopeName);
if (!provider) {
if (this._activatedLanguages.has(languageId)) {
return;
}
this._activatedLanguages.add(languageId);
try {
const scopeName = this.textmateRegistry.getScope(languageId);
if (!scopeName) {
return;
}
const provider = this.textmateRegistry.getProvider(scopeName);
if (!provider) {
return;
}

const configuration = this.textmateRegistry.getGrammarConfiguration(languageId);
const initialLanguage = getEncodedLanguageId(languageId);
const configuration = this.textmateRegistry.getGrammarConfiguration(languageId);
const initialLanguage = getEncodedLanguageId(languageId);

await this.onigasmPromise;
try {
const grammar = await this.grammarRegistry.loadGrammarWithConfiguration(scopeName, initialLanguage, configuration);
const options = configuration.tokenizerOption ? configuration.tokenizerOption : TokenizerOption.DEFAULT;
monaco.languages.setTokensProvider(languageId, createTextmateTokenizer(grammar, options));
} catch (error) {
this.logger.warn('No grammar for this language id', languageId, error);
await this.onigasmPromise;
try {
const grammar = await this.grammarRegistry.loadGrammarWithConfiguration(scopeName, initialLanguage, configuration);
const options = configuration.tokenizerOption ? configuration.tokenizerOption : TokenizerOption.DEFAULT;
monaco.languages.setTokensProvider(languageId, createTextmateTokenizer(grammar, options));
} catch (error) {
this.logger.warn('No grammar for this language id', languageId, error);
}
} finally {
this.onDidActivateLanguageEmitter.fire(languageId);
}
}
}
13 changes: 13 additions & 0 deletions packages/plugin-ext/src/hosted/browser/hosted-plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import { PluginServer } from '../../common/plugin-protocol';
import { KeysToKeysToAnyValue } from '../../common/types';
import { FileStat } from '@theia/filesystem/lib/common/filesystem';
import { PluginManagerExt, MAIN_RPC_CONTEXT } from '../../common';
import { MonacoTextmateService } from '@theia/monaco/lib/browser/textmate';

export type PluginHost = 'frontend' | string;

Expand Down Expand Up @@ -76,6 +77,9 @@ export class HostedPluginSupport {
@inject(WorkspaceService)
protected readonly workspaceService: WorkspaceService;

@inject(MonacoTextmateService)
protected readonly monacoTextmateService: MonacoTextmateService;

private theiaReadyPromise: Promise<any>;

protected readonly managers: PluginManagerExt[] = [];
Expand All @@ -89,6 +93,11 @@ export class HostedPluginSupport {
protected init(): void {
this.theiaReadyPromise = Promise.all([this.preferenceServiceImpl.ready, this.workspaceService.roots]);
this.storagePathService.onStoragePathChanged(path => this.updateStoragePath(path));

for (const id of this.monacoTextmateService.activatedLanguages) {
this.activateByLanguage(id);
}
this.monacoTextmateService.onDidActivateLanguage(id => this.activateByLanguage(id));
}

checkAndLoadPlugin(container: interfaces.Container): void {
Expand Down Expand Up @@ -197,6 +206,10 @@ export class HostedPluginSupport {
}
}

activateByLanguage(languageId: string): void {
this.activateByEvent(`onLanguage:${languageId}`);
}

}

interface PluginsInitializationData {
Expand Down
2 changes: 1 addition & 1 deletion packages/plugin-ext/src/plugin/plugin-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ class ActivatedPlugin {

export class PluginManagerExtImpl implements PluginManagerExt, PluginManager {

static SUPPORTED_ACTIVATION_EVENTS = new Set(['*']);
static SUPPORTED_ACTIVATION_EVENTS = new Set(['*', 'onLanguage']);

private readonly registry = new Map<string, Plugin>();
private readonly activations = new Map<string, (() => Promise<void>)[] | undefined>();
Expand Down

0 comments on commit cf111db

Please sign in to comment.