update vscode-textmate (async loading)

This commit is contained in:
Martin Aeschlimann 2018-06-18 16:14:58 +02:00
parent b2cbf270ad
commit 5bde5c1160
4 changed files with 126 additions and 52 deletions

View file

@ -48,7 +48,7 @@
"vscode-debugprotocol": "1.28.0",
"vscode-nsfw": "1.0.17",
"vscode-ripgrep": "^1.0.1",
"vscode-textmate": "^3.3.3",
"vscode-textmate": "^4.0.0-next.2",
"vscode-xterm": "3.5.0-beta12",
"yauzl": "^2.9.1"
},
@ -137,4 +137,4 @@
"windows-mutex": "^0.2.0",
"windows-process-tree": "0.2.2"
}
}
}

View file

@ -23,13 +23,16 @@ declare module "vscode-textmate" {
readonly name?: string;
readonly settings: IRawThemeSetting[];
}
export interface Thenable<T> extends PromiseLike<T> {
}
/**
* A registry helper that can locate grammar file paths given scope names.
*/
export interface RegistryOptions {
theme?: IRawTheme;
getFilePath(scopeName: string): string;
loadGrammar(scopeName: string): Thenable<IRawGrammar>;
getInjections?(scopeName: string): string[];
getOnigLib?(): Thenable<IOnigLib>;
}
/**
* A map from scope name to a language id. Please do not use language id 0.
@ -38,10 +41,10 @@ declare module "vscode-textmate" {
[scopeName: string]: number;
}
/**
* A map from scope name to a token type.
* A map from selectors to token types.
*/
export interface ITokenTypeMap {
[scopeName: string]: StandardTokenType;
[selector: string]: StandardTokenType;
}
export const enum StandardTokenType {
Other = 0,
@ -72,25 +75,25 @@ declare module "vscode-textmate" {
* Load the grammar for `scopeName` and all referenced included grammars asynchronously.
* Please do not use language id 0.
*/
loadGrammarWithEmbeddedLanguages(initialScopeName: string, initialLanguage: number, embeddedLanguages: IEmbeddedLanguagesMap, callback: (err: any, grammar: IGrammar) => void): void;
loadGrammarWithEmbeddedLanguages(initialScopeName: string, initialLanguage: number, embeddedLanguages: IEmbeddedLanguagesMap): Thenable<IGrammar>;
/**
* Load the grammar for `scopeName` and all referenced included grammars asynchronously.
* Please do not use language id 0.
*/
loadGrammarWithConfiguration(initialScopeName: string, initialLanguage: number, configuration: IGrammarConfiguration, callback: (err: any, grammar: IGrammar) => void): void;
loadGrammarWithConfiguration(initialScopeName: string, initialLanguage: number, configuration: IGrammarConfiguration): Thenable<IGrammar>;
/**
* Load the grammar for `scopeName` and all referenced included grammars asynchronously.
*/
loadGrammar(initialScopeName: string, callback: (err: any, grammar: IGrammar) => void): void;
private _loadGrammar(initialScopeName, callback);
loadGrammar(initialScopeName: string): Thenable<IGrammar>;
private _loadGrammar(initialScopeName, initialLanguage, embeddedLanguages, tokenTypes);
/**
* Load the grammar at `path` synchronously.
* Adds a rawGrammar.
*/
loadGrammarFromPathSync(path: string, initialLanguage?: number, embeddedLanguages?: IEmbeddedLanguagesMap): IGrammar;
addGrammar(rawGrammar: IRawGrammar, injections?: string[], initialLanguage?: number, embeddedLanguages?: IEmbeddedLanguagesMap): Thenable<IGrammar>;
/**
* Get the grammar for `scopeName`. The grammar must first be created via `loadGrammar` or `loadGrammarFromPathSync`.
* Get the grammar for `scopeName`. The grammar must first be created via `loadGrammar` or `addGrammar`.
*/
grammarForScopeName(scopeName: string, initialLanguage?: number, embeddedLanguages?: IEmbeddedLanguagesMap, tokenTypes?: ITokenTypeMap): IGrammar;
grammarForScopeName(scopeName: string, initialLanguage?: number, embeddedLanguages?: IEmbeddedLanguagesMap, tokenTypes?: ITokenTypeMap): Thenable<IGrammar>;
}
/**
* A grammar
@ -179,4 +182,75 @@ declare module "vscode-textmate" {
equals(other: StackElement): boolean;
}
export const INITIAL: StackElement;
export const parseRawGrammar: (content: string, filePath: string) => IRawGrammar;
export interface ILocation {
readonly filename: string;
readonly line: number;
readonly char: number;
}
export interface ILocatable {
readonly $vscodeTextmateLocation?: ILocation;
}
export interface IRawGrammar extends ILocatable {
repository: IRawRepository;
readonly scopeName: string;
readonly patterns: IRawRule[];
readonly injections?: {
[expression: string]: IRawRule;
};
readonly injectionSelector?: string;
readonly fileTypes?: string[];
readonly name?: string;
readonly firstLineMatch?: string;
}
export interface IRawRepositoryMap {
[name: string]: IRawRule;
$self: IRawRule;
$base: IRawRule;
}
export type IRawRepository = IRawRepositoryMap & ILocatable;
export interface IRawRule extends ILocatable {
id?: number;
readonly include?: string;
readonly name?: string;
readonly contentName?: string;
readonly match?: string;
readonly captures?: IRawCaptures;
readonly begin?: string;
readonly beginCaptures?: IRawCaptures;
readonly end?: string;
readonly endCaptures?: IRawCaptures;
readonly while?: string;
readonly whileCaptures?: IRawCaptures;
readonly patterns?: IRawRule[];
readonly repository?: IRawRepository;
readonly applyEndPatternLast?: boolean;
}
export interface IRawCapturesMap {
[captureId: string]: IRawRule;
}
export type IRawCaptures = IRawCapturesMap & ILocatable;
export interface IOnigLib {
createOnigScanner(sources: string[]): OnigScanner;
createOnigString(sources: string): OnigString;
}
export interface IOnigCaptureIndex {
start: number;
end: number;
length: number;
}
export interface IOnigMatch {
index: number;
captureIndices: IOnigCaptureIndex[];
scanner: OnigScanner;
}
export interface OnigScanner {
findNextMatchSync(string: string | OnigString, startPosition: number): IOnigMatch;
}
export interface OnigString {
readonly content: string;
readonly dispose?: () => void;
}
}

View file

@ -7,14 +7,14 @@
import * as nls from 'vs/nls';
import * as dom from 'vs/base/browser/dom';
import * as types from 'vs/base/common/types';
import * as resources from 'vs/base/common/resources';
import { Event, Emitter } from 'vs/base/common/event';
import { join, normalize } from 'path';
import { TPromise } from 'vs/base/common/winjs.base';
import { onUnexpectedError } from 'vs/base/common/errors';
import { ExtensionMessageCollector } from 'vs/workbench/services/extensions/common/extensionsRegistry';
import { ITokenizationSupport, TokenizationRegistry, IState, LanguageId, TokenMetadata } from 'vs/editor/common/modes';
import { IModeService } from 'vs/editor/common/services/modeService';
import { StackElement, IGrammar, Registry, IEmbeddedLanguagesMap as IEmbeddedLanguagesMap2, ITokenTypeMap, StandardTokenType } from 'vscode-textmate';
import { StackElement, IGrammar, Registry, IEmbeddedLanguagesMap as IEmbeddedLanguagesMap2, ITokenTypeMap, StandardTokenType, parseRawGrammar } from 'vscode-textmate';
import { IWorkbenchThemeService, ITokenColorizationRule } from 'vs/workbench/services/themes/common/workbenchThemeService';
import { ITextMateService } from 'vs/workbench/services/textMate/electron-browser/textMateService';
import { grammarsExtPoint, IEmbeddedLanguagesMap, ITMSyntaxExtensionPoint, TokenTypesContribution } from 'vs/workbench/services/textMate/electron-browser/TMGrammars';
@ -24,6 +24,7 @@ import { generateTokensCSSForColorMap } from 'vs/editor/common/modes/supports/to
import { Color } from 'vs/base/common/color';
import { INotificationService } from 'vs/platform/notification/common/notification';
import URI from 'vs/base/common/uri';
import { IFileService } from 'vs/platform/files/common/files';
export class TMScopeRegistry {
@ -38,27 +39,27 @@ export class TMScopeRegistry {
this._encounteredLanguages = [];
}
public register(scopeName: string, filePath: string, embeddedLanguages?: IEmbeddedLanguagesMap, tokenTypes?: TokenTypesContribution): void {
public register(scopeName: string, grammarLocation: URI, embeddedLanguages?: IEmbeddedLanguagesMap, tokenTypes?: TokenTypesContribution): void {
if (this._scopeNameToLanguageRegistration[scopeName]) {
const existingRegistration = this._scopeNameToLanguageRegistration[scopeName];
if (existingRegistration.grammarFilePath !== filePath) {
if (!resources.isEqual(existingRegistration.grammarLocation, grammarLocation)) {
console.warn(
`Overwriting grammar scope name to file mapping for scope ${scopeName}.\n` +
`Old grammar file: ${existingRegistration.grammarFilePath}.\n` +
`New grammar file: ${filePath}`
`Old grammar file: ${existingRegistration.grammarLocation.toString()}.\n` +
`New grammar file: ${grammarLocation.toString()}`
);
}
}
this._scopeNameToLanguageRegistration[scopeName] = new TMLanguageRegistration(scopeName, filePath, embeddedLanguages, tokenTypes);
this._scopeNameToLanguageRegistration[scopeName] = new TMLanguageRegistration(scopeName, grammarLocation, embeddedLanguages, tokenTypes);
}
public getLanguageRegistration(scopeName: string): TMLanguageRegistration {
return this._scopeNameToLanguageRegistration[scopeName] || null;
}
public getFilePath(scopeName: string): string {
public getGrammarLocation(scopeName: string): URI {
let data = this.getLanguageRegistration(scopeName);
return data ? data.grammarFilePath : null;
return data ? data.grammarLocation : null;
}
/**
@ -76,13 +77,13 @@ export class TMLanguageRegistration {
_topLevelScopeNameDataBrand: void;
readonly scopeName: string;
readonly grammarFilePath: string;
readonly grammarLocation: URI;
readonly embeddedLanguages: IEmbeddedLanguagesMap;
readonly tokenTypes: ITokenTypeMap;
constructor(scopeName: string, grammarFilePath: string, embeddedLanguages: IEmbeddedLanguagesMap, tokenTypes: TokenTypesContribution | undefined) {
constructor(scopeName: string, grammarLocation: URI, embeddedLanguages: IEmbeddedLanguagesMap, tokenTypes: TokenTypesContribution | undefined) {
this.scopeName = scopeName;
this.grammarFilePath = grammarFilePath;
this.grammarLocation = grammarLocation;
// embeddedLanguages handling
this.embeddedLanguages = Object.create(null);
@ -137,6 +138,7 @@ export class TextMateService implements ITextMateService {
private _grammarRegistry: TPromise<[Registry, StackElement]>;
private _modeService: IModeService;
private _themeService: IWorkbenchThemeService;
private _fileService: IFileService;
private _scopeRegistry: TMScopeRegistry;
private _injections: { [scopeName: string]: string[]; };
private _injectedEmbeddedLanguages: { [scopeName: string]: IEmbeddedLanguagesMap[]; };
@ -152,12 +154,14 @@ export class TextMateService implements ITextMateService {
constructor(
@IModeService modeService: IModeService,
@IWorkbenchThemeService themeService: IWorkbenchThemeService,
@IFileService fileService: IFileService,
@INotificationService notificationService: INotificationService
) {
this._styleElement = dom.createStyleSheet();
this._styleElement.className = 'vscode-tokens-styles';
this._modeService = modeService;
this._themeService = themeService;
this._fileService = fileService;
this._scopeRegistry = new TMScopeRegistry();
this.onDidEncounterLanguage = this._scopeRegistry.onDidEncounterLanguage;
this._injections = {};
@ -205,8 +209,11 @@ export class TextMateService implements ITextMateService {
if (!this._grammarRegistry) {
this._grammarRegistry = TPromise.wrap(import('vscode-textmate')).then(({ Registry, INITIAL }) => {
const grammarRegistry = new Registry({
getFilePath: (scopeName: string) => {
return this._scopeRegistry.getFilePath(scopeName);
loadGrammar: (scopeName: string) => {
const location = this._scopeRegistry.getGrammarLocation(scopeName);
return this._fileService.resolveContent(location).then(content => {
return parseRawGrammar(content.value, location.path);
});
},
getInjections: (scopeName: string) => {
return this._injections[scopeName];
@ -294,14 +301,12 @@ export class TextMateService implements ITextMateService {
return;
}
//TODO@extensionLocation
let normalizedAbsolutePath = normalize(join(extensionLocation.fsPath, syntax.path));
if (normalizedAbsolutePath.indexOf(extensionLocation.fsPath) !== 0) {
collector.warn(nls.localize('invalid.path.1', "Expected `contributes.{0}.path` ({1}) to be included inside extension's folder ({2}). This might make the extension non-portable.", grammarsExtPoint.name, normalizedAbsolutePath, extensionLocation.fsPath));
const grammarLocation = resources.joinPath(extensionLocation, syntax.path);
if (grammarLocation.path.indexOf(extensionLocation.path) !== 0) {
collector.warn(nls.localize('invalid.path.1', "Expected `contributes.{0}.path` ({1}) to be included inside extension's folder ({2}). This might make the extension non-portable.", grammarsExtPoint.name, grammarLocation.path, extensionLocation.path));
}
this._scopeRegistry.register(syntax.scopeName, normalizedAbsolutePath, syntax.embeddedLanguages, syntax.tokenTypes);
this._scopeRegistry.register(syntax.scopeName, grammarLocation, syntax.embeddedLanguages, syntax.tokenTypes);
if (syntax.injectTo) {
for (let injectScope of syntax.injectTo) {
@ -369,18 +374,13 @@ export class TextMateService implements ITextMateService {
let containsEmbeddedLanguages = (Object.keys(embeddedLanguages).length > 0);
return this._getOrCreateGrammarRegistry().then((_res) => {
const [grammarRegistry, initialState] = _res;
return new TPromise<ICreateGrammarResult>((c, e, p) => {
grammarRegistry.loadGrammarWithConfiguration(scopeName, languageId, { embeddedLanguages, tokenTypes: languageRegistration.tokenTypes }, (err, grammar) => {
if (err) {
return e(err);
}
c({
languageId: languageId,
grammar: grammar,
initialState: initialState,
containsEmbeddedLanguages: containsEmbeddedLanguages
});
});
return grammarRegistry.loadGrammarWithConfiguration(scopeName, languageId, { embeddedLanguages, tokenTypes: languageRegistration.tokenTypes }).then(grammar => {
return {
languageId: languageId,
grammar: grammar,
initialState: initialState,
containsEmbeddedLanguages: containsEmbeddedLanguages
};
});
});
}

View file

@ -4157,9 +4157,9 @@ onetime@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/onetime/-/onetime-1.1.0.tgz#a1f7838f8314c516f05ecefcbc4ccfe04b4ed789"
oniguruma@^6.0.1:
version "6.1.1"
resolved "https://registry.yarnpkg.com/oniguruma/-/oniguruma-6.1.1.tgz#1c7d96e53d116eb881dbe78b8355b4adc8225898"
oniguruma@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/oniguruma/-/oniguruma-7.0.0.tgz#cf258a8b1a2ec1d0d68964d6336df264008ebf4c"
dependencies:
nan "^2.0.9"
@ -6246,12 +6246,12 @@ vscode-ripgrep@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/vscode-ripgrep/-/vscode-ripgrep-1.0.1.tgz#eff2f2b2a49921ac0acd3ff8dfecaaeebf0184cf"
vscode-textmate@^3.3.3:
version "3.3.3"
resolved "https://registry.yarnpkg.com/vscode-textmate/-/vscode-textmate-3.3.3.tgz#8d737f2965046503a4088d47c2793aebe246d355"
vscode-textmate@^4.0.0-next.2:
version "4.0.0-next.2"
resolved "https://registry.yarnpkg.com/vscode-textmate/-/vscode-textmate-4.0.0-next.2.tgz#03b6c1feb7d297cb70e24cc1166ce2d5c619e440"
dependencies:
fast-plist "^0.1.2"
oniguruma "^6.0.1"
oniguruma "^7.0.0"
vscode-xterm@3.5.0-beta12:
version "3.5.0-beta12"