mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-16 10:58:30 -05:00
Merge from vscode 6268feb42ba4f2e2fa15484e88c9af60d254998c (#6530)
This commit is contained in:
@@ -192,7 +192,7 @@ export class ExtensionHostProcessWorker implements IExtensionHostStarter {
|
||||
const inspectorUrlMatch = output.data && output.data.match(/ws:\/\/([^\s]+:(\d+)\/[^\s]+)/);
|
||||
if (inspectorUrlMatch) {
|
||||
if (!this._environmentService.isBuilt) {
|
||||
console.log(`%c[Extension Host] %cdebugger inspector at chrome-devtools://devtools/bundled/inspector.html?experiments=true&v8only=true&ws=${inspectorUrlMatch[1]}`, 'color: blue', 'color: black');
|
||||
console.log(`%c[Extension Host] %cdebugger inspector at chrome-devtools://devtools/bundled/inspector.html?experiments=true&v8only=true&ws=${inspectorUrlMatch[1]}`, 'color: blue', 'color:');
|
||||
}
|
||||
if (!this._inspectPort) {
|
||||
this._inspectPort = Number(inspectorUrlMatch[2]);
|
||||
@@ -282,15 +282,15 @@ export class ExtensionHostProcessWorker implements IExtensionHostStarter {
|
||||
return new Promise(resolve => {
|
||||
return findFreePort(startPort, 10 /* try 10 ports */, 5000 /* try up to 5 seconds */).then(port => {
|
||||
if (!port) {
|
||||
console.warn('%c[Extension Host] %cCould not find a free port for debugging', 'color: blue', 'color: black');
|
||||
console.warn('%c[Extension Host] %cCould not find a free port for debugging', 'color: blue', 'color:');
|
||||
} else {
|
||||
if (expected && port !== expected) {
|
||||
console.warn(`%c[Extension Host] %cProvided debugging port ${expected} is not free, using ${port} instead.`, 'color: blue', 'color: black');
|
||||
console.warn(`%c[Extension Host] %cProvided debugging port ${expected} is not free, using ${port} instead.`, 'color: blue', 'color:');
|
||||
}
|
||||
if (this._isExtensionDevDebugBrk) {
|
||||
console.warn(`%c[Extension Host] %cSTOPPED on first line for debugging on port ${port}`, 'color: blue', 'color: black');
|
||||
console.warn(`%c[Extension Host] %cSTOPPED on first line for debugging on port ${port}`, 'color: blue', 'color:');
|
||||
} else {
|
||||
console.info(`%c[Extension Host] %cdebugger listening on port ${port}`, 'color: blue', 'color: black');
|
||||
console.info(`%c[Extension Host] %cdebugger listening on port ${port}`, 'color: blue', 'color:');
|
||||
}
|
||||
}
|
||||
return resolve({ expected, actual: port });
|
||||
@@ -434,7 +434,7 @@ export class ExtensionHostProcessWorker implements IExtensionHostStarter {
|
||||
|
||||
// Log on main side if running tests from cli
|
||||
if (this._isExtensionDevTestFromCli) {
|
||||
this._windowsService.log(entry.severity, ...parse(entry).args);
|
||||
this._windowsService.log(entry.severity, parse(entry).args);
|
||||
}
|
||||
|
||||
// Broadcast to other windows if we are in development mode
|
||||
|
||||
@@ -0,0 +1,131 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution';
|
||||
|
||||
KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout({
|
||||
layout: { id: 'com.apple.keylayout.Dvorak', localizedName: 'Dvorak', lang: 'en' },
|
||||
secondaryLayouts: [],
|
||||
mapping: {
|
||||
KeyA: ['a', 'A', 'å', 'Å', 0],
|
||||
KeyB: ['x', 'X', '≈', '˛', 0],
|
||||
KeyC: ['j', 'J', '∆', 'Ô', 0],
|
||||
KeyD: ['e', 'E', '´', '´', 4],
|
||||
KeyE: ['.', '>', '≥', '˘', 0],
|
||||
KeyF: ['u', 'U', '¨', '¨', 4],
|
||||
KeyG: ['i', 'I', 'ˆ', 'ˆ', 4],
|
||||
KeyH: ['d', 'D', '∂', 'Î', 0],
|
||||
KeyI: ['c', 'C', 'ç', 'Ç', 0],
|
||||
KeyJ: ['h', 'H', '˙', 'Ó', 0],
|
||||
KeyK: ['t', 'T', '†', 'ˇ', 0],
|
||||
KeyL: ['n', 'N', '˜', '˜', 4],
|
||||
KeyM: ['m', 'M', 'µ', 'Â', 0],
|
||||
KeyN: ['b', 'B', '∫', 'ı', 0],
|
||||
KeyO: ['r', 'R', '®', '‰', 0],
|
||||
KeyP: ['l', 'L', '¬', 'Ò', 0],
|
||||
KeyQ: ['\'', '"', 'æ', 'Æ', 0],
|
||||
KeyR: ['p', 'P', 'π', '∏', 0],
|
||||
KeyS: ['o', 'O', 'ø', 'Ø', 0],
|
||||
KeyT: ['y', 'Y', '¥', 'Á', 0],
|
||||
KeyU: ['g', 'G', '©', '˝', 0],
|
||||
KeyV: ['k', 'K', '˚', '', 0],
|
||||
KeyW: [',', '<', '≤', '¯', 0],
|
||||
KeyX: ['q', 'Q', 'œ', 'Œ', 0],
|
||||
KeyY: ['f', 'F', 'ƒ', 'Ï', 0],
|
||||
KeyZ: [';', ':', '…', 'Ú', 0],
|
||||
Digit1: ['1', '!', '¡', '⁄', 0],
|
||||
Digit2: ['2', '@', '™', '€', 0],
|
||||
Digit3: ['3', '#', '£', '‹', 0],
|
||||
Digit4: ['4', '$', '¢', '›', 0],
|
||||
Digit5: ['5', '%', '∞', 'fi', 0],
|
||||
Digit6: ['6', '^', '§', 'fl', 0],
|
||||
Digit7: ['7', '&', '¶', '‡', 0],
|
||||
Digit8: ['8', '*', '•', '°', 0],
|
||||
Digit9: ['9', '(', 'ª', '·', 0],
|
||||
Digit0: ['0', ')', 'º', '‚', 0],
|
||||
Enter: [],
|
||||
Escape: [],
|
||||
Backspace: [],
|
||||
Tab: [],
|
||||
Space: [' ', ' ', ' ', ' ', 0],
|
||||
Minus: ['[', '{', '“', '”', 0],
|
||||
Equal: [']', '}', '‘', '’', 0],
|
||||
BracketLeft: ['/', '?', '÷', '¿', 0],
|
||||
BracketRight: ['=', '+', '≠', '±', 0],
|
||||
Backslash: ['\\', '|', '«', '»', 0],
|
||||
Semicolon: ['s', 'S', 'ß', 'Í', 0],
|
||||
Quote: ['-', '_', '–', '—', 0],
|
||||
Backquote: ['`', '~', '`', '`', 4],
|
||||
Comma: ['w', 'W', '∑', '„', 0],
|
||||
Period: ['v', 'V', '√', '◊', 0],
|
||||
Slash: ['z', 'Z', 'Ω', '¸', 0],
|
||||
CapsLock: [],
|
||||
F1: [],
|
||||
F2: [],
|
||||
F3: [],
|
||||
F4: [],
|
||||
F5: [],
|
||||
F6: [],
|
||||
F7: [],
|
||||
F8: [],
|
||||
F9: [],
|
||||
F10: [],
|
||||
F11: [],
|
||||
F12: [],
|
||||
Insert: [],
|
||||
Home: [],
|
||||
PageUp: [],
|
||||
Delete: [],
|
||||
End: [],
|
||||
PageDown: [],
|
||||
ArrowRight: [],
|
||||
ArrowLeft: [],
|
||||
ArrowDown: [],
|
||||
ArrowUp: [],
|
||||
NumLock: [],
|
||||
NumpadDivide: ['/', '/', '/', '/', 0],
|
||||
NumpadMultiply: ['*', '*', '*', '*', 0],
|
||||
NumpadSubtract: ['-', '-', '-', '-', 0],
|
||||
NumpadAdd: ['+', '+', '+', '+', 0],
|
||||
NumpadEnter: [],
|
||||
Numpad1: ['1', '1', '1', '1', 0],
|
||||
Numpad2: ['2', '2', '2', '2', 0],
|
||||
Numpad3: ['3', '3', '3', '3', 0],
|
||||
Numpad4: ['4', '4', '4', '4', 0],
|
||||
Numpad5: ['5', '5', '5', '5', 0],
|
||||
Numpad6: ['6', '6', '6', '6', 0],
|
||||
Numpad7: ['7', '7', '7', '7', 0],
|
||||
Numpad8: ['8', '8', '8', '8', 0],
|
||||
Numpad9: ['9', '9', '9', '9', 0],
|
||||
Numpad0: ['0', '0', '0', '0', 0],
|
||||
NumpadDecimal: ['.', '.', '.', '.', 0],
|
||||
IntlBackslash: ['§', '±', '§', '±', 0],
|
||||
ContextMenu: [],
|
||||
NumpadEqual: ['=', '=', '=', '=', 0],
|
||||
F13: [],
|
||||
F14: [],
|
||||
F15: [],
|
||||
F16: [],
|
||||
F17: [],
|
||||
F18: [],
|
||||
F19: [],
|
||||
F20: [],
|
||||
AudioVolumeMute: [],
|
||||
AudioVolumeUp: ['', '=', '', '=', 0],
|
||||
AudioVolumeDown: [],
|
||||
NumpadComma: [],
|
||||
IntlRo: [],
|
||||
KanaMode: [],
|
||||
IntlYen: [],
|
||||
ControlLeft: [],
|
||||
ShiftLeft: [],
|
||||
AltLeft: [],
|
||||
MetaLeft: [],
|
||||
ControlRight: [],
|
||||
ShiftRight: [],
|
||||
AltRight: [],
|
||||
MetaRight: []
|
||||
}
|
||||
});
|
||||
@@ -18,5 +18,6 @@ import 'vs/workbench/services/keybinding/browser/keyboardLayouts/it.darwin';
|
||||
import 'vs/workbench/services/keybinding/browser/keyboardLayouts/ru.darwin';
|
||||
import 'vs/workbench/services/keybinding/browser/keyboardLayouts/pt.darwin';
|
||||
import 'vs/workbench/services/keybinding/browser/keyboardLayouts/ko.darwin';
|
||||
import 'vs/workbench/services/keybinding/browser/keyboardLayouts/dvorak.darwin';
|
||||
|
||||
export { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution';
|
||||
export { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution';
|
||||
|
||||
@@ -26,9 +26,9 @@ import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { Extensions as ConfigExtensions, IConfigurationRegistry, IConfigurationNode } from 'vs/platform/configuration/common/configurationRegistry';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { INavigatorWithKeyboard } from 'vs/workbench/services/keybinding/common/navigatorKeyboard';
|
||||
import { INotificationService, Severity } from 'vs/platform/notification/common/notification';
|
||||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||
import { ICommandService } from 'vs/platform/commands/common/commands';
|
||||
import { StorageScope, IStorageService } from 'vs/platform/storage/common/storage';
|
||||
import { IStorageService } from 'vs/platform/storage/common/storage';
|
||||
|
||||
export class BrowserKeyboardMapperFactoryBase {
|
||||
// keyboard mapper
|
||||
@@ -71,9 +71,9 @@ export class BrowserKeyboardMapperFactoryBase {
|
||||
}
|
||||
|
||||
protected constructor(
|
||||
private _notificationService: INotificationService,
|
||||
private _storageService: IStorageService,
|
||||
private _commandService: ICommandService
|
||||
// private _notificationService: INotificationService,
|
||||
// private _storageService: IStorageService,
|
||||
// private _commandService: ICommandService
|
||||
) {
|
||||
this._keyboardMapper = null;
|
||||
this._initialized = false;
|
||||
@@ -178,32 +178,34 @@ export class BrowserKeyboardMapperFactoryBase {
|
||||
setActiveKeyMapping(keymap: IKeyboardMapping | null) {
|
||||
let matchedKeyboardLayout = this.getMatchedKeymapInfo(keymap);
|
||||
if (matchedKeyboardLayout) {
|
||||
let score = matchedKeyboardLayout.score;
|
||||
// let score = matchedKeyboardLayout.score;
|
||||
|
||||
if (keymap && score < 0) {
|
||||
const donotAskUpdateKey = 'missing.keyboardlayout.donotask';
|
||||
if (this._storageService.getBoolean(donotAskUpdateKey, StorageScope.GLOBAL)) {
|
||||
return;
|
||||
}
|
||||
// Due to https://bugs.chromium.org/p/chromium/issues/detail?id=977609, any key after a dead key will generate a wrong mapping,
|
||||
// we shoud avoid yielding the false error.
|
||||
// if (keymap && score < 0) {
|
||||
// const donotAskUpdateKey = 'missing.keyboardlayout.donotask';
|
||||
// if (this._storageService.getBoolean(donotAskUpdateKey, StorageScope.GLOBAL)) {
|
||||
// return;
|
||||
// }
|
||||
|
||||
// the keyboard layout doesn't actually match the key event or the keymap from chromium
|
||||
this._notificationService.prompt(
|
||||
Severity.Info,
|
||||
nls.localize('missing.keyboardlayout', 'Fail to find matching keyboard layout'),
|
||||
[{
|
||||
label: nls.localize('keyboardLayoutMissing.configure', "Configure"),
|
||||
run: () => this._commandService.executeCommand('workbench.action.openKeyboardLayoutPicker')
|
||||
}, {
|
||||
label: nls.localize('neverAgain', "Don't Show Again"),
|
||||
isSecondary: true,
|
||||
run: () => this._storageService.store(donotAskUpdateKey, true, StorageScope.GLOBAL)
|
||||
}]
|
||||
);
|
||||
// // the keyboard layout doesn't actually match the key event or the keymap from chromium
|
||||
// this._notificationService.prompt(
|
||||
// Severity.Info,
|
||||
// nls.localize('missing.keyboardlayout', 'Fail to find matching keyboard layout'),
|
||||
// [{
|
||||
// label: nls.localize('keyboardLayoutMissing.configure', "Configure"),
|
||||
// run: () => this._commandService.executeCommand('workbench.action.openKeyboardLayoutPicker')
|
||||
// }, {
|
||||
// label: nls.localize('neverAgain', "Don't Show Again"),
|
||||
// isSecondary: true,
|
||||
// run: () => this._storageService.store(donotAskUpdateKey, true, StorageScope.GLOBAL)
|
||||
// }]
|
||||
// );
|
||||
|
||||
console.warn('Active keymap/keyevent does not match current keyboard layout', JSON.stringify(keymap), this._activeKeymapInfo ? JSON.stringify(this._activeKeymapInfo.layout) : '');
|
||||
// console.warn('Active keymap/keyevent does not match current keyboard layout', JSON.stringify(keymap), this._activeKeymapInfo ? JSON.stringify(this._activeKeymapInfo.layout) : '');
|
||||
|
||||
return;
|
||||
}
|
||||
// return;
|
||||
// }
|
||||
|
||||
if (!this._activeKeymapInfo) {
|
||||
this._activeKeymapInfo = matchedKeyboardLayout.result;
|
||||
@@ -336,7 +338,7 @@ export class BrowserKeyboardMapperFactoryBase {
|
||||
}
|
||||
|
||||
if (mapping.value === '') {
|
||||
// we don't undetstand
|
||||
// The value is empty when the key is not a printable character, we skip validation.
|
||||
if (keyboardEvent.ctrlKey || keyboardEvent.metaKey) {
|
||||
setTimeout(() => {
|
||||
this._getBrowserKeyMapping().then((keymap: IKeyboardMapping) => {
|
||||
@@ -426,7 +428,8 @@ export class BrowserKeyboardMapperFactoryBase {
|
||||
|
||||
export class BrowserKeyboardMapperFactory extends BrowserKeyboardMapperFactoryBase {
|
||||
constructor(notificationService: INotificationService, storageService: IStorageService, commandService: ICommandService) {
|
||||
super(notificationService, storageService, commandService);
|
||||
// super(notificationService, storageService, commandService);
|
||||
super();
|
||||
|
||||
const platform = isWindows ? 'win' : isMacintosh ? 'darwin' : 'linux';
|
||||
|
||||
@@ -621,4 +624,4 @@ const keyboardConfiguration: IConfigurationNode = {
|
||||
}
|
||||
};
|
||||
|
||||
configurationRegistry.registerConfiguration(keyboardConfiguration);
|
||||
configurationRegistry.registerConfiguration(keyboardConfiguration);
|
||||
|
||||
@@ -17,7 +17,8 @@ import { TestNotificationService } from 'vs/platform/notification/test/common/te
|
||||
|
||||
class TestKeyboardMapperFactory extends BrowserKeyboardMapperFactoryBase {
|
||||
constructor(notificationService: INotificationService, storageService: IStorageService, commandService: ICommandService) {
|
||||
super(notificationService, storageService, commandService);
|
||||
// super(notificationService, storageService, commandService);
|
||||
super();
|
||||
|
||||
const keymapInfos: IKeymapInfo[] = KeyboardLayoutContribution.INSTANCE.layoutInfos;
|
||||
this._keymapInfos.push(...keymapInfos.map(info => (new KeymapInfo(info.layout, info.secondaryLayouts, info.mapping, info.isUserKeyboardLayout))));
|
||||
@@ -146,4 +147,4 @@ suite('keyboard layout loader', () => {
|
||||
instance.setUSKeyboardLayout();
|
||||
assert.equal(instance.activeKeyboardLayout!.isUSStandard, true);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -43,7 +43,7 @@ export abstract class AbstractTextMateService extends Disposable implements ITex
|
||||
private _grammarDefinitions: IValidGrammarDefinition[] | null;
|
||||
private _grammarFactory: TMGrammarFactory | null;
|
||||
private _tokenizersRegistrations: IDisposable[];
|
||||
private _currentTokenColors: ITokenColorizationRule[] | null;
|
||||
protected _currentTheme: IRawTheme | null;
|
||||
|
||||
constructor(
|
||||
@IModeService private readonly _modeService: IModeService,
|
||||
@@ -64,6 +64,8 @@ export abstract class AbstractTextMateService extends Disposable implements ITex
|
||||
this._grammarFactory = null;
|
||||
this._tokenizersRegistrations = [];
|
||||
|
||||
this._currentTheme = null;
|
||||
|
||||
grammarsExtPoint.setHandler((extensions) => {
|
||||
this._grammarDefinitions = null;
|
||||
if (this._grammarFactory) {
|
||||
@@ -242,11 +244,11 @@ export abstract class AbstractTextMateService extends Disposable implements ITex
|
||||
}
|
||||
|
||||
private _updateTheme(grammarFactory: TMGrammarFactory, colorTheme: IColorTheme, forceUpdate: boolean): void {
|
||||
if (!forceUpdate && AbstractTextMateService.equalsTokenRules(this._currentTokenColors, colorTheme.tokenColors)) {
|
||||
if (!forceUpdate && this._currentTheme && AbstractTextMateService.equalsTokenRules(this._currentTheme.settings, colorTheme.tokenColors)) {
|
||||
return;
|
||||
}
|
||||
this._currentTokenColors = colorTheme.tokenColors;
|
||||
this._doUpdateTheme(grammarFactory, { name: colorTheme.label, settings: colorTheme.tokenColors });
|
||||
this._currentTheme = { name: colorTheme.label, settings: colorTheme.tokenColors };
|
||||
this._doUpdateTheme(grammarFactory, this._currentTheme);
|
||||
}
|
||||
|
||||
protected _doUpdateTheme(grammarFactory: TMGrammarFactory, theme: IRawTheme): void {
|
||||
|
||||
@@ -14,12 +14,15 @@ import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { createWebWorker, MonacoWebWorker } from 'vs/editor/common/services/webWorker';
|
||||
import { IModelService } from 'vs/editor/common/services/modelService';
|
||||
import { IOnigLib } from 'vscode-textmate';
|
||||
import { IOnigLib, IRawTheme } from 'vscode-textmate';
|
||||
import { IValidGrammarDefinition } from 'vs/workbench/services/textMate/common/TMScopeRegistry';
|
||||
import { TextMateWorker } from 'vs/workbench/services/textMate/electron-browser/textMateWorker';
|
||||
import { ITextModel } from 'vs/editor/common/model';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { UriComponents, URI } from 'vs/base/common/uri';
|
||||
import { MultilineTokensBuilder } from 'vs/editor/common/model/tokensStore';
|
||||
import { TMGrammarFactory } from 'vs/workbench/services/textMate/common/TMGrammarFactory';
|
||||
import { IModelContentChangedEvent } from 'vs/editor/common/model/textModelEvents';
|
||||
import { IStorageService } from 'vs/platform/storage/common/storage';
|
||||
|
||||
const RUN_TEXTMATE_IN_WORKER = false;
|
||||
@@ -29,6 +32,7 @@ class ModelWorkerTextMateTokenizer extends Disposable {
|
||||
private readonly _worker: TextMateWorker;
|
||||
private readonly _model: ITextModel;
|
||||
private _isSynced: boolean;
|
||||
private _pendingChanges: IModelContentChangedEvent[] = [];
|
||||
|
||||
constructor(worker: TextMateWorker, model: ITextModel) {
|
||||
super();
|
||||
@@ -42,6 +46,7 @@ class ModelWorkerTextMateTokenizer extends Disposable {
|
||||
this._register(this._model.onDidChangeContent((e) => {
|
||||
if (this._isSynced) {
|
||||
this._worker.acceptModelChanged(this._model.uri.toString(), e);
|
||||
this._pendingChanges.push(e);
|
||||
}
|
||||
}));
|
||||
|
||||
@@ -84,11 +89,36 @@ class ModelWorkerTextMateTokenizer extends Disposable {
|
||||
super.dispose();
|
||||
this._endSync();
|
||||
}
|
||||
|
||||
private _confirm(versionId: number): void {
|
||||
while (this._pendingChanges.length > 0 && this._pendingChanges[0].versionId <= versionId) {
|
||||
this._pendingChanges.shift();
|
||||
}
|
||||
}
|
||||
|
||||
public setTokens(versionId: number, rawTokens: ArrayBuffer): void {
|
||||
this._confirm(versionId);
|
||||
const tokens = MultilineTokensBuilder.deserialize(new Uint8Array(rawTokens));
|
||||
|
||||
for (let i = 0; i < this._pendingChanges.length; i++) {
|
||||
const change = this._pendingChanges[i];
|
||||
for (let j = 0; j < tokens.length; j++) {
|
||||
for (let k = 0; k < change.changes.length; k++) {
|
||||
tokens[j].applyEdit(change.changes[k].range, change.changes[k].text);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this._model.setTokens(tokens);
|
||||
}
|
||||
}
|
||||
|
||||
export class TextMateWorkerHost {
|
||||
|
||||
constructor(@IFileService private readonly _fileService: IFileService) {
|
||||
constructor(
|
||||
private readonly textMateService: TextMateService,
|
||||
@IFileService private readonly _fileService: IFileService
|
||||
) {
|
||||
}
|
||||
|
||||
async readFile(_resource: UriComponents): Promise<string> {
|
||||
@@ -96,6 +126,11 @@ export class TextMateWorkerHost {
|
||||
const content = await this._fileService.readFile(resource);
|
||||
return content.value.toString();
|
||||
}
|
||||
|
||||
async setTokens(_resource: UriComponents, versionId: number, tokens: Uint8Array): Promise<void> {
|
||||
const resource = URI.revive(_resource);
|
||||
this.textMateService.setTokens(resource, versionId, tokens);
|
||||
}
|
||||
}
|
||||
|
||||
export class TextMateService extends AbstractTextMateService {
|
||||
@@ -155,7 +190,7 @@ export class TextMateService extends AbstractTextMateService {
|
||||
this._killWorker();
|
||||
|
||||
if (RUN_TEXTMATE_IN_WORKER) {
|
||||
const workerHost = new TextMateWorkerHost(this._fileService);
|
||||
const workerHost = new TextMateWorkerHost(this, this._fileService);
|
||||
const worker = createWebWorker<TextMateWorker>(this._modelService, {
|
||||
createData: {
|
||||
grammarDefinitions
|
||||
@@ -172,11 +207,21 @@ export class TextMateService extends AbstractTextMateService {
|
||||
return;
|
||||
}
|
||||
this._workerProxy = proxy;
|
||||
if (this._currentTheme) {
|
||||
this._workerProxy.acceptTheme(this._currentTheme);
|
||||
}
|
||||
this._modelService.getModels().forEach((model) => this._onModelAdded(model));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
protected _doUpdateTheme(grammarFactory: TMGrammarFactory, theme: IRawTheme): void {
|
||||
super._doUpdateTheme(grammarFactory, theme);
|
||||
if (this._currentTheme && this._workerProxy) {
|
||||
this._workerProxy.acceptTheme(this._currentTheme);
|
||||
}
|
||||
}
|
||||
|
||||
protected _onDidDisposeGrammarFactory(): void {
|
||||
this._killWorker();
|
||||
}
|
||||
@@ -193,6 +238,14 @@ export class TextMateService extends AbstractTextMateService {
|
||||
}
|
||||
this._workerProxy = null;
|
||||
}
|
||||
|
||||
setTokens(resource: URI, versionId: number, tokens: ArrayBuffer): void {
|
||||
const key = resource.toString();
|
||||
if (!this._tokenizers[key]) {
|
||||
return;
|
||||
}
|
||||
this._tokenizers[key].setTokens(versionId, tokens);
|
||||
}
|
||||
}
|
||||
|
||||
registerSingleton(ITextMateService, TextMateService);
|
||||
registerSingleton(ITextMateService, TextMateService);
|
||||
|
||||
@@ -10,6 +10,10 @@ import { IValidEmbeddedLanguagesMap, IValidTokenTypeMap, IValidGrammarDefinition
|
||||
import { TMGrammarFactory, ICreateGrammarResult } from 'vs/workbench/services/textMate/common/TMGrammarFactory';
|
||||
import { IModelChangedEvent, MirrorTextModel } from 'vs/editor/common/model/mirrorTextModel';
|
||||
import { TextMateWorkerHost } from 'vs/workbench/services/textMate/electron-browser/textMateService';
|
||||
import { TokenizationStateStore } from 'vs/editor/common/model/textModelTokens';
|
||||
import { IGrammar, StackElement, IRawTheme } from 'vscode-textmate';
|
||||
import { MultilineTokensBuilder, countEOL } from 'vs/editor/common/model/tokensStore';
|
||||
import { LineTokens } from 'vs/editor/common/core/lineTokens';
|
||||
|
||||
export interface IValidGrammarDefinitionDTO {
|
||||
location: UriComponents;
|
||||
@@ -34,26 +38,79 @@ export interface IRawModelData {
|
||||
|
||||
class TextMateWorkerModel extends MirrorTextModel {
|
||||
|
||||
private readonly _tokenizationStateStore: TokenizationStateStore;
|
||||
private readonly _worker: TextMateWorker;
|
||||
private _languageId: LanguageId;
|
||||
private _grammar: IGrammar | null;
|
||||
private _isDisposed: boolean;
|
||||
|
||||
constructor(uri: URI, lines: string[], eol: string, versionId: number, worker: TextMateWorker, languageId: LanguageId) {
|
||||
super(uri, lines, eol, versionId);
|
||||
this._tokenizationStateStore = new TokenizationStateStore();
|
||||
this._worker = worker;
|
||||
this._languageId = languageId;
|
||||
this._isDisposed = false;
|
||||
this._grammar = null;
|
||||
this._resetTokenization();
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
this._isDisposed = true;
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
public onLanguageId(languageId: LanguageId): void {
|
||||
this._languageId = languageId;
|
||||
this._resetTokenization();
|
||||
}
|
||||
|
||||
onLanguageId(languageId: LanguageId): void {
|
||||
this._languageId = languageId;
|
||||
this._resetTokenization();
|
||||
onEvents(e: IModelChangedEvent): void {
|
||||
super.onEvents(e);
|
||||
for (let i = 0; i < e.changes.length; i++) {
|
||||
const change = e.changes[i];
|
||||
const [eolCount] = countEOL(change.text);
|
||||
this._tokenizationStateStore.applyEdits(change.range, eolCount);
|
||||
}
|
||||
this._ensureTokens();
|
||||
}
|
||||
|
||||
private _resetTokenization(): void {
|
||||
this._worker.getOrCreateGrammar(this._languageId).then((r) => {
|
||||
console.log(r);
|
||||
this._grammar = null;
|
||||
this._tokenizationStateStore.flush(null);
|
||||
|
||||
const languageId = this._languageId;
|
||||
this._worker.getOrCreateGrammar(languageId).then((r) => {
|
||||
if (this._isDisposed || languageId !== this._languageId) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._grammar = r.grammar;
|
||||
this._tokenizationStateStore.flush(r.initialState);
|
||||
this._ensureTokens();
|
||||
});
|
||||
}
|
||||
|
||||
private _ensureTokens(): void {
|
||||
if (!this._grammar) {
|
||||
return;
|
||||
}
|
||||
const builder = new MultilineTokensBuilder();
|
||||
const lineCount = this._lines.length;
|
||||
|
||||
// Validate all states up to and including endLineIndex
|
||||
for (let lineIndex = this._tokenizationStateStore.invalidLineStartIndex; lineIndex < lineCount; lineIndex++) {
|
||||
const text = this._lines[lineIndex];
|
||||
const lineStartState = this._tokenizationStateStore.getBeginState(lineIndex);
|
||||
|
||||
const r = this._grammar.tokenizeLine2(text, <StackElement>lineStartState!);
|
||||
LineTokens.convertToEndOffset(r.tokens, text.length);
|
||||
builder.add(lineIndex + 1, r.tokens);
|
||||
this._tokenizationStateStore.setEndState(lineCount, lineIndex, r.ruleStack);
|
||||
lineIndex = this._tokenizationStateStore.invalidLineStartIndex - 1; // -1 because the outer loop increments it
|
||||
}
|
||||
|
||||
this._worker._setTokens(this._uri, this._versionId, builder.serialize());
|
||||
}
|
||||
}
|
||||
|
||||
export class TextMateWorker {
|
||||
@@ -91,7 +148,7 @@ export class TextMateWorker {
|
||||
}
|
||||
|
||||
this._grammarFactory = new TMGrammarFactory({
|
||||
logTrace: (msg: string) => console.log(msg),
|
||||
logTrace: (msg: string) => {/* console.log(msg) */ },
|
||||
logError: (msg: string, err: any) => console.error(msg, err),
|
||||
readFile: (resource: URI) => this._host.readFile(resource)
|
||||
}, grammarDefinitions, vscodeTextmate, undefined);
|
||||
@@ -112,7 +169,10 @@ export class TextMateWorker {
|
||||
}
|
||||
|
||||
public acceptRemovedModel(strURL: string): void {
|
||||
delete this._models[strURL];
|
||||
if (this._models[strURL]) {
|
||||
this._models[strURL].dispose();
|
||||
delete this._models[strURL];
|
||||
}
|
||||
}
|
||||
|
||||
public getOrCreateGrammar(languageId: LanguageId): Promise<ICreateGrammarResult> {
|
||||
@@ -121,6 +181,14 @@ export class TextMateWorker {
|
||||
}
|
||||
return this._grammarCache[languageId];
|
||||
}
|
||||
|
||||
public acceptTheme(theme: IRawTheme): void {
|
||||
this._grammarFactory.setTheme(theme);
|
||||
}
|
||||
|
||||
public _setTokens(resource: URI, versionId: number, tokens: Uint8Array): void {
|
||||
this._host.setTokens(resource, versionId, tokens);
|
||||
}
|
||||
}
|
||||
|
||||
export function create(ctx: IWorkerContext<TextMateWorkerHost>, createData: ICreateData): TextMateWorker {
|
||||
|
||||
Reference in New Issue
Block a user