Merge from vscode 6268feb42ba4f2e2fa15484e88c9af60d254998c (#6530)

This commit is contained in:
Anthony Dresser
2019-07-29 21:03:02 -07:00
committed by GitHub
parent 2c8a22bb0d
commit 6db84eefa3
104 changed files with 1797 additions and 3740 deletions
+1
View File
@@ -128,6 +128,7 @@ const copyrightFilter = [
'!extensions/markdown-language-features/media/highlight.css', '!extensions/markdown-language-features/media/highlight.css',
'!extensions/html-language-features/server/src/modes/typescript/*', '!extensions/html-language-features/server/src/modes/typescript/*',
'!extensions/*/server/bin/*', '!extensions/*/server/bin/*',
'!src/vs/editor/test/node/classification/typescript-test.ts',
// {{SQL CARBON EDIT}} // {{SQL CARBON EDIT}}
'!extensions/notebook/src/intellisense/text.ts', '!extensions/notebook/src/intellisense/text.ts',
'!extensions/mssql/src/objectExplorerNodeProvider/webhdfs.ts', '!extensions/mssql/src/objectExplorerNodeProvider/webhdfs.ts',
+2 -3
View File
@@ -31,6 +31,7 @@ function extractEditor(options) {
let compilerOptions; let compilerOptions;
if (tsConfig.extends) { if (tsConfig.extends) {
compilerOptions = Object.assign({}, require(path.join(options.sourcesRoot, tsConfig.extends)).compilerOptions, tsConfig.compilerOptions); compilerOptions = Object.assign({}, require(path.join(options.sourcesRoot, tsConfig.extends)).compilerOptions, tsConfig.compilerOptions);
delete tsConfig.extends;
} }
else { else {
compilerOptions = tsConfig.compilerOptions; compilerOptions = tsConfig.compilerOptions;
@@ -40,9 +41,9 @@ function extractEditor(options) {
compilerOptions.noUnusedLocals = false; compilerOptions.noUnusedLocals = false;
compilerOptions.preserveConstEnums = false; compilerOptions.preserveConstEnums = false;
compilerOptions.declaration = false; compilerOptions.declaration = false;
compilerOptions.noImplicitAny = false;
compilerOptions.moduleResolution = ts.ModuleResolutionKind.Classic; compilerOptions.moduleResolution = ts.ModuleResolutionKind.Classic;
options.compilerOptions = compilerOptions; options.compilerOptions = compilerOptions;
console.log(`Running with shakeLevel ${tss.toStringShakeLevel(options.shakeLevel)}`);
let result = tss.shake(options); let result = tss.shake(options);
for (let fileName in result) { for (let fileName in result) {
if (result.hasOwnProperty(fileName)) { if (result.hasOwnProperty(fileName)) {
@@ -91,8 +92,6 @@ function extractEditor(options) {
} }
delete tsConfig.compilerOptions.moduleResolution; delete tsConfig.compilerOptions.moduleResolution;
writeOutputFile('tsconfig.json', JSON.stringify(tsConfig, null, '\t')); writeOutputFile('tsconfig.json', JSON.stringify(tsConfig, null, '\t'));
const tsConfigBase = JSON.parse(fs.readFileSync(path.join(options.sourcesRoot, 'tsconfig.base.json')).toString());
writeOutputFile('tsconfig.base.json', JSON.stringify(tsConfigBase, null, '\t'));
[ [
'vs/css.build.js', 'vs/css.build.js',
'vs/css.d.ts', 'vs/css.d.ts',
+3 -3
View File
@@ -35,6 +35,7 @@ export function extractEditor(options: tss.ITreeShakingOptions & { destRoot: str
let compilerOptions: { [key: string]: any }; let compilerOptions: { [key: string]: any };
if (tsConfig.extends) { if (tsConfig.extends) {
compilerOptions = Object.assign({}, require(path.join(options.sourcesRoot, tsConfig.extends)).compilerOptions, tsConfig.compilerOptions); compilerOptions = Object.assign({}, require(path.join(options.sourcesRoot, tsConfig.extends)).compilerOptions, tsConfig.compilerOptions);
delete tsConfig.extends;
} else { } else {
compilerOptions = tsConfig.compilerOptions; compilerOptions = tsConfig.compilerOptions;
} }
@@ -44,12 +45,13 @@ export function extractEditor(options: tss.ITreeShakingOptions & { destRoot: str
compilerOptions.noUnusedLocals = false; compilerOptions.noUnusedLocals = false;
compilerOptions.preserveConstEnums = false; compilerOptions.preserveConstEnums = false;
compilerOptions.declaration = false; compilerOptions.declaration = false;
compilerOptions.noImplicitAny = false;
compilerOptions.moduleResolution = ts.ModuleResolutionKind.Classic; compilerOptions.moduleResolution = ts.ModuleResolutionKind.Classic;
options.compilerOptions = compilerOptions; options.compilerOptions = compilerOptions;
console.log(`Running with shakeLevel ${tss.toStringShakeLevel(options.shakeLevel)}`);
let result = tss.shake(options); let result = tss.shake(options);
for (let fileName in result) { for (let fileName in result) {
if (result.hasOwnProperty(fileName)) { if (result.hasOwnProperty(fileName)) {
@@ -100,8 +102,6 @@ export function extractEditor(options: tss.ITreeShakingOptions & { destRoot: str
delete tsConfig.compilerOptions.moduleResolution; delete tsConfig.compilerOptions.moduleResolution;
writeOutputFile('tsconfig.json', JSON.stringify(tsConfig, null, '\t')); writeOutputFile('tsconfig.json', JSON.stringify(tsConfig, null, '\t'));
const tsConfigBase = JSON.parse(fs.readFileSync(path.join(options.sourcesRoot, 'tsconfig.base.json')).toString());
writeOutputFile('tsconfig.base.json', JSON.stringify(tsConfigBase, null, '\t'));
[ [
'vs/css.build.js', 'vs/css.build.js',
+12 -4
View File
@@ -14,6 +14,17 @@ var ShakeLevel;
ShakeLevel[ShakeLevel["InnerFile"] = 1] = "InnerFile"; ShakeLevel[ShakeLevel["InnerFile"] = 1] = "InnerFile";
ShakeLevel[ShakeLevel["ClassMembers"] = 2] = "ClassMembers"; ShakeLevel[ShakeLevel["ClassMembers"] = 2] = "ClassMembers";
})(ShakeLevel = exports.ShakeLevel || (exports.ShakeLevel = {})); })(ShakeLevel = exports.ShakeLevel || (exports.ShakeLevel = {}));
function toStringShakeLevel(shakeLevel) {
switch (shakeLevel) {
case 0 /* Files */:
return 'Files (0)';
case 1 /* InnerFile */:
return 'InnerFile (1)';
case 2 /* ClassMembers */:
return 'ClassMembers (2)';
}
}
exports.toStringShakeLevel = toStringShakeLevel;
function printDiagnostics(diagnostics) { function printDiagnostics(diagnostics) {
for (const diag of diagnostics) { for (const diag of diagnostics) {
let result = ''; let result = '';
@@ -394,6 +405,7 @@ function markNodes(languageService, options) {
|| memberName === 'toJSON' || memberName === 'toJSON'
|| memberName === 'toString' || memberName === 'toString'
|| memberName === 'dispose' // TODO: keeping all `dispose` methods || memberName === 'dispose' // TODO: keeping all `dispose` methods
|| /^_(.*)Brand$/.test(memberName || '') // TODO: keeping all members ending with `Brand`...
) { ) {
enqueue_black(member); enqueue_black(member);
} }
@@ -513,10 +525,6 @@ function generateResult(languageService, shakeLevel) {
// keep method // keep method
continue; continue;
} }
if (/^_(.*)Brand$/.test(member.name.getText())) {
// TODO: keep all members ending with `Brand`...
continue;
}
let pos = member.pos - node.pos; let pos = member.pos - node.pos;
let end = member.end - node.pos; let end = member.end - node.pos;
toWrite = toWrite.substring(0, pos) + toWrite.substring(end); toWrite = toWrite.substring(0, pos) + toWrite.substring(end);
+12 -4
View File
@@ -17,6 +17,17 @@ export const enum ShakeLevel {
ClassMembers = 2 ClassMembers = 2
} }
export function toStringShakeLevel(shakeLevel: ShakeLevel): string {
switch(shakeLevel) {
case ShakeLevel.Files:
return 'Files (0)';
case ShakeLevel.InnerFile:
return 'InnerFile (1)';
case ShakeLevel.ClassMembers:
return 'ClassMembers (2)';
}
}
export interface ITreeShakingOptions { export interface ITreeShakingOptions {
/** /**
* The full path to the root where sources are. * The full path to the root where sources are.
@@ -513,6 +524,7 @@ function markNodes(languageService: ts.LanguageService, options: ITreeShakingOpt
|| memberName === 'toJSON' || memberName === 'toJSON'
|| memberName === 'toString' || memberName === 'toString'
|| memberName === 'dispose'// TODO: keeping all `dispose` methods || memberName === 'dispose'// TODO: keeping all `dispose` methods
|| /^_(.*)Brand$/.test(memberName || '') // TODO: keeping all members ending with `Brand`...
) { ) {
enqueue_black(member); enqueue_black(member);
} }
@@ -642,10 +654,6 @@ function generateResult(languageService: ts.LanguageService, shakeLevel: ShakeLe
// keep method // keep method
continue; continue;
} }
if (/^_(.*)Brand$/.test(member.name.getText())) {
// TODO: keep all members ending with `Brand`...
continue;
}
let pos = member.pos - node.pos; let pos = member.pos - node.pos;
let end = member.end - node.pos; let end = member.end - node.pos;
+2 -2
View File
@@ -306,8 +306,8 @@ function generateDeclarationFile(recipe, sourceFileGetter) {
let usageImports = []; let usageImports = [];
let usage = []; let usage = [];
let failed = false; let failed = false;
usage.push(`var a;`); usage.push(`var a: any;`);
usage.push(`var b;`); usage.push(`var b: any;`);
const generateUsageImport = (moduleId) => { const generateUsageImport = (moduleId) => {
let importName = 'm' + (++usageCounter); let importName = 'm' + (++usageCounter);
usageImports.push(`import * as ${importName} from './${moduleId.replace(/\.d\.ts$/, '')}';`); usageImports.push(`import * as ${importName} from './${moduleId.replace(/\.d\.ts$/, '')}';`);
+2 -2
View File
@@ -366,8 +366,8 @@ function generateDeclarationFile(recipe: string, sourceFileGetter: SourceFileGet
let failed = false; let failed = false;
usage.push(`var a;`); usage.push(`var a: any;`);
usage.push(`var b;`); usage.push(`var b: any;`);
const generateUsageImport = (moduleId: string) => { const generateUsageImport = (moduleId: string) => {
let importName = 'm' + (++usageCounter); let importName = 'm' + (++usageCounter);
+1 -1
View File
@@ -44,7 +44,7 @@
"service-downloader": "github:anthonydresser/service-downloader#0.1.5", "service-downloader": "github:anthonydresser/service-downloader#0.1.5",
"typescript": "3.5.2", "typescript": "3.5.2",
"vsce": "1.48.0", "vsce": "1.48.0",
"vscode-telemetry-extractor": "^1.5.1", "vscode-telemetry-extractor": "1.5.3",
"xml2js": "^0.4.17" "xml2js": "^0.4.17"
}, },
"scripts": { "scripts": {
+4 -4
View File
@@ -3623,10 +3623,10 @@ vscode-ripgrep@^1.5.5:
resolved "https://registry.yarnpkg.com/vscode-ripgrep/-/vscode-ripgrep-1.5.5.tgz#24c0e9cb356cf889c98e15ecb58f9cf654a1d961" resolved "https://registry.yarnpkg.com/vscode-ripgrep/-/vscode-ripgrep-1.5.5.tgz#24c0e9cb356cf889c98e15ecb58f9cf654a1d961"
integrity sha512-OrPrAmcun4+uZAuNcQvE6CCPskh+5AsjANod/Q3zRcJcGNxgoOSGlQN9RPtatkUNmkN8Nn8mZBnS1jMylu/dKg== integrity sha512-OrPrAmcun4+uZAuNcQvE6CCPskh+5AsjANod/Q3zRcJcGNxgoOSGlQN9RPtatkUNmkN8Nn8mZBnS1jMylu/dKg==
vscode-telemetry-extractor@^1.5.1: vscode-telemetry-extractor@1.5.3:
version "1.5.1" version "1.5.3"
resolved "https://registry.yarnpkg.com/vscode-telemetry-extractor/-/vscode-telemetry-extractor-1.5.1.tgz#67249e4ca9c65a21800ca53880732f8cef98d0fa" resolved "https://registry.yarnpkg.com/vscode-telemetry-extractor/-/vscode-telemetry-extractor-1.5.3.tgz#c17f9065a47425edafd23ea161e80c23274e009d"
integrity sha512-B5SnEdRiDrI4o6NMG9iHmengoaW1rxUQmS/sCaripgnchm+P79JURmKxhfXr5eRo4Mr1QSenFT/SDNaEop7aoQ== integrity sha512-feioJ1e1KyMa9rzblnLbSOduo+Ny0l62H3/bSDgfgCSnU/km+tTSYxPBvZHVr7iQfQGC95J61yC/ObqS9EbaQg==
dependencies: dependencies:
command-line-args "^5.1.1" command-line-args "^5.1.1"
ts-morph "^3.1.3" ts-morph "^3.1.3"
@@ -14,7 +14,7 @@ import * as fs from 'fs';
import { URI } from 'vscode-uri'; import { URI } from 'vscode-uri';
import * as URL from 'url'; import * as URL from 'url';
import { formatError, runSafe, runSafeAsync } from './utils/runner'; import { formatError, runSafe, runSafeAsync } from './utils/runner';
import { JSONDocument, JSONSchema, getLanguageService, DocumentLanguageSettings, SchemaConfiguration } from 'vscode-json-languageservice'; import { JSONDocument, JSONSchema, getLanguageService, DocumentLanguageSettings, SchemaConfiguration, ClientCapabilities } from 'vscode-json-languageservice';
import { getLanguageModelCache } from './languageModelCache'; import { getLanguageModelCache } from './languageModelCache';
interface ISchemaAssociations { interface ISchemaAssociations {
@@ -103,6 +103,7 @@ function getSchemaRequestService(handledSchemas: { [schema: string]: boolean })
let languageService = getLanguageService({ let languageService = getLanguageService({
workspaceContext, workspaceContext,
contributions: [], contributions: [],
clientCapabilities: ClientCapabilities.LATEST
}); });
// Create a text document manager. // Create a text document manager.
@@ -1,11 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
var updateGrammar = require('../../../build/npm/update-grammar');
updateGrammar.update('jeff-hykin/cpp-textmate-grammar', '/syntaxes/objc.tmLanguage.json', './syntaxes/objective-c.tmLanguage.json', undefined, 'master', 'source/languages/cpp');
updateGrammar.update('jeff-hykin/cpp-textmate-grammar', '/syntaxes/objcpp.tmLanguage.json', './syntaxes/objective-c++.tmLanguage.json', undefined, 'master', 'source/languages/cpp');
@@ -1,52 +0,0 @@
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
#import "UseQuotes.h"
#import <Use/GTLT.h>
/*
Multi
Line
Comments
*/
@implementation Test
- (void) applicationWillFinishLaunching:(NSNotification *)notification
{
}
- (IBAction)onSelectInput:(id)sender
{
NSString* defaultDir = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, true)[0];
NSOpenPanel* panel = [NSOpenPanel openPanel];
[panel setAllowedFileTypes:[[NSArray alloc] initWithObjects:@"ipa", @"xcarchive", @"app", nil]];
[panel beginWithCompletionHandler:^(NSInteger result)
{
if (result == NSFileHandlingPanelOKButton)
[self.inputTextField setStringValue:[panel.URL path]];
}];
return YES;
int hex = 0xFEF1F0F;
float ing = 3.14;
ing = 3.14e0;
ing = 31.4e-2;
}
-(id) initWithParams:(id<anObject>) aHandler withDeviceStateManager:(id<anotherObject>) deviceStateManager
{
// add a tap gesture recognizer
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTap:)];
NSMutableArray *gestureRecognizers = [NSMutableArray array];
[gestureRecognizers addObject:tapGesture];
[gestureRecognizers addObjectsFromArray:scnView.gestureRecognizers];
scnView.gestureRecognizers = gestureRecognizers;
return tapGesture;
return nil;
}
@end
File diff suppressed because it is too large Load Diff
@@ -1,63 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as assert from 'assert';
import * as vscode from 'vscode';
suite('workspace-namespace', () => {
suite('Tasks', () => {
test('CustomExecution2 task should start and shutdown successfully', (done) => {
interface CustomTestingTaskDefinition extends vscode.TaskDefinition {
/**
* One of the task properties. This can be used to customize the task in the tasks.json
*/
customProp1: string;
}
const taskType: string = 'customTesting';
const taskName = 'First custom task';
const reg1 = vscode.window.onDidOpenTerminal(term => {
reg1.dispose();
const reg2 = term.onDidWriteData(e => {
reg2.dispose();
assert.equal(e, 'testing\r\n');
term.dispose();
});
});
const taskProvider = vscode.tasks.registerTaskProvider(taskType, {
provideTasks: () => {
const result: vscode.Task[] = [];
const kind: CustomTestingTaskDefinition = {
type: taskType,
customProp1: 'testing task one'
};
const writeEmitter = new vscode.EventEmitter<string>();
const execution = new vscode.CustomExecution2((): Thenable<vscode.Pseudoterminal> => {
const pty: vscode.Pseudoterminal = {
onDidWrite: writeEmitter.event,
open: () => {
writeEmitter.fire('testing\r\n');
},
close: () => {
taskProvider.dispose();
done();
}
};
return Promise.resolve(pty);
});
const task = new vscode.Task2(kind, vscode.TaskScope.Workspace, taskName, taskType, execution);
result.push(task);
return result;
},
resolveTask(_task: vscode.Task): vscode.Task | undefined {
assert.fail('resolveTask should not trigger during the test');
return undefined;
}
});
vscode.commands.executeCommand('workbench.action.tasks.runTask', `${taskType}: ${taskName}`);
});
});
});
@@ -1,8 +0,0 @@
{
"search.exclude": {
"**/search-exclude/**": true
},
"files.exclude": {
"**/files-exclude/**": true
}
}
@@ -1 +0,0 @@
file
@@ -1 +0,0 @@
file
+12 -6
View File
@@ -1,6 +1,6 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -e set -ex
if [[ "$OSTYPE" == "darwin"* ]]; then if [[ "$OSTYPE" == "darwin"* ]]; then
realpath() { [[ $1 = /* ]] && echo "$1" || echo "$PWD/${1#./}"; } realpath() { [[ $1 = /* ]] && echo "$1" || echo "$PWD/${1#./}"; }
@@ -58,15 +58,21 @@ function code() {
function code-wsl() function code-wsl()
{ {
# in a wsl shell # in a wsl shell
local WIN_CODE_CLI_CMD=$(wslpath -w "$ROOT/scripts/code-cli.bat" 2>/dev/null) ELECTRON="$ROOT/.build/electron/Code - OSS.exe"
if ! [ -z "$WIN_CODE_CLI_CMD" ]; then if [ -f "$ELECTRON" ]; then
local CWD=$(pwd)
cd $ROOT
export WSLENV=ELECTRON_RUN_AS_NODE/w:$WSLENV
local WSL_EXT_ID="ms-vscode-remote.remote-wsl" local WSL_EXT_ID="ms-vscode-remote.remote-wsl"
local WSL_EXT_WLOC=$(cmd.exe /c "$WIN_CODE_CLI_CMD" --locate-extension $WSL_EXT_ID) local WSL_EXT_WLOC=$(ELECTRON_RUN_AS_NODE=1 "$ROOT/.build/electron/Code - OSS.exe" "out/cli.js" --locate-extension $WSL_EXT_ID)
if ! [ -z "$WSL_EXT_WLOC" ]; then cd $CWD
if [ -n "$WSL_EXT_WLOC" ]; then
# replace \r\n with \n in WSL_EXT_WLOC # replace \r\n with \n in WSL_EXT_WLOC
local WSL_CODE=$(wslpath -u "${WSL_EXT_WLOC%%[[:cntrl:]]}")/scripts/wslCode-dev.sh local WSL_CODE=$(wslpath -u "${WSL_EXT_WLOC%%[[:cntrl:]]}")/scripts/wslCode-dev.sh
$WSL_CODE "$ROOT" "$@" $WSL_CODE "$ROOT" "$@"
exit $? exit $?
else
echo "Remote WSL not installed, trying to run VSCode in WSL."
fi fi
fi fi
} }
@@ -74,4 +80,4 @@ function code-wsl()
if ! [ -z ${IN_WSL+x} ]; then if ! [ -z ${IN_WSL+x} ]; then
code-wsl "$@" code-wsl "$@"
fi fi
code "$@" code "$@"
@@ -46,9 +46,10 @@ class AccountPanel extends ViewletPanel {
@IContextMenuService contextMenuService: IContextMenuService, @IContextMenuService contextMenuService: IContextMenuService,
@IConfigurationService configurationService: IConfigurationService, @IConfigurationService configurationService: IConfigurationService,
@IInstantiationService private instantiationService: IInstantiationService, @IInstantiationService private instantiationService: IInstantiationService,
@IThemeService private themeService: IThemeService @IThemeService private themeService: IThemeService,
@IContextKeyService contextKeyService: IContextKeyService
) { ) {
super(options, keybindingService, contextMenuService, configurationService); super(options, keybindingService, contextMenuService, configurationService, contextKeyService);
} }
protected renderBody(container: HTMLElement): void { protected renderBody(container: HTMLElement): void {
@@ -121,7 +122,7 @@ export class AccountDialog extends Modal {
@IKeybindingService private _keybindingService: IKeybindingService, @IKeybindingService private _keybindingService: IKeybindingService,
@IConfigurationService private _configurationService: IConfigurationService, @IConfigurationService private _configurationService: IConfigurationService,
@ITelemetryService telemetryService: ITelemetryService, @ITelemetryService telemetryService: ITelemetryService,
@IContextKeyService contextKeyService: IContextKeyService, @IContextKeyService private readonly contextKeyService: IContextKeyService,
@IClipboardService clipboardService: IClipboardService, @IClipboardService clipboardService: IClipboardService,
@ILogService logService: ILogService @ILogService logService: ILogService
) { ) {
@@ -290,7 +291,8 @@ export class AccountDialog extends Modal {
this._contextMenuService, this._contextMenuService,
this._configurationService, this._configurationService,
this._instantiationService, this._instantiationService,
this._themeService this._themeService,
this.contextKeyService
); );
attachPanelStyler(providerView, this._themeService); attachPanelStyler(providerView, this._themeService);
@@ -42,9 +42,10 @@ export class CategoryView extends ViewletPanel {
options: IViewletPanelOptions, options: IViewletPanelOptions,
@IKeybindingService keybindingService: IKeybindingService, @IKeybindingService keybindingService: IKeybindingService,
@IContextMenuService contextMenuService: IContextMenuService, @IContextMenuService contextMenuService: IContextMenuService,
@IConfigurationService configurationService: IConfigurationService @IConfigurationService configurationService: IConfigurationService,
@IContextKeyService contextKeyService: IContextKeyService
) { ) {
super(options, keybindingService, contextMenuService, configurationService); super(options, keybindingService, contextMenuService, configurationService, contextKeyService);
} }
// we want a fixed size, so when we render to will measure our content and set that to be our // we want a fixed size, so when we render to will measure our content and set that to be our
@@ -12,7 +12,7 @@ import { IContextMenuService } from 'vs/platform/contextview/browser/contextView
import { IMenuService, MenuId, MenuItemAction } from 'vs/platform/actions/common/actions'; import { IMenuService, MenuId, MenuItemAction } from 'vs/platform/actions/common/actions';
import { ContextAwareMenuEntryActionViewItem, createAndFillInActionBarActions, createAndFillInContextMenuActions } from 'vs/platform/actions/browser/menuEntryActionViewItem'; import { ContextAwareMenuEntryActionViewItem, createAndFillInActionBarActions, createAndFillInContextMenuActions } from 'vs/platform/actions/browser/menuEntryActionViewItem';
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { IViewsService, TreeItemCollapsibleState, ITreeViewDataProvider, TreeViewItemHandleArg, ITreeViewDescriptor, IViewsRegistry, ViewContainer, ITreeItemLabel, Extensions } from 'vs/workbench/common/views'; import { TreeItemCollapsibleState, ITreeViewDataProvider, TreeViewItemHandleArg, ITreeViewDescriptor, IViewsRegistry, ViewContainer, ITreeItemLabel, Extensions } from 'vs/workbench/common/views';
import { IViewletViewOptions } from 'vs/workbench/browser/parts/views/viewsViewlet'; import { IViewletViewOptions } from 'vs/workbench/browser/parts/views/viewsViewlet';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { INotificationService } from 'vs/platform/notification/common/notification'; import { INotificationService } from 'vs/platform/notification/common/notification';
@@ -48,7 +48,6 @@ import { CollapseAllAction } from 'vs/base/browser/ui/tree/treeDefaults';
import { ITreeItem, ITreeView } from 'sql/workbench/common/views'; import { ITreeItem, ITreeView } from 'sql/workbench/common/views';
import { IOEShimService } from 'sql/workbench/parts/objectExplorer/common/objectExplorerViewTreeShim'; import { IOEShimService } from 'sql/workbench/parts/objectExplorer/common/objectExplorerViewTreeShim';
import { NodeContextKey } from 'sql/workbench/parts/dataExplorer/common/nodeContext'; import { NodeContextKey } from 'sql/workbench/parts/dataExplorer/common/nodeContext';
import { mssqlProviderName } from 'sql/platform/connection/common/constants';
export class CustomTreeViewPanel extends ViewletPanel { export class CustomTreeViewPanel extends ViewletPanel {
@@ -60,9 +59,9 @@ export class CustomTreeViewPanel extends ViewletPanel {
@IKeybindingService keybindingService: IKeybindingService, @IKeybindingService keybindingService: IKeybindingService,
@IContextMenuService contextMenuService: IContextMenuService, @IContextMenuService contextMenuService: IContextMenuService,
@IConfigurationService configurationService: IConfigurationService, @IConfigurationService configurationService: IConfigurationService,
@IViewsService viewsService: IViewsService, @IContextKeyService contextKeyService: IContextKeyService,
) { ) {
super({ ...(options as IViewletPanelOptions), ariaHeaderLabel: options.title }, keybindingService, contextMenuService, configurationService); super({ ...(options as IViewletPanelOptions), ariaHeaderLabel: options.title }, keybindingService, contextMenuService, configurationService, contextKeyService);
const { treeView } = (<ITreeViewDescriptor>Registry.as<IViewsRegistry>(Extensions.ViewsRegistry).getView(options.id)); const { treeView } = (<ITreeViewDescriptor>Registry.as<IViewsRegistry>(Extensions.ViewsRegistry).getView(options.id));
this.treeView = treeView as ITreeView; this.treeView = treeView as ITreeView;
this._register(this.treeView.onDidChangeActions(() => this.updateActions(), this)); this._register(this.treeView.onDidChangeActions(() => this.updateActions(), this));
@@ -19,6 +19,7 @@ import {
AddServerAction, AddServerGroupAction AddServerAction, AddServerGroupAction
} from 'sql/workbench/parts/objectExplorer/browser/connectionTreeAction'; } from 'sql/workbench/parts/objectExplorer/browser/connectionTreeAction';
import { IObjectExplorerService } from 'sql/workbench/services/objectExplorer/common/objectExplorerService'; import { IObjectExplorerService } from 'sql/workbench/services/objectExplorer/common/objectExplorerService';
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
export class ConnectionViewletPanel extends ViewletPanel { export class ConnectionViewletPanel extends ViewletPanel {
@@ -34,9 +35,10 @@ export class ConnectionViewletPanel extends ViewletPanel {
@IContextMenuService contextMenuService: IContextMenuService, @IContextMenuService contextMenuService: IContextMenuService,
@IInstantiationService private readonly instantiationService: IInstantiationService, @IInstantiationService private readonly instantiationService: IInstantiationService,
@IConfigurationService configurationService: IConfigurationService, @IConfigurationService configurationService: IConfigurationService,
@IObjectExplorerService private readonly objectExplorerService: IObjectExplorerService @IObjectExplorerService private readonly objectExplorerService: IObjectExplorerService,
@IContextKeyService contextKeyService: IContextKeyService
) { ) {
super({ ...(options as IViewletPanelOptions), ariaHeaderLabel: options.title }, keybindingService, contextMenuService, configurationService); super({ ...(options as IViewletPanelOptions), ariaHeaderLabel: options.title }, keybindingService, contextMenuService, configurationService, contextKeyService);
this._addServerAction = this.instantiationService.createInstance(AddServerAction, this._addServerAction = this.instantiationService.createInstance(AddServerAction,
AddServerAction.ID, AddServerAction.ID,
AddServerAction.LABEL); AddServerAction.LABEL);
@@ -58,9 +58,10 @@ class InsightTableView<T> extends ViewletPanel {
options: IViewletPanelOptions, options: IViewletPanelOptions,
@IKeybindingService keybindingService: IKeybindingService, @IKeybindingService keybindingService: IKeybindingService,
@IContextMenuService contextMenuService: IContextMenuService, @IContextMenuService contextMenuService: IContextMenuService,
@IConfigurationService configurationService: IConfigurationService @IConfigurationService configurationService: IConfigurationService,
@IContextKeyService contextKeyService: IContextKeyService
) { ) {
super(options, keybindingService, contextMenuService, configurationService); super(options, keybindingService, contextMenuService, configurationService, contextKeyService);
} }
protected renderBody(container: HTMLElement): void { protected renderBody(container: HTMLElement): void {
+1 -1
View File
@@ -65,7 +65,7 @@ export class CheckboxActionViewItem extends BaseActionViewItem {
} }
} }
dipsose(): void { dispose(): void {
this.disposables.dispose(); this.disposables.dispose();
super.dispose(); super.dispose();
} }
@@ -16,6 +16,19 @@
background: url('case-sensitive-hc.svg') center center no-repeat; background: url('case-sensitive-hc.svg') center center no-repeat;
} }
.vs .monaco-custom-checkbox.monaco-preserve-case {
background: url('preserve-case-light.svg') center center no-repeat;
}
.vs-dark .monaco-custom-checkbox.monaco-preserve-case {
background: url('preserve-case-dark.svg') center center no-repeat;
}
.hc-black .monaco-custom-checkbox.monaco-preserve-case,
.hc-black .monaco-custom-checkbox.monaco-preserve-case:hover {
background: url('preserve-case-hc.svg') center center no-repeat;
}
.vs .monaco-custom-checkbox.monaco-whole-word { .vs .monaco-custom-checkbox.monaco-whole-word {
background: url('whole-word-light.svg') center center no-repeat; background: url('whole-word-light.svg') center center no-repeat;
} }
@@ -40,4 +53,4 @@
.hc-black .monaco-custom-checkbox.monaco-regex, .hc-black .monaco-custom-checkbox.monaco-regex,
.hc-black .monaco-custom-checkbox.monaco-regex:hover { .hc-black .monaco-custom-checkbox.monaco-regex:hover {
background: url('regex-hc.svg') center center no-repeat; background: url('regex-hc.svg') center center no-repeat;
} }
@@ -0,0 +1,4 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M8.53437 12.4673H7.4361L6.53859 10.0936H2.94854L2.10418 12.4673H1L4.24757 4H5.27499L8.53437 12.4673ZM6.21383 9.20202L4.88528 5.59426C4.84198 5.47617 4.79868 5.28722 4.75538 5.02741H4.73176C4.69239 5.26754 4.64713 5.45649 4.59595 5.59426L3.27921 9.20202H6.21383Z" fill="#C5C5C5"/>
<path d="M9.78617 12.4673V4H12.1953C12.9275 4 13.5081 4.17911 13.9372 4.53733C14.3662 4.89554 14.5808 5.36201 14.5808 5.93674C14.5808 6.41698 14.4509 6.83425 14.1911 7.18853C13.9313 7.54281 13.573 7.79474 13.1164 7.94433V7.96795C13.6872 8.03487 14.1438 8.25137 14.4863 8.61746C14.8288 8.97961 15 9.45199 15 10.0346C15 10.7589 14.7402 11.3454 14.2206 11.7942C13.701 12.2429 13.0456 12.4673 12.2543 12.4673H9.78617ZM10.7782 4.89751V7.63138H11.7938C12.337 7.63138 12.7641 7.50148 13.0751 7.24167C13.3861 6.97793 13.5415 6.6079 13.5415 6.13159C13.5415 5.30887 13.0003 4.89751 11.9178 4.89751H10.7782ZM10.7782 8.52299V11.5698H12.1244C12.707 11.5698 13.1577 11.432 13.4766 11.1565C13.7994 10.8809 13.9608 10.503 13.9608 10.0228C13.9608 9.02292 13.2798 8.52299 11.9178 8.52299H10.7782Z" fill="#C5C5C5"/>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

@@ -0,0 +1,4 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M8.53437 12.4673H7.4361L6.53859 10.0936H2.94854L2.10418 12.4673H1L4.24757 4H5.27499L8.53437 12.4673ZM6.21383 9.20202L4.88528 5.59426C4.84198 5.47617 4.79868 5.28722 4.75538 5.02741H4.73176C4.69239 5.26754 4.64713 5.45649 4.59595 5.59426L3.27921 9.20202H6.21383Z" fill="white"/>
<path d="M9.78617 12.4673V4H12.1953C12.9275 4 13.5081 4.17911 13.9372 4.53733C14.3662 4.89554 14.5808 5.36201 14.5808 5.93674C14.5808 6.41698 14.4509 6.83425 14.1911 7.18853C13.9313 7.54281 13.573 7.79474 13.1164 7.94433V7.96795C13.6872 8.03487 14.1438 8.25137 14.4863 8.61746C14.8288 8.97961 15 9.45199 15 10.0346C15 10.7589 14.7402 11.3454 14.2206 11.7942C13.701 12.2429 13.0456 12.4673 12.2543 12.4673H9.78617ZM10.7782 4.89751V7.63138H11.7938C12.337 7.63138 12.7641 7.50148 13.0751 7.24167C13.3861 6.97793 13.5415 6.6079 13.5415 6.13159C13.5415 5.30887 13.0003 4.89751 11.9178 4.89751H10.7782ZM10.7782 8.52299V11.5698H12.1244C12.707 11.5698 13.1577 11.432 13.4766 11.1565C13.7994 10.8809 13.9608 10.503 13.9608 10.0228C13.9608 9.02292 13.2798 8.52299 11.9178 8.52299H10.7782Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

@@ -0,0 +1,4 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M8.53437 12.4673H7.4361L6.53859 10.0936H2.94854L2.10418 12.4673H1L4.24757 4H5.27499L8.53437 12.4673ZM6.21383 9.20202L4.88528 5.59426C4.84198 5.47617 4.79868 5.28722 4.75538 5.02741H4.73176C4.69239 5.26754 4.64713 5.45649 4.59595 5.59426L3.27921 9.20202H6.21383Z" fill="#424242"/>
<path d="M9.78617 12.4673V4H12.1953C12.9275 4 13.5081 4.17911 13.9372 4.53733C14.3662 4.89554 14.5808 5.36201 14.5808 5.93674C14.5808 6.41698 14.4509 6.83425 14.1911 7.18853C13.9313 7.54281 13.573 7.79474 13.1164 7.94433V7.96795C13.6872 8.03487 14.1438 8.25137 14.4863 8.61746C14.8288 8.97961 15 9.45199 15 10.0346C15 10.7589 14.7402 11.3454 14.2206 11.7942C13.701 12.2429 13.0456 12.4673 12.2543 12.4673H9.78617ZM10.7782 4.89751V7.63138H11.7938C12.337 7.63138 12.7641 7.50148 13.0751 7.24167C13.3861 6.97793 13.5415 6.6079 13.5415 6.13159C13.5415 5.30887 13.0003 4.89751 11.9178 4.89751H10.7782ZM10.7782 8.52299V11.5698H12.1244C12.707 11.5698 13.1577 11.432 13.4766 11.1565C13.7994 10.8809 13.9608 10.503 13.9608 10.0228C13.9608 9.02292 13.2798 8.52299 11.9178 8.52299H10.7782Z" fill="#424242"/>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

+13 -1
View File
@@ -7,7 +7,7 @@ import 'vs/css!./gridview';
import { Orientation } from 'vs/base/browser/ui/sash/sash'; import { Orientation } from 'vs/base/browser/ui/sash/sash';
import { Disposable } from 'vs/base/common/lifecycle'; import { Disposable } from 'vs/base/common/lifecycle';
import { tail2 as tail, equals } from 'vs/base/common/arrays'; import { tail2 as tail, equals } from 'vs/base/common/arrays';
import { orthogonal, IView as IGridViewView, GridView, Sizing as GridViewSizing, Box, IGridViewStyles, IViewSize } from './gridview'; import { orthogonal, IView as IGridViewView, GridView, Sizing as GridViewSizing, Box, IGridViewStyles, IViewSize, ILayoutController, LayoutController } from './gridview';
import { Event } from 'vs/base/common/event'; import { Event } from 'vs/base/common/event';
import { InvisibleSizing } from 'vs/base/browser/ui/splitview/splitview'; import { InvisibleSizing } from 'vs/base/browser/ui/splitview/splitview';
@@ -197,6 +197,7 @@ export interface IGridOptions {
readonly styles?: IGridStyles; readonly styles?: IGridStyles;
readonly proportionalLayout?: boolean; readonly proportionalLayout?: boolean;
readonly firstViewVisibleCachedSize?: number; readonly firstViewVisibleCachedSize?: number;
readonly layoutController?: ILayoutController;
} }
export class Grid<T extends IView = IView> extends Disposable { export class Grid<T extends IView = IView> extends Disposable {
@@ -217,6 +218,8 @@ export class Grid<T extends IView = IView> extends Disposable {
get element(): HTMLElement { return this.gridview.element; } get element(): HTMLElement { return this.gridview.element; }
private didLayout = false;
constructor(view: T, options: IGridOptions = {}) { constructor(view: T, options: IGridOptions = {}) {
super(); super();
this.gridview = new GridView(options); this.gridview = new GridView(options);
@@ -237,6 +240,7 @@ export class Grid<T extends IView = IView> extends Disposable {
layout(width: number, height: number): void { layout(width: number, height: number): void {
this.gridview.layout(width, height); this.gridview.layout(width, height);
this.didLayout = true;
} }
hasView(view: T): boolean { hasView(view: T): boolean {
@@ -344,6 +348,10 @@ export class Grid<T extends IView = IView> extends Disposable {
} }
getNeighborViews(view: T, direction: Direction, wrap: boolean = false): T[] { getNeighborViews(view: T, direction: Direction, wrap: boolean = false): T[] {
if (!this.didLayout) {
throw new Error('Can\'t call getNeighborViews before first layout');
}
const location = this.getViewLocation(view); const location = this.getViewLocation(view);
const root = this.getViews(); const root = this.getViews();
const node = getGridNode(root, location); const node = getGridNode(root, location);
@@ -527,6 +535,9 @@ export class SerializableGrid<T extends ISerializableView> extends Grid<T> {
throw new Error('Invalid serialized state, first leaf not found'); throw new Error('Invalid serialized state, first leaf not found');
} }
const layoutController = new LayoutController(false);
options = { ...options, layoutController };
if (typeof firstLeaf.cachedVisibleSize === 'number') { if (typeof firstLeaf.cachedVisibleSize === 'number') {
options = { ...options, firstViewVisibleCachedSize: firstLeaf.cachedVisibleSize }; options = { ...options, firstViewVisibleCachedSize: firstLeaf.cachedVisibleSize };
} }
@@ -536,6 +547,7 @@ export class SerializableGrid<T extends ISerializableView> extends Grid<T> {
result.restoreViews(firstLeaf.view, orientation, root); result.restoreViews(firstLeaf.view, orientation, root);
result.initialLayoutContext = { width, height, root }; result.initialLayoutContext = { width, height, root };
layoutController.isLayoutEnabled = true;
return result; return result;
} }
+29 -10
View File
@@ -67,9 +67,18 @@ const defaultStyles: IGridViewStyles = {
separatorBorder: Color.transparent separatorBorder: Color.transparent
}; };
export interface ILayoutController {
readonly isLayoutEnabled: boolean;
}
export class LayoutController implements ILayoutController {
constructor(public isLayoutEnabled: boolean) { }
}
export interface IGridViewOptions { export interface IGridViewOptions {
styles?: IGridViewStyles; readonly styles?: IGridViewStyles;
proportionalLayout?: boolean; // default true readonly proportionalLayout?: boolean; // default true
readonly layoutController?: ILayoutController;
} }
class BranchNode implements ISplitView, IDisposable { class BranchNode implements ISplitView, IDisposable {
@@ -466,7 +475,8 @@ class LeafNode implements ISplitView, IDisposable {
constructor( constructor(
readonly view: IView, readonly view: IView,
readonly orientation: Orientation, readonly orientation: Orientation,
orthogonalSize: number = 0 readonly layoutController: ILayoutController,
orthogonalSize: number
) { ) {
this._orthogonalSize = orthogonalSize; this._orthogonalSize = orthogonalSize;
@@ -536,7 +546,10 @@ class LeafNode implements ISplitView, IDisposable {
layout(size: number): void { layout(size: number): void {
this._size = size; this._size = size;
return this.view.layout(this.width, this.height, orthogonal(this.orientation));
if (this.layoutController.isLayoutEnabled) {
this.view.layout(this.width, this.height, orthogonal(this.orientation));
}
} }
setVisible(visible: boolean): void { setVisible(visible: boolean): void {
@@ -553,7 +566,10 @@ class LeafNode implements ISplitView, IDisposable {
orthogonalLayout(size: number): void { orthogonalLayout(size: number): void {
this._orthogonalSize = size; this._orthogonalSize = size;
return this.view.layout(this.width, this.height, orthogonal(this.orientation));
if (this.layoutController.isLayoutEnabled) {
this.view.layout(this.width, this.height, orthogonal(this.orientation));
}
} }
dispose(): void { } dispose(): void { }
@@ -584,7 +600,7 @@ function flipNode<T extends Node>(node: T, size: number, orthogonalSize: number)
return result as T; return result as T;
} else { } else {
return new LeafNode((node as LeafNode).view, orthogonal(node.orientation), orthogonalSize) as T; return new LeafNode((node as LeafNode).view, orthogonal(node.orientation), (node as LeafNode).layoutController, orthogonalSize) as T;
} }
} }
@@ -644,11 +660,14 @@ export class GridView implements IDisposable {
private _onDidChange = new Relay<IViewSize | undefined>(); private _onDidChange = new Relay<IViewSize | undefined>();
readonly onDidChange = this._onDidChange.event; readonly onDidChange = this._onDidChange.event;
private layoutController: LayoutController;
constructor(options: IGridViewOptions = {}) { constructor(options: IGridViewOptions = {}) {
this.element = $('.monaco-grid-view'); this.element = $('.monaco-grid-view');
this.styles = options.styles || defaultStyles; this.styles = options.styles || defaultStyles;
this.proportionalLayout = typeof options.proportionalLayout !== 'undefined' ? !!options.proportionalLayout : true; this.proportionalLayout = typeof options.proportionalLayout !== 'undefined' ? !!options.proportionalLayout : true;
this.root = new BranchNode(Orientation.VERTICAL, this.styles, this.proportionalLayout); this.root = new BranchNode(Orientation.VERTICAL, this.styles, this.proportionalLayout);
this.layoutController = options.layoutController || new LayoutController(true);
} }
style(styles: IGridViewStyles): void { style(styles: IGridViewStyles): void {
@@ -670,7 +689,7 @@ export class GridView implements IDisposable {
const [pathToParent, parent] = this.getNode(rest); const [pathToParent, parent] = this.getNode(rest);
if (parent instanceof BranchNode) { if (parent instanceof BranchNode) {
const node = new LeafNode(view, orthogonal(parent.orientation), parent.orthogonalSize); const node = new LeafNode(view, orthogonal(parent.orientation), this.layoutController, parent.orthogonalSize);
parent.addChild(node, size, index); parent.addChild(node, size, index);
} else { } else {
@@ -690,14 +709,14 @@ export class GridView implements IDisposable {
grandParent.addChild(newParent, parent.size, parentIndex); grandParent.addChild(newParent, parent.size, parentIndex);
newParent.orthogonalLayout(parent.orthogonalSize); newParent.orthogonalLayout(parent.orthogonalSize);
const newSibling = new LeafNode(parent.view, grandParent.orientation, parent.size); const newSibling = new LeafNode(parent.view, grandParent.orientation, this.layoutController, parent.size);
newParent.addChild(newSibling, newSiblingSize, 0); newParent.addChild(newSibling, newSiblingSize, 0);
if (typeof size !== 'number' && size.type === 'split') { if (typeof size !== 'number' && size.type === 'split') {
size = Sizing.Split(0); size = Sizing.Split(0);
} }
const node = new LeafNode(view, grandParent.orientation, parent.size); const node = new LeafNode(view, grandParent.orientation, this.layoutController, parent.size);
newParent.addChild(node, size, index); newParent.addChild(node, size, index);
} }
} }
@@ -759,7 +778,7 @@ export class GridView implements IDisposable {
grandParent.addChild(child, child.size, parentIndex + i); grandParent.addChild(child, child.size, parentIndex + i);
} }
} else { } else {
const newSibling = new LeafNode(sibling.view, orthogonal(sibling.orientation), sibling.size); const newSibling = new LeafNode(sibling.view, orthogonal(sibling.orientation), this.layoutController, sibling.size);
grandParent.addChild(newSibling, sibling.orthogonalSize, parentIndex); grandParent.addChild(newSibling, sibling.orthogonalSize, parentIndex);
} }
+2 -2
View File
@@ -105,7 +105,7 @@ export class VSBuffer {
} }
} }
function readUInt32BE(source: Uint8Array, offset: number): number { export function readUInt32BE(source: Uint8Array, offset: number): number {
return ( return (
source[offset] * 2 ** 24 source[offset] * 2 ** 24
+ source[offset + 1] * 2 ** 16 + source[offset + 1] * 2 ** 16
@@ -114,7 +114,7 @@ function readUInt32BE(source: Uint8Array, offset: number): number {
); );
} }
function writeUInt32BE(destination: Uint8Array, value: number, offset: number): void { export function writeUInt32BE(destination: Uint8Array, value: number, offset: number): void {
destination[offset + 3] = value; destination[offset + 3] = value;
value = value >>> 8; value = value >>> 8;
destination[offset + 2] = value; destination[offset + 2] = value;
+26 -21
View File
@@ -12,7 +12,7 @@ const INITIALIZE = '$initialize';
export interface IWorker extends IDisposable { export interface IWorker extends IDisposable {
getId(): number; getId(): number;
postMessage(message: string): void; postMessage(message: any, transfer: Transferable[]): void;
} }
export interface IWorkerCallback { export interface IWorkerCallback {
@@ -60,7 +60,7 @@ interface IMessageReply {
} }
interface IMessageHandler { interface IMessageHandler {
sendMessage(msg: string): void; sendMessage(msg: any, transfer?: ArrayBuffer[]): void;
handleMessage(method: string, args: any[]): Promise<any>; handleMessage(method: string, args: any[]): Promise<any>;
} }
@@ -98,14 +98,7 @@ class SimpleWorkerProtocol {
}); });
} }
public handleMessage(serializedMessage: string): void { public handleMessage(message: IMessage): void {
let message: IMessage;
try {
message = JSON.parse(serializedMessage);
} catch (e) {
// nothing
return;
}
if (!message || !message.vsWorker) { if (!message || !message.vsWorker) {
return; return;
} }
@@ -167,9 +160,21 @@ class SimpleWorkerProtocol {
} }
private _send(msg: IRequestMessage | IReplyMessage): void { private _send(msg: IRequestMessage | IReplyMessage): void {
let strMsg = JSON.stringify(msg); let transfer: ArrayBuffer[] = [];
// console.log('SENDING: ' + strMsg); if (msg.req) {
this._handler.sendMessage(strMsg); const m = <IRequestMessage>msg;
for (let i = 0; i < m.args.length; i++) {
if (m.args[i] instanceof ArrayBuffer) {
transfer.push(m.args[i]);
}
}
} else {
const m = <IReplyMessage>msg;
if (m.res instanceof ArrayBuffer) {
transfer.push(m.res);
}
}
this._handler.sendMessage(msg, transfer);
} }
} }
@@ -195,7 +200,7 @@ export class SimpleWorkerClient<W extends object, H extends object> extends Disp
this._worker = this._register(workerFactory.create( this._worker = this._register(workerFactory.create(
'vs/base/common/worker/simpleWorker', 'vs/base/common/worker/simpleWorker',
(msg: string) => { (msg: any) => {
this._protocol.handleMessage(msg); this._protocol.handleMessage(msg);
}, },
(err: any) => { (err: any) => {
@@ -208,8 +213,8 @@ export class SimpleWorkerClient<W extends object, H extends object> extends Disp
)); ));
this._protocol = new SimpleWorkerProtocol({ this._protocol = new SimpleWorkerProtocol({
sendMessage: (msg: string): void => { sendMessage: (msg: any, transfer: ArrayBuffer[]): void => {
this._worker.postMessage(msg); this._worker.postMessage(msg, transfer);
}, },
handleMessage: (method: string, args: any[]): Promise<any> => { handleMessage: (method: string, args: any[]): Promise<any> => {
if (typeof (host as any)[method] !== 'function') { if (typeof (host as any)[method] !== 'function') {
@@ -240,7 +245,7 @@ export class SimpleWorkerClient<W extends object, H extends object> extends Disp
// Send initialize message // Send initialize message
this._onModuleLoaded = this._protocol.sendMessage(INITIALIZE, [ this._onModuleLoaded = this._protocol.sendMessage(INITIALIZE, [
this._worker.getId(), this._worker.getId(),
loaderConfiguration, JSON.parse(JSON.stringify(loaderConfiguration)),
moduleId, moduleId,
hostMethods, hostMethods,
]); ]);
@@ -297,18 +302,18 @@ export class SimpleWorkerServer<H extends object> {
private _requestHandler: IRequestHandler | null; private _requestHandler: IRequestHandler | null;
private _protocol: SimpleWorkerProtocol; private _protocol: SimpleWorkerProtocol;
constructor(postSerializedMessage: (msg: string) => void, requestHandlerFactory: IRequestHandlerFactory<H> | null) { constructor(postMessage: (msg: any, transfer?: Transferable[]) => void, requestHandlerFactory: IRequestHandlerFactory<H> | null) {
this._requestHandlerFactory = requestHandlerFactory; this._requestHandlerFactory = requestHandlerFactory;
this._requestHandler = null; this._requestHandler = null;
this._protocol = new SimpleWorkerProtocol({ this._protocol = new SimpleWorkerProtocol({
sendMessage: (msg: string): void => { sendMessage: (msg: any, transfer: ArrayBuffer[]): void => {
postSerializedMessage(msg); postMessage(msg, transfer);
}, },
handleMessage: (method: string, args: any[]): Promise<any> => this._handleMessage(method, args) handleMessage: (method: string, args: any[]): Promise<any> => this._handleMessage(method, args)
}); });
} }
public onmessage(msg: string): void { public onmessage(msg: any): void {
this._protocol.handleMessage(msg); this._protocol.handleMessage(msg);
} }
+3 -3
View File
@@ -63,7 +63,7 @@ class WebWorker implements IWorker {
} else { } else {
this.worker = Promise.resolve(workerOrPromise); this.worker = Promise.resolve(workerOrPromise);
} }
this.postMessage(moduleId); this.postMessage(moduleId, []);
this.worker.then((w) => { this.worker.then((w) => {
w.onmessage = function (ev: any) { w.onmessage = function (ev: any) {
onMessageCallback(ev.data); onMessageCallback(ev.data);
@@ -79,9 +79,9 @@ class WebWorker implements IWorker {
return this.id; return this.id;
} }
public postMessage(msg: string): void { public postMessage(message: any, transfer: Transferable[]): void {
if (this.worker) { if (this.worker) {
this.worker.then(w => w.postMessage(msg)); this.worker.then(w => w.postMessage(message, transfer));
} }
} }
+1 -4
View File
@@ -19,9 +19,6 @@
<!-- Workaround to pass product configuration--> <!-- Workaround to pass product configuration-->
<meta id="vscode-remote-product-configuration" data-settings="{{PRODUCT_CONFIGURATION}}"> <meta id="vscode-remote-product-configuration" data-settings="{{PRODUCT_CONFIGURATION}}">
<!-- Workaround to pass remote connection token-->
<meta id="vscode-remote-connection-token" data-settings="{{CONNECTION_AUTH_TOKEN}}">
</head> </head>
<body aria-label=""> <body aria-label="">
@@ -35,4 +32,4 @@
<!-- Startup via workbench.js --> <!-- Startup via workbench.js -->
<script src="./out/vs/code/browser/workbench/workbench.js"></script> <script src="./out/vs/code/browser/workbench/workbench.js"></script>
</html> </html>
+6
View File
@@ -14,6 +14,7 @@ import { IModelContentChange, IModelContentChangedEvent, IModelDecorationsChange
import { SearchData } from 'vs/editor/common/model/textModelSearch'; import { SearchData } from 'vs/editor/common/model/textModelSearch';
import { LanguageId, LanguageIdentifier, FormattingOptions } from 'vs/editor/common/modes'; import { LanguageId, LanguageIdentifier, FormattingOptions } from 'vs/editor/common/modes';
import { ThemeColor } from 'vs/platform/theme/common/themeService'; import { ThemeColor } from 'vs/platform/theme/common/themeService';
import { MultilineTokens } from 'vs/editor/common/model/tokensStore';
/** /**
* Vertical Lane in the overview ruler of the editor. * Vertical Lane in the overview ruler of the editor.
@@ -779,6 +780,11 @@ export interface ITextModel {
*/ */
findPreviousMatch(searchString: string, searchStart: IPosition, isRegex: boolean, matchCase: boolean, wordSeparators: string | null, captureMatches: boolean): FindMatch | null; findPreviousMatch(searchString: string, searchStart: IPosition, isRegex: boolean, matchCase: boolean, wordSeparators: string | null, captureMatches: boolean): FindMatch | null;
/**
* @internal
*/
setTokens(tokens: MultilineTokens[]): void;
/** /**
* Flush all tokenization state. * Flush all tokenization state.
* @internal * @internal
+4 -4
View File
@@ -22,7 +22,7 @@ import { IntervalNode, IntervalTree, getNodeIsInOverviewRuler, recomputeMaxEnd }
import { PieceTreeTextBufferBuilder } from 'vs/editor/common/model/pieceTreeTextBuffer/pieceTreeTextBufferBuilder'; import { PieceTreeTextBufferBuilder } from 'vs/editor/common/model/pieceTreeTextBuffer/pieceTreeTextBufferBuilder';
import { IModelContentChangedEvent, IModelDecorationsChangedEvent, IModelLanguageChangedEvent, IModelLanguageConfigurationChangedEvent, IModelOptionsChangedEvent, IModelTokensChangedEvent, InternalModelContentChangeEvent, ModelRawChange, ModelRawContentChangedEvent, ModelRawEOLChanged, ModelRawFlush, ModelRawLineChanged, ModelRawLinesDeleted, ModelRawLinesInserted } from 'vs/editor/common/model/textModelEvents'; import { IModelContentChangedEvent, IModelDecorationsChangedEvent, IModelLanguageChangedEvent, IModelLanguageConfigurationChangedEvent, IModelOptionsChangedEvent, IModelTokensChangedEvent, InternalModelContentChangeEvent, ModelRawChange, ModelRawContentChangedEvent, ModelRawEOLChanged, ModelRawFlush, ModelRawLineChanged, ModelRawLinesDeleted, ModelRawLinesInserted } from 'vs/editor/common/model/textModelEvents';
import { SearchData, SearchParams, TextModelSearch } from 'vs/editor/common/model/textModelSearch'; import { SearchData, SearchParams, TextModelSearch } from 'vs/editor/common/model/textModelSearch';
import { TextModelTokenization, countEOL } from 'vs/editor/common/model/textModelTokens'; import { TextModelTokenization } from 'vs/editor/common/model/textModelTokens';
import { getWordAtText } from 'vs/editor/common/model/wordHelper'; import { getWordAtText } from 'vs/editor/common/model/wordHelper';
import { LanguageId, LanguageIdentifier, FormattingOptions } from 'vs/editor/common/modes'; import { LanguageId, LanguageIdentifier, FormattingOptions } from 'vs/editor/common/modes';
import { LanguageConfigurationRegistry } from 'vs/editor/common/modes/languageConfigurationRegistry'; import { LanguageConfigurationRegistry } from 'vs/editor/common/modes/languageConfigurationRegistry';
@@ -32,7 +32,7 @@ import { BracketsUtils, RichEditBracket, RichEditBrackets } from 'vs/editor/comm
import { ITheme, ThemeColor } from 'vs/platform/theme/common/themeService'; import { ITheme, ThemeColor } from 'vs/platform/theme/common/themeService';
import { withUndefinedAsNull } from 'vs/base/common/types'; import { withUndefinedAsNull } from 'vs/base/common/types';
import { VSBufferReadableStream, VSBuffer } from 'vs/base/common/buffer'; import { VSBufferReadableStream, VSBuffer } from 'vs/base/common/buffer';
import { TokensStore, MultilineTokens } from 'vs/editor/common/model/tokensStore'; import { TokensStore, MultilineTokens, countEOL } from 'vs/editor/common/model/tokensStore';
import { Color } from 'vs/base/common/color'; import { Color } from 'vs/base/common/color';
function createTextBufferBuilder() { function createTextBufferBuilder() {
@@ -1279,7 +1279,7 @@ export class TextModel extends Disposable implements model.ITextModel {
for (let i = 0, len = contentChanges.length; i < len; i++) { for (let i = 0, len = contentChanges.length; i < len; i++) {
const change = contentChanges[i]; const change = contentChanges[i];
const [eolCount, firstLineLength] = countEOL(change.text); const [eolCount, firstLineLength] = countEOL(change.text);
this._tokens.applyEdits(change.range, eolCount, firstLineLength); this._tokens.acceptEdit(change.range, eolCount, firstLineLength);
this._onDidChangeDecorations.fire(); this._onDidChangeDecorations.fire();
this._decorationsTree.acceptReplace(change.rangeOffset, change.rangeLength, change.text.length, change.forceMoveMarkers); this._decorationsTree.acceptReplace(change.rangeOffset, change.rangeLength, change.text.length, change.forceMoveMarkers);
@@ -1704,7 +1704,7 @@ export class TextModel extends Disposable implements model.ITextModel {
//#region Tokenization //#region Tokenization
public setLineTokens(lineNumber: number, tokens: Uint32Array): void { public setLineTokens(lineNumber: number, tokens: Uint32Array | ArrayBuffer | null): void {
if (lineNumber < 1 || lineNumber > this.getLineCount()) { if (lineNumber < 1 || lineNumber > this.getLineCount()) {
throw new Error('Illegal value for lineNumber'); throw new Error('Illegal value for lineNumber');
} }
+4 -32
View File
@@ -15,38 +15,7 @@ import { nullTokenize2 } from 'vs/editor/common/modes/nullMode';
import { TextModel } from 'vs/editor/common/model/textModel'; import { TextModel } from 'vs/editor/common/model/textModel';
import { Disposable } from 'vs/base/common/lifecycle'; import { Disposable } from 'vs/base/common/lifecycle';
import { StopWatch } from 'vs/base/common/stopwatch'; import { StopWatch } from 'vs/base/common/stopwatch';
import { CharCode } from 'vs/base/common/charCode'; import { MultilineTokensBuilder, countEOL } from 'vs/editor/common/model/tokensStore';
import { MultilineTokensBuilder } from 'vs/editor/common/model/tokensStore';
export function countEOL(text: string): [number, number] {
let eolCount = 0;
let firstLineLength = 0;
for (let i = 0, len = text.length; i < len; i++) {
const chr = text.charCodeAt(i);
if (chr === CharCode.CarriageReturn) {
if (eolCount === 0) {
firstLineLength = i;
}
eolCount++;
if (i + 1 < len && text.charCodeAt(i + 1) === CharCode.LineFeed) {
// \r\n... case
i++; // skip \n
} else {
// \r... case
}
} else if (chr === CharCode.LineFeed) {
if (eolCount === 0) {
firstLineLength = i;
}
eolCount++;
}
}
if (eolCount === 0) {
firstLineLength = text.length;
}
return [eolCount, firstLineLength];
}
const enum Constants { const enum Constants {
CHEAP_TOKENIZATION_LENGTH_LIMIT = 2048 CHEAP_TOKENIZATION_LENGTH_LIMIT = 2048
@@ -117,6 +86,9 @@ export class TokenizationStateStore {
if (deleteCount === 0) { if (deleteCount === 0) {
return; return;
} }
if (start + deleteCount > this._len) {
deleteCount = this._len - start;
}
this._beginState.splice(start, deleteCount); this._beginState.splice(start, deleteCount);
this._valid.splice(start, deleteCount); this._valid.splice(start, deleteCount);
this._len -= deleteCount; this._len -= deleteCount;
+275 -26
View File
@@ -8,6 +8,38 @@ import { LineTokens } from 'vs/editor/common/core/lineTokens';
import { Position } from 'vs/editor/common/core/position'; import { Position } from 'vs/editor/common/core/position';
import { IRange } from 'vs/editor/common/core/range'; import { IRange } from 'vs/editor/common/core/range';
import { ColorId, FontStyle, LanguageId, MetadataConsts, StandardTokenType, TokenMetadata } from 'vs/editor/common/modes'; import { ColorId, FontStyle, LanguageId, MetadataConsts, StandardTokenType, TokenMetadata } from 'vs/editor/common/modes';
import { writeUInt32BE, readUInt32BE } from 'vs/base/common/buffer';
import { CharCode } from 'vs/base/common/charCode';
export function countEOL(text: string): [number, number] {
let eolCount = 0;
let firstLineLength = 0;
for (let i = 0, len = text.length; i < len; i++) {
const chr = text.charCodeAt(i);
if (chr === CharCode.CarriageReturn) {
if (eolCount === 0) {
firstLineLength = i;
}
eolCount++;
if (i + 1 < len && text.charCodeAt(i + 1) === CharCode.LineFeed) {
// \r\n... case
i++; // skip \n
} else {
// \r... case
}
} else if (chr === CharCode.LineFeed) {
if (eolCount === 0) {
firstLineLength = i;
}
eolCount++;
}
}
if (eolCount === 0) {
firstLineLength = text.length;
}
return [eolCount, firstLineLength];
}
function getDefaultMetadata(topLevelLanguageId: LanguageId): number { function getDefaultMetadata(topLevelLanguageId: LanguageId): number {
return ( return (
@@ -39,23 +71,226 @@ export class MultilineTokensBuilder {
return; return;
} }
} }
this.tokens.push(new MultilineTokens(lineNumber, lineTokens)); this.tokens.push(new MultilineTokens(lineNumber, [lineTokens]));
}
public static deserialize(buff: Uint8Array): MultilineTokens[] {
let offset = 0;
const count = readUInt32BE(buff, offset); offset += 4;
let result: MultilineTokens[] = [];
for (let i = 0; i < count; i++) {
offset = MultilineTokens.deserialize(buff, offset, result);
}
return result;
}
public serialize(): Uint8Array {
const size = this._serializeSize();
const result = new Uint8Array(size);
this._serialize(result);
return result;
}
private _serializeSize(): number {
let result = 0;
result += 4; // 4 bytes for the count
for (let i = 0; i < this.tokens.length; i++) {
result += this.tokens[i].serializeSize();
}
return result;
}
private _serialize(destination: Uint8Array): void {
let offset = 0;
writeUInt32BE(destination, this.tokens.length, offset); offset += 4;
for (let i = 0; i < this.tokens.length; i++) {
offset = this.tokens[i].serialize(destination, offset);
}
} }
} }
export class MultilineTokens { export class MultilineTokens {
public readonly startLineNumber: number; public startLineNumber: number;
public readonly tokens: Uint32Array[]; public tokens: (Uint32Array | ArrayBuffer | null)[];
constructor(lineNumber: number, tokens: Uint32Array) { constructor(startLineNumber: number, tokens: Uint32Array[]) {
this.startLineNumber = lineNumber; this.startLineNumber = startLineNumber;
this.tokens = [tokens]; this.tokens = tokens;
}
public static deserialize(buff: Uint8Array, offset: number, result: MultilineTokens[]): number {
const view32 = new Uint32Array(buff.buffer);
const startLineNumber = readUInt32BE(buff, offset); offset += 4;
const count = readUInt32BE(buff, offset); offset += 4;
let tokens: Uint32Array[] = [];
for (let i = 0; i < count; i++) {
const byteCount = readUInt32BE(buff, offset); offset += 4;
tokens.push(view32.subarray(offset / 4, offset / 4 + byteCount / 4));
offset += byteCount;
}
result.push(new MultilineTokens(startLineNumber, tokens));
return offset;
}
public serializeSize(): number {
let result = 0;
result += 4; // 4 bytes for the start line number
result += 4; // 4 bytes for the line count
for (let i = 0; i < this.tokens.length; i++) {
const lineTokens = this.tokens[i];
if (!(lineTokens instanceof Uint32Array)) {
throw new Error(`Not supported!`);
}
result += 4; // 4 bytes for the byte count
result += lineTokens.byteLength;
}
return result;
}
public serialize(destination: Uint8Array, offset: number): number {
writeUInt32BE(destination, this.startLineNumber, offset); offset += 4;
writeUInt32BE(destination, this.tokens.length, offset); offset += 4;
for (let i = 0; i < this.tokens.length; i++) {
const lineTokens = this.tokens[i];
if (!(lineTokens instanceof Uint32Array)) {
throw new Error(`Not supported!`);
}
writeUInt32BE(destination, lineTokens.byteLength, offset); offset += 4;
destination.set(new Uint8Array(lineTokens.buffer), offset); offset += lineTokens.byteLength;
}
return offset;
}
public applyEdit(range: IRange, text: string): void {
const [eolCount, firstLineLength] = countEOL(text);
this._acceptDeleteRange(range);
this._acceptInsertText(new Position(range.startLineNumber, range.startColumn), eolCount, firstLineLength);
}
private _acceptDeleteRange(range: IRange): void {
if (range.startLineNumber === range.endLineNumber && range.startColumn === range.endColumn) {
// Nothing to delete
return;
}
const firstLineIndex = range.startLineNumber - this.startLineNumber;
const lastLineIndex = range.endLineNumber - this.startLineNumber;
if (lastLineIndex < 0) {
// this deletion occurs entirely before this block, so we only need to adjust line numbers
const deletedLinesCount = lastLineIndex - firstLineIndex;
this.startLineNumber -= deletedLinesCount;
return;
}
if (firstLineIndex >= this.tokens.length) {
// this deletion occurs entirely after this block, so there is nothing to do
return;
}
if (firstLineIndex < 0 && lastLineIndex >= this.tokens.length) {
// this deletion completely encompasses this block
this.startLineNumber = 0;
this.tokens = [];
}
if (firstLineIndex === lastLineIndex) {
// a delete on a single line
this.tokens[firstLineIndex] = TokensStore._delete(this.tokens[firstLineIndex], range.startColumn - 1, range.endColumn - 1);
return;
}
if (firstLineIndex >= 0) {
// The first line survives
this.tokens[firstLineIndex] = TokensStore._deleteEnding(this.tokens[firstLineIndex], range.startColumn - 1);
if (lastLineIndex < this.tokens.length) {
// The last line survives
const lastLineTokens = TokensStore._deleteBeginning(this.tokens[lastLineIndex], range.endColumn - 1);
// Take remaining text on last line and append it to remaining text on first line
this.tokens[firstLineIndex] = TokensStore._append(this.tokens[firstLineIndex], lastLineTokens);
// Delete middle lines
this.tokens.splice(firstLineIndex + 1, lastLineIndex - firstLineIndex);
} else {
// The last line does not survive
// Take remaining text on last line and append it to remaining text on first line
this.tokens[firstLineIndex] = TokensStore._append(this.tokens[firstLineIndex], null);
// Delete lines
this.tokens = this.tokens.slice(0, firstLineIndex + 1);
}
} else {
// The first line does not survive
const deletedBefore = -firstLineIndex;
this.startLineNumber -= deletedBefore;
// Remove beginning from last line
this.tokens[lastLineIndex] = TokensStore._deleteBeginning(this.tokens[lastLineIndex], range.endColumn - 1);
// Delete lines
this.tokens = this.tokens.slice(lastLineIndex);
}
}
private _acceptInsertText(position: Position, eolCount: number, firstLineLength: number): void {
if (eolCount === 0 && firstLineLength === 0) {
// Nothing to insert
return;
}
const lineIndex = position.lineNumber - this.startLineNumber;
if (lineIndex < 0) {
// this insertion occurs before this block, so we only need to adjust line numbers
this.startLineNumber += eolCount;
return;
}
if (lineIndex >= this.tokens.length) {
// this insertion occurs after this block, so there is nothing to do
return;
}
if (eolCount === 0) {
// Inserting text on one line
this.tokens[lineIndex] = TokensStore._insert(this.tokens[lineIndex], position.column - 1, firstLineLength);
return;
}
this.tokens[lineIndex] = TokensStore._deleteEnding(this.tokens[lineIndex], position.column - 1);
this.tokens[lineIndex] = TokensStore._insert(this.tokens[lineIndex], position.column - 1, firstLineLength);
this._insertLines(position.lineNumber, eolCount);
}
private _insertLines(insertIndex: number, insertCount: number): void {
if (insertCount === 0) {
return;
}
let lineTokens: (Uint32Array | ArrayBuffer | null)[] = [];
for (let i = 0; i < insertCount; i++) {
lineTokens[i] = null;
}
this.tokens = arrays.arrayInsert(this.tokens, insertIndex, lineTokens);
}
}
function toUint32Array(arr: Uint32Array | ArrayBuffer): Uint32Array {
if (arr instanceof Uint32Array) {
return arr;
} else {
return new Uint32Array(arr);
} }
} }
export class TokensStore { export class TokensStore {
private _lineTokens: (ArrayBuffer | null)[]; private _lineTokens: (Uint32Array | ArrayBuffer | null)[];
private _len: number; private _len: number;
constructor() { constructor() {
@@ -69,13 +304,13 @@ export class TokensStore {
} }
public getTokens(topLevelLanguageId: LanguageId, lineIndex: number, lineText: string): LineTokens { public getTokens(topLevelLanguageId: LanguageId, lineIndex: number, lineText: string): LineTokens {
let rawLineTokens: ArrayBuffer | null = null; let rawLineTokens: Uint32Array | ArrayBuffer | null = null;
if (lineIndex < this._len) { if (lineIndex < this._len) {
rawLineTokens = this._lineTokens[lineIndex]; rawLineTokens = this._lineTokens[lineIndex];
} }
if (rawLineTokens !== null && rawLineTokens !== EMPTY_LINE_TOKENS) { if (rawLineTokens !== null && rawLineTokens !== EMPTY_LINE_TOKENS) {
return new LineTokens(new Uint32Array(rawLineTokens), lineText); return new LineTokens(toUint32Array(rawLineTokens), lineText);
} }
let lineTokens = new Uint32Array(2); let lineTokens = new Uint32Array(2);
@@ -84,7 +319,10 @@ export class TokensStore {
return new LineTokens(lineTokens, lineText); return new LineTokens(lineTokens, lineText);
} }
private static _massageTokens(topLevelLanguageId: LanguageId, lineTextLength: number, tokens: Uint32Array): ArrayBuffer { private static _massageTokens(topLevelLanguageId: LanguageId, lineTextLength: number, _tokens: Uint32Array | ArrayBuffer | null): Uint32Array | ArrayBuffer {
const tokens = _tokens ? toUint32Array(_tokens) : null;
if (lineTextLength === 0) { if (lineTextLength === 0) {
let hasDifferentLanguageId = false; let hasDifferentLanguageId = false;
if (tokens && tokens.length > 1) { if (tokens && tokens.length > 1) {
@@ -97,12 +335,20 @@ export class TokensStore {
} }
if (!tokens || tokens.length === 0) { if (!tokens || tokens.length === 0) {
tokens = new Uint32Array(2); const tokens = new Uint32Array(2);
tokens[0] = lineTextLength; tokens[0] = lineTextLength;
tokens[1] = getDefaultMetadata(topLevelLanguageId); tokens[1] = getDefaultMetadata(topLevelLanguageId);
return tokens.buffer;
} }
return tokens.buffer; // Ensure the last token covers the end of the text
tokens[tokens.length - 2] = lineTextLength;
if (tokens.byteOffset === 0 && tokens.byteLength === tokens.buffer.byteLength) {
// Store directly the ArrayBuffer pointer to save an object
return tokens.buffer;
}
return tokens;
} }
private _ensureLine(lineIndex: number): void { private _ensureLine(lineIndex: number): void {
@@ -116,6 +362,9 @@ export class TokensStore {
if (deleteCount === 0) { if (deleteCount === 0) {
return; return;
} }
if (start + deleteCount > this._len) {
deleteCount = this._len - start;
}
this._lineTokens.splice(start, deleteCount); this._lineTokens.splice(start, deleteCount);
this._len -= deleteCount; this._len -= deleteCount;
} }
@@ -124,7 +373,7 @@ export class TokensStore {
if (insertCount === 0) { if (insertCount === 0) {
return; return;
} }
let lineTokens: (ArrayBuffer | null)[] = []; let lineTokens: (Uint32Array | ArrayBuffer | null)[] = [];
for (let i = 0; i < insertCount; i++) { for (let i = 0; i < insertCount; i++) {
lineTokens[i] = null; lineTokens[i] = null;
} }
@@ -132,7 +381,7 @@ export class TokensStore {
this._len += insertCount; this._len += insertCount;
} }
public setTokens(topLevelLanguageId: LanguageId, lineIndex: number, lineTextLength: number, _tokens: Uint32Array): void { public setTokens(topLevelLanguageId: LanguageId, lineIndex: number, lineTextLength: number, _tokens: Uint32Array | ArrayBuffer | null): void {
const tokens = TokensStore._massageTokens(topLevelLanguageId, lineTextLength, _tokens); const tokens = TokensStore._massageTokens(topLevelLanguageId, lineTextLength, _tokens);
this._ensureLine(lineIndex); this._ensureLine(lineIndex);
this._lineTokens[lineIndex] = tokens; this._lineTokens[lineIndex] = tokens;
@@ -140,7 +389,7 @@ export class TokensStore {
//#region Editing //#region Editing
public applyEdits(range: IRange, eolCount: number, firstLineLength: number): void { public acceptEdit(range: IRange, eolCount: number, firstLineLength: number): void {
this._acceptDeleteRange(range); this._acceptDeleteRange(range);
this._acceptInsertText(new Position(range.startLineNumber, range.startColumn), eolCount, firstLineLength); this._acceptInsertText(new Position(range.startLineNumber, range.startColumn), eolCount, firstLineLength);
} }
@@ -165,7 +414,7 @@ export class TokensStore {
this._lineTokens[firstLineIndex] = TokensStore._deleteEnding(this._lineTokens[firstLineIndex], range.startColumn - 1); this._lineTokens[firstLineIndex] = TokensStore._deleteEnding(this._lineTokens[firstLineIndex], range.startColumn - 1);
const lastLineIndex = range.endLineNumber - 1; const lastLineIndex = range.endLineNumber - 1;
let lastLineTokens: ArrayBuffer | null = null; let lastLineTokens: Uint32Array | ArrayBuffer | null = null;
if (lastLineIndex < this._len) { if (lastLineIndex < this._len) {
lastLineTokens = TokensStore._deleteBeginning(this._lineTokens[lastLineIndex], range.endColumn - 1); lastLineTokens = TokensStore._deleteBeginning(this._lineTokens[lastLineIndex], range.endColumn - 1);
} }
@@ -201,29 +450,29 @@ export class TokensStore {
this._insertLines(position.lineNumber, eolCount); this._insertLines(position.lineNumber, eolCount);
} }
private static _deleteBeginning(lineTokens: ArrayBuffer | null, toChIndex: number): ArrayBuffer | null { public static _deleteBeginning(lineTokens: Uint32Array | ArrayBuffer | null, toChIndex: number): Uint32Array | ArrayBuffer | null {
if (lineTokens === null || lineTokens === EMPTY_LINE_TOKENS) { if (lineTokens === null || lineTokens === EMPTY_LINE_TOKENS) {
return lineTokens; return lineTokens;
} }
return TokensStore._delete(lineTokens, 0, toChIndex); return TokensStore._delete(lineTokens, 0, toChIndex);
} }
private static _deleteEnding(lineTokens: ArrayBuffer | null, fromChIndex: number): ArrayBuffer | null { public static _deleteEnding(lineTokens: Uint32Array | ArrayBuffer | null, fromChIndex: number): Uint32Array | ArrayBuffer | null {
if (lineTokens === null || lineTokens === EMPTY_LINE_TOKENS) { if (lineTokens === null || lineTokens === EMPTY_LINE_TOKENS) {
return lineTokens; return lineTokens;
} }
const tokens = new Uint32Array(lineTokens); const tokens = toUint32Array(lineTokens);
const lineTextLength = tokens[tokens.length - 2]; const lineTextLength = tokens[tokens.length - 2];
return TokensStore._delete(lineTokens, fromChIndex, lineTextLength); return TokensStore._delete(lineTokens, fromChIndex, lineTextLength);
} }
private static _delete(lineTokens: ArrayBuffer | null, fromChIndex: number, toChIndex: number): ArrayBuffer | null { public static _delete(lineTokens: Uint32Array | ArrayBuffer | null, fromChIndex: number, toChIndex: number): Uint32Array | ArrayBuffer | null {
if (lineTokens === null || lineTokens === EMPTY_LINE_TOKENS || fromChIndex === toChIndex) { if (lineTokens === null || lineTokens === EMPTY_LINE_TOKENS || fromChIndex === toChIndex) {
return lineTokens; return lineTokens;
} }
const tokens = new Uint32Array(lineTokens); const tokens = toUint32Array(lineTokens);
const tokensCount = (tokens.length >>> 1); const tokensCount = (tokens.length >>> 1);
// special case: deleting everything // special case: deleting everything
@@ -275,7 +524,7 @@ export class TokensStore {
return tmp.buffer; return tmp.buffer;
} }
private static _append(lineTokens: ArrayBuffer | null, _otherTokens: ArrayBuffer | null): ArrayBuffer | null { public static _append(lineTokens: Uint32Array | ArrayBuffer | null, _otherTokens: Uint32Array | ArrayBuffer | null): Uint32Array | ArrayBuffer | null {
if (_otherTokens === EMPTY_LINE_TOKENS) { if (_otherTokens === EMPTY_LINE_TOKENS) {
return lineTokens; return lineTokens;
} }
@@ -289,8 +538,8 @@ export class TokensStore {
// cannot determine combined line length... // cannot determine combined line length...
return null; return null;
} }
const myTokens = new Uint32Array(lineTokens); const myTokens = toUint32Array(lineTokens);
const otherTokens = new Uint32Array(_otherTokens); const otherTokens = toUint32Array(_otherTokens);
const otherTokensCount = (otherTokens.length >>> 1); const otherTokensCount = (otherTokens.length >>> 1);
let result = new Uint32Array(myTokens.length + otherTokens.length); let result = new Uint32Array(myTokens.length + otherTokens.length);
@@ -304,13 +553,13 @@ export class TokensStore {
return result.buffer; return result.buffer;
} }
private static _insert(lineTokens: ArrayBuffer | null, chIndex: number, textLength: number): ArrayBuffer | null { public static _insert(lineTokens: Uint32Array | ArrayBuffer | null, chIndex: number, textLength: number): Uint32Array | ArrayBuffer | null {
if (lineTokens === null || lineTokens === EMPTY_LINE_TOKENS) { if (lineTokens === null || lineTokens === EMPTY_LINE_TOKENS) {
// nothing to do // nothing to do
return lineTokens; return lineTokens;
} }
const tokens = new Uint32Array(lineTokens); const tokens = toUint32Array(lineTokens);
const tokensCount = (tokens.length >>> 1); const tokensCount = (tokens.length >>> 1);
let fromTokenIndex = LineTokens.findIndexInTokensArray(tokens, chIndex); let fromTokenIndex = LineTokens.findIndexInTokensArray(tokens, chIndex);
@@ -0,0 +1,304 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { StandardTokenType } from 'vs/editor/common/modes';
import { CharCode } from 'vs/base/common/charCode';
class ParserContext {
public readonly text: string;
public readonly len: number;
public readonly tokens: number[];
public pos: number;
private currentTokenStartOffset: number;
private currentTokenType: StandardTokenType;
constructor(text: string) {
this.text = text;
this.len = this.text.length;
this.tokens = [];
this.pos = 0;
this.currentTokenStartOffset = 0;
this.currentTokenType = StandardTokenType.Other;
}
private _safeCharCodeAt(index: number): number {
if (index >= this.len) {
return CharCode.Null;
}
return this.text.charCodeAt(index);
}
peek(distance: number = 0): number {
return this._safeCharCodeAt(this.pos + distance);
}
next(): number {
const result = this._safeCharCodeAt(this.pos);
this.pos++;
return result;
}
advance(distance: number): void {
this.pos += distance;
}
eof(): boolean {
return this.pos >= this.len;
}
beginToken(tokenType: StandardTokenType, deltaPos: number = 0): void {
this.currentTokenStartOffset = this.pos + deltaPos;
this.currentTokenType = tokenType;
}
endToken(deltaPos: number = 0): void {
const length = this.pos + deltaPos - this.currentTokenStartOffset;
// check if it is touching previous token
if (this.tokens.length > 0) {
const previousStartOffset = this.tokens[this.tokens.length - 3];
const previousLength = this.tokens[this.tokens.length - 2];
const previousTokenType = this.tokens[this.tokens.length - 1];
const previousEndOffset = previousStartOffset + previousLength;
if (this.currentTokenStartOffset === previousEndOffset && previousTokenType === this.currentTokenType) {
// extend previous token
this.tokens[this.tokens.length - 2] += length;
return;
}
}
this.tokens.push(this.currentTokenStartOffset, length, this.currentTokenType);
}
}
export function parse(text: string): number[] {
const ctx = new ParserContext(text);
while (!ctx.eof()) {
parseRoot(ctx);
}
return ctx.tokens;
}
function parseRoot(ctx: ParserContext): void {
let curlyCount = 0;
while (!ctx.eof()) {
const ch = ctx.peek();
switch (ch) {
case CharCode.SingleQuote:
parseSimpleString(ctx, CharCode.SingleQuote);
break;
case CharCode.DoubleQuote:
parseSimpleString(ctx, CharCode.DoubleQuote);
break;
case CharCode.BackTick:
parseInterpolatedString(ctx);
break;
case CharCode.Slash:
parseSlash(ctx);
break;
case CharCode.OpenCurlyBrace:
ctx.advance(1);
curlyCount++;
break;
case CharCode.CloseCurlyBrace:
ctx.advance(1);
curlyCount--;
if (curlyCount < 0) {
return;
}
break;
default:
ctx.advance(1);
}
}
}
function parseSimpleString(ctx: ParserContext, closingQuote: number): void {
ctx.beginToken(StandardTokenType.String);
// skip the opening quote
ctx.advance(1);
while (!ctx.eof()) {
const ch = ctx.next();
if (ch === CharCode.Backslash) {
// skip \r\n or any other character following a backslash
const advanceCount = (ctx.peek() === CharCode.CarriageReturn && ctx.peek(1) === CharCode.LineFeed ? 2 : 1);
ctx.advance(advanceCount);
} else if (ch === closingQuote) {
// hit end quote, so stop
break;
}
}
ctx.endToken();
}
function parseInterpolatedString(ctx: ParserContext): void {
ctx.beginToken(StandardTokenType.String);
// skip the opening quote
ctx.advance(1);
while (!ctx.eof()) {
const ch = ctx.next();
if (ch === CharCode.Backslash) {
// skip \r\n or any other character following a backslash
const advanceCount = (ctx.peek() === CharCode.CarriageReturn && ctx.peek(1) === CharCode.LineFeed ? 2 : 1);
ctx.advance(advanceCount);
} else if (ch === CharCode.BackTick) {
// hit end quote, so stop
break;
} else if (ch === CharCode.DollarSign) {
if (ctx.peek() === CharCode.OpenCurlyBrace) {
ctx.advance(1);
ctx.endToken();
parseRoot(ctx);
ctx.beginToken(StandardTokenType.String, -1);
}
}
}
ctx.endToken();
}
function parseSlash(ctx: ParserContext): void {
const nextCh = ctx.peek(1);
if (nextCh === CharCode.Asterisk) {
parseMultiLineComment(ctx);
return;
}
if (nextCh === CharCode.Slash) {
parseSingleLineComment(ctx);
return;
}
if (tryParseRegex(ctx)) {
return;
}
ctx.advance(1);
}
function tryParseRegex(ctx: ParserContext): boolean {
// See https://www.ecma-international.org/ecma-262/10.0/index.html#prod-RegularExpressionLiteral
// TODO: avoid regex...
let contentBefore = ctx.text.substr(ctx.pos - 100, 100);
if (/[a-zA-Z0-9](\s*)$/.test(contentBefore)) {
// Cannot start after an identifier
return false;
}
let pos = 0;
let len = ctx.len - ctx.pos;
let inClass = false;
// skip /
pos++;
while (pos < len) {
const ch = ctx.peek(pos++);
if (ch === CharCode.CarriageReturn || ch === CharCode.LineFeed) {
return false;
}
if (ch === CharCode.Backslash) {
const nextCh = ctx.peek();
if (nextCh === CharCode.CarriageReturn || nextCh === CharCode.LineFeed) {
return false;
}
// skip next character
pos++;
continue;
}
if (inClass) {
if (ch === CharCode.CloseSquareBracket) {
inClass = false;
continue;
}
} else {
if (ch === CharCode.Slash) {
// cannot be directly followed by a /
if (ctx.peek(pos) === CharCode.Slash) {
return false;
}
// consume flags
do {
let nextCh = ctx.peek(pos);
if (nextCh >= CharCode.a && nextCh <= CharCode.z) {
pos++;
continue;
} else {
break;
}
} while (true);
// TODO: avoid regex...
if (/^(\s*)(\.|;|\/|,|\)|\]|\}|$)/.test(ctx.text.substr(ctx.pos + pos))) {
// Must be followed by an operator of kinds
ctx.beginToken(StandardTokenType.RegEx);
ctx.advance(pos);
ctx.endToken();
return true;
}
return false;
}
if (ch === CharCode.OpenSquareBracket) {
inClass = true;
continue;
}
}
}
return false;
}
function parseMultiLineComment(ctx: ParserContext): void {
ctx.beginToken(StandardTokenType.Comment);
// skip the /*
ctx.advance(2);
while (!ctx.eof()) {
const ch = ctx.next();
if (ch === CharCode.Asterisk) {
if (ctx.peek() === CharCode.Slash) {
ctx.advance(1);
break;
}
}
}
ctx.endToken();
}
function parseSingleLineComment(ctx: ParserContext): void {
ctx.beginToken(StandardTokenType.Comment);
// skip the //
ctx.advance(2);
while (!ctx.eof()) {
const ch = ctx.next();
if (ch === CharCode.CarriageReturn || ch === CharCode.LineFeed) {
break;
}
}
ctx.endToken();
}
+2 -2
View File
@@ -485,7 +485,7 @@ export class FindModelBoundToEditorModel {
let resultText: string; let resultText: string;
const preserveCase = this._state.preserveCase; const preserveCase = this._state.preserveCase;
if (replacePattern.hasReplacementPatterns) { if (replacePattern.hasReplacementPatterns || preserveCase) {
resultText = modelText.replace(searchRegex, function () { resultText = modelText.replace(searchRegex, function () {
return replacePattern.buildReplaceString(<string[]><any>arguments, preserveCase); return replacePattern.buildReplaceString(<string[]><any>arguments, preserveCase);
}); });
@@ -500,7 +500,7 @@ export class FindModelBoundToEditorModel {
private _regularReplaceAll(findScope: Range | null): void { private _regularReplaceAll(findScope: Range | null): void {
const replacePattern = this._getReplacePattern(); const replacePattern = this._getReplacePattern();
// Get all the ranges (even more than the highlighted ones) // Get all the ranges (even more than the highlighted ones)
let matches = this._findMatches(findScope, replacePattern.hasReplacementPatterns, Constants.MAX_SAFE_SMALL_INTEGER); let matches = this._findMatches(findScope, replacePattern.hasReplacementPatterns || this._state.preserveCase, Constants.MAX_SAFE_SMALL_INTEGER);
let replaceStrings: string[] = []; let replaceStrings: string[] = [];
for (let i = 0, len = matches.length; i < len; i++) { for (let i = 0, len = matches.length; i < len; i++) {
+1 -1
View File
@@ -929,7 +929,7 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas
})); }));
this._preserveCase = this._register(new Checkbox({ this._preserveCase = this._register(new Checkbox({
actionClassName: 'monaco-case-sensitive', actionClassName: 'monaco-preserve-case',
title: NLS_PRESERVE_CASE_LABEL, title: NLS_PRESERVE_CASE_LABEL,
isChecked: false, isChecked: false,
})); }));
@@ -1947,6 +1947,42 @@ suite('FindModel', () => {
findState.dispose(); findState.dispose();
}); });
findTest('replaceAll preserving case', (editor, cursor) => {
let findState = new FindReplaceState();
findState.change({ searchString: 'hello', replaceString: 'goodbye', isRegex: false, matchCase: false, preserveCase: true }, false);
let findModel = new FindModelBoundToEditorModel(editor, findState);
assertFindState(
editor,
[1, 1, 1, 1],
null,
[
[6, 14, 6, 19],
[6, 27, 6, 32],
[7, 14, 7, 19],
[8, 14, 8, 19],
[9, 14, 9, 19],
]
);
findModel.replaceAll();
assert.equal(editor.getModel()!.getLineContent(6), ' cout << "goodbye world, Goodbye!" << endl;');
assert.equal(editor.getModel()!.getLineContent(7), ' cout << "goodbye world again" << endl;');
assert.equal(editor.getModel()!.getLineContent(8), ' cout << "Goodbye world again" << endl;');
assert.equal(editor.getModel()!.getLineContent(9), ' cout << "goodbyeworld again" << endl;');
assertFindState(
editor,
[1, 1, 1, 1],
null,
[]
);
findModel.dispose();
findState.dispose();
});
findTest('issue #18711 replaceAll with empty string', (editor, cursor) => { findTest('issue #18711 replaceAll with empty string', (editor, cursor) => {
let findState = new FindReplaceState(); let findState = new FindReplaceState();
findState.change({ searchString: 'hello', replaceString: '', wholeWord: true }, false); findState.change({ searchString: 'hello', replaceString: '', wholeWord: true }, false);
@@ -27,6 +27,7 @@ import { CommandsRegistry, ICommandHandler } from 'vs/platform/commands/common/c
import { URI } from 'vs/base/common/uri'; import { URI } from 'vs/base/common/uri';
import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService'; import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService';
import { CancellationToken } from 'vs/base/common/cancellation'; import { CancellationToken } from 'vs/base/common/cancellation';
import { coalesce, flatten } from 'vs/base/common/arrays';
export const defaultReferenceSearchOptions: RequestOptions = { export const defaultReferenceSearchOptions: RequestOptions = {
getMetaTitle(model) { getMetaTitle(model) {
@@ -287,15 +288,7 @@ export function provideReferences(model: ITextModel, position: Position, token:
}); });
}); });
return Promise.all(promises).then(references => { return Promise.all(promises).then(references => flatten(coalesce(references)));
let result: Location[] = [];
for (let ref of references) {
if (ref) {
result.push(...ref);
}
}
return result;
});
} }
registerDefaultLanguageCommand('_executeReferenceProvider', (model, position) => provideReferences(model, position, CancellationToken.None)); registerDefaultLanguageCommand('_executeReferenceProvider', (model, position) => provideReferences(model, position, CancellationToken.None));
@@ -7,8 +7,6 @@ import * as nls from 'vs/nls';
import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
import { EditorAction, ServicesAccessor, registerEditorAction } from 'vs/editor/browser/editorExtensions'; import { EditorAction, ServicesAccessor, registerEditorAction } from 'vs/editor/browser/editorExtensions';
import { StopWatch } from 'vs/base/common/stopwatch'; import { StopWatch } from 'vs/base/common/stopwatch';
import { StandardTokenType } from 'vs/editor/common/modes';
import { ITextModel } from 'vs/editor/common/model';
class ForceRetokenizeAction extends EditorAction { class ForceRetokenizeAction extends EditorAction {
constructor() { constructor() {
@@ -31,51 +29,6 @@ class ForceRetokenizeAction extends EditorAction {
sw.stop(); sw.stop();
console.log(`tokenization took ${sw.elapsed()}`); console.log(`tokenization took ${sw.elapsed()}`);
if (!true) {
extractTokenTypes(model);
}
}
}
function extractTokenTypes(model: ITextModel): void {
const eolLength = model.getEOL().length;
let result: number[] = [];
let resultLen: number = 0;
let lastTokenType: StandardTokenType = StandardTokenType.Other;
let lastEndOffset: number = 0;
let offset = 0;
for (let lineNumber = 1, lineCount = model.getLineCount(); lineNumber <= lineCount; lineNumber++) {
const lineTokens = model.getLineTokens(lineNumber);
for (let i = 0, len = lineTokens.getCount(); i < len; i++) {
const tokenType = lineTokens.getStandardTokenType(i);
if (tokenType === StandardTokenType.Other) {
continue;
}
const startOffset = offset + lineTokens.getStartOffset(i);
const endOffset = offset + lineTokens.getEndOffset(i);
const length = endOffset - startOffset;
if (length === 0) {
continue;
}
if (lastTokenType === tokenType && lastEndOffset === startOffset) {
result[resultLen - 2] += length;
lastEndOffset += length;
continue;
}
result[resultLen++] = startOffset; // - lastEndOffset
result[resultLen++] = length;
result[resultLen++] = tokenType;
lastTokenType = tokenType;
lastEndOffset = endOffset;
}
offset += lineTokens.getLineContent().length + eolLength;
} }
} }
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 25 KiB

@@ -857,6 +857,11 @@ export class MonarchTokenizer implements modes.ITokenizationSupport {
return null; return null;
} }
if (mimetypeOrModeId === this._modeId) {
// embedding myself...
return mimetypeOrModeId;
}
let modeId = this._modeService.getModeId(mimetypeOrModeId); let modeId = this._modeService.getModeId(mimetypeOrModeId);
if (modeId) { if (modeId) {
@@ -0,0 +1,71 @@
///
/* tslint:disable */
const x01 = "string";
/// ^^^^^^^^ string
const x02 = '\'';
/// ^^^^ string
const x03 = '\n\'\t';
/// ^^^^^^^^ string
const x04 = 'this is\
/// ^^^^^^^^^ string\
a multiline string';
/// <------------------- string
const x05 = x01;// just some text
/// ^^^^^^^^^^^^^^^^^ comment
const x06 = x05;/* multi
/// ^^^^^^^^ comment
line *comment */
/// <---------------- comment
const x07 = 4 / 5;
const x08 = `howdy`;
/// ^^^^^^^ string
const x09 = `\'\"\``;
/// ^^^^^^^^ string
const x10 = `$[]`;
/// ^^^^^ string
const x11 = `${x07 +/**/3}px`;
/// ^^^ string
/// ^^^^ comment
/// ^^^^ string
const x12 = `${x07 + (function () { return 5; })()/**/}px`;
/// ^^^ string
/// ^^^^ comment
/// ^^^^ string
const x13 = /([\w\-]+)?(#([\w\-]+))?((.([\w\-]+))*)/;
/// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ regex
const x14 = /\./g;
/// ^^^^^ regex
const x15 = Math.abs(x07) / x07; // speed
/// ^^^^^^^^ comment
const x16 = / x07; /.test('3');
/// ^^^^^^^^ regex
/// ^^^ string
const x17 = `.dialog-modal-block${true ? '.dimmed' : ''}`;
/// ^^^^^^^^^^^^^^^^^^^^^^ string
/// ^^^^^^^^^ string
/// ^^^^ string
const x18 = Math.min((14 <= 0.5 ? 123 / (2 * 1) : ''.length / (2 - (2 * 1))), 1);
/// ^^ string
const x19 = `${3 / '5'.length} km/h)`;
/// ^^^ string
/// ^^^ string
/// ^^^^^^^ string
@@ -0,0 +1,139 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as assert from 'assert';
import { StandardTokenType } from 'vs/editor/common/modes';
import * as fs from 'fs';
import { getPathFromAmdModule } from 'vs/base/common/amd';
import { parse } from 'vs/editor/common/modes/tokenization/typescript';
import { toStandardTokenType } from 'vs/editor/common/modes/supports/tokenization';
interface IParseFunc {
(text: string): number[];
}
interface IAssertion {
testLineNumber: number;
startOffset: number;
length: number;
tokenType: StandardTokenType;
}
interface ITest {
content: string;
assertions: IAssertion[];
}
function parseTest(fileName: string): ITest {
interface ILineWithAssertions {
line: string;
assertions: ILineAssertion[];
}
interface ILineAssertion {
testLineNumber: number;
startOffset: number;
length: number;
expectedTokenType: StandardTokenType;
}
const testContents = fs.readFileSync(fileName).toString();
const lines = testContents.split(/\r\n|\n/);
const magicToken = lines[0];
let currentElement: ILineWithAssertions = {
line: lines[1],
assertions: []
};
let parsedTest: ILineWithAssertions[] = [];
for (let i = 2; i < lines.length; i++) {
let line = lines[i];
if (line.substr(0, magicToken.length) === magicToken) {
// this is an assertion line
let m1 = line.substr(magicToken.length).match(/^( +)([\^]+) (\w+)\\?$/);
if (m1) {
currentElement.assertions.push({
testLineNumber: i + 1,
startOffset: magicToken.length + m1[1].length,
length: m1[2].length,
expectedTokenType: toStandardTokenType(m1[3])
});
} else {
let m2 = line.substr(magicToken.length).match(/^( +)<(-+) (\w+)\\?$/);
if (m2) {
currentElement.assertions.push({
testLineNumber: i + 1,
startOffset: 0,
length: m2[2].length,
expectedTokenType: toStandardTokenType(m2[3])
});
} else {
throw new Error(`Invalid test line at line number ${i + 1}.`);
}
}
} else {
// this is a line to be parsed
parsedTest.push(currentElement);
currentElement = {
line: line,
assertions: []
};
}
}
parsedTest.push(currentElement);
let assertions: IAssertion[] = [];
let offset = 0;
for (let i = 0; i < parsedTest.length; i++) {
const parsedTestLine = parsedTest[i];
for (let j = 0; j < parsedTestLine.assertions.length; j++) {
const assertion = parsedTestLine.assertions[j];
assertions.push({
testLineNumber: assertion.testLineNumber,
startOffset: offset + assertion.startOffset,
length: assertion.length,
tokenType: assertion.expectedTokenType
});
}
offset += parsedTestLine.line.length + 1;
}
let content: string = parsedTest.map(parsedTestLine => parsedTestLine.line).join('\n');
return { content, assertions };
}
function executeTest(fileName: string, parseFunc: IParseFunc): void {
const { content, assertions } = parseTest(fileName);
const actual = parseFunc(content);
let actualIndex = 0, actualCount = actual.length / 3;
for (let i = 0; i < assertions.length; i++) {
const assertion = assertions[i];
while (actualIndex < actualCount && actual[3 * actualIndex] + actual[3 * actualIndex + 1] <= assertion.startOffset) {
actualIndex++;
}
assert.ok(
actual[3 * actualIndex] <= assertion.startOffset,
`Line ${assertion.testLineNumber} : startOffset : ${actual[3 * actualIndex]} <= ${assertion.startOffset}`
);
assert.ok(
actual[3 * actualIndex] + actual[3 * actualIndex + 1] >= assertion.startOffset + assertion.length,
`Line ${assertion.testLineNumber} : length : ${actual[3 * actualIndex]} + ${actual[3 * actualIndex + 1]} >= ${assertion.startOffset} + ${assertion.length}.`
);
assert.equal(
actual[3 * actualIndex + 2],
assertion.tokenType,
`Line ${assertion.testLineNumber} : tokenType`);
}
}
suite('Classification', () => {
test('TypeScript', () => {
executeTest(getPathFromAmdModule(require, 'vs/editor/test/node/classification/typescript-test.ts').replace(/\bout\b/, 'src'), parse);
});
});
@@ -21,10 +21,10 @@ export const enum ContextKeyExprType {
} }
export interface IContextKeyExprMapper { export interface IContextKeyExprMapper {
mapDefined(key: string): ContextKeyDefinedExpr; mapDefined(key: string): ContextKeyExpr;
mapNot(key: string): ContextKeyNotExpr; mapNot(key: string): ContextKeyExpr;
mapEquals(key: string, value: any): ContextKeyEqualsExpr; mapEquals(key: string, value: any): ContextKeyExpr;
mapNotEquals(key: string, value: any): ContextKeyNotEqualsExpr; mapNotEquals(key: string, value: any): ContextKeyExpr;
mapRegex(key: string, regexp: RegExp | null): ContextKeyRegexExpr; mapRegex(key: string, regexp: RegExp | null): ContextKeyRegexExpr;
} }
@@ -217,7 +217,7 @@ function cmp(a: ContextKeyExpr, b: ContextKeyExpr): number {
} }
export class ContextKeyDefinedExpr implements ContextKeyExpr { export class ContextKeyDefinedExpr implements ContextKeyExpr {
public static create(key: string): ContextKeyExpr { public static create(key: string): ContextKeyDefinedExpr {
return new ContextKeyDefinedExpr(key); return new ContextKeyDefinedExpr(key);
} }
@@ -451,7 +451,7 @@ export class ContextKeyNotExpr implements ContextKeyExpr {
export class ContextKeyRegexExpr implements ContextKeyExpr { export class ContextKeyRegexExpr implements ContextKeyExpr {
public static create(key: string, regexp: RegExp | null): ContextKeyExpr { public static create(key: string, regexp: RegExp | null): ContextKeyRegexExpr {
return new ContextKeyRegexExpr(key, regexp); return new ContextKeyRegexExpr(key, regexp);
} }
+24 -3
View File
@@ -10,7 +10,28 @@ export class SignService implements ISignService {
_serviceBrand: ServiceIdentifier<ISignService>; _serviceBrand: ServiceIdentifier<ISignService>;
async sign(value: string): Promise<string> { private readonly _tkn: string | null;
return Promise.resolve(document.getElementById('vscode-remote-connection-token')!.getAttribute('data-settings')!);
constructor(token: string | undefined) {
if (typeof token !== 'undefined') {
this._tkn = token;
} else {
this._tkn = SignService._readTokenFromURL();
}
} }
}
private static _readTokenFromURL(): string | null {
if (!document.location.hash) {
return null;
}
const m = document.location.hash.match(/[#&]tkn=([^&]+)/);
if (!m) {
return null;
}
return m[1];
}
async sign(value: string): Promise<string> {
return Promise.resolve(this._tkn || '');
}
}
+2 -2
View File
@@ -258,7 +258,7 @@ export const defaultListStyles: IColorMapping = {
listFilterWidgetOutline: listFilterWidgetOutline, listFilterWidgetOutline: listFilterWidgetOutline,
listFilterWidgetNoMatchesOutline: listFilterWidgetNoMatchesOutline, listFilterWidgetNoMatchesOutline: listFilterWidgetNoMatchesOutline,
listMatchesShadow: widgetShadow, listMatchesShadow: widgetShadow,
treeIndentGuidesStroke treeIndentGuidesStroke: treeIndentGuidesStroke
}; };
export interface IButtonStyleOverrides extends IStyleOverrides { export interface IButtonStyleOverrides extends IStyleOverrides {
@@ -357,4 +357,4 @@ export const defaultDialogStyles = <IDialogStyleOverrides>{
export function attachDialogStyler(widget: IThemable, themeService: IThemeService, style?: IDialogStyleOverrides): IDisposable { export function attachDialogStyler(widget: IThemable, themeService: IThemeService, style?: IDialogStyleOverrides): IDisposable {
return attachStyler(themeService, { ...defaultDialogStyles, ...style }, widget); return attachStyler(themeService, { ...defaultDialogStyles, ...style }, widget);
} }
+1 -1
View File
@@ -156,7 +156,7 @@ export interface IWindowsService {
openExtensionDevelopmentHostWindow(args: ParsedArgs, env: IProcessEnvironment): Promise<void>; openExtensionDevelopmentHostWindow(args: ParsedArgs, env: IProcessEnvironment): Promise<void>;
getWindows(): Promise<{ id: number; workspace?: IWorkspaceIdentifier; folderUri?: ISingleFolderWorkspaceIdentifier; title: string; filename?: string; }[]>; getWindows(): Promise<{ id: number; workspace?: IWorkspaceIdentifier; folderUri?: ISingleFolderWorkspaceIdentifier; title: string; filename?: string; }[]>;
getWindowCount(): Promise<number>; getWindowCount(): Promise<number>;
log(severity: string, ...messages: string[]): Promise<void>; log(severity: string, args: string[]): Promise<void>;
showItemInFolder(path: URI): Promise<void>; showItemInFolder(path: URI): Promise<void>;
getActiveWindowId(): Promise<number | undefined>; getActiveWindowId(): Promise<number | undefined>;
@@ -226,8 +226,8 @@ export class WindowsService implements IWindowsService {
return this.channel.call('getWindowCount'); return this.channel.call('getWindowCount');
} }
log(severity: string, ...messages: string[]): Promise<void> { log(severity: string, args: string[]): Promise<void> {
return this.channel.call('log', [severity, messages]); return this.channel.call('log', [severity, args]);
} }
showItemInFolder(path: URI): Promise<void> { showItemInFolder(path: URI): Promise<void> {
@@ -334,7 +334,7 @@ export class WindowsService extends Disposable implements IWindowsService, IURLH
return this.windowsMainService.getWindows().length; return this.windowsMainService.getWindows().length;
} }
async log(severity: string, ...messages: string[]): Promise<void> { async log(severity: string, args: string[]): Promise<void> {
let consoleFn = console.log; let consoleFn = console.log;
switch (severity) { switch (severity) {
@@ -349,7 +349,7 @@ export class WindowsService extends Disposable implements IWindowsService, IURLH
break; break;
} }
consoleFn(...messages); consoleFn.call(console, ...args);
} }
async showItemInFolder(resource: URI): Promise<void> { async showItemInFolder(resource: URI): Promise<void> {
+7
View File
@@ -4283,6 +4283,13 @@ declare module 'vscode' {
* instead of fading it out. * instead of fading it out.
*/ */
Unnecessary = 1, Unnecessary = 1,
/**
* Deprecated or obsolete code.
*
* Diagnostics with this tag are rendered with a strike through.
*/
Deprecated = 2,
} }
/** /**
-12
View File
@@ -1305,16 +1305,4 @@ declare module 'vscode' {
//#endregion //#endregion
//#region Deprecated support
export enum DiagnosticTag {
/**
* Deprecated or obsolete code.
*
* Diagnostics with this tag are rendered with a strike through.
*/
Deprecated = 2,
}
//#endregion
} }
@@ -40,7 +40,7 @@ export class MainThreadConsole implements MainThreadConsoleShape {
// Log on main side if running tests from cli // Log on main side if running tests from cli
if (this._isExtensionDevTestFromCli) { 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 // Broadcast to other windows if we are in development mode
@@ -51,21 +51,21 @@ export class TextEditorEdit {
private readonly _document: vscode.TextDocument; private readonly _document: vscode.TextDocument;
private readonly _documentVersionId: number; private readonly _documentVersionId: number;
private _collectedEdits: ITextEditOperation[];
private _setEndOfLine: EndOfLine | undefined;
private readonly _undoStopBefore: boolean; private readonly _undoStopBefore: boolean;
private readonly _undoStopAfter: boolean; private readonly _undoStopAfter: boolean;
private _collectedEdits: ITextEditOperation[] = [];
private _setEndOfLine: EndOfLine | undefined = undefined;
private _finalized: boolean = false;
constructor(document: vscode.TextDocument, options: { undoStopBefore: boolean; undoStopAfter: boolean; }) { constructor(document: vscode.TextDocument, options: { undoStopBefore: boolean; undoStopAfter: boolean; }) {
this._document = document; this._document = document;
this._documentVersionId = document.version; this._documentVersionId = document.version;
this._collectedEdits = [];
this._setEndOfLine = undefined;
this._undoStopBefore = options.undoStopBefore; this._undoStopBefore = options.undoStopBefore;
this._undoStopAfter = options.undoStopAfter; this._undoStopAfter = options.undoStopAfter;
} }
finalize(): IEditData { finalize(): IEditData {
this._finalized = true;
return { return {
documentVersionId: this._documentVersionId, documentVersionId: this._documentVersionId,
edits: this._collectedEdits, edits: this._collectedEdits,
@@ -75,7 +75,14 @@ export class TextEditorEdit {
}; };
} }
private _throwIfFinalized() {
if (this._finalized) {
throw new Error('Edit is only valid while callback runs');
}
}
replace(location: Position | Range | Selection, value: string): void { replace(location: Position | Range | Selection, value: string): void {
this._throwIfFinalized();
let range: Range | null = null; let range: Range | null = null;
if (location instanceof Position) { if (location instanceof Position) {
@@ -90,10 +97,12 @@ export class TextEditorEdit {
} }
insert(location: Position, value: string): void { insert(location: Position, value: string): void {
this._throwIfFinalized();
this._pushEdit(new Range(location, location), value, true); this._pushEdit(new Range(location, location), value, true);
} }
delete(location: Range | Selection): void { delete(location: Range | Selection): void {
this._throwIfFinalized();
let range: Range | null = null; let range: Range | null = null;
if (location instanceof Range) { if (location instanceof Range) {
@@ -115,6 +124,7 @@ export class TextEditorEdit {
} }
setEndOfLine(endOfLine: EndOfLine): void { setEndOfLine(endOfLine: EndOfLine): void {
this._throwIfFinalized();
if (endOfLine !== EndOfLine.LF && endOfLine !== EndOfLine.CRLF) { if (endOfLine !== EndOfLine.LF && endOfLine !== EndOfLine.CRLF) {
throw illegalArgument('endOfLine'); throw illegalArgument('endOfLine');
} }
@@ -582,11 +582,7 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape {
} }
} }
// Get the initial cwd
const terminalConfig = configProvider.getConfiguration('terminal.integrated');
const activeWorkspaceRootUri = URI.revive(activeWorkspaceRootUriComponents); const activeWorkspaceRootUri = URI.revive(activeWorkspaceRootUriComponents);
const initialCwd = terminalEnvironment.getCwd(shellLaunchConfig, os.homedir(), activeWorkspaceRootUri, terminalConfig.cwd);
// Get the environment // Get the environment
const apiLastActiveWorkspace = await this._extHostWorkspace.getWorkspaceFolder(activeWorkspaceRootUri); const apiLastActiveWorkspace = await this._extHostWorkspace.getWorkspaceFolder(activeWorkspaceRootUri);
const lastActiveWorkspace = apiLastActiveWorkspace ? { const lastActiveWorkspace = apiLastActiveWorkspace ? {
@@ -597,6 +593,12 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape {
throw new Error('Not implemented'); throw new Error('Not implemented');
} }
} as IWorkspaceFolder : null; } as IWorkspaceFolder : null;
// Get the initial cwd
const terminalConfig = configProvider.getConfiguration('terminal.integrated');
const initialCwd = terminalEnvironment.getCwd(shellLaunchConfig, os.homedir(), lastActiveWorkspace ? lastActiveWorkspace : undefined, this._variableResolver, activeWorkspaceRootUri, terminalConfig.cwd, this._logService);
const envFromConfig = this._apiInspectConfigToPlain(configProvider.getConfiguration('terminal.integrated').inspect<ITerminalEnvironment>(`env.${platformKey}`)); const envFromConfig = this._apiInspectConfigToPlain(configProvider.getConfiguration('terminal.integrated').inspect<ITerminalEnvironment>(`env.${platformKey}`));
const baseEnv = terminalConfig.get<boolean>('inheritEnv', true) ? process.env as platform.IProcessEnvironment : await this._getNonInheritedEnv(); const baseEnv = terminalConfig.get<boolean>('inheritEnv', true) ? process.env as platform.IProcessEnvironment : await this._getNonInheritedEnv();
const env = terminalEnvironment.createTerminalEnvironment( const env = terminalEnvironment.createTerminalEnvironment(
+31 -13
View File
@@ -27,7 +27,7 @@ import { IWindowService, MenuBarVisibility, getTitleBarStyle } from 'vs/platform
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
import { IEditorService, IResourceEditor } from 'vs/workbench/services/editor/common/editorService'; import { IEditorService, IResourceEditor } from 'vs/workbench/services/editor/common/editorService';
import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService'; import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
import { Sizing, Direction, Grid, SerializableGrid, ISerializableView, ISerializedGrid } from 'vs/base/browser/ui/grid/grid'; import { Sizing, Direction, Grid, SerializableGrid, ISerializableView, ISerializedGrid, GridBranchNode, GridLeafNode, isGridBranchNode } from 'vs/base/browser/ui/grid/grid';
import { WorkbenchLegacyLayout } from 'vs/workbench/browser/legacyLayout'; import { WorkbenchLegacyLayout } from 'vs/workbench/browser/legacyLayout';
import { IDimension } from 'vs/platform/layout/browser/layoutService'; import { IDimension } from 'vs/platform/layout/browser/layoutService';
import { Part } from 'vs/workbench/browser/part'; import { Part } from 'vs/workbench/browser/part';
@@ -749,21 +749,25 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi
try { try {
workbenchGrid = SerializableGrid.deserialize(parsedGrid, { fromJSON }, { proportionalLayout: false }); workbenchGrid = SerializableGrid.deserialize(parsedGrid, { fromJSON }, { proportionalLayout: false });
// Set some layout state const root = workbenchGrid.getViews();
this.state.sideBar.position = Position.LEFT; const titleBarSection = root.children[0];
for (let view of workbenchGrid.getNeighborViews(this.sideBarPartView, Direction.Right)) {
if (view === this.activityBarPartView) { if (isGridBranchNode(titleBarSection) || titleBarSection.view !== this.titleBarPartView) {
this.state.sideBar.position = Position.RIGHT; throw new Error('Bad grid');
}
} }
this.state.panel.position = Position.BOTTOM; const middleSection = root.children[1] as GridBranchNode<ISerializableView>;
for (let view of workbenchGrid.getNeighborViews(this.panelPartView, Direction.Left)) { const sideBarPosition = (middleSection.children[0] as GridLeafNode<ISerializableView>).view === this.activityBarPartView ? Position.LEFT : Position.RIGHT;
if (view === this.editorPartView) { if (sideBarPosition !== this.state.sideBar.position) {
this.state.panel.position = Position.RIGHT; throw new Error('Bad Grid');
} }
const panelPosition = isGridBranchNode(middleSection.children[2]) || isGridBranchNode(middleSection.children[0]) ? Position.BOTTOM : Position.RIGHT;
if (panelPosition !== this.state.panel.position) {
throw new Error('Bad Grid');
} }
} catch (err) { } catch (err) {
workbenchGrid = undefined;
console.error(err); console.error(err);
} }
} }
@@ -783,6 +787,10 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi
this.setPanelHidden(!visible, true); this.setPanelHidden(!visible, true);
})); }));
this._register((this.editorPartView as PanelPart).onDidVisibilityChange((visible) => {
this.setEditorHidden(!visible, true);
}));
this._register(this.lifecycleService.onBeforeShutdown(beforeShutdownEvent => { this._register(this.lifecycleService.onBeforeShutdown(beforeShutdownEvent => {
beforeShutdownEvent.veto(new Promise((resolve) => { beforeShutdownEvent.veto(new Promise((resolve) => {
const grid = this.workbenchGrid as SerializableGrid<ISerializableView>; const grid = this.workbenchGrid as SerializableGrid<ISerializableView>;
@@ -849,8 +857,9 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi
statusBarInGrid = true; statusBarInGrid = true;
} }
if (!titlebarInGrid && getTitleBarStyle(this.configurationService, this.environmentService) === 'custom') { if (!titlebarInGrid) {
this.workbenchGrid.addView(this.titleBarPartView, Sizing.Split, this.editorPartView, Direction.Up); this.workbenchGrid.addView(this.titleBarPartView, Sizing.Split, this.editorPartView, Direction.Up);
titlebarInGrid = true; titlebarInGrid = true;
} }
@@ -1157,6 +1166,11 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi
} else { } else {
size.width = this.state.panel.sizeBeforeMaximize; size.width = this.state.panel.sizeBeforeMaximize;
} }
// Unhide the editor if needed
if (this.state.editor.hidden) {
this.setEditorHidden(false);
}
} }
this.workbenchGrid.resizeView(this.panelPartView, size); this.workbenchGrid.resizeView(this.panelPartView, size);
@@ -1166,6 +1180,10 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi
} }
isPanelMaximized(): boolean { isPanelMaximized(): boolean {
if (!this.workbenchGrid) {
return false;
}
if (this.workbenchGrid instanceof Grid) { if (this.workbenchGrid instanceof Grid) {
try { try {
// The panel is maximum when the editor is minimum // The panel is maximum when the editor is minimum
@@ -111,6 +111,9 @@ export class EditorPart extends Part implements IEditorGroupsService, IEditorGro
private _onDidSizeConstraintsChange = this._register(new Relay<{ width: number; height: number; } | undefined>()); private _onDidSizeConstraintsChange = this._register(new Relay<{ width: number; height: number; } | undefined>());
get onDidSizeConstraintsChange(): Event<{ width: number; height: number; } | undefined> { return Event.any(this.onDidSetGridWidget.event, this._onDidSizeConstraintsChange.event); } get onDidSizeConstraintsChange(): Event<{ width: number; height: number; } | undefined> { return Event.any(this.onDidSetGridWidget.event, this._onDidSizeConstraintsChange.event); }
private _onDidVisibilityChange = this._register(new Emitter<boolean>());
readonly onDidVisibilityChange: Event<boolean> = this._onDidVisibilityChange.event;
//#endregion //#endregion
private readonly workspaceMemento: MementoObject; private readonly workspaceMemento: MementoObject;
@@ -743,6 +746,8 @@ export class EditorPart extends Part implements IEditorGroupsService, IEditorGro
get minimumHeight(): number { return this.centeredLayoutWidget.minimumHeight; } get minimumHeight(): number { return this.centeredLayoutWidget.minimumHeight; }
get maximumHeight(): number { return this.centeredLayoutWidget.maximumHeight; } get maximumHeight(): number { return this.centeredLayoutWidget.maximumHeight; }
readonly snap = true;
get onDidChange(): Event<IViewSize | undefined> { return this.centeredLayoutWidget.onDidChange; } get onDidChange(): Event<IViewSize | undefined> { return this.centeredLayoutWidget.onDidChange; }
readonly priority: LayoutPriority = LayoutPriority.High; readonly priority: LayoutPriority = LayoutPriority.High;
@@ -986,6 +991,10 @@ export class EditorPart extends Part implements IEditorGroupsService, IEditorGro
//#endregion //#endregion
setVisible(visible: boolean): void {
this._onDidVisibilityChange.fire(visible);
}
toJSON(): object { toJSON(): object {
return { return {
type: Parts.EDITOR_PART type: Parts.EDITOR_PART
@@ -13,7 +13,7 @@ import { IContextMenuService } from 'vs/platform/contextview/browser/contextView
import { IMenuService, MenuId, MenuItemAction } from 'vs/platform/actions/common/actions'; import { IMenuService, MenuId, MenuItemAction } from 'vs/platform/actions/common/actions';
import { ContextAwareMenuEntryActionViewItem, createAndFillInActionBarActions, createAndFillInContextMenuActions } from 'vs/platform/actions/browser/menuEntryActionViewItem'; import { ContextAwareMenuEntryActionViewItem, createAndFillInActionBarActions, createAndFillInContextMenuActions } from 'vs/platform/actions/browser/menuEntryActionViewItem';
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { IViewsService, ITreeView, ITreeItem, TreeItemCollapsibleState, ITreeViewDataProvider, TreeViewItemHandleArg, ITreeViewDescriptor, IViewsRegistry, ViewContainer, ITreeItemLabel, Extensions } from 'vs/workbench/common/views'; import { ITreeView, ITreeItem, TreeItemCollapsibleState, ITreeViewDataProvider, TreeViewItemHandleArg, ITreeViewDescriptor, IViewsRegistry, ViewContainer, ITreeItemLabel, Extensions } from 'vs/workbench/common/views';
import { IViewletViewOptions } from 'vs/workbench/browser/parts/views/viewsViewlet'; import { IViewletViewOptions } from 'vs/workbench/browser/parts/views/viewsViewlet';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { INotificationService } from 'vs/platform/notification/common/notification'; import { INotificationService } from 'vs/platform/notification/common/notification';
@@ -56,9 +56,9 @@ export class CustomTreeViewPanel extends ViewletPanel {
@IKeybindingService keybindingService: IKeybindingService, @IKeybindingService keybindingService: IKeybindingService,
@IContextMenuService contextMenuService: IContextMenuService, @IContextMenuService contextMenuService: IContextMenuService,
@IConfigurationService configurationService: IConfigurationService, @IConfigurationService configurationService: IConfigurationService,
@IViewsService viewsService: IViewsService, @IContextKeyService contextKeyService: IContextKeyService,
) { ) {
super({ ...(options as IViewletPanelOptions), ariaHeaderLabel: options.title }, keybindingService, contextMenuService, configurationService); super({ ...(options as IViewletPanelOptions), ariaHeaderLabel: options.title }, keybindingService, contextMenuService, configurationService, contextKeyService);
const { treeView } = (<ITreeViewDescriptor>Registry.as<IViewsRegistry>(Extensions.ViewsRegistry).getView(options.id)); const { treeView } = (<ITreeViewDescriptor>Registry.as<IViewsRegistry>(Extensions.ViewsRegistry).getView(options.id));
this.treeView = treeView; this.treeView = treeView;
this._register(this.treeView.onDidChangeActions(() => this.updateActions(), this)); this._register(this.treeView.onDidChangeActions(() => this.updateActions(), this));
@@ -405,7 +405,7 @@ export class CustomTreeView extends Disposable implements ITreeView {
})); }));
this.tree.setInput(this.root).then(() => this.updateContentAreas()); this.tree.setInput(this.root).then(() => this.updateContentAreas());
const customTreeNavigator = new TreeResourceNavigator2(this.tree); const customTreeNavigator = new TreeResourceNavigator2(this.tree, { openOnFocus: false, openOnSelection: false });
this._register(customTreeNavigator); this._register(customTreeNavigator);
this._register(customTreeNavigator.onDidOpenResource(e => { this._register(customTreeNavigator.onDidOpenResource(e => {
if (!e.browserEvent) { if (!e.browserEvent) {
@@ -113,7 +113,8 @@
flex: 1; flex: 1;
text-overflow: ellipsis; text-overflow: ellipsis;
overflow: hidden; overflow: hidden;
flex-wrap: nowrap flex-wrap: nowrap;
padding-left: 3px;
} }
.customview-tree .monaco-list .monaco-list-row .custom-view-tree-node-item .custom-view-tree-node-item-resourceLabel { .customview-tree .monaco-list .monaco-list-row .custom-view-tree-node-item .custom-view-tree-node-item-resourceLabel {
@@ -156,4 +157,4 @@
background-size: 16px; background-size: 16px;
background-position: 50% 50%; background-position: 50% 50%;
background-repeat: no-repeat; background-repeat: no-repeat;
} }
@@ -26,8 +26,9 @@ import { PanelView, IPanelViewOptions, IPanelOptions, Panel } from 'vs/base/brow
import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService'; import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService';
import { StandardMouseEvent } from 'vs/base/browser/mouseEvent'; import { StandardMouseEvent } from 'vs/base/browser/mouseEvent';
import { IView } from 'vs/workbench/common/views'; import { IView, FocusedViewContext } from 'vs/workbench/common/views';
import { IStorageService } from 'vs/platform/storage/common/storage'; import { IStorageService } from 'vs/platform/storage/common/storage';
import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
export interface IPanelColors extends IColorMapping { export interface IPanelColors extends IColorMapping {
dropBackground?: ColorIdentifier; dropBackground?: ColorIdentifier;
@@ -58,6 +59,8 @@ export abstract class ViewletPanel extends Panel implements IView {
protected _onDidChangeTitleArea = this._register(new Emitter<void>()); protected _onDidChangeTitleArea = this._register(new Emitter<void>());
readonly onDidChangeTitleArea: Event<void> = this._onDidChangeTitleArea.event; readonly onDidChangeTitleArea: Event<void> = this._onDidChangeTitleArea.event;
private focusedViewContextKey: IContextKey<string>;
private _isVisible: boolean = false; private _isVisible: boolean = false;
readonly id: string; readonly id: string;
readonly title: string; readonly title: string;
@@ -71,13 +74,15 @@ export abstract class ViewletPanel extends Panel implements IView {
options: IViewletPanelOptions, options: IViewletPanelOptions,
@IKeybindingService protected keybindingService: IKeybindingService, @IKeybindingService protected keybindingService: IKeybindingService,
@IContextMenuService protected contextMenuService: IContextMenuService, @IContextMenuService protected contextMenuService: IContextMenuService,
@IConfigurationService protected readonly configurationService: IConfigurationService @IConfigurationService protected readonly configurationService: IConfigurationService,
@IContextKeyService contextKeyService: IContextKeyService
) { ) {
super(options); super(options);
this.id = options.id; this.id = options.id;
this.title = options.title; this.title = options.title;
this.actionRunner = options.actionRunner; this.actionRunner = options.actionRunner;
this.focusedViewContextKey = FocusedViewContext.bindTo(contextKeyService);
} }
setVisible(visible: boolean): void { setVisible(visible: boolean): void {
@@ -112,8 +117,14 @@ export abstract class ViewletPanel extends Panel implements IView {
const focusTracker = trackFocus(this.element); const focusTracker = trackFocus(this.element);
this._register(focusTracker); this._register(focusTracker);
this._register(focusTracker.onDidFocus(() => this._onDidFocus.fire())); this._register(focusTracker.onDidFocus(() => {
this._register(focusTracker.onDidBlur(() => this._onDidBlur.fire())); this.focusedViewContextKey.set(this.id);
this._onDidFocus.fire();
}));
this._register(focusTracker.onDidBlur(() => {
this.focusedViewContextKey.reset();
this._onDidBlur.fire();
}));
} }
protected renderHeader(container: HTMLElement): void { protected renderHeader(container: HTMLElement): void {
+101 -66
View File
@@ -12,7 +12,7 @@ import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet';
import { IContextKeyService, IContextKeyChangeEvent, IReadableSet, IContextKey, RawContextKey, ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; import { IContextKeyService, IContextKeyChangeEvent, IReadableSet, IContextKey, RawContextKey, ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
import { Event, Emitter } from 'vs/base/common/event'; import { Event, Emitter } from 'vs/base/common/event';
import { sortedDiff, firstIndex, move, isNonEmptyArray } from 'vs/base/common/arrays'; import { sortedDiff, firstIndex, move, isNonEmptyArray } from 'vs/base/common/arrays';
import { isUndefinedOrNull } from 'vs/base/common/types'; import { isUndefinedOrNull, isUndefined } from 'vs/base/common/types';
import { MenuId, MenuRegistry, ICommandAction } from 'vs/platform/actions/common/actions'; import { MenuId, MenuRegistry, ICommandAction } from 'vs/platform/actions/common/actions';
import { CommandsRegistry } from 'vs/platform/commands/common/commands'; import { CommandsRegistry } from 'vs/platform/commands/common/commands';
import { localize } from 'vs/nls'; import { localize } from 'vs/nls';
@@ -205,9 +205,9 @@ class ViewDescriptorCollection extends Disposable implements IViewDescriptorColl
} }
export interface IViewState { export interface IViewState {
visibleGlobal: boolean; visibleGlobal: boolean | undefined;
visibleWorkspace: boolean; visibleWorkspace: boolean | undefined;
collapsed: boolean; collapsed: boolean | undefined;
order?: number; order?: number;
size?: number; size?: number;
} }
@@ -287,7 +287,7 @@ export class ContributableViewsModel extends Disposable {
} }
if (visible) { if (visible) {
this._onDidAdd.fire([{ index: visibleIndex, viewDescriptor, size: state.size, collapsed: state.collapsed }]); this._onDidAdd.fire([{ index: visibleIndex, viewDescriptor, size: state.size, collapsed: !!state.collapsed }]);
} else { } else {
this._onDidRemove.fire([{ index: visibleIndex, viewDescriptor }]); this._onDidRemove.fire([{ index: visibleIndex, viewDescriptor }]);
} }
@@ -300,7 +300,7 @@ export class ContributableViewsModel extends Disposable {
throw new Error(`Unknown view ${id}`); throw new Error(`Unknown view ${id}`);
} }
return state.collapsed; return !!state.collapsed;
} }
setCollapsed(id: string, collapsed: boolean): void { setCollapsed(id: string, collapsed: boolean): void {
@@ -354,7 +354,7 @@ export class ContributableViewsModel extends Disposable {
if (!viewState) { if (!viewState) {
throw new Error(`Unknown view ${viewDescriptor.id}`); throw new Error(`Unknown view ${viewDescriptor.id}`);
} }
return viewDescriptor.workspace ? viewState.visibleWorkspace : viewState.visibleGlobal; return viewDescriptor.workspace ? !!viewState.visibleWorkspace : !!viewState.visibleGlobal;
} }
private find(id: string): { index: number, visibleIndex: number, viewDescriptor: IViewDescriptor, state: IViewState } { private find(id: string): { index: number, visibleIndex: number, viewDescriptor: IViewDescriptor, state: IViewState } {
@@ -444,7 +444,7 @@ export class ContributableViewsModel extends Disposable {
const state = this.viewStates.get(viewDescriptor.id)!; const state = this.viewStates.get(viewDescriptor.id)!;
if (this.isViewDescriptorVisible(viewDescriptor)) { if (this.isViewDescriptorVisible(viewDescriptor)) {
toAdd.push({ index: startIndex++, viewDescriptor, size: state.size, collapsed: state.collapsed }); toAdd.push({ index: startIndex++, viewDescriptor, size: state.size, collapsed: !!state.collapsed });
} }
} }
} }
@@ -461,10 +461,23 @@ export class ContributableViewsModel extends Disposable {
} }
} }
interface IStoredWorkspaceViewState {
collapsed: boolean;
isHidden: boolean;
size?: number;
order?: number;
}
interface IStoredGlobalViewState {
id: string;
isHidden: boolean;
order?: number;
}
export class PersistentContributableViewsModel extends ContributableViewsModel { export class PersistentContributableViewsModel extends ContributableViewsModel {
private viewletStateStorageId: string; private readonly workspaceViewsStateStorageId: string;
private readonly hiddenViewsStorageId: string; private readonly globalViewsStateStorageId: string;
private storageService: IStorageService; private storageService: IStorageService;
@@ -474,13 +487,13 @@ export class PersistentContributableViewsModel extends ContributableViewsModel {
@IViewsService viewsService: IViewsService, @IViewsService viewsService: IViewsService,
@IStorageService storageService: IStorageService, @IStorageService storageService: IStorageService,
) { ) {
const hiddenViewsStorageId = `${viewletStateStorageId}.hidden`; const globalViewsStateStorageId = `${viewletStateStorageId}.hidden`;
const viewStates = PersistentContributableViewsModel.loadViewsStates(viewletStateStorageId, hiddenViewsStorageId, storageService); const viewStates = PersistentContributableViewsModel.loadViewsStates(viewletStateStorageId, globalViewsStateStorageId, storageService);
super(container, viewsService, viewStates); super(container, viewsService, viewStates);
this.viewletStateStorageId = viewletStateStorageId; this.workspaceViewsStateStorageId = viewletStateStorageId;
this.hiddenViewsStorageId = hiddenViewsStorageId; this.globalViewsStateStorageId = globalViewsStateStorageId;
this.storageService = storageService; this.storageService = storageService;
this._register(Event.any( this._register(Event.any(
@@ -492,84 +505,106 @@ export class PersistentContributableViewsModel extends ContributableViewsModel {
} }
private saveViewsStates(viewDescriptors: IViewDescriptor[]): void { private saveViewsStates(viewDescriptors: IViewDescriptor[]): void {
const storedViewsStates: { [id: string]: { collapsed: boolean, size?: number, order?: number } } = {}; this.saveWorkspaceViewsStates();
this.saveGlobalViewsStates();
}
private saveWorkspaceViewsStates(): void {
const storedViewsStates: { [id: string]: IStoredWorkspaceViewState } = {};
let hasState = false; let hasState = false;
for (const viewDescriptor of this.viewDescriptors) { for (const viewDescriptor of this.viewDescriptors) {
const viewState = this.viewStates.get(viewDescriptor.id); const viewState = this.viewStates.get(viewDescriptor.id);
if (viewState) { if (viewState) {
storedViewsStates[viewDescriptor.id] = { collapsed: viewState.collapsed, size: viewState.size, order: viewState.order }; storedViewsStates[viewDescriptor.id] = {
collapsed: !!viewState.collapsed,
isHidden: !viewState.visibleWorkspace,
size: viewState.size,
order: viewDescriptor.workspace && viewState ? viewState.order : undefined
};
hasState = true; hasState = true;
} }
} }
if (hasState) { if (hasState) {
this.storageService.store(this.viewletStateStorageId, JSON.stringify(storedViewsStates), StorageScope.WORKSPACE); this.storageService.store(this.workspaceViewsStateStorageId, JSON.stringify(storedViewsStates), StorageScope.WORKSPACE);
} else { } else {
this.storageService.remove(this.viewletStateStorageId, StorageScope.WORKSPACE); this.storageService.remove(this.workspaceViewsStateStorageId, StorageScope.WORKSPACE);
}
this.saveVisibilityStates(viewDescriptors);
}
private saveVisibilityStates(viewDescriptors: IViewDescriptor[]): void {
const globalViews: IViewDescriptor[] = viewDescriptors.filter(v => !v.workspace);
const workspaceViews: IViewDescriptor[] = viewDescriptors.filter(v => v.workspace);
if (globalViews.length) {
this.saveVisibilityStatesInScope(globalViews, StorageScope.GLOBAL);
}
if (workspaceViews.length) {
this.saveVisibilityStatesInScope(workspaceViews, StorageScope.WORKSPACE);
} }
} }
private saveVisibilityStatesInScope(viewDescriptors: IViewDescriptor[], scope: StorageScope): void { private saveGlobalViewsStates(): void {
const storedViewsVisibilityStates = PersistentContributableViewsModel.loadViewsVisibilityState(this.hiddenViewsStorageId, this.storageService, scope); const storedViewsVisibilityStates = PersistentContributableViewsModel.loadGlobalViewsState(this.globalViewsStateStorageId, this.storageService, StorageScope.GLOBAL);
for (const viewDescriptor of viewDescriptors) { for (const viewDescriptor of this.viewDescriptors) {
if (viewDescriptor.canToggleVisibility) { const viewState = this.viewStates.get(viewDescriptor.id);
const viewState = this.viewStates.get(viewDescriptor.id); storedViewsVisibilityStates.set(viewDescriptor.id, {
storedViewsVisibilityStates.set(viewDescriptor.id, { id: viewDescriptor.id, isHidden: viewState ? (scope === StorageScope.GLOBAL ? !viewState.visibleGlobal : !viewState.visibleWorkspace) : false }); id: viewDescriptor.id,
} isHidden: viewState && viewDescriptor.canToggleVisibility ? !viewState.visibleGlobal : false,
order: !viewDescriptor.workspace && viewState ? viewState.order : undefined
});
} }
this.storageService.store(this.hiddenViewsStorageId, JSON.stringify(values(storedViewsVisibilityStates)), scope); this.storageService.store(this.globalViewsStateStorageId, JSON.stringify(values(storedViewsVisibilityStates)), StorageScope.GLOBAL);
} }
private static loadViewsStates(viewletStateStorageId: string, hiddenViewsStorageId: string, storageService: IStorageService): Map<string, IViewState> {
private static loadViewsStates(workspaceViewsStateStorageId: string, globalViewsStateStorageId: string, storageService: IStorageService): Map<string, IViewState> {
const viewStates = new Map<string, IViewState>(); const viewStates = new Map<string, IViewState>();
const storedViewsStates = JSON.parse(storageService.get(viewletStateStorageId, StorageScope.WORKSPACE, '{}')); const workspaceViewsStates = <{ [id: string]: IStoredWorkspaceViewState }>JSON.parse(storageService.get(workspaceViewsStateStorageId, StorageScope.WORKSPACE, '{}'));
const globalVisibilityStates = this.loadViewsVisibilityState(hiddenViewsStorageId, storageService, StorageScope.GLOBAL); for (const id of Object.keys(workspaceViewsStates)) {
const workspaceVisibilityStates = this.loadViewsVisibilityState(hiddenViewsStorageId, storageService, StorageScope.WORKSPACE); const workspaceViewState = workspaceViewsStates[id];
viewStates.set(id, {
visibleGlobal: undefined,
visibleWorkspace: isUndefined(workspaceViewState.isHidden) ? undefined : !workspaceViewState.isHidden,
collapsed: workspaceViewState.collapsed,
order: workspaceViewState.order
});
}
for (const { id, isHidden } of values(globalVisibilityStates)) { // Migrate to `viewletStateStorageId`
const viewState = storedViewsStates[id]; const workspaceVisibilityStates = this.loadGlobalViewsState(globalViewsStateStorageId, storageService, StorageScope.WORKSPACE);
if (viewState) { if (workspaceVisibilityStates.size > 0) {
viewStates.set(id, <IViewState>{ ...viewState, ...{ visibleGlobal: !isHidden } }); for (const { id, isHidden } of values(workspaceVisibilityStates)) {
} else { let viewState = viewStates.get(id);
// New workspace // Not migrated to `viewletStateStorageId`
viewStates.set(id, <IViewState>{ ...{ visibleGlobal: !isHidden } }); if (viewState) {
if (isUndefined(viewState.visibleWorkspace)) {
viewState.visibleWorkspace = !isHidden;
}
} else {
viewStates.set(id, {
collapsed: undefined,
visibleGlobal: undefined,
visibleWorkspace: !isHidden,
});
}
} }
storageService.remove(globalViewsStateStorageId, StorageScope.WORKSPACE);
} }
for (const { id, isHidden } of values(workspaceVisibilityStates)) {
const viewState = storedViewsStates[id]; const globalViewsStates = this.loadGlobalViewsState(globalViewsStateStorageId, storageService, StorageScope.GLOBAL);
for (const { id, isHidden, order } of values(globalViewsStates)) {
let viewState = viewStates.get(id);
if (viewState) { if (viewState) {
viewStates.set(id, <IViewState>{ ...viewState, ...{ visibleWorkspace: !isHidden } }); viewState.visibleGlobal = !isHidden;
if (!isUndefined(order)) {
viewState.order = order;
}
} else { } else {
// New workspace viewStates.set(id, {
viewStates.set(id, <IViewState>{ ...{ visibleWorkspace: !isHidden } }); visibleGlobal: !isHidden,
} order,
} collapsed: undefined,
for (const id of Object.keys(storedViewsStates)) { visibleWorkspace: undefined,
if (!viewStates.has(id)) { });
viewStates.set(id, <IViewState>{ ...storedViewsStates[id] });
} }
} }
return viewStates; return viewStates;
} }
private static loadViewsVisibilityState(hiddenViewsStorageId: string, storageService: IStorageService, scope: StorageScope): Map<string, { id: string, isHidden: boolean }> { private static loadGlobalViewsState(globalViewsStateStorageId: string, storageService: IStorageService, scope: StorageScope): Map<string, IStoredGlobalViewState> {
const storedVisibilityStates = <Array<string | { id: string, isHidden: boolean }>>JSON.parse(storageService.get(hiddenViewsStorageId, scope, '[]')); const storedValue = <Array<string | IStoredGlobalViewState>>JSON.parse(storageService.get(globalViewsStateStorageId, scope, '[]'));
let hasDuplicates = false; let hasDuplicates = false;
const storedViewsVisibilityStates = storedVisibilityStates.reduce((result, storedState) => { const storedGlobalViewsState = storedValue.reduce((result, storedState) => {
if (typeof storedState === 'string' /* migration */) { if (typeof storedState === 'string' /* migration */) {
hasDuplicates = hasDuplicates || result.has(storedState); hasDuplicates = hasDuplicates || result.has(storedState);
result.set(storedState, { id: storedState, isHidden: true }); result.set(storedState, { id: storedState, isHidden: true });
@@ -578,13 +613,13 @@ export class PersistentContributableViewsModel extends ContributableViewsModel {
result.set(storedState.id, storedState); result.set(storedState.id, storedState);
} }
return result; return result;
}, new Map<string, { id: string, isHidden: boolean }>()); }, new Map<string, IStoredGlobalViewState>());
if (hasDuplicates) { if (hasDuplicates) {
storageService.store(hiddenViewsStorageId, JSON.stringify(values(storedViewsVisibilityStates)), scope); storageService.store(globalViewsStateStorageId, JSON.stringify(values(storedGlobalViewsState)), scope);
} }
return storedViewsVisibilityStates; return storedGlobalViewsState;
} }
} }
+1 -1
View File
@@ -131,7 +131,7 @@ class CodeRendererMain extends Disposable {
serviceCollection.set(IRemoteAuthorityResolverService, remoteAuthorityResolverService); serviceCollection.set(IRemoteAuthorityResolverService, remoteAuthorityResolverService);
// Signing // Signing
const signService = new SignService(); const signService = new SignService(this.configuration.connectionToken);
serviceCollection.set(ISignService, signService); serviceCollection.set(ISignService, signService);
// Remote Agent // Remote Agent
@@ -801,7 +801,7 @@ export class SimpleWindowsService implements IWindowsService {
return Promise.resolve(this.windowCount); return Promise.resolve(this.windowCount);
} }
log(_severity: string, ..._messages: string[]): Promise<void> { log(_severity: string, _args: string[]): Promise<void> {
return Promise.resolve(); return Promise.resolve();
} }
+2 -1
View File
@@ -6,7 +6,7 @@
import { Command } from 'vs/editor/common/modes'; import { Command } from 'vs/editor/common/modes';
import { UriComponents } from 'vs/base/common/uri'; import { UriComponents } from 'vs/base/common/uri';
import { Event, Emitter } from 'vs/base/common/event'; import { Event, Emitter } from 'vs/base/common/event';
import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; import { ContextKeyExpr, RawContextKey } from 'vs/platform/contextkey/common/contextkey';
import { ITreeViewDataProvider } from 'vs/workbench/common/views'; import { ITreeViewDataProvider } from 'vs/workbench/common/views';
import { localize } from 'vs/nls'; import { localize } from 'vs/nls';
import { IViewlet } from 'vs/workbench/common/viewlet'; import { IViewlet } from 'vs/workbench/common/viewlet';
@@ -21,6 +21,7 @@ import { IMarkdownString } from 'vs/base/common/htmlContent';
import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions'; import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
export const TEST_VIEW_CONTAINER_ID = 'workbench.view.extension.test'; export const TEST_VIEW_CONTAINER_ID = 'workbench.view.extension.test';
export const FocusedViewContext = new RawContextKey<string>('focusedView', '');
export namespace Extensions { export namespace Extensions {
export const ViewContainersRegistry = 'workbench.registry.view.containers'; export const ViewContainersRegistry = 'workbench.registry.view.containers';
@@ -30,6 +30,7 @@ import { IConfigurationService } from 'vs/platform/configuration/common/configur
import { IEditorService, SIDE_GROUP, ACTIVE_GROUP } from 'vs/workbench/services/editor/common/editorService'; import { IEditorService, SIDE_GROUP, ACTIVE_GROUP } from 'vs/workbench/services/editor/common/editorService';
import { ViewletPanel, IViewletPanelOptions } from 'vs/workbench/browser/parts/views/panelViewlet'; import { ViewletPanel, IViewletPanelOptions } from 'vs/workbench/browser/parts/views/panelViewlet';
import { ILabelService } from 'vs/platform/label/common/label'; import { ILabelService } from 'vs/platform/label/common/label';
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
const $ = dom.$; const $ = dom.$;
@@ -56,9 +57,10 @@ export class BreakpointsView extends ViewletPanel {
@IThemeService private readonly themeService: IThemeService, @IThemeService private readonly themeService: IThemeService,
@IEditorService private readonly editorService: IEditorService, @IEditorService private readonly editorService: IEditorService,
@IContextViewService private readonly contextViewService: IContextViewService, @IContextViewService private readonly contextViewService: IContextViewService,
@IConfigurationService configurationService: IConfigurationService @IConfigurationService configurationService: IConfigurationService,
@IContextKeyService contextKeyService: IContextKeyService,
) { ) {
super({ ...(options as IViewletPanelOptions), ariaHeaderLabel: nls.localize('breakpointsSection', "Breakpoints Section") }, keybindingService, contextMenuService, configurationService); super({ ...(options as IViewletPanelOptions), ariaHeaderLabel: nls.localize('breakpointsSection', "Breakpoints Section") }, keybindingService, contextMenuService, configurationService, contextKeyService);
this.minimumBodySize = this.maximumBodySize = this.getExpandedBodySize(); this.minimumBodySize = this.maximumBodySize = this.getExpandedBodySize();
this._register(this.debugService.getModel().onDidChangeBreakpoints(() => this.onBreakpointsChange())); this._register(this.debugService.getModel().onDidChangeBreakpoints(() => this.onBreakpointsChange()));
@@ -60,7 +60,7 @@ export class CallStackView extends ViewletPanel {
@IMenuService menuService: IMenuService, @IMenuService menuService: IMenuService,
@IContextKeyService readonly contextKeyService: IContextKeyService, @IContextKeyService readonly contextKeyService: IContextKeyService,
) { ) {
super({ ...(options as IViewletPanelOptions), ariaHeaderLabel: nls.localize('callstackSection', "Call Stack Section") }, keybindingService, contextMenuService, configurationService); super({ ...(options as IViewletPanelOptions), ariaHeaderLabel: nls.localize('callstackSection', "Call Stack Section") }, keybindingService, contextMenuService, configurationService, contextKeyService);
this.callStackItemType = CONTEXT_CALLSTACK_ITEM_TYPE.bindTo(contextKeyService); this.callStackItemType = CONTEXT_CALLSTACK_ITEM_TYPE.bindTo(contextKeyService);
this.contributedContextMenu = menuService.createMenu(MenuId.DebugCallStackContext, contextKeyService); this.contributedContextMenu = menuService.createMenu(MenuId.DebugCallStackContext, contextKeyService);
@@ -402,7 +402,7 @@ export class LoadedScriptsView extends ViewletPanel {
@IDebugService private readonly debugService: IDebugService, @IDebugService private readonly debugService: IDebugService,
@ILabelService private readonly labelService: ILabelService @ILabelService private readonly labelService: ILabelService
) { ) {
super({ ...(options as IViewletPanelOptions), ariaHeaderLabel: nls.localize('loadedScriptsSection', "Loaded Scripts Section") }, keybindingService, contextMenuService, configurationService); super({ ...(options as IViewletPanelOptions), ariaHeaderLabel: nls.localize('loadedScriptsSection', "Loaded Scripts Section") }, keybindingService, contextMenuService, configurationService, contextKeyService);
this.loadedScriptsItemType = CONTEXT_LOADED_SCRIPTS_ITEM_TYPE.bindTo(contextKeyService); this.loadedScriptsItemType = CONTEXT_LOADED_SCRIPTS_ITEM_TYPE.bindTo(contextKeyService);
} }
@@ -29,6 +29,7 @@ import { onUnexpectedError } from 'vs/base/common/errors';
import { FuzzyScore, createMatches } from 'vs/base/common/filters'; import { FuzzyScore, createMatches } from 'vs/base/common/filters';
import { HighlightedLabel, IHighlight } from 'vs/base/browser/ui/highlightedlabel/highlightedLabel'; import { HighlightedLabel, IHighlight } from 'vs/base/browser/ui/highlightedlabel/highlightedLabel';
import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService'; import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService';
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
const $ = dom.$; const $ = dom.$;
let forgetScopes = true; let forgetScopes = true;
@@ -49,9 +50,10 @@ export class VariablesView extends ViewletPanel {
@IKeybindingService keybindingService: IKeybindingService, @IKeybindingService keybindingService: IKeybindingService,
@IConfigurationService configurationService: IConfigurationService, @IConfigurationService configurationService: IConfigurationService,
@IInstantiationService private readonly instantiationService: IInstantiationService, @IInstantiationService private readonly instantiationService: IInstantiationService,
@IClipboardService private readonly clipboardService: IClipboardService @IClipboardService private readonly clipboardService: IClipboardService,
@IContextKeyService contextKeyService: IContextKeyService
) { ) {
super({ ...(options as IViewletPanelOptions), ariaHeaderLabel: nls.localize('variablesSection', "Variables Section") }, keybindingService, contextMenuService, configurationService); super({ ...(options as IViewletPanelOptions), ariaHeaderLabel: nls.localize('variablesSection', "Variables Section") }, keybindingService, contextMenuService, configurationService, contextKeyService);
// Use scheduler to prevent unnecessary flashing // Use scheduler to prevent unnecessary flashing
this.onFocusStackFrameScheduler = new RunOnceScheduler(() => { this.onFocusStackFrameScheduler = new RunOnceScheduler(() => {
@@ -29,6 +29,7 @@ import { ElementsDragAndDropData } from 'vs/base/browser/ui/list/listView';
import { FuzzyScore } from 'vs/base/common/filters'; import { FuzzyScore } from 'vs/base/common/filters';
import { IHighlight } from 'vs/base/browser/ui/highlightedlabel/highlightedLabel'; import { IHighlight } from 'vs/base/browser/ui/highlightedlabel/highlightedLabel';
import { variableSetEmitter, VariablesRenderer } from 'vs/workbench/contrib/debug/browser/variablesView'; import { variableSetEmitter, VariablesRenderer } from 'vs/workbench/contrib/debug/browser/variablesView';
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
const MAX_VALUE_RENDER_LENGTH_IN_VIEWLET = 1024; const MAX_VALUE_RENDER_LENGTH_IN_VIEWLET = 1024;
@@ -45,8 +46,9 @@ export class WatchExpressionsView extends ViewletPanel {
@IKeybindingService keybindingService: IKeybindingService, @IKeybindingService keybindingService: IKeybindingService,
@IInstantiationService private readonly instantiationService: IInstantiationService, @IInstantiationService private readonly instantiationService: IInstantiationService,
@IConfigurationService configurationService: IConfigurationService, @IConfigurationService configurationService: IConfigurationService,
@IContextKeyService contextKeyService: IContextKeyService,
) { ) {
super({ ...(options as IViewletPanelOptions), ariaHeaderLabel: nls.localize('watchExpressionsSection', "Watch Expressions Section") }, keybindingService, contextMenuService, configurationService); super({ ...(options as IViewletPanelOptions), ariaHeaderLabel: nls.localize('watchExpressionsSection', "Watch Expressions Section") }, keybindingService, contextMenuService, configurationService, contextKeyService);
this.onWatchExpressionsUpdatedScheduler = new RunOnceScheduler(() => { this.onWatchExpressionsUpdatedScheduler = new RunOnceScheduler(() => {
this.needsRefresh = false; this.needsRefresh = false;
@@ -13,9 +13,9 @@ import { Event, Emitter } from 'vs/base/common/event';
import { Cache, CacheResult } from 'vs/base/common/cache'; import { Cache, CacheResult } from 'vs/base/common/cache';
import { Action } from 'vs/base/common/actions'; import { Action } from 'vs/base/common/actions';
import { isPromiseCanceledError } from 'vs/base/common/errors'; import { isPromiseCanceledError } from 'vs/base/common/errors';
import { dispose, toDisposable, Disposable, DisposableStore } from 'vs/base/common/lifecycle'; import { dispose, toDisposable, Disposable, DisposableStore, IDisposable } from 'vs/base/common/lifecycle';
import { domEvent } from 'vs/base/browser/event'; import { domEvent } from 'vs/base/browser/event';
import { append, $, addClass, removeClass, finalHandler, join, toggleClass, hide, show } from 'vs/base/browser/dom'; import { append, $, addClass, removeClass, finalHandler, join, toggleClass, hide, show, addDisposableListener, EventType } from 'vs/base/browser/dom';
import { BaseEditor } from 'vs/workbench/browser/parts/editor/baseEditor'; import { BaseEditor } from 'vs/workbench/browser/parts/editor/baseEditor';
import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet'; import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
@@ -52,6 +52,7 @@ import { isUndefined } from 'vs/base/common/types';
import { IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService'; import { IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService';
import { URI } from 'vs/base/common/uri'; import { URI } from 'vs/base/common/uri';
import { IWebviewService, Webview } from 'vs/workbench/contrib/webview/common/webview'; import { IWebviewService, Webview } from 'vs/workbench/contrib/webview/common/webview';
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
// {{SQL CARBON EDIT}} // {{SQL CARBON EDIT}}
import { renderDashboardContributions } from 'sql/workbench/parts/extensions/browser/contributionRenders'; import { renderDashboardContributions } from 'sql/workbench/parts/extensions/browser/contributionRenders';
@@ -280,6 +281,20 @@ export class ExtensionEditor extends BaseEditor {
this.content = append(body, $('.content')); this.content = append(body, $('.content'));
} }
private onClick(element: HTMLElement, callback: () => void): IDisposable {
const disposables: DisposableStore = new DisposableStore();
disposables.add(addDisposableListener(element, EventType.CLICK, finalHandler(callback)));
disposables.add(addDisposableListener(element, EventType.KEY_UP, e => {
const keyboardEvent = new StandardKeyboardEvent(e);
if (keyboardEvent.equals(KeyCode.Space) || keyboardEvent.equals(KeyCode.Enter)) {
e.preventDefault();
e.stopPropagation();
callback();
}
}));
return disposables;
}
async setInput(input: ExtensionsInput, options: EditorOptions, token: CancellationToken): Promise<void> { async setInput(input: ExtensionsInput, options: EditorOptions, token: CancellationToken): Promise<void> {
const runningExtensions = await this.extensionService.getExtensions(); const runningExtensions = await this.extensionService.getExtensions();
const colorThemes = await this.workbenchThemeService.getColorThemes(); const colorThemes = await this.workbenchThemeService.getColorThemes();
@@ -328,26 +343,21 @@ export class ExtensionEditor extends BaseEditor {
toggleClass(this.publisher, 'clickable', !!extension.url); toggleClass(this.publisher, 'clickable', !!extension.url);
toggleClass(this.rating, 'clickable', !!extension.url); toggleClass(this.rating, 'clickable', !!extension.url);
if (extension.url) { if (extension.url) {
this.name.onclick = finalHandler(() => window.open(extension.url)); this.transientDisposables.add(this.onClick(this.name, () => window.open(extension.url)));
this.rating.onclick = finalHandler(() => window.open(`${extension.url}#review-details`)); this.transientDisposables.add(this.onClick(this.rating, () => window.open(`${extension.url}#review-details`)));
this.publisher.onclick = finalHandler(() => { this.transientDisposables.add(this.onClick(this.publisher, () => {
this.viewletService.openViewlet(VIEWLET_ID, true) this.viewletService.openViewlet(VIEWLET_ID, true)
.then(viewlet => viewlet as IExtensionsViewlet) .then(viewlet => viewlet as IExtensionsViewlet)
.then(viewlet => viewlet.search(`publisher:"${extension.publisherDisplayName}"`)); .then(viewlet => viewlet.search(`publisher:"${extension.publisherDisplayName}"`));
}); }));
if (extension.licenseUrl) { if (extension.licenseUrl) {
this.license.onclick = finalHandler(() => window.open(extension.licenseUrl)); this.transientDisposables.add(this.onClick(this.license, () => window.open(extension.licenseUrl)));
this.license.style.display = 'initial'; this.license.style.display = 'initial';
} else { } else {
this.license.onclick = null;
this.license.style.display = 'none'; this.license.style.display = 'none';
} }
} else { } else {
this.name.onclick = null;
this.rating.onclick = null;
this.publisher.onclick = null;
this.license.onclick = null;
this.license.style.display = 'none'; this.license.style.display = 'none';
} }
@@ -362,11 +372,10 @@ export class ExtensionEditor extends BaseEditor {
// {{SQL CARBON EDIT}} - End // {{SQL CARBON EDIT}} - End
if (extension.repository) { if (extension.repository) {
this.repository.onclick = finalHandler(() => window.open(extension.repository)); this.transientDisposables.add(this.onClick(this.repository, () => window.open(extension.repository)));
this.repository.style.display = 'initial'; this.repository.style.display = 'initial';
} }
else { else {
this.repository.onclick = null;
this.repository.style.display = 'none'; this.repository.style.display = 'none';
} }
@@ -712,7 +721,7 @@ export class ExtensionEditor extends BaseEditor {
} }
const details = $('details', { open: true, ontoggle: onDetailsToggle }, const details = $('details', { open: true, ontoggle: onDetailsToggle },
$('summary', undefined, localize('settings', "Settings ({0})", contrib.length)), $('summary', { tabindex: '0' }, localize('settings', "Settings ({0})", contrib.length)),
$('table', undefined, $('table', undefined,
$('tr', undefined, $('tr', undefined,
$('th', undefined, localize('setting name', "Name")), $('th', undefined, localize('setting name', "Name")),
@@ -740,7 +749,7 @@ export class ExtensionEditor extends BaseEditor {
} }
const details = $('details', { open: true, ontoggle: onDetailsToggle }, const details = $('details', { open: true, ontoggle: onDetailsToggle },
$('summary', undefined, localize('debuggers', "Debuggers ({0})", contrib.length)), $('summary', { tabindex: '0' }, localize('debuggers', "Debuggers ({0})", contrib.length)),
$('table', undefined, $('table', undefined,
$('tr', undefined, $('tr', undefined,
$('th', undefined, localize('debugger name', "Name")), $('th', undefined, localize('debugger name', "Name")),
@@ -771,7 +780,7 @@ export class ExtensionEditor extends BaseEditor {
} }
const details = $('details', { open: true, ontoggle: onDetailsToggle }, const details = $('details', { open: true, ontoggle: onDetailsToggle },
$('summary', undefined, localize('viewContainers', "View Containers ({0})", viewContainers.length)), $('summary', { tabindex: '0' }, localize('viewContainers', "View Containers ({0})", viewContainers.length)),
$('table', undefined, $('table', undefined,
$('tr', undefined, $('th', undefined, localize('view container id', "ID")), $('th', undefined, localize('view container title', "Title")), $('th', undefined, localize('view container location', "Where"))), $('tr', undefined, $('th', undefined, localize('view container id', "ID")), $('th', undefined, localize('view container title', "Title")), $('th', undefined, localize('view container location', "Where"))),
...viewContainers.map(viewContainer => $('tr', undefined, $('td', undefined, viewContainer.id), $('td', undefined, viewContainer.title), $('td', undefined, viewContainer.location))) ...viewContainers.map(viewContainer => $('tr', undefined, $('td', undefined, viewContainer.id), $('td', undefined, viewContainer.title), $('td', undefined, viewContainer.location)))
@@ -797,7 +806,7 @@ export class ExtensionEditor extends BaseEditor {
} }
const details = $('details', { open: true, ontoggle: onDetailsToggle }, const details = $('details', { open: true, ontoggle: onDetailsToggle },
$('summary', undefined, localize('views', "Views ({0})", views.length)), $('summary', { tabindex: '0' }, localize('views', "Views ({0})", views.length)),
$('table', undefined, $('table', undefined,
$('tr', undefined, $('th', undefined, localize('view id', "ID")), $('th', undefined, localize('view name', "Name")), $('th', undefined, localize('view location', "Where"))), $('tr', undefined, $('th', undefined, localize('view id', "ID")), $('th', undefined, localize('view name', "Name")), $('th', undefined, localize('view location', "Where"))),
...views.map(view => $('tr', undefined, $('td', undefined, view.id), $('td', undefined, view.name), $('td', undefined, view.location))) ...views.map(view => $('tr', undefined, $('td', undefined, view.id), $('td', undefined, view.name), $('td', undefined, view.location)))
@@ -817,7 +826,7 @@ export class ExtensionEditor extends BaseEditor {
} }
const details = $('details', { open: true, ontoggle: onDetailsToggle }, const details = $('details', { open: true, ontoggle: onDetailsToggle },
$('summary', undefined, localize('localizations', "Localizations ({0})", localizations.length)), $('summary', { tabindex: '0' }, localize('localizations', "Localizations ({0})", localizations.length)),
$('table', undefined, $('table', undefined,
$('tr', undefined, $('th', undefined, localize('localizations language id', "Language Id")), $('th', undefined, localize('localizations language name', "Language Name")), $('th', undefined, localize('localizations localized language name', "Language Name (Localized)"))), $('tr', undefined, $('th', undefined, localize('localizations language id', "Language Id")), $('th', undefined, localize('localizations language name', "Language Name")), $('th', undefined, localize('localizations localized language name', "Language Name (Localized)"))),
...localizations.map(localization => $('tr', undefined, $('td', undefined, localization.languageId), $('td', undefined, localization.languageName || ''), $('td', undefined, localization.localizedLanguageName || ''))) ...localizations.map(localization => $('tr', undefined, $('td', undefined, localization.languageId), $('td', undefined, localization.languageName || ''), $('td', undefined, localization.localizedLanguageName || '')))
@@ -837,7 +846,7 @@ export class ExtensionEditor extends BaseEditor {
} }
const details = $('details', { open: true, ontoggle: onDetailsToggle }, const details = $('details', { open: true, ontoggle: onDetailsToggle },
$('summary', undefined, localize('colorThemes', "Color Themes ({0})", contrib.length)), $('summary', { tabindex: '0' }, localize('colorThemes', "Color Themes ({0})", contrib.length)),
$('ul', undefined, ...contrib.map(theme => $('li', undefined, theme.label))) $('ul', undefined, ...contrib.map(theme => $('li', undefined, theme.label)))
); );
@@ -854,7 +863,7 @@ export class ExtensionEditor extends BaseEditor {
} }
const details = $('details', { open: true, ontoggle: onDetailsToggle }, const details = $('details', { open: true, ontoggle: onDetailsToggle },
$('summary', undefined, localize('iconThemes', "Icon Themes ({0})", contrib.length)), $('summary', { tabindex: '0' }, localize('iconThemes', "Icon Themes ({0})", contrib.length)),
$('ul', undefined, ...contrib.map(theme => $('li', undefined, theme.label))) $('ul', undefined, ...contrib.map(theme => $('li', undefined, theme.label)))
); );
@@ -883,7 +892,7 @@ export class ExtensionEditor extends BaseEditor {
} }
const details = $('details', { open: true, ontoggle: onDetailsToggle }, const details = $('details', { open: true, ontoggle: onDetailsToggle },
$('summary', undefined, localize('colors', "Colors ({0})", colors.length)), $('summary', { tabindex: '0' }, localize('colors', "Colors ({0})", colors.length)),
$('table', undefined, $('table', undefined,
$('tr', undefined, $('tr', undefined,
$('th', undefined, localize('colorId', "Id")), $('th', undefined, localize('colorId', "Id")),
@@ -916,7 +925,7 @@ export class ExtensionEditor extends BaseEditor {
} }
const details = $('details', { open: true, ontoggle: onDetailsToggle }, const details = $('details', { open: true, ontoggle: onDetailsToggle },
$('summary', undefined, localize('JSON Validation', "JSON Validation ({0})", contrib.length)), $('summary', { tabindex: '0' }, localize('JSON Validation', "JSON Validation ({0})", contrib.length)),
$('table', undefined, $('table', undefined,
$('tr', undefined, $('tr', undefined,
$('th', undefined, localize('fileMatch', "File Match")), $('th', undefined, localize('fileMatch', "File Match")),
@@ -990,7 +999,7 @@ export class ExtensionEditor extends BaseEditor {
}; };
const details = $('details', { open: true, ontoggle: onDetailsToggle }, const details = $('details', { open: true, ontoggle: onDetailsToggle },
$('summary', undefined, localize('commands', "Commands ({0})", commands.length)), $('summary', { tabindex: '0' }, localize('commands', "Commands ({0})", commands.length)),
$('table', undefined, $('table', undefined,
$('tr', undefined, $('tr', undefined,
$('th', undefined, localize('command name', "Name")), $('th', undefined, localize('command name', "Name")),
@@ -1057,7 +1066,7 @@ export class ExtensionEditor extends BaseEditor {
} }
const details = $('details', { open: true, ontoggle: onDetailsToggle }, const details = $('details', { open: true, ontoggle: onDetailsToggle },
$('summary', undefined, localize('languages', "Languages ({0})", languages.length)), $('summary', { tabindex: '0' }, localize('languages', "Languages ({0})", languages.length)),
$('table', undefined, $('table', undefined,
$('tr', undefined, $('tr', undefined,
$('th', undefined, localize('language id', "ID")), $('th', undefined, localize('language id', "ID")),
@@ -10,7 +10,7 @@ import { Event, Emitter } from 'vs/base/common/event';
import { isPromiseCanceledError, getErrorMessage } from 'vs/base/common/errors'; import { isPromiseCanceledError, getErrorMessage } from 'vs/base/common/errors';
import { PagedModel, IPagedModel, IPager, DelayedPagedModel } from 'vs/base/common/paging'; import { PagedModel, IPagedModel, IPager, DelayedPagedModel } from 'vs/base/common/paging';
import { SortBy, SortOrder, IQueryOptions } from 'vs/platform/extensionManagement/common/extensionManagement'; import { SortBy, SortOrder, IQueryOptions } from 'vs/platform/extensionManagement/common/extensionManagement';
import { IExtensionManagementServer, IExtensionManagementServerService, IExtensionTipsService, IExtensionRecommendation } from 'vs/workbench/services/extensionManagement/common/extensionManagement'; import { IExtensionManagementServer, IExtensionManagementServerService, IExtensionTipsService, IExtensionRecommendation, EnablementState } from 'vs/workbench/services/extensionManagement/common/extensionManagement';
import { areSameExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil'; import { areSameExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
@@ -44,11 +44,11 @@ import { IAction } from 'vs/base/common/actions';
import { ExtensionType, ExtensionIdentifier, IExtensionDescription, isLanguagePackExtension } from 'vs/platform/extensions/common/extensions'; import { ExtensionType, ExtensionIdentifier, IExtensionDescription, isLanguagePackExtension } from 'vs/platform/extensions/common/extensions';
import { IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService'; import { IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService';
import { CancelablePromise, createCancelablePromise } from 'vs/base/common/async'; import { CancelablePromise, createCancelablePromise } from 'vs/base/common/async';
import { isUIExtension } from 'vs/workbench/services/extensions/common/extensionsUtil';
import { IProductService } from 'vs/platform/product/common/product'; import { IProductService } from 'vs/platform/product/common/product';
import { SeverityIcon } from 'vs/platform/severityIcon/common/severityIcon'; import { SeverityIcon } from 'vs/platform/severityIcon/common/severityIcon';
// {{SQL CARBON EDIT}} import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import product from 'vs/platform/product/node/product';
import product from 'vs/platform/product/node/product'; // {{SQL CARBON EDIT}}
class ExtensionsViewState extends Disposable implements IExtensionsViewState { class ExtensionsViewState extends Disposable implements IExtensionsViewState {
@@ -104,8 +104,9 @@ export class ExtensionsListView extends ViewletPanel {
@IWorkbenchThemeService private readonly workbenchThemeService: IWorkbenchThemeService, @IWorkbenchThemeService private readonly workbenchThemeService: IWorkbenchThemeService,
@IExtensionManagementServerService protected readonly extensionManagementServerService: IExtensionManagementServerService, @IExtensionManagementServerService protected readonly extensionManagementServerService: IExtensionManagementServerService,
@IProductService protected readonly productService: IProductService, @IProductService protected readonly productService: IProductService,
@IContextKeyService contextKeyService: IContextKeyService,
) { ) {
super({ ...(options as IViewletPanelOptions), ariaHeaderLabel: options.title }, keybindingService, contextMenuService, configurationService); super({ ...(options as IViewletPanelOptions), ariaHeaderLabel: options.title }, keybindingService, contextMenuService, configurationService, contextKeyService);
this.server = options.server; this.server = options.server;
} }
@@ -934,9 +935,10 @@ export class ServerExtensionsView extends ExtensionsListView {
@IExtensionsWorkbenchService extensionsWorkbenchService: IExtensionsWorkbenchService, @IExtensionsWorkbenchService extensionsWorkbenchService: IExtensionsWorkbenchService,
@IExtensionManagementServerService extensionManagementServerService: IExtensionManagementServerService, @IExtensionManagementServerService extensionManagementServerService: IExtensionManagementServerService,
@IProductService productService: IProductService, @IProductService productService: IProductService,
@IContextKeyService contextKeyService: IContextKeyService,
) { ) {
options.server = server; options.server = server;
super(options, notificationService, keybindingService, contextMenuService, instantiationService, themeService, extensionService, extensionsWorkbenchService, editorService, tipsService, telemetryService, configurationService, contextService, experimentService, workbenchThemeService, extensionManagementServerService, productService); super(options, notificationService, keybindingService, contextMenuService, instantiationService, themeService, extensionService, extensionsWorkbenchService, editorService, tipsService, telemetryService, configurationService, contextService, experimentService, workbenchThemeService, extensionManagementServerService, productService, contextKeyService);
this._register(onDidChangeTitle(title => this.updateTitle(title))); this._register(onDidChangeTitle(title => this.updateTitle(title)));
} }
@@ -1080,10 +1082,14 @@ export class WorkspaceRecommendedExtensionsView extends ExtensionsListView {
return this.tipsService.getWorkspaceRecommendations() return this.tipsService.getWorkspaceRecommendations()
.then(recommendations => recommendations.filter(({ extensionId }) => { .then(recommendations => recommendations.filter(({ extensionId }) => {
const extension = this.extensionsWorkbenchService.local.filter(i => areSameExtensions({ id: extensionId }, i.identifier))[0]; const extension = this.extensionsWorkbenchService.local.filter(i => areSameExtensions({ id: extensionId }, i.identifier))[0];
if (!extension || !extension.local || extension.state !== ExtensionState.Installed) { if (!extension
|| !extension.local
|| extension.state !== ExtensionState.Installed
|| extension.enablementState === EnablementState.DisabledByExtensionKind
) {
return true; return true;
} }
return isUIExtension(extension.local.manifest, this.productService, this.configurationService) ? extension.server !== this.extensionManagementServerService.localExtensionManagementServer : extension.server !== this.extensionManagementServerService.remoteExtensionManagementServer; return false;
})); }));
} }
} }
@@ -256,11 +256,8 @@
font-weight: bold; font-weight: bold;
font-size: 120%; font-size: 120%;
border-bottom: 1px solid rgba(128, 128, 128, 0.22); border-bottom: 1px solid rgba(128, 128, 128, 0.22);
padding-bottom: 6px; padding: 3px 6px;
} line-height: 22px;
.extension-editor > .body > .content details > summary:focus {
outline: none;
} }
.extension-editor > .body > .content details > summary::-webkit-details-marker { .extension-editor > .body > .content details > summary::-webkit-details-marker {
@@ -386,4 +383,4 @@
font-size: 90%; font-size: 90%;
font-weight: 600; font-weight: 600;
opacity: 0.6; opacity: 0.6;
} }
@@ -12,12 +12,13 @@ export class Query {
} }
static suggestions(query: string): string[] { static suggestions(query: string): string[] {
const commands = ['installed', 'outdated', 'enabled', 'disabled', 'builtin', 'recommended', 'sort', 'category', 'tag', 'ext']; const commands = ['installed', 'outdated', 'enabled', 'disabled', 'builtin', 'recommended', 'sort', 'category', 'tag', 'ext', 'id'];
const subcommands = { const subcommands = {
'sort': ['installs', 'rating', 'name'], 'sort': ['installs', 'rating', 'name'],
'category': ['"programming languages"', 'snippets', 'linters', 'themes', 'debuggers', 'formatters', 'keymaps', '"scm providers"', 'other', '"extension packs"', '"language packs"'], 'category': ['"programming languages"', 'snippets', 'linters', 'themes', 'debuggers', 'formatters', 'keymaps', '"scm providers"', 'other', '"extension packs"', '"language packs"'],
'tag': [''], 'tag': [''],
'ext': [''] 'ext': [''],
'id': ['']
}; };
let queryContains = (substr: string) => query.indexOf(substr) > -1; let queryContains = (substr: string) => query.indexOf(substr) > -1;
@@ -77,4 +78,4 @@ export class Query {
equals(other: Query): boolean { equals(other: Query): boolean {
return this.value === other.value && this.sortBy === other.sortBy; return this.value === other.value && this.sortBy === other.sortBy;
} }
} }
@@ -10,7 +10,7 @@ import { Disposable } from 'vs/base/common/lifecycle';
import { match } from 'vs/base/common/glob'; import { match } from 'vs/base/common/glob';
import * as json from 'vs/base/common/json'; import * as json from 'vs/base/common/json';
import { IExtensionManagementService, IExtensionGalleryService, EXTENSION_IDENTIFIER_PATTERN, InstallOperation, ILocalExtension } from 'vs/platform/extensionManagement/common/extensionManagement'; import { IExtensionManagementService, IExtensionGalleryService, EXTENSION_IDENTIFIER_PATTERN, InstallOperation, ILocalExtension } from 'vs/platform/extensionManagement/common/extensionManagement';
import { IExtensionTipsService, ExtensionRecommendationReason, IExtensionsConfigContent, RecommendationChangeNotification, IExtensionRecommendation, ExtensionRecommendationSource } from 'vs/workbench/services/extensionManagement/common/extensionManagement'; import { IExtensionTipsService, ExtensionRecommendationReason, IExtensionsConfigContent, RecommendationChangeNotification, IExtensionRecommendation, ExtensionRecommendationSource, IExtensionEnablementService, EnablementState } from 'vs/workbench/services/extensionManagement/common/extensionManagement';
import { IModelService } from 'vs/editor/common/services/modelService'; import { IModelService } from 'vs/editor/common/services/modelService';
import { ITextModel } from 'vs/editor/common/model'; import { ITextModel } from 'vs/editor/common/model';
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
@@ -101,6 +101,7 @@ export class ExtensionTipsService extends Disposable implements IExtensionTipsSe
@IModelService private readonly _modelService: IModelService, @IModelService private readonly _modelService: IModelService,
@IStorageService private readonly storageService: IStorageService, @IStorageService private readonly storageService: IStorageService,
@IExtensionManagementService private readonly extensionsService: IExtensionManagementService, @IExtensionManagementService private readonly extensionsService: IExtensionManagementService,
@IExtensionEnablementService private readonly extensionEnablementService: IExtensionEnablementService,
@IInstantiationService private readonly instantiationService: IInstantiationService, @IInstantiationService private readonly instantiationService: IInstantiationService,
@IFileService private readonly fileService: IFileService, @IFileService private readonly fileService: IFileService,
@IWorkspaceContextService private readonly contextService: IWorkspaceContextService, @IWorkspaceContextService private readonly contextService: IWorkspaceContextService,
@@ -433,6 +434,7 @@ export class ExtensionTipsService extends Disposable implements IExtensionTipsSe
} }
this.extensionsService.getInstalled(ExtensionType.User).then(local => { this.extensionsService.getInstalled(ExtensionType.User).then(local => {
local = local.filter(l => this.extensionEnablementService.getEnablementState(l) !== EnablementState.DisabledByExtensionKind); // Filter extensions disabled by kind
const recommendations = filteredRecs.filter(({ extensionId }) => local.every(local => !areSameExtensions({ id: extensionId }, local.identifier))); const recommendations = filteredRecs.filter(({ extensionId }) => local.every(local => !areSameExtensions({ id: extensionId }, local.identifier)));
if (!recommendations.length) { if (!recommendations.length) {
@@ -44,6 +44,8 @@ import { ISharedProcessService } from 'vs/platform/ipc/electron-browser/sharedPr
import { ExtensionManagementServerService } from 'vs/workbench/services/extensionManagement/electron-browser/extensionManagementServerService'; import { ExtensionManagementServerService } from 'vs/workbench/services/extensionManagement/electron-browser/extensionManagementServerService';
import { IProductService } from 'vs/platform/product/common/product'; import { IProductService } from 'vs/platform/product/common/product';
import { ILabelService } from 'vs/platform/label/common/label'; import { ILabelService } from 'vs/platform/label/common/label';
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { MockContextKeyService } from 'vs/platform/keybinding/test/common/mockKeybindingService';
suite('ExtensionsListView Tests', () => { suite('ExtensionsListView Tests', () => {
@@ -93,6 +95,7 @@ suite('ExtensionsListView Tests', () => {
instantiationService.stub(IExtensionManagementService, 'onUninstallExtension', uninstallEvent.event); instantiationService.stub(IExtensionManagementService, 'onUninstallExtension', uninstallEvent.event);
instantiationService.stub(IExtensionManagementService, 'onDidUninstallExtension', didUninstallEvent.event); instantiationService.stub(IExtensionManagementService, 'onDidUninstallExtension', didUninstallEvent.event);
instantiationService.stub(IRemoteAgentService, RemoteAgentService); instantiationService.stub(IRemoteAgentService, RemoteAgentService);
instantiationService.stub(IContextKeyService, MockContextKeyService);
instantiationService.stub(IExtensionManagementServerService, new class extends ExtensionManagementServerService { instantiationService.stub(IExtensionManagementServerService, new class extends ExtensionManagementServerService {
private _localExtensionManagementServer: IExtensionManagementServer = { extensionManagementService: instantiationService.get(IExtensionManagementService), label: 'local', authority: 'vscode-local' }; private _localExtensionManagementServer: IExtensionManagementServer = { extensionManagementService: instantiationService.get(IExtensionManagementService), label: 'local', authority: 'vscode-local' };
@@ -25,6 +25,7 @@ import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/
import { ILabelService } from 'vs/platform/label/common/label'; import { ILabelService } from 'vs/platform/label/common/label';
import { Schemas } from 'vs/base/common/network'; import { Schemas } from 'vs/base/common/network';
import { isWeb } from 'vs/base/common/platform'; import { isWeb } from 'vs/base/common/platform';
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
export class EmptyView extends ViewletPanel { export class EmptyView extends ViewletPanel {
@@ -44,9 +45,10 @@ export class EmptyView extends ViewletPanel {
@IWorkspaceContextService private readonly contextService: IWorkspaceContextService, @IWorkspaceContextService private readonly contextService: IWorkspaceContextService,
@IConfigurationService configurationService: IConfigurationService, @IConfigurationService configurationService: IConfigurationService,
@IWorkbenchEnvironmentService private environmentService: IWorkbenchEnvironmentService, @IWorkbenchEnvironmentService private environmentService: IWorkbenchEnvironmentService,
@ILabelService private labelService: ILabelService @ILabelService private labelService: ILabelService,
@IContextKeyService contextKeyService: IContextKeyService
) { ) {
super({ ...(options as IViewletPanelOptions), ariaHeaderLabel: nls.localize('explorerSection', "Files Explorer Section") }, keybindingService, contextMenuService, configurationService); super({ ...(options as IViewletPanelOptions), ariaHeaderLabel: nls.localize('explorerSection', "Files Explorer Section") }, keybindingService, contextMenuService, configurationService, contextKeyService);
this._register(this.contextService.onDidChangeWorkbenchState(() => this.setLabels())); this._register(this.contextService.onDidChangeWorkbenchState(() => this.setLabels()));
this._register(this.labelService.onDidChangeFormatters(() => this.setLabels())); this._register(this.labelService.onDidChangeFormatters(() => this.setLabels()));
} }
@@ -90,7 +90,7 @@ export class ExplorerView extends ViewletPanel {
@IClipboardService private clipboardService: IClipboardService, @IClipboardService private clipboardService: IClipboardService,
@IFileService private readonly fileService: IFileService @IFileService private readonly fileService: IFileService
) { ) {
super({ ...(options as IViewletPanelOptions), id: ExplorerView.ID, ariaHeaderLabel: nls.localize('explorerSection', "Files Explorer Section") }, keybindingService, contextMenuService, configurationService); super({ ...(options as IViewletPanelOptions), id: ExplorerView.ID, ariaHeaderLabel: nls.localize('explorerSection', "Files Explorer Section") }, keybindingService, contextMenuService, configurationService, contextKeyService);
this.resourceContext = instantiationService.createInstance(ResourceContextKey); this.resourceContext = instantiationService.createInstance(ResourceContextKey);
this._register(this.resourceContext); this._register(this.resourceContext);
@@ -80,7 +80,7 @@ export class OpenEditorsView extends ViewletPanel {
super({ super({
...(options as IViewletPanelOptions), ...(options as IViewletPanelOptions),
ariaHeaderLabel: nls.localize({ key: 'openEditosrSection', comment: ['Open is an adjective'] }, "Open Editors Section"), ariaHeaderLabel: nls.localize({ key: 'openEditosrSection', comment: ['Open is an adjective'] }, "Open Editors Section"),
}, keybindingService, contextMenuService, configurationService); }, keybindingService, contextMenuService, configurationService, contextKeyService);
this.structuralRefreshDelay = 0; this.structuralRefreshDelay = 0;
this.listRefreshScheduler = new RunOnceScheduler(() => { this.listRefreshScheduler = new RunOnceScheduler(() => {
@@ -159,6 +159,7 @@ export class MarkersFilterActionViewItem extends BaseActionViewItem {
toggleLayout(small: boolean) { toggleLayout(small: boolean) {
if (this.container) { if (this.container) {
DOM.toggleClass(this.container, 'small', small); DOM.toggleClass(this.container, 'small', small);
this.adjustInputBox();
} }
} }
@@ -247,7 +248,7 @@ export class MarkersFilterActionViewItem extends BaseActionViewItem {
} }
private adjustInputBox(): void { private adjustInputBox(): void {
this.filterInputBox.inputElement.style.paddingRight = (DOM.getTotalWidth(this.controlsContainer) || 20) + 'px'; this.filterInputBox.inputElement.style.paddingRight = DOM.hasClass(this.container, 'small') || DOM.hasClass(this.filterBadge, 'hidden') ? '25px' : '150px';
} }
// Action toolbar is swallowing some keys for action items which should not be for an input box // Action toolbar is swallowing some keys for action items which should not be for an input box
@@ -266,7 +266,7 @@ export class OutlinePanel extends ViewletPanel {
@IContextKeyService contextKeyService: IContextKeyService, @IContextKeyService contextKeyService: IContextKeyService,
@IContextMenuService contextMenuService: IContextMenuService, @IContextMenuService contextMenuService: IContextMenuService,
) { ) {
super(options, keybindingService, contextMenuService, configurationService); super(options, keybindingService, contextMenuService, configurationService, contextKeyService);
this._outlineViewState.restore(this._storageService); this._outlineViewState.restore(this._storageService);
this._contextKeyFocused = OutlineViewFocused.bindTo(contextKeyService); this._contextKeyFocused = OutlineViewFocused.bindTo(contextKeyService);
this._contextKeyFiltered = OutlineViewFiltered.bindTo(contextKeyService); this._contextKeyFiltered = OutlineViewFiltered.bindTo(contextKeyService);
@@ -135,6 +135,7 @@ export class SettingsEditor2 extends BaseEditor {
private tocFocusedElement: SettingsTreeGroupElement | null; private tocFocusedElement: SettingsTreeGroupElement | null;
private settingsTreeScrollTop = 0; private settingsTreeScrollTop = 0;
private dimension: DOM.Dimension;
constructor( constructor(
@ITelemetryService telemetryService: ITelemetryService, @ITelemetryService telemetryService: ITelemetryService,
@@ -287,10 +288,11 @@ export class SettingsEditor2 extends BaseEditor {
} }
layout(dimension: DOM.Dimension): void { layout(dimension: DOM.Dimension): void {
this.dimension = dimension;
this.layoutTrees(dimension); this.layoutTrees(dimension);
const innerWidth = dimension.width - 24 * 2; // 24px padding on left and right const innerWidth = Math.min(1000, dimension.width) - 24 * 2; // 24px padding on left and right;
const monacoWidth = (innerWidth > 1000 ? 1000 : innerWidth) - 10; const monacoWidth = innerWidth - 10 - this.countElement.clientWidth - 12; // minus padding inside inputbox, countElement width, extra padding before countElement
this.searchWidget.layout({ height: 20, width: monacoWidth }); this.searchWidget.layout({ height: 20, width: monacoWidth });
DOM.toggleClass(this.rootElement, 'mid-width', dimension.width < 1000 && dimension.width >= 600); DOM.toggleClass(this.rootElement, 'mid-width', dimension.width < 1000 && dimension.width >= 600);
@@ -1239,7 +1241,11 @@ export class SettingsEditor2 extends BaseEditor {
: 'none'; : 'none';
if (!this.searchResultModel) { if (!this.searchResultModel) {
this.countElement.style.display = 'none'; if (this.countElement.style.display !== 'none') {
this.countElement.style.display = 'none';
this.layout(this.dimension);
}
DOM.removeClass(this.rootElement, 'no-results'); DOM.removeClass(this.rootElement, 'no-results');
return; return;
} }
@@ -1252,7 +1258,10 @@ export class SettingsEditor2 extends BaseEditor {
default: this.countElement.innerText = localize('moreThanOneResult', "{0} Settings Found", count); default: this.countElement.innerText = localize('moreThanOneResult', "{0} Settings Found", count);
} }
this.countElement.style.display = 'block'; if (this.countElement.style.display !== 'block') {
this.countElement.style.display = 'block';
this.layout(this.dimension);
}
DOM.toggleClass(this.rootElement, 'no-results', count === 0); DOM.toggleClass(this.rootElement, 'no-results', count === 0);
} }
} }
@@ -73,6 +73,8 @@ export class RemoteWindowActiveIndicator extends Disposable implements IWorkbenc
this._register(CommandsRegistry.registerCommand(CLOSE_REMOTE_COMMAND_ID, _ => this.remoteAuthority && windowService.openNewWindow({ reuseWindow: true }))); this._register(CommandsRegistry.registerCommand(CLOSE_REMOTE_COMMAND_ID, _ => this.remoteAuthority && windowService.openNewWindow({ reuseWindow: true })));
this.remoteAuthority = environmentService.configuration.remoteAuthority; this.remoteAuthority = environmentService.configuration.remoteAuthority;
Deprecated_RemoteAuthorityContext.bindTo(this.contextKeyService).set(this.remoteAuthority || '');
if (this.remoteAuthority) { if (this.remoteAuthority) {
// Pending entry until extensions are ready // Pending entry until extensions are ready
this.renderWindowIndicator(nls.localize('host.open', "$(sync~spin) Opening Remote..."), undefined, WINDOW_ACTIONS_COMMAND_ID); this.renderWindowIndicator(nls.localize('host.open', "$(sync~spin) Opening Remote..."), undefined, WINDOW_ACTIONS_COMMAND_ID);
@@ -121,7 +123,7 @@ export class RemoteWindowActiveIndicator extends Disposable implements IWorkbenc
if (this.connectionState !== newState) { if (this.connectionState !== newState) {
this.connectionState = newState; this.connectionState = newState;
RemoteConnectionState.bindTo(this.contextKeyService).set(this.connectionState); RemoteConnectionState.bindTo(this.contextKeyService).set(this.connectionState);
Deprecated_RemoteAuthorityContext.bindTo(this.contextKeyService).set(isDisconnected ? 'disconnected/${this.remoteAuthority!}' : this.remoteAuthority!); Deprecated_RemoteAuthorityContext.bindTo(this.contextKeyService).set(isDisconnected ? `disconnected/${this.remoteAuthority!}` : this.remoteAuthority!);
this.updateWindowIndicator(); this.updateWindowIndicator();
} }
} }
@@ -234,7 +234,7 @@ export class MainPanel extends ViewletPanel {
@IMenuService private readonly menuService: IMenuService, @IMenuService private readonly menuService: IMenuService,
@IConfigurationService configurationService: IConfigurationService @IConfigurationService configurationService: IConfigurationService
) { ) {
super(options, keybindingService, contextMenuService, configurationService); super(options, keybindingService, contextMenuService, configurationService, contextKeyService);
} }
protected renderBody(container: HTMLElement): void { protected renderBody(container: HTMLElement): void {
@@ -324,7 +324,7 @@ export class MainPanel extends ViewletPanel {
} }
private onListSelectionChange(e: IListEvent<ISCMRepository>): void { private onListSelectionChange(e: IListEvent<ISCMRepository>): void {
if (e.elements.length > 0 && e.browserEvent) { if (e.elements.length > 0) {
const scrollTop = this.list.scrollTop; const scrollTop = this.list.scrollTop;
this.viewModel.setVisibleRepositories(e.elements); this.viewModel.setVisibleRepositories(e.elements);
this.list.scrollTop = scrollTop; this.list.scrollTop = scrollTop;
@@ -495,6 +495,7 @@ class ResourceRenderer implements IListRenderer<ISCMResource, ResourceTemplate>
const icon = theme.type === LIGHT ? resource.decorations.icon : resource.decorations.iconDark; const icon = theme.type === LIGHT ? resource.decorations.icon : resource.decorations.iconDark;
template.fileLabel.setFile(resource.sourceUri, { fileDecorations: { colors: false, badges: !icon, data: resource.decorations } }); template.fileLabel.setFile(resource.sourceUri, { fileDecorations: { colors: false, badges: !icon, data: resource.decorations } });
template.actionBar.clear();
template.actionBar.context = resource; template.actionBar.context = resource;
const disposables = new DisposableStore(); const disposables = new DisposableStore();
@@ -733,7 +734,7 @@ export class RepositoryPanel extends ViewletPanel {
@IContextKeyService contextKeyService: IContextKeyService, @IContextKeyService contextKeyService: IContextKeyService,
@IMenuService protected menuService: IMenuService @IMenuService protected menuService: IMenuService
) { ) {
super(options, keybindingService, contextMenuService, configurationService); super(options, keybindingService, contextMenuService, configurationService, contextKeyService);
this.menus = instantiationService.createInstance(SCMMenus, this.repository.provider); this.menus = instantiationService.createInstance(SCMMenus, this.repository.provider);
this._register(this.menus); this._register(this.menus);
@@ -154,7 +154,7 @@ export class SearchView extends ViewletPanel {
@IKeybindingService keybindingService: IKeybindingService, @IKeybindingService keybindingService: IKeybindingService,
@IStorageService storageService: IStorageService, @IStorageService storageService: IStorageService,
) { ) {
super({ ...(options as IViewletPanelOptions), id: VIEW_ID, ariaHeaderLabel: nls.localize('searchView', "Search") }, keybindingService, contextMenuService, configurationService); super({ ...(options as IViewletPanelOptions), id: VIEW_ID, ariaHeaderLabel: nls.localize('searchView', "Search") }, keybindingService, contextMenuService, configurationService, contextKeyService);
this.viewletVisible = Constants.SearchViewVisibleKey.bindTo(contextKeyService); this.viewletVisible = Constants.SearchViewVisibleKey.bindTo(contextKeyService);
this.viewletFocused = Constants.SearchViewFocusedKey.bindTo(contextKeyService); this.viewletFocused = Constants.SearchViewFocusedKey.bindTo(contextKeyService);
@@ -81,10 +81,10 @@ class PartsSplash {
const layoutInfo = !this._shouldSaveLayoutInfo() ? undefined : { const layoutInfo = !this._shouldSaveLayoutInfo() ? undefined : {
sideBarSide: this._layoutService.getSideBarPosition() === Position.RIGHT ? 'right' : 'left', sideBarSide: this._layoutService.getSideBarPosition() === Position.RIGHT ? 'right' : 'left',
editorPartMinWidth: DEFAULT_EDITOR_MIN_DIMENSIONS.width, editorPartMinWidth: DEFAULT_EDITOR_MIN_DIMENSIONS.width,
titleBarHeight: getTotalHeight(this._layoutService.getContainer(Parts.TITLEBAR_PART)), titleBarHeight: this._layoutService.isVisible(Parts.TITLEBAR_PART) ? getTotalHeight(this._layoutService.getContainer(Parts.TITLEBAR_PART)) : 0,
activityBarWidth: getTotalWidth(this._layoutService.getContainer(Parts.ACTIVITYBAR_PART)), activityBarWidth: this._layoutService.isVisible(Parts.ACTIVITYBAR_PART) ? getTotalWidth(this._layoutService.getContainer(Parts.ACTIVITYBAR_PART)) : 0,
sideBarWidth: getTotalWidth(this._layoutService.getContainer(Parts.SIDEBAR_PART)), sideBarWidth: this._layoutService.isVisible(Parts.SIDEBAR_PART) ? getTotalWidth(this._layoutService.getContainer(Parts.SIDEBAR_PART)) : 0,
statusBarHeight: getTotalHeight(this._layoutService.getContainer(Parts.STATUSBAR_PART)), statusBarHeight: this._layoutService.isVisible(Parts.STATUSBAR_PART) ? getTotalHeight(this._layoutService.getContainer(Parts.STATUSBAR_PART)) : 0,
}; };
this._textFileService.write( this._textFileService.write(
URI.file(join(this._envService.userDataPath, 'rapid_render.json')), URI.file(join(this._envService.userDataPath, 'rapid_render.json')),
@@ -29,6 +29,12 @@ const dotnetBuild: TaskEntry = {
'\t\t\t"label": "build",', '\t\t\t"label": "build",',
'\t\t\t"command": "dotnet build",', '\t\t\t"command": "dotnet build",',
'\t\t\t"type": "shell",', '\t\t\t"type": "shell",',
'\t\t\t"args": [',
'\t\t\t\t// Ask dotnet build to generate full paths for file names.',
'\t\t\t\t"/property:GenerateFullPaths=true",',
'\t\t\t\t// Do not generate summary otherwise it leads to duplicate errors in Problems panel',
'\t\t\t\t"/consoleloggerparameters:NoSummary"',
'\t\t\t],',
'\t\t\t"group": "build",', '\t\t\t"group": "build",',
'\t\t\t"presentation": {', '\t\t\t"presentation": {',
'\t\t\t\t"reveal": "silent"', '\t\t\t\t"reveal": "silent"',
@@ -58,7 +64,9 @@ const msbuild: TaskEntry = {
'\t\t\t"args": [', '\t\t\t"args": [',
'\t\t\t\t// Ask msbuild to generate full paths for file names.', '\t\t\t\t// Ask msbuild to generate full paths for file names.',
'\t\t\t\t"/property:GenerateFullPaths=true",', '\t\t\t\t"/property:GenerateFullPaths=true",',
'\t\t\t\t"/t:build"', '\t\t\t\t"/t:build",',
'\t\t\t\t// Do not generate summary otherwise it leads to duplicate errors in Problems panel',
'\t\t\t\t"/consoleloggerparameters:NoSummary"',
'\t\t\t],', '\t\t\t],',
'\t\t\t"group": "build",', '\t\t\t"group": "build",',
'\t\t\t"presentation": {', '\t\t\t"presentation": {',
@@ -211,7 +211,15 @@ export class TerminalProcessManager implements ITerminalProcessManager {
} }
} }
const initialCwd = terminalEnvironment.getCwd(shellLaunchConfig, this._environmentService.userHome, activeWorkspaceRootUri, this._configHelper.config.cwd); const initialCwd = terminalEnvironment.getCwd(
shellLaunchConfig,
this._environmentService.userHome,
lastActiveWorkspace ? lastActiveWorkspace : undefined,
this._configurationResolverService,
activeWorkspaceRootUri,
this._configHelper.config.cwd,
this._logService
);
const envFromConfigValue = this._workspaceConfigurationService.inspect<ITerminalEnvironment | undefined>(`terminal.integrated.env.${platformKey}`); const envFromConfigValue = this._workspaceConfigurationService.inspect<ITerminalEnvironment | undefined>(`terminal.integrated.env.${platformKey}`);
const isWorkspaceShellAllowed = this._configHelper.checkWorkspaceShellPermissions(); const isWorkspaceShellAllowed = this._configHelper.checkWorkspaceShellPermissions();
this._configHelper.showRecommendations(shellLaunchConfig); this._configHelper.showRecommendations(shellLaunchConfig);
@@ -10,6 +10,7 @@ import { IWorkspaceFolder } from 'vs/platform/workspace/common/workspace';
import { IShellLaunchConfig, ITerminalEnvironment } from 'vs/workbench/contrib/terminal/common/terminal'; import { IShellLaunchConfig, ITerminalEnvironment } from 'vs/workbench/contrib/terminal/common/terminal';
import { IConfigurationResolverService } from 'vs/workbench/services/configurationResolver/common/configurationResolver'; import { IConfigurationResolverService } from 'vs/workbench/services/configurationResolver/common/configurationResolver';
import { sanitizeProcessEnvironment } from 'vs/base/common/processes'; import { sanitizeProcessEnvironment } from 'vs/base/common/processes';
import { ILogService } from 'vs/platform/log/common/log';
/** /**
* This module contains utility functions related to the environment, cwd and paths. * This module contains utility functions related to the environment, cwd and paths.
@@ -119,18 +120,37 @@ function _getLangEnvVariable(locale?: string) {
return parts.join('_') + '.UTF-8'; return parts.join('_') + '.UTF-8';
} }
export function getCwd(shell: IShellLaunchConfig, userHome: string, root?: Uri, customCwd?: string): string { export function getCwd(
shell: IShellLaunchConfig,
userHome: string,
lastActiveWorkspace: IWorkspaceFolder | undefined,
configurationResolverService: IConfigurationResolverService | undefined,
root: Uri | undefined,
customCwd: string | undefined,
logService?: ILogService
): string {
if (shell.cwd) { if (shell.cwd) {
return (typeof shell.cwd === 'object') ? shell.cwd.fsPath : shell.cwd; return (typeof shell.cwd === 'object') ? shell.cwd.fsPath : shell.cwd;
} }
let cwd: string | undefined; let cwd: string | undefined;
// TODO: Handle non-existent customCwd
if (!shell.ignoreConfigurationCwd && customCwd) { if (!shell.ignoreConfigurationCwd && customCwd) {
if (path.isAbsolute(customCwd)) { if (configurationResolverService) {
try {
cwd = configurationResolverService.resolve(lastActiveWorkspace, customCwd);
} catch (e) {
// There was an issue resolving a variable, just use the unresolved customCwd which
// which will fail, and log the error in the console.
cwd = customCwd;
if (logService) {
logService.error('Resolving terminal.integrated.cwd', e);
}
}
}
if (path.isAbsolute(customCwd) && !cwd) {
cwd = customCwd; cwd = customCwd;
} else if (root) { } else if (root && !cwd) {
cwd = path.join(root.fsPath, customCwd); cwd = path.join(root.fsPath, customCwd);
} }
} }
@@ -101,31 +101,31 @@ suite('Workbench - TerminalEnvironment', () => {
} }
test('should default to userHome for an empty workspace', () => { test('should default to userHome for an empty workspace', () => {
assertPathsMatch(terminalEnvironment.getCwd({ executable: undefined, args: [] }, '/userHome/', undefined, undefined), '/userHome/'); assertPathsMatch(terminalEnvironment.getCwd({ executable: undefined, args: [] }, '/userHome/', undefined, undefined, undefined, undefined), '/userHome/');
}); });
test('should use to the workspace if it exists', () => { test('should use to the workspace if it exists', () => {
assertPathsMatch(terminalEnvironment.getCwd({ executable: undefined, args: [] }, '/userHome/', Uri.file('/foo'), undefined), '/foo'); assertPathsMatch(terminalEnvironment.getCwd({ executable: undefined, args: [] }, '/userHome/', undefined, undefined, Uri.file('/foo'), undefined), '/foo');
}); });
test('should use an absolute custom cwd as is', () => { test('should use an absolute custom cwd as is', () => {
assertPathsMatch(terminalEnvironment.getCwd({ executable: undefined, args: [] }, '/userHome/', undefined, '/foo'), '/foo'); assertPathsMatch(terminalEnvironment.getCwd({ executable: undefined, args: [] }, '/userHome/', undefined, undefined, undefined, '/foo'), '/foo');
}); });
test('should normalize a relative custom cwd against the workspace path', () => { test('should normalize a relative custom cwd against the workspace path', () => {
assertPathsMatch(terminalEnvironment.getCwd({ executable: undefined, args: [] }, '/userHome/', Uri.file('/bar'), 'foo'), '/bar/foo'); assertPathsMatch(terminalEnvironment.getCwd({ executable: undefined, args: [] }, '/userHome/', undefined, undefined, Uri.file('/bar'), 'foo'), '/bar/foo');
assertPathsMatch(terminalEnvironment.getCwd({ executable: undefined, args: [] }, '/userHome/', Uri.file('/bar'), './foo'), '/bar/foo'); assertPathsMatch(terminalEnvironment.getCwd({ executable: undefined, args: [] }, '/userHome/', undefined, undefined, Uri.file('/bar'), './foo'), '/bar/foo');
assertPathsMatch(terminalEnvironment.getCwd({ executable: undefined, args: [] }, '/userHome/', Uri.file('/bar'), '../foo'), '/foo'); assertPathsMatch(terminalEnvironment.getCwd({ executable: undefined, args: [] }, '/userHome/', undefined, undefined, Uri.file('/bar'), '../foo'), '/foo');
}); });
test('should fall back for relative a custom cwd that doesn\'t have a workspace', () => { test('should fall back for relative a custom cwd that doesn\'t have a workspace', () => {
assertPathsMatch(terminalEnvironment.getCwd({ executable: undefined, args: [] }, '/userHome/', undefined, 'foo'), '/userHome/'); assertPathsMatch(terminalEnvironment.getCwd({ executable: undefined, args: [] }, '/userHome/', undefined, undefined, undefined, 'foo'), '/userHome/');
assertPathsMatch(terminalEnvironment.getCwd({ executable: undefined, args: [] }, '/userHome/', undefined, './foo'), '/userHome/'); assertPathsMatch(terminalEnvironment.getCwd({ executable: undefined, args: [] }, '/userHome/', undefined, undefined, undefined, './foo'), '/userHome/');
assertPathsMatch(terminalEnvironment.getCwd({ executable: undefined, args: [] }, '/userHome/', undefined, '../foo'), '/userHome/'); assertPathsMatch(terminalEnvironment.getCwd({ executable: undefined, args: [] }, '/userHome/', undefined, undefined, undefined, '../foo'), '/userHome/');
}); });
test('should ignore custom cwd when told to ignore', () => { test('should ignore custom cwd when told to ignore', () => {
assertPathsMatch(terminalEnvironment.getCwd({ executable: undefined, args: [], ignoreConfigurationCwd: true }, '/userHome/', Uri.file('/bar'), '/foo'), '/bar'); assertPathsMatch(terminalEnvironment.getCwd({ executable: undefined, args: [], ignoreConfigurationCwd: true }, '/userHome/', undefined, undefined, Uri.file('/bar'), '/foo'), '/bar');
}); });
}); });
}); });
@@ -192,7 +192,7 @@ export class ExtensionHostProcessWorker implements IExtensionHostStarter {
const inspectorUrlMatch = output.data && output.data.match(/ws:\/\/([^\s]+:(\d+)\/[^\s]+)/); const inspectorUrlMatch = output.data && output.data.match(/ws:\/\/([^\s]+:(\d+)\/[^\s]+)/);
if (inspectorUrlMatch) { if (inspectorUrlMatch) {
if (!this._environmentService.isBuilt) { 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) { if (!this._inspectPort) {
this._inspectPort = Number(inspectorUrlMatch[2]); this._inspectPort = Number(inspectorUrlMatch[2]);
@@ -282,15 +282,15 @@ export class ExtensionHostProcessWorker implements IExtensionHostStarter {
return new Promise(resolve => { return new Promise(resolve => {
return findFreePort(startPort, 10 /* try 10 ports */, 5000 /* try up to 5 seconds */).then(port => { return findFreePort(startPort, 10 /* try 10 ports */, 5000 /* try up to 5 seconds */).then(port => {
if (!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 { } else {
if (expected && port !== expected) { 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) { 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 { } 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 }); return resolve({ expected, actual: port });
@@ -434,7 +434,7 @@ export class ExtensionHostProcessWorker implements IExtensionHostStarter {
// Log on main side if running tests from cli // Log on main side if running tests from cli
if (this._isExtensionDevTestFromCli) { 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 // 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/ru.darwin';
import 'vs/workbench/services/keybinding/browser/keyboardLayouts/pt.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/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 { Extensions as ConfigExtensions, IConfigurationRegistry, IConfigurationNode } from 'vs/platform/configuration/common/configurationRegistry';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { INavigatorWithKeyboard } from 'vs/workbench/services/keybinding/common/navigatorKeyboard'; 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 { 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 { export class BrowserKeyboardMapperFactoryBase {
// keyboard mapper // keyboard mapper
@@ -71,9 +71,9 @@ export class BrowserKeyboardMapperFactoryBase {
} }
protected constructor( protected constructor(
private _notificationService: INotificationService, // private _notificationService: INotificationService,
private _storageService: IStorageService, // private _storageService: IStorageService,
private _commandService: ICommandService // private _commandService: ICommandService
) { ) {
this._keyboardMapper = null; this._keyboardMapper = null;
this._initialized = false; this._initialized = false;
@@ -178,32 +178,34 @@ export class BrowserKeyboardMapperFactoryBase {
setActiveKeyMapping(keymap: IKeyboardMapping | null) { setActiveKeyMapping(keymap: IKeyboardMapping | null) {
let matchedKeyboardLayout = this.getMatchedKeymapInfo(keymap); let matchedKeyboardLayout = this.getMatchedKeymapInfo(keymap);
if (matchedKeyboardLayout) { if (matchedKeyboardLayout) {
let score = matchedKeyboardLayout.score; // let score = matchedKeyboardLayout.score;
if (keymap && score < 0) { // Due to https://bugs.chromium.org/p/chromium/issues/detail?id=977609, any key after a dead key will generate a wrong mapping,
const donotAskUpdateKey = 'missing.keyboardlayout.donotask'; // we shoud avoid yielding the false error.
if (this._storageService.getBoolean(donotAskUpdateKey, StorageScope.GLOBAL)) { // if (keymap && score < 0) {
return; // 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 // // the keyboard layout doesn't actually match the key event or the keymap from chromium
this._notificationService.prompt( // this._notificationService.prompt(
Severity.Info, // Severity.Info,
nls.localize('missing.keyboardlayout', 'Fail to find matching keyboard layout'), // nls.localize('missing.keyboardlayout', 'Fail to find matching keyboard layout'),
[{ // [{
label: nls.localize('keyboardLayoutMissing.configure', "Configure"), // label: nls.localize('keyboardLayoutMissing.configure', "Configure"),
run: () => this._commandService.executeCommand('workbench.action.openKeyboardLayoutPicker') // run: () => this._commandService.executeCommand('workbench.action.openKeyboardLayoutPicker')
}, { // }, {
label: nls.localize('neverAgain', "Don't Show Again"), // label: nls.localize('neverAgain', "Don't Show Again"),
isSecondary: true, // isSecondary: true,
run: () => this._storageService.store(donotAskUpdateKey, true, StorageScope.GLOBAL) // 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) { if (!this._activeKeymapInfo) {
this._activeKeymapInfo = matchedKeyboardLayout.result; this._activeKeymapInfo = matchedKeyboardLayout.result;
@@ -336,7 +338,7 @@ export class BrowserKeyboardMapperFactoryBase {
} }
if (mapping.value === '') { 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) { if (keyboardEvent.ctrlKey || keyboardEvent.metaKey) {
setTimeout(() => { setTimeout(() => {
this._getBrowserKeyMapping().then((keymap: IKeyboardMapping) => { this._getBrowserKeyMapping().then((keymap: IKeyboardMapping) => {
@@ -426,7 +428,8 @@ export class BrowserKeyboardMapperFactoryBase {
export class BrowserKeyboardMapperFactory extends BrowserKeyboardMapperFactoryBase { export class BrowserKeyboardMapperFactory extends BrowserKeyboardMapperFactoryBase {
constructor(notificationService: INotificationService, storageService: IStorageService, commandService: ICommandService) { constructor(notificationService: INotificationService, storageService: IStorageService, commandService: ICommandService) {
super(notificationService, storageService, commandService); // super(notificationService, storageService, commandService);
super();
const platform = isWindows ? 'win' : isMacintosh ? 'darwin' : 'linux'; 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 { class TestKeyboardMapperFactory extends BrowserKeyboardMapperFactoryBase {
constructor(notificationService: INotificationService, storageService: IStorageService, commandService: ICommandService) { constructor(notificationService: INotificationService, storageService: IStorageService, commandService: ICommandService) {
super(notificationService, storageService, commandService); // super(notificationService, storageService, commandService);
super();
const keymapInfos: IKeymapInfo[] = KeyboardLayoutContribution.INSTANCE.layoutInfos; const keymapInfos: IKeymapInfo[] = KeyboardLayoutContribution.INSTANCE.layoutInfos;
this._keymapInfos.push(...keymapInfos.map(info => (new KeymapInfo(info.layout, info.secondaryLayouts, info.mapping, info.isUserKeyboardLayout)))); 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(); instance.setUSKeyboardLayout();
assert.equal(instance.activeKeyboardLayout!.isUSStandard, true); assert.equal(instance.activeKeyboardLayout!.isUSStandard, true);
}); });
}); });
@@ -43,7 +43,7 @@ export abstract class AbstractTextMateService extends Disposable implements ITex
private _grammarDefinitions: IValidGrammarDefinition[] | null; private _grammarDefinitions: IValidGrammarDefinition[] | null;
private _grammarFactory: TMGrammarFactory | null; private _grammarFactory: TMGrammarFactory | null;
private _tokenizersRegistrations: IDisposable[]; private _tokenizersRegistrations: IDisposable[];
private _currentTokenColors: ITokenColorizationRule[] | null; protected _currentTheme: IRawTheme | null;
constructor( constructor(
@IModeService private readonly _modeService: IModeService, @IModeService private readonly _modeService: IModeService,
@@ -64,6 +64,8 @@ export abstract class AbstractTextMateService extends Disposable implements ITex
this._grammarFactory = null; this._grammarFactory = null;
this._tokenizersRegistrations = []; this._tokenizersRegistrations = [];
this._currentTheme = null;
grammarsExtPoint.setHandler((extensions) => { grammarsExtPoint.setHandler((extensions) => {
this._grammarDefinitions = null; this._grammarDefinitions = null;
if (this._grammarFactory) { if (this._grammarFactory) {
@@ -242,11 +244,11 @@ export abstract class AbstractTextMateService extends Disposable implements ITex
} }
private _updateTheme(grammarFactory: TMGrammarFactory, colorTheme: IColorTheme, forceUpdate: boolean): void { 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; return;
} }
this._currentTokenColors = colorTheme.tokenColors; this._currentTheme = { name: colorTheme.label, settings: colorTheme.tokenColors };
this._doUpdateTheme(grammarFactory, { name: colorTheme.label, settings: colorTheme.tokenColors }); this._doUpdateTheme(grammarFactory, this._currentTheme);
} }
protected _doUpdateTheme(grammarFactory: TMGrammarFactory, theme: IRawTheme): void { protected _doUpdateTheme(grammarFactory: TMGrammarFactory, theme: IRawTheme): void {

Some files were not shown because too many files have changed in this diff Show More