Skip to content

Commit

Permalink
Trigger loading configuration for embedded modes
Browse files Browse the repository at this point in the history
Load configuration for languages when they are first encountered as an embedded mode in TextMate (#14136)
  • Loading branch information
alexdima committed Oct 24, 2016
1 parent 03f13f1 commit b62ca81
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 20 deletions.
30 changes: 14 additions & 16 deletions src/vs/editor/node/languageConfiguration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { LanguageConfigurationRegistry } from 'vs/editor/common/modes/languageCo
import { Extensions, IJSONContributionRegistry } from 'vs/platform/jsonschemas/common/jsonContributionRegistry';
import { Registry } from 'vs/platform/platform';
import { IJSONSchema } from 'vs/base/common/jsonSchema';
import { MainProcessTextMateSyntax } from 'vs/editor/node/textMate/TMSyntax';

type CharacterPair = [string, string];

Expand All @@ -32,31 +33,28 @@ interface ILanguageConfiguration {
export class LanguageConfigurationFileHandler {

private _modeService: IModeService;
private _done: { [modeId: string]: boolean; };

constructor(
tmSyntax: MainProcessTextMateSyntax,
@IModeService modeService: IModeService
) {
this._modeService = modeService;
this._done = Object.create(null);

this._handleModes(this._modeService.getRegisteredModes());
this._modeService.onDidAddModes((modes) => this._handleModes(modes));
// Listen for hints that a language configuration is needed/usefull and then load it once
this._modeService.onDidCreateMode((mode) => this._loadConfigurationsForMode(mode.getId()));
tmSyntax.onDidEncounterLanguage((language) => this._loadConfigurationsForMode(language));
}

private _handleModes(modes: string[]): void {
modes.forEach(modeId => this._handleMode(modeId));
}

private _handleMode(modeId: string): void {
let disposable = this._modeService.onDidCreateMode((mode) => {
if (mode.getId() !== modeId) {
return;
}

let configurationFiles = this._modeService.getConfigurationFiles(modeId);
configurationFiles.forEach((configFilePath) => this._handleConfigFile(modeId, configFilePath));
private _loadConfigurationsForMode(modeId: string): void {
if (this._done[modeId]) {
return;
}
this._done[modeId] = true;

disposable.dispose();
});
let configurationFiles = this._modeService.getConfigurationFiles(modeId);
configurationFiles.forEach((configFilePath) => this._handleConfigFile(modeId, configFilePath));
}

private _handleConfigFile(modeId: string, configFilePath: string): void {
Expand Down
19 changes: 17 additions & 2 deletions src/vs/editor/node/textMate/TMSyntax.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import * as nls from 'vs/nls';
import { onUnexpectedError } from 'vs/base/common/errors';
import * as paths from 'vs/base/common/paths';
import * as strings from 'vs/base/common/strings';
import Event, { Emitter } from 'vs/base/common/event';
import { IExtensionMessageCollector, ExtensionsRegistry } from 'vs/platform/extensions/common/extensionsRegistry';
import { ILineTokens, ITokenizationSupport, TokenizationRegistry } from 'vs/editor/common/modes';
import { TMState } from 'vs/editor/common/modes/TMState';
Expand All @@ -24,7 +25,7 @@ export interface ITMSyntaxExtensionPoint {
injectTo: string[];
}

// @martin TS(2.0.2) - Type IJsonSchema has no defined property require. Keeping semantic using any cast
// TODO@Martin TS(2.0.2) - Type IJsonSchema has no defined property require. Keeping semantic using any cast
let grammarsExtPoint = ExtensionsRegistry.registerExtensionPoint<ITMSyntaxExtensionPoint[]>('grammars', <any>{
description: nls.localize('vscode.extension.contributes.grammars', 'Contributes textmate tokenizers.'),
type: 'array',
Expand Down Expand Up @@ -61,11 +62,16 @@ export class TMScopeRegistry {

private _scopeNameToFilePath: { [scopeName: string]: string; };
private _scopeNameToLanguage: { [scopeName: string]: string; };
private _encounteredLanguages: { [language: string]: boolean; };
private _cachedScopesRegex: RegExp;

private _onDidEncounterLanguage: Emitter<string> = new Emitter<string>();
public onDidEncounterLanguage: Event<string> = this._onDidEncounterLanguage.event;

constructor() {
this._scopeNameToFilePath = Object.create(null);
this._scopeNameToLanguage = Object.create(null);
this._encounteredLanguages = Object.create(null);
this._cachedScopesRegex = null;
}

Expand Down Expand Up @@ -111,7 +117,13 @@ export class TMScopeRegistry {
return null;
}

return this._scopeNameToLanguage[m[1]] || null;
let language = this._scopeNameToLanguage[m[1]] || null;
if (language && !this._encounteredLanguages[language]) {
this._encounteredLanguages[language] = true;
this._onDidEncounterLanguage.fire(language);
}

return language;
}
}

Expand All @@ -121,11 +133,14 @@ export class MainProcessTextMateSyntax {
private _scopeRegistry: TMScopeRegistry;
private _injections: { [scopeName: string]: string[]; };

public onDidEncounterLanguage: Event<string>;

constructor(
@IModeService modeService: IModeService
) {
this._modeService = modeService;
this._scopeRegistry = new TMScopeRegistry();
this.onDidEncounterLanguage = this._scopeRegistry.onDidEncounterLanguage;
this._injections = {};

this._grammarRegistry = new Registry({
Expand Down
4 changes: 2 additions & 2 deletions src/vs/workbench/api/node/extHost.contribution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,10 +86,10 @@ export class ExtHostContribution implements IWorkbenchContribution {
col.finish(true, this.threadService);

// Other interested parties
create(MainProcessTextMateSyntax);
let tmSyntax = create(MainProcessTextMateSyntax);
create(MainProcessTextMateSnippet);
create(JSONValidationExtensionPoint);
create(LanguageConfigurationFileHandler);
this.instantiationService.createInstance(LanguageConfigurationFileHandler, tmSyntax);
create(MainThreadFileSystemEventService);
create(SaveParticipant);
}
Expand Down

0 comments on commit b62ca81

Please sign in to comment.