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/html-language-features/server/src/modes/typescript/*',
'!extensions/*/server/bin/*',
'!src/vs/editor/test/node/classification/typescript-test.ts',
// {{SQL CARBON EDIT}}
'!extensions/notebook/src/intellisense/text.ts',
'!extensions/mssql/src/objectExplorerNodeProvider/webhdfs.ts',
+2 -3
View File
@@ -31,6 +31,7 @@ function extractEditor(options) {
let compilerOptions;
if (tsConfig.extends) {
compilerOptions = Object.assign({}, require(path.join(options.sourcesRoot, tsConfig.extends)).compilerOptions, tsConfig.compilerOptions);
delete tsConfig.extends;
}
else {
compilerOptions = tsConfig.compilerOptions;
@@ -40,9 +41,9 @@ function extractEditor(options) {
compilerOptions.noUnusedLocals = false;
compilerOptions.preserveConstEnums = false;
compilerOptions.declaration = false;
compilerOptions.noImplicitAny = false;
compilerOptions.moduleResolution = ts.ModuleResolutionKind.Classic;
options.compilerOptions = compilerOptions;
console.log(`Running with shakeLevel ${tss.toStringShakeLevel(options.shakeLevel)}`);
let result = tss.shake(options);
for (let fileName in result) {
if (result.hasOwnProperty(fileName)) {
@@ -91,8 +92,6 @@ function extractEditor(options) {
}
delete tsConfig.compilerOptions.moduleResolution;
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.d.ts',
+3 -3
View File
@@ -35,6 +35,7 @@ export function extractEditor(options: tss.ITreeShakingOptions & { destRoot: str
let compilerOptions: { [key: string]: any };
if (tsConfig.extends) {
compilerOptions = Object.assign({}, require(path.join(options.sourcesRoot, tsConfig.extends)).compilerOptions, tsConfig.compilerOptions);
delete tsConfig.extends;
} else {
compilerOptions = tsConfig.compilerOptions;
}
@@ -44,12 +45,13 @@ export function extractEditor(options: tss.ITreeShakingOptions & { destRoot: str
compilerOptions.noUnusedLocals = false;
compilerOptions.preserveConstEnums = false;
compilerOptions.declaration = false;
compilerOptions.noImplicitAny = false;
compilerOptions.moduleResolution = ts.ModuleResolutionKind.Classic;
options.compilerOptions = compilerOptions;
console.log(`Running with shakeLevel ${tss.toStringShakeLevel(options.shakeLevel)}`);
let result = tss.shake(options);
for (let fileName in result) {
if (result.hasOwnProperty(fileName)) {
@@ -100,8 +102,6 @@ export function extractEditor(options: tss.ITreeShakingOptions & { destRoot: str
delete tsConfig.compilerOptions.moduleResolution;
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',
+12 -4
View File
@@ -14,6 +14,17 @@ var ShakeLevel;
ShakeLevel[ShakeLevel["InnerFile"] = 1] = "InnerFile";
ShakeLevel[ShakeLevel["ClassMembers"] = 2] = "ClassMembers";
})(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) {
for (const diag of diagnostics) {
let result = '';
@@ -394,6 +405,7 @@ function markNodes(languageService, options) {
|| memberName === 'toJSON'
|| memberName === 'toString'
|| memberName === 'dispose' // TODO: keeping all `dispose` methods
|| /^_(.*)Brand$/.test(memberName || '') // TODO: keeping all members ending with `Brand`...
) {
enqueue_black(member);
}
@@ -513,10 +525,6 @@ function generateResult(languageService, shakeLevel) {
// keep method
continue;
}
if (/^_(.*)Brand$/.test(member.name.getText())) {
// TODO: keep all members ending with `Brand`...
continue;
}
let pos = member.pos - node.pos;
let end = member.end - node.pos;
toWrite = toWrite.substring(0, pos) + toWrite.substring(end);
+12 -4
View File
@@ -17,6 +17,17 @@ export const enum ShakeLevel {
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 {
/**
* The full path to the root where sources are.
@@ -513,6 +524,7 @@ function markNodes(languageService: ts.LanguageService, options: ITreeShakingOpt
|| memberName === 'toJSON'
|| memberName === 'toString'
|| memberName === 'dispose'// TODO: keeping all `dispose` methods
|| /^_(.*)Brand$/.test(memberName || '') // TODO: keeping all members ending with `Brand`...
) {
enqueue_black(member);
}
@@ -642,10 +654,6 @@ function generateResult(languageService: ts.LanguageService, shakeLevel: ShakeLe
// keep method
continue;
}
if (/^_(.*)Brand$/.test(member.name.getText())) {
// TODO: keep all members ending with `Brand`...
continue;
}
let pos = member.pos - node.pos;
let end = member.end - node.pos;
+2 -2
View File
@@ -306,8 +306,8 @@ function generateDeclarationFile(recipe, sourceFileGetter) {
let usageImports = [];
let usage = [];
let failed = false;
usage.push(`var a;`);
usage.push(`var b;`);
usage.push(`var a: any;`);
usage.push(`var b: any;`);
const generateUsageImport = (moduleId) => {
let importName = 'm' + (++usageCounter);
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;
usage.push(`var a;`);
usage.push(`var b;`);
usage.push(`var a: any;`);
usage.push(`var b: any;`);
const generateUsageImport = (moduleId: string) => {
let importName = 'm' + (++usageCounter);
+1 -1
View File
@@ -44,7 +44,7 @@
"service-downloader": "github:anthonydresser/service-downloader#0.1.5",
"typescript": "3.5.2",
"vsce": "1.48.0",
"vscode-telemetry-extractor": "^1.5.1",
"vscode-telemetry-extractor": "1.5.3",
"xml2js": "^0.4.17"
},
"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"
integrity sha512-OrPrAmcun4+uZAuNcQvE6CCPskh+5AsjANod/Q3zRcJcGNxgoOSGlQN9RPtatkUNmkN8Nn8mZBnS1jMylu/dKg==
vscode-telemetry-extractor@^1.5.1:
version "1.5.1"
resolved "https://registry.yarnpkg.com/vscode-telemetry-extractor/-/vscode-telemetry-extractor-1.5.1.tgz#67249e4ca9c65a21800ca53880732f8cef98d0fa"
integrity sha512-B5SnEdRiDrI4o6NMG9iHmengoaW1rxUQmS/sCaripgnchm+P79JURmKxhfXr5eRo4Mr1QSenFT/SDNaEop7aoQ==
vscode-telemetry-extractor@1.5.3:
version "1.5.3"
resolved "https://registry.yarnpkg.com/vscode-telemetry-extractor/-/vscode-telemetry-extractor-1.5.3.tgz#c17f9065a47425edafd23ea161e80c23274e009d"
integrity sha512-feioJ1e1KyMa9rzblnLbSOduo+Ny0l62H3/bSDgfgCSnU/km+tTSYxPBvZHVr7iQfQGC95J61yC/ObqS9EbaQg==
dependencies:
command-line-args "^5.1.1"
ts-morph "^3.1.3"
@@ -14,7 +14,7 @@ import * as fs from 'fs';
import { URI } from 'vscode-uri';
import * as URL from 'url';
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';
interface ISchemaAssociations {
@@ -103,6 +103,7 @@ function getSchemaRequestService(handledSchemas: { [schema: string]: boolean })
let languageService = getLanguageService({
workspaceContext,
contributions: [],
clientCapabilities: ClientCapabilities.LATEST
});
// 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
set -e
set -ex
if [[ "$OSTYPE" == "darwin"* ]]; then
realpath() { [[ $1 = /* ]] && echo "$1" || echo "$PWD/${1#./}"; }
@@ -58,15 +58,21 @@ function code() {
function code-wsl()
{
# in a wsl shell
local WIN_CODE_CLI_CMD=$(wslpath -w "$ROOT/scripts/code-cli.bat" 2>/dev/null)
if ! [ -z "$WIN_CODE_CLI_CMD" ]; then
ELECTRON="$ROOT/.build/electron/Code - OSS.exe"
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_WLOC=$(cmd.exe /c "$WIN_CODE_CLI_CMD" --locate-extension $WSL_EXT_ID)
if ! [ -z "$WSL_EXT_WLOC" ]; then
local WSL_EXT_WLOC=$(ELECTRON_RUN_AS_NODE=1 "$ROOT/.build/electron/Code - OSS.exe" "out/cli.js" --locate-extension $WSL_EXT_ID)
cd $CWD
if [ -n "$WSL_EXT_WLOC" ]; then
# replace \r\n with \n in WSL_EXT_WLOC
local WSL_CODE=$(wslpath -u "${WSL_EXT_WLOC%%[[:cntrl:]]}")/scripts/wslCode-dev.sh
$WSL_CODE "$ROOT" "$@"
exit $?
else
echo "Remote WSL not installed, trying to run VSCode in WSL."
fi
fi
}
@@ -74,4 +80,4 @@ function code-wsl()
if ! [ -z ${IN_WSL+x} ]; then
code-wsl "$@"
fi
code "$@"
code "$@"
@@ -46,9 +46,10 @@ class AccountPanel extends ViewletPanel {
@IContextMenuService contextMenuService: IContextMenuService,
@IConfigurationService configurationService: IConfigurationService,
@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 {
@@ -121,7 +122,7 @@ export class AccountDialog extends Modal {
@IKeybindingService private _keybindingService: IKeybindingService,
@IConfigurationService private _configurationService: IConfigurationService,
@ITelemetryService telemetryService: ITelemetryService,
@IContextKeyService contextKeyService: IContextKeyService,
@IContextKeyService private readonly contextKeyService: IContextKeyService,
@IClipboardService clipboardService: IClipboardService,
@ILogService logService: ILogService
) {
@@ -290,7 +291,8 @@ export class AccountDialog extends Modal {
this._contextMenuService,
this._configurationService,
this._instantiationService,
this._themeService
this._themeService,
this.contextKeyService
);
attachPanelStyler(providerView, this._themeService);
@@ -42,9 +42,10 @@ export class CategoryView extends ViewletPanel {
options: IViewletPanelOptions,
@IKeybindingService keybindingService: IKeybindingService,
@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
@@ -12,7 +12,7 @@ import { IContextMenuService } from 'vs/platform/contextview/browser/contextView
import { IMenuService, MenuId, MenuItemAction } from 'vs/platform/actions/common/actions';
import { ContextAwareMenuEntryActionViewItem, createAndFillInActionBarActions, createAndFillInContextMenuActions } from 'vs/platform/actions/browser/menuEntryActionViewItem';
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 { IConfigurationService } from 'vs/platform/configuration/common/configuration';
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 { IOEShimService } from 'sql/workbench/parts/objectExplorer/common/objectExplorerViewTreeShim';
import { NodeContextKey } from 'sql/workbench/parts/dataExplorer/common/nodeContext';
import { mssqlProviderName } from 'sql/platform/connection/common/constants';
export class CustomTreeViewPanel extends ViewletPanel {
@@ -60,9 +59,9 @@ export class CustomTreeViewPanel extends ViewletPanel {
@IKeybindingService keybindingService: IKeybindingService,
@IContextMenuService contextMenuService: IContextMenuService,
@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));
this.treeView = treeView as ITreeView;
this._register(this.treeView.onDidChangeActions(() => this.updateActions(), this));
@@ -19,6 +19,7 @@ import {
AddServerAction, AddServerGroupAction
} from 'sql/workbench/parts/objectExplorer/browser/connectionTreeAction';
import { IObjectExplorerService } from 'sql/workbench/services/objectExplorer/common/objectExplorerService';
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
export class ConnectionViewletPanel extends ViewletPanel {
@@ -34,9 +35,10 @@ export class ConnectionViewletPanel extends ViewletPanel {
@IContextMenuService contextMenuService: IContextMenuService,
@IInstantiationService private readonly instantiationService: IInstantiationService,
@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,
AddServerAction.ID,
AddServerAction.LABEL);
@@ -58,9 +58,10 @@ class InsightTableView<T> extends ViewletPanel {
options: IViewletPanelOptions,
@IKeybindingService keybindingService: IKeybindingService,
@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 {
+1 -1
View File
@@ -65,7 +65,7 @@ export class CheckboxActionViewItem extends BaseActionViewItem {
}
}
dipsose(): void {
dispose(): void {
this.disposables.dispose();
super.dispose();
}
@@ -16,6 +16,19 @@
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 {
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:hover {
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 { Disposable } from 'vs/base/common/lifecycle';
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 { InvisibleSizing } from 'vs/base/browser/ui/splitview/splitview';
@@ -197,6 +197,7 @@ export interface IGridOptions {
readonly styles?: IGridStyles;
readonly proportionalLayout?: boolean;
readonly firstViewVisibleCachedSize?: number;
readonly layoutController?: ILayoutController;
}
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; }
private didLayout = false;
constructor(view: T, options: IGridOptions = {}) {
super();
this.gridview = new GridView(options);
@@ -237,6 +240,7 @@ export class Grid<T extends IView = IView> extends Disposable {
layout(width: number, height: number): void {
this.gridview.layout(width, height);
this.didLayout = true;
}
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[] {
if (!this.didLayout) {
throw new Error('Can\'t call getNeighborViews before first layout');
}
const location = this.getViewLocation(view);
const root = this.getViews();
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');
}
const layoutController = new LayoutController(false);
options = { ...options, layoutController };
if (typeof firstLeaf.cachedVisibleSize === 'number') {
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.initialLayoutContext = { width, height, root };
layoutController.isLayoutEnabled = true;
return result;
}
+29 -10
View File
@@ -67,9 +67,18 @@ const defaultStyles: IGridViewStyles = {
separatorBorder: Color.transparent
};
export interface ILayoutController {
readonly isLayoutEnabled: boolean;
}
export class LayoutController implements ILayoutController {
constructor(public isLayoutEnabled: boolean) { }
}
export interface IGridViewOptions {
styles?: IGridViewStyles;
proportionalLayout?: boolean; // default true
readonly styles?: IGridViewStyles;
readonly proportionalLayout?: boolean; // default true
readonly layoutController?: ILayoutController;
}
class BranchNode implements ISplitView, IDisposable {
@@ -466,7 +475,8 @@ class LeafNode implements ISplitView, IDisposable {
constructor(
readonly view: IView,
readonly orientation: Orientation,
orthogonalSize: number = 0
readonly layoutController: ILayoutController,
orthogonalSize: number
) {
this._orthogonalSize = orthogonalSize;
@@ -536,7 +546,10 @@ class LeafNode implements ISplitView, IDisposable {
layout(size: number): void {
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 {
@@ -553,7 +566,10 @@ class LeafNode implements ISplitView, IDisposable {
orthogonalLayout(size: number): void {
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 { }
@@ -584,7 +600,7 @@ function flipNode<T extends Node>(node: T, size: number, orthogonalSize: number)
return result as T;
} 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>();
readonly onDidChange = this._onDidChange.event;
private layoutController: LayoutController;
constructor(options: IGridViewOptions = {}) {
this.element = $('.monaco-grid-view');
this.styles = options.styles || defaultStyles;
this.proportionalLayout = typeof options.proportionalLayout !== 'undefined' ? !!options.proportionalLayout : true;
this.root = new BranchNode(Orientation.VERTICAL, this.styles, this.proportionalLayout);
this.layoutController = options.layoutController || new LayoutController(true);
}
style(styles: IGridViewStyles): void {
@@ -670,7 +689,7 @@ export class GridView implements IDisposable {
const [pathToParent, parent] = this.getNode(rest);
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);
} else {
@@ -690,14 +709,14 @@ export class GridView implements IDisposable {
grandParent.addChild(newParent, parent.size, parentIndex);
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);
if (typeof size !== 'number' && size.type === 'split') {
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);
}
}
@@ -759,7 +778,7 @@ export class GridView implements IDisposable {
grandParent.addChild(child, child.size, parentIndex + i);
}
} 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);
}
+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 (
source[offset] * 2 ** 24
+ 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;
value = value >>> 8;
destination[offset + 2] = value;
+26 -21
View File
@@ -12,7 +12,7 @@ const INITIALIZE = '$initialize';
export interface IWorker extends IDisposable {
getId(): number;
postMessage(message: string): void;
postMessage(message: any, transfer: Transferable[]): void;
}
export interface IWorkerCallback {
@@ -60,7 +60,7 @@ interface IMessageReply {
}
interface IMessageHandler {
sendMessage(msg: string): void;
sendMessage(msg: any, transfer?: ArrayBuffer[]): void;
handleMessage(method: string, args: any[]): Promise<any>;
}
@@ -98,14 +98,7 @@ class SimpleWorkerProtocol {
});
}
public handleMessage(serializedMessage: string): void {
let message: IMessage;
try {
message = JSON.parse(serializedMessage);
} catch (e) {
// nothing
return;
}
public handleMessage(message: IMessage): void {
if (!message || !message.vsWorker) {
return;
}
@@ -167,9 +160,21 @@ class SimpleWorkerProtocol {
}
private _send(msg: IRequestMessage | IReplyMessage): void {
let strMsg = JSON.stringify(msg);
// console.log('SENDING: ' + strMsg);
this._handler.sendMessage(strMsg);
let transfer: ArrayBuffer[] = [];
if (msg.req) {
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(
'vs/base/common/worker/simpleWorker',
(msg: string) => {
(msg: any) => {
this._protocol.handleMessage(msg);
},
(err: any) => {
@@ -208,8 +213,8 @@ export class SimpleWorkerClient<W extends object, H extends object> extends Disp
));
this._protocol = new SimpleWorkerProtocol({
sendMessage: (msg: string): void => {
this._worker.postMessage(msg);
sendMessage: (msg: any, transfer: ArrayBuffer[]): void => {
this._worker.postMessage(msg, transfer);
},
handleMessage: (method: string, args: any[]): Promise<any> => {
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
this._onModuleLoaded = this._protocol.sendMessage(INITIALIZE, [
this._worker.getId(),
loaderConfiguration,
JSON.parse(JSON.stringify(loaderConfiguration)),
moduleId,
hostMethods,
]);
@@ -297,18 +302,18 @@ export class SimpleWorkerServer<H extends object> {
private _requestHandler: IRequestHandler | null;
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._requestHandler = null;
this._protocol = new SimpleWorkerProtocol({
sendMessage: (msg: string): void => {
postSerializedMessage(msg);
sendMessage: (msg: any, transfer: ArrayBuffer[]): void => {
postMessage(msg, transfer);
},
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);
}
+3 -3
View File
@@ -63,7 +63,7 @@ class WebWorker implements IWorker {
} else {
this.worker = Promise.resolve(workerOrPromise);
}
this.postMessage(moduleId);
this.postMessage(moduleId, []);
this.worker.then((w) => {
w.onmessage = function (ev: any) {
onMessageCallback(ev.data);
@@ -79,9 +79,9 @@ class WebWorker implements IWorker {
return this.id;
}
public postMessage(msg: string): void {
public postMessage(message: any, transfer: Transferable[]): void {
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-->
<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>
<body aria-label="">
@@ -35,4 +32,4 @@
<!-- Startup via workbench.js -->
<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 { LanguageId, LanguageIdentifier, FormattingOptions } from 'vs/editor/common/modes';
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.
@@ -779,6 +780,11 @@ export interface ITextModel {
*/
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.
* @internal
+4 -4
View File
@@ -22,7 +22,7 @@ import { IntervalNode, IntervalTree, getNodeIsInOverviewRuler, recomputeMaxEnd }
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 { 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 { LanguageId, LanguageIdentifier, FormattingOptions } from 'vs/editor/common/modes';
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 { withUndefinedAsNull } from 'vs/base/common/types';
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';
function createTextBufferBuilder() {
@@ -1279,7 +1279,7 @@ export class TextModel extends Disposable implements model.ITextModel {
for (let i = 0, len = contentChanges.length; i < len; i++) {
const change = contentChanges[i];
const [eolCount, firstLineLength] = countEOL(change.text);
this._tokens.applyEdits(change.range, eolCount, firstLineLength);
this._tokens.acceptEdit(change.range, eolCount, firstLineLength);
this._onDidChangeDecorations.fire();
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
public setLineTokens(lineNumber: number, tokens: Uint32Array): void {
public setLineTokens(lineNumber: number, tokens: Uint32Array | ArrayBuffer | null): void {
if (lineNumber < 1 || lineNumber > this.getLineCount()) {
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 { Disposable } from 'vs/base/common/lifecycle';
import { StopWatch } from 'vs/base/common/stopwatch';
import { CharCode } from 'vs/base/common/charCode';
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];
}
import { MultilineTokensBuilder, countEOL } from 'vs/editor/common/model/tokensStore';
const enum Constants {
CHEAP_TOKENIZATION_LENGTH_LIMIT = 2048
@@ -117,6 +86,9 @@ export class TokenizationStateStore {
if (deleteCount === 0) {
return;
}
if (start + deleteCount > this._len) {
deleteCount = this._len - start;
}
this._beginState.splice(start, deleteCount);
this._valid.splice(start, 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 { IRange } from 'vs/editor/common/core/range';
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 {
return (
@@ -39,23 +71,226 @@ export class MultilineTokensBuilder {
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 {
public readonly startLineNumber: number;
public readonly tokens: Uint32Array[];
public startLineNumber: number;
public tokens: (Uint32Array | ArrayBuffer | null)[];
constructor(lineNumber: number, tokens: Uint32Array) {
this.startLineNumber = lineNumber;
this.tokens = [tokens];
constructor(startLineNumber: number, tokens: Uint32Array[]) {
this.startLineNumber = startLineNumber;
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 {
private _lineTokens: (ArrayBuffer | null)[];
private _lineTokens: (Uint32Array | ArrayBuffer | null)[];
private _len: number;
constructor() {
@@ -69,13 +304,13 @@ export class TokensStore {
}
public getTokens(topLevelLanguageId: LanguageId, lineIndex: number, lineText: string): LineTokens {
let rawLineTokens: ArrayBuffer | null = null;
let rawLineTokens: Uint32Array | ArrayBuffer | null = null;
if (lineIndex < this._len) {
rawLineTokens = this._lineTokens[lineIndex];
}
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);
@@ -84,7 +319,10 @@ export class TokensStore {
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) {
let hasDifferentLanguageId = false;
if (tokens && tokens.length > 1) {
@@ -97,12 +335,20 @@ export class TokensStore {
}
if (!tokens || tokens.length === 0) {
tokens = new Uint32Array(2);
const tokens = new Uint32Array(2);
tokens[0] = lineTextLength;
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 {
@@ -116,6 +362,9 @@ export class TokensStore {
if (deleteCount === 0) {
return;
}
if (start + deleteCount > this._len) {
deleteCount = this._len - start;
}
this._lineTokens.splice(start, deleteCount);
this._len -= deleteCount;
}
@@ -124,7 +373,7 @@ export class TokensStore {
if (insertCount === 0) {
return;
}
let lineTokens: (ArrayBuffer | null)[] = [];
let lineTokens: (Uint32Array | ArrayBuffer | null)[] = [];
for (let i = 0; i < insertCount; i++) {
lineTokens[i] = null;
}
@@ -132,7 +381,7 @@ export class TokensStore {
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);
this._ensureLine(lineIndex);
this._lineTokens[lineIndex] = tokens;
@@ -140,7 +389,7 @@ export class TokensStore {
//#region Editing
public applyEdits(range: IRange, eolCount: number, firstLineLength: number): void {
public acceptEdit(range: IRange, eolCount: number, firstLineLength: number): void {
this._acceptDeleteRange(range);
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);
const lastLineIndex = range.endLineNumber - 1;
let lastLineTokens: ArrayBuffer | null = null;
let lastLineTokens: Uint32Array | ArrayBuffer | null = null;
if (lastLineIndex < this._len) {
lastLineTokens = TokensStore._deleteBeginning(this._lineTokens[lastLineIndex], range.endColumn - 1);
}
@@ -201,29 +450,29 @@ export class TokensStore {
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) {
return lineTokens;
}
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) {
return lineTokens;
}
const tokens = new Uint32Array(lineTokens);
const tokens = toUint32Array(lineTokens);
const lineTextLength = tokens[tokens.length - 2];
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) {
return lineTokens;
}
const tokens = new Uint32Array(lineTokens);
const tokens = toUint32Array(lineTokens);
const tokensCount = (tokens.length >>> 1);
// special case: deleting everything
@@ -275,7 +524,7 @@ export class TokensStore {
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) {
return lineTokens;
}
@@ -289,8 +538,8 @@ export class TokensStore {
// cannot determine combined line length...
return null;
}
const myTokens = new Uint32Array(lineTokens);
const otherTokens = new Uint32Array(_otherTokens);
const myTokens = toUint32Array(lineTokens);
const otherTokens = toUint32Array(_otherTokens);
const otherTokensCount = (otherTokens.length >>> 1);
let result = new Uint32Array(myTokens.length + otherTokens.length);
@@ -304,13 +553,13 @@ export class TokensStore {
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) {
// nothing to do
return lineTokens;
}
const tokens = new Uint32Array(lineTokens);
const tokens = toUint32Array(lineTokens);
const tokensCount = (tokens.length >>> 1);
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;
const preserveCase = this._state.preserveCase;
if (replacePattern.hasReplacementPatterns) {
if (replacePattern.hasReplacementPatterns || preserveCase) {
resultText = modelText.replace(searchRegex, function () {
return replacePattern.buildReplaceString(<string[]><any>arguments, preserveCase);
});
@@ -500,7 +500,7 @@ export class FindModelBoundToEditorModel {
private _regularReplaceAll(findScope: Range | null): void {
const replacePattern = this._getReplacePattern();
// 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[] = [];
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({
actionClassName: 'monaco-case-sensitive',
actionClassName: 'monaco-preserve-case',
title: NLS_PRESERVE_CASE_LABEL,
isChecked: false,
}));
@@ -1947,6 +1947,42 @@ suite('FindModel', () => {
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) => {
let findState = new FindReplaceState();
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 { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService';
import { CancellationToken } from 'vs/base/common/cancellation';
import { coalesce, flatten } from 'vs/base/common/arrays';
export const defaultReferenceSearchOptions: RequestOptions = {
getMetaTitle(model) {
@@ -287,15 +288,7 @@ export function provideReferences(model: ITextModel, position: Position, token:
});
});
return Promise.all(promises).then(references => {
let result: Location[] = [];
for (let ref of references) {
if (ref) {
result.push(...ref);
}
}
return result;
});
return Promise.all(promises).then(references => flatten(coalesce(references)));
}
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 { EditorAction, ServicesAccessor, registerEditorAction } from 'vs/editor/browser/editorExtensions';
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 {
constructor() {
@@ -31,51 +29,6 @@ class ForceRetokenizeAction extends EditorAction {
sw.stop();
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;
}
if (mimetypeOrModeId === this._modeId) {
// embedding myself...
return mimetypeOrModeId;
}
let modeId = this._modeService.getModeId(mimetypeOrModeId);
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 {
mapDefined(key: string): ContextKeyDefinedExpr;
mapNot(key: string): ContextKeyNotExpr;
mapEquals(key: string, value: any): ContextKeyEqualsExpr;
mapNotEquals(key: string, value: any): ContextKeyNotEqualsExpr;
mapDefined(key: string): ContextKeyExpr;
mapNot(key: string): ContextKeyExpr;
mapEquals(key: string, value: any): ContextKeyExpr;
mapNotEquals(key: string, value: any): ContextKeyExpr;
mapRegex(key: string, regexp: RegExp | null): ContextKeyRegexExpr;
}
@@ -217,7 +217,7 @@ function cmp(a: ContextKeyExpr, b: ContextKeyExpr): number {
}
export class ContextKeyDefinedExpr implements ContextKeyExpr {
public static create(key: string): ContextKeyExpr {
public static create(key: string): ContextKeyDefinedExpr {
return new ContextKeyDefinedExpr(key);
}
@@ -451,7 +451,7 @@ export class ContextKeyNotExpr 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);
}
+24 -3
View File
@@ -10,7 +10,28 @@ export class SignService implements ISignService {
_serviceBrand: ServiceIdentifier<ISignService>;
async sign(value: string): Promise<string> {
return Promise.resolve(document.getElementById('vscode-remote-connection-token')!.getAttribute('data-settings')!);
private readonly _tkn: string | null;
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,
listFilterWidgetNoMatchesOutline: listFilterWidgetNoMatchesOutline,
listMatchesShadow: widgetShadow,
treeIndentGuidesStroke
treeIndentGuidesStroke: treeIndentGuidesStroke
};
export interface IButtonStyleOverrides extends IStyleOverrides {
@@ -357,4 +357,4 @@ export const defaultDialogStyles = <IDialogStyleOverrides>{
export function attachDialogStyler(widget: IThemable, themeService: IThemeService, style?: IDialogStyleOverrides): IDisposable {
return attachStyler(themeService, { ...defaultDialogStyles, ...style }, widget);
}
}
+1 -1
View File
@@ -156,7 +156,7 @@ export interface IWindowsService {
openExtensionDevelopmentHostWindow(args: ParsedArgs, env: IProcessEnvironment): Promise<void>;
getWindows(): Promise<{ id: number; workspace?: IWorkspaceIdentifier; folderUri?: ISingleFolderWorkspaceIdentifier; title: string; filename?: string; }[]>;
getWindowCount(): Promise<number>;
log(severity: string, ...messages: string[]): Promise<void>;
log(severity: string, args: string[]): Promise<void>;
showItemInFolder(path: URI): Promise<void>;
getActiveWindowId(): Promise<number | undefined>;
@@ -226,8 +226,8 @@ export class WindowsService implements IWindowsService {
return this.channel.call('getWindowCount');
}
log(severity: string, ...messages: string[]): Promise<void> {
return this.channel.call('log', [severity, messages]);
log(severity: string, args: string[]): Promise<void> {
return this.channel.call('log', [severity, args]);
}
showItemInFolder(path: URI): Promise<void> {
@@ -334,7 +334,7 @@ export class WindowsService extends Disposable implements IWindowsService, IURLH
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;
switch (severity) {
@@ -349,7 +349,7 @@ export class WindowsService extends Disposable implements IWindowsService, IURLH
break;
}
consoleFn(...messages);
consoleFn.call(console, ...args);
}
async showItemInFolder(resource: URI): Promise<void> {
+7
View File
@@ -4283,6 +4283,13 @@ declare module 'vscode' {
* instead of fading it out.
*/
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
//#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
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
@@ -51,21 +51,21 @@ export class TextEditorEdit {
private readonly _document: vscode.TextDocument;
private readonly _documentVersionId: number;
private _collectedEdits: ITextEditOperation[];
private _setEndOfLine: EndOfLine | undefined;
private readonly _undoStopBefore: 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; }) {
this._document = document;
this._documentVersionId = document.version;
this._collectedEdits = [];
this._setEndOfLine = undefined;
this._undoStopBefore = options.undoStopBefore;
this._undoStopAfter = options.undoStopAfter;
}
finalize(): IEditData {
this._finalized = true;
return {
documentVersionId: this._documentVersionId,
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 {
this._throwIfFinalized();
let range: Range | null = null;
if (location instanceof Position) {
@@ -90,10 +97,12 @@ export class TextEditorEdit {
}
insert(location: Position, value: string): void {
this._throwIfFinalized();
this._pushEdit(new Range(location, location), value, true);
}
delete(location: Range | Selection): void {
this._throwIfFinalized();
let range: Range | null = null;
if (location instanceof Range) {
@@ -115,6 +124,7 @@ export class TextEditorEdit {
}
setEndOfLine(endOfLine: EndOfLine): void {
this._throwIfFinalized();
if (endOfLine !== EndOfLine.LF && endOfLine !== EndOfLine.CRLF) {
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 initialCwd = terminalEnvironment.getCwd(shellLaunchConfig, os.homedir(), activeWorkspaceRootUri, terminalConfig.cwd);
// Get the environment
const apiLastActiveWorkspace = await this._extHostWorkspace.getWorkspaceFolder(activeWorkspaceRootUri);
const lastActiveWorkspace = apiLastActiveWorkspace ? {
@@ -597,6 +593,12 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape {
throw new Error('Not implemented');
}
} 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 baseEnv = terminalConfig.get<boolean>('inheritEnv', true) ? process.env as platform.IProcessEnvironment : await this._getNonInheritedEnv();
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 { IEditorService, IResourceEditor } from 'vs/workbench/services/editor/common/editorService';
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 { IDimension } from 'vs/platform/layout/browser/layoutService';
import { Part } from 'vs/workbench/browser/part';
@@ -749,21 +749,25 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi
try {
workbenchGrid = SerializableGrid.deserialize(parsedGrid, { fromJSON }, { proportionalLayout: false });
// Set some layout state
this.state.sideBar.position = Position.LEFT;
for (let view of workbenchGrid.getNeighborViews(this.sideBarPartView, Direction.Right)) {
if (view === this.activityBarPartView) {
this.state.sideBar.position = Position.RIGHT;
}
const root = workbenchGrid.getViews();
const titleBarSection = root.children[0];
if (isGridBranchNode(titleBarSection) || titleBarSection.view !== this.titleBarPartView) {
throw new Error('Bad grid');
}
this.state.panel.position = Position.BOTTOM;
for (let view of workbenchGrid.getNeighborViews(this.panelPartView, Direction.Left)) {
if (view === this.editorPartView) {
this.state.panel.position = Position.RIGHT;
}
const middleSection = root.children[1] as GridBranchNode<ISerializableView>;
const sideBarPosition = (middleSection.children[0] as GridLeafNode<ISerializableView>).view === this.activityBarPartView ? Position.LEFT : Position.RIGHT;
if (sideBarPosition !== this.state.sideBar.position) {
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) {
workbenchGrid = undefined;
console.error(err);
}
}
@@ -783,6 +787,10 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi
this.setPanelHidden(!visible, true);
}));
this._register((this.editorPartView as PanelPart).onDidVisibilityChange((visible) => {
this.setEditorHidden(!visible, true);
}));
this._register(this.lifecycleService.onBeforeShutdown(beforeShutdownEvent => {
beforeShutdownEvent.veto(new Promise((resolve) => {
const grid = this.workbenchGrid as SerializableGrid<ISerializableView>;
@@ -849,8 +857,9 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi
statusBarInGrid = true;
}
if (!titlebarInGrid && getTitleBarStyle(this.configurationService, this.environmentService) === 'custom') {
if (!titlebarInGrid) {
this.workbenchGrid.addView(this.titleBarPartView, Sizing.Split, this.editorPartView, Direction.Up);
titlebarInGrid = true;
}
@@ -1157,6 +1166,11 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi
} else {
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);
@@ -1166,6 +1180,10 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi
}
isPanelMaximized(): boolean {
if (!this.workbenchGrid) {
return false;
}
if (this.workbenchGrid instanceof Grid) {
try {
// 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>());
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
private readonly workspaceMemento: MementoObject;
@@ -743,6 +746,8 @@ export class EditorPart extends Part implements IEditorGroupsService, IEditorGro
get minimumHeight(): number { return this.centeredLayoutWidget.minimumHeight; }
get maximumHeight(): number { return this.centeredLayoutWidget.maximumHeight; }
readonly snap = true;
get onDidChange(): Event<IViewSize | undefined> { return this.centeredLayoutWidget.onDidChange; }
readonly priority: LayoutPriority = LayoutPriority.High;
@@ -986,6 +991,10 @@ export class EditorPart extends Part implements IEditorGroupsService, IEditorGro
//#endregion
setVisible(visible: boolean): void {
this._onDidVisibilityChange.fire(visible);
}
toJSON(): object {
return {
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 { ContextAwareMenuEntryActionViewItem, createAndFillInActionBarActions, createAndFillInContextMenuActions } from 'vs/platform/actions/browser/menuEntryActionViewItem';
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 { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { INotificationService } from 'vs/platform/notification/common/notification';
@@ -56,9 +56,9 @@ export class CustomTreeViewPanel extends ViewletPanel {
@IKeybindingService keybindingService: IKeybindingService,
@IContextMenuService contextMenuService: IContextMenuService,
@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));
this.treeView = treeView;
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());
const customTreeNavigator = new TreeResourceNavigator2(this.tree);
const customTreeNavigator = new TreeResourceNavigator2(this.tree, { openOnFocus: false, openOnSelection: false });
this._register(customTreeNavigator);
this._register(customTreeNavigator.onDidOpenResource(e => {
if (!e.browserEvent) {
@@ -113,7 +113,8 @@
flex: 1;
text-overflow: ellipsis;
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 {
@@ -156,4 +157,4 @@
background-size: 16px;
background-position: 50% 50%;
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 { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService';
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 { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
export interface IPanelColors extends IColorMapping {
dropBackground?: ColorIdentifier;
@@ -58,6 +59,8 @@ export abstract class ViewletPanel extends Panel implements IView {
protected _onDidChangeTitleArea = this._register(new Emitter<void>());
readonly onDidChangeTitleArea: Event<void> = this._onDidChangeTitleArea.event;
private focusedViewContextKey: IContextKey<string>;
private _isVisible: boolean = false;
readonly id: string;
readonly title: string;
@@ -71,13 +74,15 @@ export abstract class ViewletPanel extends Panel implements IView {
options: IViewletPanelOptions,
@IKeybindingService protected keybindingService: IKeybindingService,
@IContextMenuService protected contextMenuService: IContextMenuService,
@IConfigurationService protected readonly configurationService: IConfigurationService
@IConfigurationService protected readonly configurationService: IConfigurationService,
@IContextKeyService contextKeyService: IContextKeyService
) {
super(options);
this.id = options.id;
this.title = options.title;
this.actionRunner = options.actionRunner;
this.focusedViewContextKey = FocusedViewContext.bindTo(contextKeyService);
}
setVisible(visible: boolean): void {
@@ -112,8 +117,14 @@ export abstract class ViewletPanel extends Panel implements IView {
const focusTracker = trackFocus(this.element);
this._register(focusTracker);
this._register(focusTracker.onDidFocus(() => this._onDidFocus.fire()));
this._register(focusTracker.onDidBlur(() => this._onDidBlur.fire()));
this._register(focusTracker.onDidFocus(() => {
this.focusedViewContextKey.set(this.id);
this._onDidFocus.fire();
}));
this._register(focusTracker.onDidBlur(() => {
this.focusedViewContextKey.reset();
this._onDidBlur.fire();
}));
}
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 { Event, Emitter } from 'vs/base/common/event';
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 { CommandsRegistry } from 'vs/platform/commands/common/commands';
import { localize } from 'vs/nls';
@@ -205,9 +205,9 @@ class ViewDescriptorCollection extends Disposable implements IViewDescriptorColl
}
export interface IViewState {
visibleGlobal: boolean;
visibleWorkspace: boolean;
collapsed: boolean;
visibleGlobal: boolean | undefined;
visibleWorkspace: boolean | undefined;
collapsed: boolean | undefined;
order?: number;
size?: number;
}
@@ -287,7 +287,7 @@ export class ContributableViewsModel extends Disposable {
}
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 {
this._onDidRemove.fire([{ index: visibleIndex, viewDescriptor }]);
}
@@ -300,7 +300,7 @@ export class ContributableViewsModel extends Disposable {
throw new Error(`Unknown view ${id}`);
}
return state.collapsed;
return !!state.collapsed;
}
setCollapsed(id: string, collapsed: boolean): void {
@@ -354,7 +354,7 @@ export class ContributableViewsModel extends Disposable {
if (!viewState) {
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 } {
@@ -444,7 +444,7 @@ export class ContributableViewsModel extends Disposable {
const state = this.viewStates.get(viewDescriptor.id)!;
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 {
private viewletStateStorageId: string;
private readonly hiddenViewsStorageId: string;
private readonly workspaceViewsStateStorageId: string;
private readonly globalViewsStateStorageId: string;
private storageService: IStorageService;
@@ -474,13 +487,13 @@ export class PersistentContributableViewsModel extends ContributableViewsModel {
@IViewsService viewsService: IViewsService,
@IStorageService storageService: IStorageService,
) {
const hiddenViewsStorageId = `${viewletStateStorageId}.hidden`;
const viewStates = PersistentContributableViewsModel.loadViewsStates(viewletStateStorageId, hiddenViewsStorageId, storageService);
const globalViewsStateStorageId = `${viewletStateStorageId}.hidden`;
const viewStates = PersistentContributableViewsModel.loadViewsStates(viewletStateStorageId, globalViewsStateStorageId, storageService);
super(container, viewsService, viewStates);
this.viewletStateStorageId = viewletStateStorageId;
this.hiddenViewsStorageId = hiddenViewsStorageId;
this.workspaceViewsStateStorageId = viewletStateStorageId;
this.globalViewsStateStorageId = globalViewsStateStorageId;
this.storageService = storageService;
this._register(Event.any(
@@ -492,84 +505,106 @@ export class PersistentContributableViewsModel extends ContributableViewsModel {
}
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;
for (const viewDescriptor of this.viewDescriptors) {
const viewState = this.viewStates.get(viewDescriptor.id);
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;
}
}
if (hasState) {
this.storageService.store(this.viewletStateStorageId, JSON.stringify(storedViewsStates), StorageScope.WORKSPACE);
this.storageService.store(this.workspaceViewsStateStorageId, JSON.stringify(storedViewsStates), StorageScope.WORKSPACE);
} else {
this.storageService.remove(this.viewletStateStorageId, 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);
this.storageService.remove(this.workspaceViewsStateStorageId, StorageScope.WORKSPACE);
}
}
private saveVisibilityStatesInScope(viewDescriptors: IViewDescriptor[], scope: StorageScope): void {
const storedViewsVisibilityStates = PersistentContributableViewsModel.loadViewsVisibilityState(this.hiddenViewsStorageId, this.storageService, scope);
for (const viewDescriptor of viewDescriptors) {
if (viewDescriptor.canToggleVisibility) {
const viewState = this.viewStates.get(viewDescriptor.id);
storedViewsVisibilityStates.set(viewDescriptor.id, { id: viewDescriptor.id, isHidden: viewState ? (scope === StorageScope.GLOBAL ? !viewState.visibleGlobal : !viewState.visibleWorkspace) : false });
}
private saveGlobalViewsStates(): void {
const storedViewsVisibilityStates = PersistentContributableViewsModel.loadGlobalViewsState(this.globalViewsStateStorageId, this.storageService, StorageScope.GLOBAL);
for (const viewDescriptor of this.viewDescriptors) {
const viewState = this.viewStates.get(viewDescriptor.id);
storedViewsVisibilityStates.set(viewDescriptor.id, {
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 storedViewsStates = JSON.parse(storageService.get(viewletStateStorageId, StorageScope.WORKSPACE, '{}'));
const globalVisibilityStates = this.loadViewsVisibilityState(hiddenViewsStorageId, storageService, StorageScope.GLOBAL);
const workspaceVisibilityStates = this.loadViewsVisibilityState(hiddenViewsStorageId, storageService, StorageScope.WORKSPACE);
const workspaceViewsStates = <{ [id: string]: IStoredWorkspaceViewState }>JSON.parse(storageService.get(workspaceViewsStateStorageId, StorageScope.WORKSPACE, '{}'));
for (const id of Object.keys(workspaceViewsStates)) {
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)) {
const viewState = storedViewsStates[id];
if (viewState) {
viewStates.set(id, <IViewState>{ ...viewState, ...{ visibleGlobal: !isHidden } });
} else {
// New workspace
viewStates.set(id, <IViewState>{ ...{ visibleGlobal: !isHidden } });
// Migrate to `viewletStateStorageId`
const workspaceVisibilityStates = this.loadGlobalViewsState(globalViewsStateStorageId, storageService, StorageScope.WORKSPACE);
if (workspaceVisibilityStates.size > 0) {
for (const { id, isHidden } of values(workspaceVisibilityStates)) {
let viewState = viewStates.get(id);
// Not migrated to `viewletStateStorageId`
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) {
viewStates.set(id, <IViewState>{ ...viewState, ...{ visibleWorkspace: !isHidden } });
viewState.visibleGlobal = !isHidden;
if (!isUndefined(order)) {
viewState.order = order;
}
} else {
// New workspace
viewStates.set(id, <IViewState>{ ...{ visibleWorkspace: !isHidden } });
}
}
for (const id of Object.keys(storedViewsStates)) {
if (!viewStates.has(id)) {
viewStates.set(id, <IViewState>{ ...storedViewsStates[id] });
viewStates.set(id, {
visibleGlobal: !isHidden,
order,
collapsed: undefined,
visibleWorkspace: undefined,
});
}
}
return viewStates;
}
private static loadViewsVisibilityState(hiddenViewsStorageId: string, storageService: IStorageService, scope: StorageScope): Map<string, { id: string, isHidden: boolean }> {
const storedVisibilityStates = <Array<string | { id: string, isHidden: boolean }>>JSON.parse(storageService.get(hiddenViewsStorageId, scope, '[]'));
private static loadGlobalViewsState(globalViewsStateStorageId: string, storageService: IStorageService, scope: StorageScope): Map<string, IStoredGlobalViewState> {
const storedValue = <Array<string | IStoredGlobalViewState>>JSON.parse(storageService.get(globalViewsStateStorageId, scope, '[]'));
let hasDuplicates = false;
const storedViewsVisibilityStates = storedVisibilityStates.reduce((result, storedState) => {
const storedGlobalViewsState = storedValue.reduce((result, storedState) => {
if (typeof storedState === 'string' /* migration */) {
hasDuplicates = hasDuplicates || result.has(storedState);
result.set(storedState, { id: storedState, isHidden: true });
@@ -578,13 +613,13 @@ export class PersistentContributableViewsModel extends ContributableViewsModel {
result.set(storedState.id, storedState);
}
return result;
}, new Map<string, { id: string, isHidden: boolean }>());
}, new Map<string, IStoredGlobalViewState>());
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);
// Signing
const signService = new SignService();
const signService = new SignService(this.configuration.connectionToken);
serviceCollection.set(ISignService, signService);
// Remote Agent
@@ -801,7 +801,7 @@ export class SimpleWindowsService implements IWindowsService {
return Promise.resolve(this.windowCount);
}
log(_severity: string, ..._messages: string[]): Promise<void> {
log(_severity: string, _args: string[]): Promise<void> {
return Promise.resolve();
}
+2 -1
View File
@@ -6,7 +6,7 @@
import { Command } from 'vs/editor/common/modes';
import { UriComponents } from 'vs/base/common/uri';
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 { localize } from 'vs/nls';
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';
export const TEST_VIEW_CONTAINER_ID = 'workbench.view.extension.test';
export const FocusedViewContext = new RawContextKey<string>('focusedView', '');
export namespace Extensions {
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 { ViewletPanel, IViewletPanelOptions } from 'vs/workbench/browser/parts/views/panelViewlet';
import { ILabelService } from 'vs/platform/label/common/label';
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
const $ = dom.$;
@@ -56,9 +57,10 @@ export class BreakpointsView extends ViewletPanel {
@IThemeService private readonly themeService: IThemeService,
@IEditorService private readonly editorService: IEditorService,
@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._register(this.debugService.getModel().onDidChangeBreakpoints(() => this.onBreakpointsChange()));
@@ -60,7 +60,7 @@ export class CallStackView extends ViewletPanel {
@IMenuService menuService: IMenuService,
@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.contributedContextMenu = menuService.createMenu(MenuId.DebugCallStackContext, contextKeyService);
@@ -402,7 +402,7 @@ export class LoadedScriptsView extends ViewletPanel {
@IDebugService private readonly debugService: IDebugService,
@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);
}
@@ -29,6 +29,7 @@ import { onUnexpectedError } from 'vs/base/common/errors';
import { FuzzyScore, createMatches } from 'vs/base/common/filters';
import { HighlightedLabel, IHighlight } from 'vs/base/browser/ui/highlightedlabel/highlightedLabel';
import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService';
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
const $ = dom.$;
let forgetScopes = true;
@@ -49,9 +50,10 @@ export class VariablesView extends ViewletPanel {
@IKeybindingService keybindingService: IKeybindingService,
@IConfigurationService configurationService: IConfigurationService,
@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
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 { IHighlight } from 'vs/base/browser/ui/highlightedlabel/highlightedLabel';
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;
@@ -45,8 +46,9 @@ export class WatchExpressionsView extends ViewletPanel {
@IKeybindingService keybindingService: IKeybindingService,
@IInstantiationService private readonly instantiationService: IInstantiationService,
@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.needsRefresh = false;
@@ -13,9 +13,9 @@ import { Event, Emitter } from 'vs/base/common/event';
import { Cache, CacheResult } from 'vs/base/common/cache';
import { Action } from 'vs/base/common/actions';
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 { 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 { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet';
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 { URI } from 'vs/base/common/uri';
import { IWebviewService, Webview } from 'vs/workbench/contrib/webview/common/webview';
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
// {{SQL CARBON EDIT}}
import { renderDashboardContributions } from 'sql/workbench/parts/extensions/browser/contributionRenders';
@@ -280,6 +281,20 @@ export class ExtensionEditor extends BaseEditor {
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> {
const runningExtensions = await this.extensionService.getExtensions();
const colorThemes = await this.workbenchThemeService.getColorThemes();
@@ -328,26 +343,21 @@ export class ExtensionEditor extends BaseEditor {
toggleClass(this.publisher, 'clickable', !!extension.url);
toggleClass(this.rating, 'clickable', !!extension.url);
if (extension.url) {
this.name.onclick = finalHandler(() => window.open(extension.url));
this.rating.onclick = finalHandler(() => window.open(`${extension.url}#review-details`));
this.publisher.onclick = finalHandler(() => {
this.transientDisposables.add(this.onClick(this.name, () => window.open(extension.url)));
this.transientDisposables.add(this.onClick(this.rating, () => window.open(`${extension.url}#review-details`)));
this.transientDisposables.add(this.onClick(this.publisher, () => {
this.viewletService.openViewlet(VIEWLET_ID, true)
.then(viewlet => viewlet as IExtensionsViewlet)
.then(viewlet => viewlet.search(`publisher:"${extension.publisherDisplayName}"`));
});
}));
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';
} else {
this.license.onclick = null;
this.license.style.display = 'none';
}
} else {
this.name.onclick = null;
this.rating.onclick = null;
this.publisher.onclick = null;
this.license.onclick = null;
this.license.style.display = 'none';
}
@@ -362,11 +372,10 @@ export class ExtensionEditor extends BaseEditor {
// {{SQL CARBON EDIT}} - End
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';
}
else {
this.repository.onclick = null;
this.repository.style.display = 'none';
}
@@ -712,7 +721,7 @@ export class ExtensionEditor extends BaseEditor {
}
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,
$('tr', undefined,
$('th', undefined, localize('setting name', "Name")),
@@ -740,7 +749,7 @@ export class ExtensionEditor extends BaseEditor {
}
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,
$('tr', undefined,
$('th', undefined, localize('debugger name', "Name")),
@@ -771,7 +780,7 @@ export class ExtensionEditor extends BaseEditor {
}
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,
$('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)))
@@ -797,7 +806,7 @@ export class ExtensionEditor extends BaseEditor {
}
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,
$('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)))
@@ -817,7 +826,7 @@ export class ExtensionEditor extends BaseEditor {
}
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,
$('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 || '')))
@@ -837,7 +846,7 @@ export class ExtensionEditor extends BaseEditor {
}
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)))
);
@@ -854,7 +863,7 @@ export class ExtensionEditor extends BaseEditor {
}
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)))
);
@@ -883,7 +892,7 @@ export class ExtensionEditor extends BaseEditor {
}
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,
$('tr', undefined,
$('th', undefined, localize('colorId', "Id")),
@@ -916,7 +925,7 @@ export class ExtensionEditor extends BaseEditor {
}
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,
$('tr', undefined,
$('th', undefined, localize('fileMatch', "File Match")),
@@ -990,7 +999,7 @@ export class ExtensionEditor extends BaseEditor {
};
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,
$('tr', undefined,
$('th', undefined, localize('command name', "Name")),
@@ -1057,7 +1066,7 @@ export class ExtensionEditor extends BaseEditor {
}
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,
$('tr', undefined,
$('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 { PagedModel, IPagedModel, IPager, DelayedPagedModel } from 'vs/base/common/paging';
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 { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
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 { IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService';
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 { SeverityIcon } from 'vs/platform/severityIcon/common/severityIcon';
// {{SQL CARBON EDIT}}
import product from 'vs/platform/product/node/product';
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import product from 'vs/platform/product/node/product'; // {{SQL CARBON EDIT}}
class ExtensionsViewState extends Disposable implements IExtensionsViewState {
@@ -104,8 +104,9 @@ export class ExtensionsListView extends ViewletPanel {
@IWorkbenchThemeService private readonly workbenchThemeService: IWorkbenchThemeService,
@IExtensionManagementServerService protected readonly extensionManagementServerService: IExtensionManagementServerService,
@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;
}
@@ -934,9 +935,10 @@ export class ServerExtensionsView extends ExtensionsListView {
@IExtensionsWorkbenchService extensionsWorkbenchService: IExtensionsWorkbenchService,
@IExtensionManagementServerService extensionManagementServerService: IExtensionManagementServerService,
@IProductService productService: IProductService,
@IContextKeyService contextKeyService: IContextKeyService,
) {
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)));
}
@@ -1080,10 +1082,14 @@ export class WorkspaceRecommendedExtensionsView extends ExtensionsListView {
return this.tipsService.getWorkspaceRecommendations()
.then(recommendations => recommendations.filter(({ extensionId }) => {
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 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-size: 120%;
border-bottom: 1px solid rgba(128, 128, 128, 0.22);
padding-bottom: 6px;
}
.extension-editor > .body > .content details > summary:focus {
outline: none;
padding: 3px 6px;
line-height: 22px;
}
.extension-editor > .body > .content details > summary::-webkit-details-marker {
@@ -386,4 +383,4 @@
font-size: 90%;
font-weight: 600;
opacity: 0.6;
}
}
@@ -12,12 +12,13 @@ export class Query {
}
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 = {
'sort': ['installs', 'rating', 'name'],
'category': ['"programming languages"', 'snippets', 'linters', 'themes', 'debuggers', 'formatters', 'keymaps', '"scm providers"', 'other', '"extension packs"', '"language packs"'],
'tag': [''],
'ext': ['']
'ext': [''],
'id': ['']
};
let queryContains = (substr: string) => query.indexOf(substr) > -1;
@@ -77,4 +78,4 @@ export class Query {
equals(other: Query): boolean {
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 * as json from 'vs/base/common/json';
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 { ITextModel } from 'vs/editor/common/model';
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,
@IStorageService private readonly storageService: IStorageService,
@IExtensionManagementService private readonly extensionsService: IExtensionManagementService,
@IExtensionEnablementService private readonly extensionEnablementService: IExtensionEnablementService,
@IInstantiationService private readonly instantiationService: IInstantiationService,
@IFileService private readonly fileService: IFileService,
@IWorkspaceContextService private readonly contextService: IWorkspaceContextService,
@@ -433,6 +434,7 @@ export class ExtensionTipsService extends Disposable implements IExtensionTipsSe
}
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)));
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 { IProductService } from 'vs/platform/product/common/product';
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', () => {
@@ -93,6 +95,7 @@ suite('ExtensionsListView Tests', () => {
instantiationService.stub(IExtensionManagementService, 'onUninstallExtension', uninstallEvent.event);
instantiationService.stub(IExtensionManagementService, 'onDidUninstallExtension', didUninstallEvent.event);
instantiationService.stub(IRemoteAgentService, RemoteAgentService);
instantiationService.stub(IContextKeyService, MockContextKeyService);
instantiationService.stub(IExtensionManagementServerService, new class extends ExtensionManagementServerService {
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 { Schemas } from 'vs/base/common/network';
import { isWeb } from 'vs/base/common/platform';
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
export class EmptyView extends ViewletPanel {
@@ -44,9 +45,10 @@ export class EmptyView extends ViewletPanel {
@IWorkspaceContextService private readonly contextService: IWorkspaceContextService,
@IConfigurationService configurationService: IConfigurationService,
@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.labelService.onDidChangeFormatters(() => this.setLabels()));
}
@@ -90,7 +90,7 @@ export class ExplorerView extends ViewletPanel {
@IClipboardService private clipboardService: IClipboardService,
@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._register(this.resourceContext);
@@ -80,7 +80,7 @@ export class OpenEditorsView extends ViewletPanel {
super({
...(options as IViewletPanelOptions),
ariaHeaderLabel: nls.localize({ key: 'openEditosrSection', comment: ['Open is an adjective'] }, "Open Editors Section"),
}, keybindingService, contextMenuService, configurationService);
}, keybindingService, contextMenuService, configurationService, contextKeyService);
this.structuralRefreshDelay = 0;
this.listRefreshScheduler = new RunOnceScheduler(() => {
@@ -159,6 +159,7 @@ export class MarkersFilterActionViewItem extends BaseActionViewItem {
toggleLayout(small: boolean) {
if (this.container) {
DOM.toggleClass(this.container, 'small', small);
this.adjustInputBox();
}
}
@@ -247,7 +248,7 @@ export class MarkersFilterActionViewItem extends BaseActionViewItem {
}
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
@@ -266,7 +266,7 @@ export class OutlinePanel extends ViewletPanel {
@IContextKeyService contextKeyService: IContextKeyService,
@IContextMenuService contextMenuService: IContextMenuService,
) {
super(options, keybindingService, contextMenuService, configurationService);
super(options, keybindingService, contextMenuService, configurationService, contextKeyService);
this._outlineViewState.restore(this._storageService);
this._contextKeyFocused = OutlineViewFocused.bindTo(contextKeyService);
this._contextKeyFiltered = OutlineViewFiltered.bindTo(contextKeyService);
@@ -135,6 +135,7 @@ export class SettingsEditor2 extends BaseEditor {
private tocFocusedElement: SettingsTreeGroupElement | null;
private settingsTreeScrollTop = 0;
private dimension: DOM.Dimension;
constructor(
@ITelemetryService telemetryService: ITelemetryService,
@@ -287,10 +288,11 @@ export class SettingsEditor2 extends BaseEditor {
}
layout(dimension: DOM.Dimension): void {
this.dimension = dimension;
this.layoutTrees(dimension);
const innerWidth = dimension.width - 24 * 2; // 24px padding on left and right
const monacoWidth = (innerWidth > 1000 ? 1000 : innerWidth) - 10;
const innerWidth = Math.min(1000, dimension.width) - 24 * 2; // 24px padding on left and right;
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 });
DOM.toggleClass(this.rootElement, 'mid-width', dimension.width < 1000 && dimension.width >= 600);
@@ -1239,7 +1241,11 @@ export class SettingsEditor2 extends BaseEditor {
: 'none';
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');
return;
}
@@ -1252,7 +1258,10 @@ export class SettingsEditor2 extends BaseEditor {
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);
}
}
@@ -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.remoteAuthority = environmentService.configuration.remoteAuthority;
Deprecated_RemoteAuthorityContext.bindTo(this.contextKeyService).set(this.remoteAuthority || '');
if (this.remoteAuthority) {
// Pending entry until extensions are ready
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) {
this.connectionState = newState;
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();
}
}
@@ -234,7 +234,7 @@ export class MainPanel extends ViewletPanel {
@IMenuService private readonly menuService: IMenuService,
@IConfigurationService configurationService: IConfigurationService
) {
super(options, keybindingService, contextMenuService, configurationService);
super(options, keybindingService, contextMenuService, configurationService, contextKeyService);
}
protected renderBody(container: HTMLElement): void {
@@ -324,7 +324,7 @@ export class MainPanel extends ViewletPanel {
}
private onListSelectionChange(e: IListEvent<ISCMRepository>): void {
if (e.elements.length > 0 && e.browserEvent) {
if (e.elements.length > 0) {
const scrollTop = this.list.scrollTop;
this.viewModel.setVisibleRepositories(e.elements);
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;
template.fileLabel.setFile(resource.sourceUri, { fileDecorations: { colors: false, badges: !icon, data: resource.decorations } });
template.actionBar.clear();
template.actionBar.context = resource;
const disposables = new DisposableStore();
@@ -733,7 +734,7 @@ export class RepositoryPanel extends ViewletPanel {
@IContextKeyService contextKeyService: IContextKeyService,
@IMenuService protected menuService: IMenuService
) {
super(options, keybindingService, contextMenuService, configurationService);
super(options, keybindingService, contextMenuService, configurationService, contextKeyService);
this.menus = instantiationService.createInstance(SCMMenus, this.repository.provider);
this._register(this.menus);
@@ -154,7 +154,7 @@ export class SearchView extends ViewletPanel {
@IKeybindingService keybindingService: IKeybindingService,
@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.viewletFocused = Constants.SearchViewFocusedKey.bindTo(contextKeyService);
@@ -81,10 +81,10 @@ class PartsSplash {
const layoutInfo = !this._shouldSaveLayoutInfo() ? undefined : {
sideBarSide: this._layoutService.getSideBarPosition() === Position.RIGHT ? 'right' : 'left',
editorPartMinWidth: DEFAULT_EDITOR_MIN_DIMENSIONS.width,
titleBarHeight: getTotalHeight(this._layoutService.getContainer(Parts.TITLEBAR_PART)),
activityBarWidth: getTotalWidth(this._layoutService.getContainer(Parts.ACTIVITYBAR_PART)),
sideBarWidth: getTotalWidth(this._layoutService.getContainer(Parts.SIDEBAR_PART)),
statusBarHeight: getTotalHeight(this._layoutService.getContainer(Parts.STATUSBAR_PART)),
titleBarHeight: this._layoutService.isVisible(Parts.TITLEBAR_PART) ? getTotalHeight(this._layoutService.getContainer(Parts.TITLEBAR_PART)) : 0,
activityBarWidth: this._layoutService.isVisible(Parts.ACTIVITYBAR_PART) ? getTotalWidth(this._layoutService.getContainer(Parts.ACTIVITYBAR_PART)) : 0,
sideBarWidth: this._layoutService.isVisible(Parts.SIDEBAR_PART) ? getTotalWidth(this._layoutService.getContainer(Parts.SIDEBAR_PART)) : 0,
statusBarHeight: this._layoutService.isVisible(Parts.STATUSBAR_PART) ? getTotalHeight(this._layoutService.getContainer(Parts.STATUSBAR_PART)) : 0,
};
this._textFileService.write(
URI.file(join(this._envService.userDataPath, 'rapid_render.json')),
@@ -29,6 +29,12 @@ const dotnetBuild: TaskEntry = {
'\t\t\t"label": "build",',
'\t\t\t"command": "dotnet build",',
'\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"presentation": {',
'\t\t\t\t"reveal": "silent"',
@@ -58,7 +64,9 @@ const msbuild: TaskEntry = {
'\t\t\t"args": [',
'\t\t\t\t// Ask msbuild to generate full paths for file names.',
'\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"group": "build",',
'\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 isWorkspaceShellAllowed = this._configHelper.checkWorkspaceShellPermissions();
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 { IConfigurationResolverService } from 'vs/workbench/services/configurationResolver/common/configurationResolver';
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.
@@ -119,18 +120,37 @@ function _getLangEnvVariable(locale?: string) {
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) {
return (typeof shell.cwd === 'object') ? shell.cwd.fsPath : shell.cwd;
}
let cwd: string | undefined;
// TODO: Handle non-existent 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;
} else if (root) {
} else if (root && !cwd) {
cwd = path.join(root.fsPath, customCwd);
}
}
@@ -101,31 +101,31 @@ suite('Workbench - TerminalEnvironment', () => {
}
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', () => {
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', () => {
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', () => {
assertPathsMatch(terminalEnvironment.getCwd({ executable: undefined, args: [] }, '/userHome/', 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/', Uri.file('/bar'), '../foo'), '/foo');
assertPathsMatch(terminalEnvironment.getCwd({ executable: undefined, args: [] }, '/userHome/', undefined, undefined, 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/', undefined, undefined, Uri.file('/bar'), '../foo'), '/foo');
});
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, './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, undefined, undefined, './foo'), '/userHome/');
assertPathsMatch(terminalEnvironment.getCwd({ executable: undefined, args: [] }, '/userHome/', undefined, undefined, undefined, '../foo'), '/userHome/');
});
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]+)/);
if (inspectorUrlMatch) {
if (!this._environmentService.isBuilt) {
console.log(`%c[Extension Host] %cdebugger inspector at chrome-devtools://devtools/bundled/inspector.html?experiments=true&v8only=true&ws=${inspectorUrlMatch[1]}`, 'color: blue', 'color: black');
console.log(`%c[Extension Host] %cdebugger inspector at chrome-devtools://devtools/bundled/inspector.html?experiments=true&v8only=true&ws=${inspectorUrlMatch[1]}`, 'color: blue', 'color:');
}
if (!this._inspectPort) {
this._inspectPort = Number(inspectorUrlMatch[2]);
@@ -282,15 +282,15 @@ export class ExtensionHostProcessWorker implements IExtensionHostStarter {
return new Promise(resolve => {
return findFreePort(startPort, 10 /* try 10 ports */, 5000 /* try up to 5 seconds */).then(port => {
if (!port) {
console.warn('%c[Extension Host] %cCould not find a free port for debugging', 'color: blue', 'color: black');
console.warn('%c[Extension Host] %cCould not find a free port for debugging', 'color: blue', 'color:');
} else {
if (expected && port !== expected) {
console.warn(`%c[Extension Host] %cProvided debugging port ${expected} is not free, using ${port} instead.`, 'color: blue', 'color: black');
console.warn(`%c[Extension Host] %cProvided debugging port ${expected} is not free, using ${port} instead.`, 'color: blue', 'color:');
}
if (this._isExtensionDevDebugBrk) {
console.warn(`%c[Extension Host] %cSTOPPED on first line for debugging on port ${port}`, 'color: blue', 'color: black');
console.warn(`%c[Extension Host] %cSTOPPED on first line for debugging on port ${port}`, 'color: blue', 'color:');
} else {
console.info(`%c[Extension Host] %cdebugger listening on port ${port}`, 'color: blue', 'color: black');
console.info(`%c[Extension Host] %cdebugger listening on port ${port}`, 'color: blue', 'color:');
}
}
return resolve({ expected, actual: port });
@@ -434,7 +434,7 @@ export class ExtensionHostProcessWorker implements IExtensionHostStarter {
// Log on main side if running tests from cli
if (this._isExtensionDevTestFromCli) {
this._windowsService.log(entry.severity, ...parse(entry).args);
this._windowsService.log(entry.severity, parse(entry).args);
}
// Broadcast to other windows if we are in development mode
@@ -0,0 +1,131 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution';
KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout({
layout: { id: 'com.apple.keylayout.Dvorak', localizedName: 'Dvorak', lang: 'en' },
secondaryLayouts: [],
mapping: {
KeyA: ['a', 'A', 'å', 'Å', 0],
KeyB: ['x', 'X', '≈', '˛', 0],
KeyC: ['j', 'J', '∆', 'Ô', 0],
KeyD: ['e', 'E', '´', '´', 4],
KeyE: ['.', '>', '≥', '˘', 0],
KeyF: ['u', 'U', '¨', '¨', 4],
KeyG: ['i', 'I', 'ˆ', 'ˆ', 4],
KeyH: ['d', 'D', '∂', 'Î', 0],
KeyI: ['c', 'C', 'ç', 'Ç', 0],
KeyJ: ['h', 'H', '˙', 'Ó', 0],
KeyK: ['t', 'T', '†', 'ˇ', 0],
KeyL: ['n', 'N', '˜', '˜', 4],
KeyM: ['m', 'M', 'µ', 'Â', 0],
KeyN: ['b', 'B', '∫', 'ı', 0],
KeyO: ['r', 'R', '®', '‰', 0],
KeyP: ['l', 'L', '¬', 'Ò', 0],
KeyQ: ['\'', '"', 'æ', 'Æ', 0],
KeyR: ['p', 'P', 'π', '∏', 0],
KeyS: ['o', 'O', 'ø', 'Ø', 0],
KeyT: ['y', 'Y', '¥', 'Á', 0],
KeyU: ['g', 'G', '©', '˝', 0],
KeyV: ['k', 'K', '˚', '', 0],
KeyW: [',', '<', '≤', '¯', 0],
KeyX: ['q', 'Q', 'œ', 'Œ', 0],
KeyY: ['f', 'F', 'ƒ', 'Ï', 0],
KeyZ: [';', ':', '…', 'Ú', 0],
Digit1: ['1', '!', '¡', '', 0],
Digit2: ['2', '@', '™', '€', 0],
Digit3: ['3', '#', '£', '', 0],
Digit4: ['4', '$', '¢', '', 0],
Digit5: ['5', '%', '∞', 'fi', 0],
Digit6: ['6', '^', '§', 'fl', 0],
Digit7: ['7', '&', '¶', '‡', 0],
Digit8: ['8', '*', '•', '°', 0],
Digit9: ['9', '(', 'ª', '·', 0],
Digit0: ['0', ')', 'º', '', 0],
Enter: [],
Escape: [],
Backspace: [],
Tab: [],
Space: [' ', ' ', ' ', ' ', 0],
Minus: ['[', '{', '“', '”', 0],
Equal: [']', '}', '', '', 0],
BracketLeft: ['/', '?', '÷', '¿', 0],
BracketRight: ['=', '+', '≠', '±', 0],
Backslash: ['\\', '|', '«', '»', 0],
Semicolon: ['s', 'S', 'ß', 'Í', 0],
Quote: ['-', '_', '', '—', 0],
Backquote: ['`', '~', '`', '`', 4],
Comma: ['w', 'W', '∑', '„', 0],
Period: ['v', 'V', '√', '◊', 0],
Slash: ['z', 'Z', 'Ω', '¸', 0],
CapsLock: [],
F1: [],
F2: [],
F3: [],
F4: [],
F5: [],
F6: [],
F7: [],
F8: [],
F9: [],
F10: [],
F11: [],
F12: [],
Insert: [],
Home: [],
PageUp: [],
Delete: [],
End: [],
PageDown: [],
ArrowRight: [],
ArrowLeft: [],
ArrowDown: [],
ArrowUp: [],
NumLock: [],
NumpadDivide: ['/', '/', '/', '/', 0],
NumpadMultiply: ['*', '*', '*', '*', 0],
NumpadSubtract: ['-', '-', '-', '-', 0],
NumpadAdd: ['+', '+', '+', '+', 0],
NumpadEnter: [],
Numpad1: ['1', '1', '1', '1', 0],
Numpad2: ['2', '2', '2', '2', 0],
Numpad3: ['3', '3', '3', '3', 0],
Numpad4: ['4', '4', '4', '4', 0],
Numpad5: ['5', '5', '5', '5', 0],
Numpad6: ['6', '6', '6', '6', 0],
Numpad7: ['7', '7', '7', '7', 0],
Numpad8: ['8', '8', '8', '8', 0],
Numpad9: ['9', '9', '9', '9', 0],
Numpad0: ['0', '0', '0', '0', 0],
NumpadDecimal: ['.', '.', '.', '.', 0],
IntlBackslash: ['§', '±', '§', '±', 0],
ContextMenu: [],
NumpadEqual: ['=', '=', '=', '=', 0],
F13: [],
F14: [],
F15: [],
F16: [],
F17: [],
F18: [],
F19: [],
F20: [],
AudioVolumeMute: [],
AudioVolumeUp: ['', '=', '', '=', 0],
AudioVolumeDown: [],
NumpadComma: [],
IntlRo: [],
KanaMode: [],
IntlYen: [],
ControlLeft: [],
ShiftLeft: [],
AltLeft: [],
MetaLeft: [],
ControlRight: [],
ShiftRight: [],
AltRight: [],
MetaRight: []
}
});
@@ -18,5 +18,6 @@ import 'vs/workbench/services/keybinding/browser/keyboardLayouts/it.darwin';
import 'vs/workbench/services/keybinding/browser/keyboardLayouts/ru.darwin';
import 'vs/workbench/services/keybinding/browser/keyboardLayouts/pt.darwin';
import 'vs/workbench/services/keybinding/browser/keyboardLayouts/ko.darwin';
import 'vs/workbench/services/keybinding/browser/keyboardLayouts/dvorak.darwin';
export { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution';
export { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution';
@@ -26,9 +26,9 @@ import { Registry } from 'vs/platform/registry/common/platform';
import { Extensions as ConfigExtensions, IConfigurationRegistry, IConfigurationNode } from 'vs/platform/configuration/common/configurationRegistry';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { INavigatorWithKeyboard } from 'vs/workbench/services/keybinding/common/navigatorKeyboard';
import { INotificationService, Severity } from 'vs/platform/notification/common/notification';
import { INotificationService } from 'vs/platform/notification/common/notification';
import { ICommandService } from 'vs/platform/commands/common/commands';
import { StorageScope, IStorageService } from 'vs/platform/storage/common/storage';
import { IStorageService } from 'vs/platform/storage/common/storage';
export class BrowserKeyboardMapperFactoryBase {
// keyboard mapper
@@ -71,9 +71,9 @@ export class BrowserKeyboardMapperFactoryBase {
}
protected constructor(
private _notificationService: INotificationService,
private _storageService: IStorageService,
private _commandService: ICommandService
// private _notificationService: INotificationService,
// private _storageService: IStorageService,
// private _commandService: ICommandService
) {
this._keyboardMapper = null;
this._initialized = false;
@@ -178,32 +178,34 @@ export class BrowserKeyboardMapperFactoryBase {
setActiveKeyMapping(keymap: IKeyboardMapping | null) {
let matchedKeyboardLayout = this.getMatchedKeymapInfo(keymap);
if (matchedKeyboardLayout) {
let score = matchedKeyboardLayout.score;
// let score = matchedKeyboardLayout.score;
if (keymap && score < 0) {
const donotAskUpdateKey = 'missing.keyboardlayout.donotask';
if (this._storageService.getBoolean(donotAskUpdateKey, StorageScope.GLOBAL)) {
return;
}
// Due to https://bugs.chromium.org/p/chromium/issues/detail?id=977609, any key after a dead key will generate a wrong mapping,
// we shoud avoid yielding the false error.
// if (keymap && score < 0) {
// const donotAskUpdateKey = 'missing.keyboardlayout.donotask';
// if (this._storageService.getBoolean(donotAskUpdateKey, StorageScope.GLOBAL)) {
// return;
// }
// the keyboard layout doesn't actually match the key event or the keymap from chromium
this._notificationService.prompt(
Severity.Info,
nls.localize('missing.keyboardlayout', 'Fail to find matching keyboard layout'),
[{
label: nls.localize('keyboardLayoutMissing.configure', "Configure"),
run: () => this._commandService.executeCommand('workbench.action.openKeyboardLayoutPicker')
}, {
label: nls.localize('neverAgain', "Don't Show Again"),
isSecondary: true,
run: () => this._storageService.store(donotAskUpdateKey, true, StorageScope.GLOBAL)
}]
);
// // the keyboard layout doesn't actually match the key event or the keymap from chromium
// this._notificationService.prompt(
// Severity.Info,
// nls.localize('missing.keyboardlayout', 'Fail to find matching keyboard layout'),
// [{
// label: nls.localize('keyboardLayoutMissing.configure', "Configure"),
// run: () => this._commandService.executeCommand('workbench.action.openKeyboardLayoutPicker')
// }, {
// label: nls.localize('neverAgain', "Don't Show Again"),
// isSecondary: true,
// run: () => this._storageService.store(donotAskUpdateKey, true, StorageScope.GLOBAL)
// }]
// );
console.warn('Active keymap/keyevent does not match current keyboard layout', JSON.stringify(keymap), this._activeKeymapInfo ? JSON.stringify(this._activeKeymapInfo.layout) : '');
// console.warn('Active keymap/keyevent does not match current keyboard layout', JSON.stringify(keymap), this._activeKeymapInfo ? JSON.stringify(this._activeKeymapInfo.layout) : '');
return;
}
// return;
// }
if (!this._activeKeymapInfo) {
this._activeKeymapInfo = matchedKeyboardLayout.result;
@@ -336,7 +338,7 @@ export class BrowserKeyboardMapperFactoryBase {
}
if (mapping.value === '') {
// we don't undetstand
// The value is empty when the key is not a printable character, we skip validation.
if (keyboardEvent.ctrlKey || keyboardEvent.metaKey) {
setTimeout(() => {
this._getBrowserKeyMapping().then((keymap: IKeyboardMapping) => {
@@ -426,7 +428,8 @@ export class BrowserKeyboardMapperFactoryBase {
export class BrowserKeyboardMapperFactory extends BrowserKeyboardMapperFactoryBase {
constructor(notificationService: INotificationService, storageService: IStorageService, commandService: ICommandService) {
super(notificationService, storageService, commandService);
// super(notificationService, storageService, commandService);
super();
const platform = isWindows ? 'win' : isMacintosh ? 'darwin' : 'linux';
@@ -621,4 +624,4 @@ const keyboardConfiguration: IConfigurationNode = {
}
};
configurationRegistry.registerConfiguration(keyboardConfiguration);
configurationRegistry.registerConfiguration(keyboardConfiguration);
@@ -17,7 +17,8 @@ import { TestNotificationService } from 'vs/platform/notification/test/common/te
class TestKeyboardMapperFactory extends BrowserKeyboardMapperFactoryBase {
constructor(notificationService: INotificationService, storageService: IStorageService, commandService: ICommandService) {
super(notificationService, storageService, commandService);
// super(notificationService, storageService, commandService);
super();
const keymapInfos: IKeymapInfo[] = KeyboardLayoutContribution.INSTANCE.layoutInfos;
this._keymapInfos.push(...keymapInfos.map(info => (new KeymapInfo(info.layout, info.secondaryLayouts, info.mapping, info.isUserKeyboardLayout))));
@@ -146,4 +147,4 @@ suite('keyboard layout loader', () => {
instance.setUSKeyboardLayout();
assert.equal(instance.activeKeyboardLayout!.isUSStandard, true);
});
});
});
@@ -43,7 +43,7 @@ export abstract class AbstractTextMateService extends Disposable implements ITex
private _grammarDefinitions: IValidGrammarDefinition[] | null;
private _grammarFactory: TMGrammarFactory | null;
private _tokenizersRegistrations: IDisposable[];
private _currentTokenColors: ITokenColorizationRule[] | null;
protected _currentTheme: IRawTheme | null;
constructor(
@IModeService private readonly _modeService: IModeService,
@@ -64,6 +64,8 @@ export abstract class AbstractTextMateService extends Disposable implements ITex
this._grammarFactory = null;
this._tokenizersRegistrations = [];
this._currentTheme = null;
grammarsExtPoint.setHandler((extensions) => {
this._grammarDefinitions = null;
if (this._grammarFactory) {
@@ -242,11 +244,11 @@ export abstract class AbstractTextMateService extends Disposable implements ITex
}
private _updateTheme(grammarFactory: TMGrammarFactory, colorTheme: IColorTheme, forceUpdate: boolean): void {
if (!forceUpdate && AbstractTextMateService.equalsTokenRules(this._currentTokenColors, colorTheme.tokenColors)) {
if (!forceUpdate && this._currentTheme && AbstractTextMateService.equalsTokenRules(this._currentTheme.settings, colorTheme.tokenColors)) {
return;
}
this._currentTokenColors = colorTheme.tokenColors;
this._doUpdateTheme(grammarFactory, { name: colorTheme.label, settings: colorTheme.tokenColors });
this._currentTheme = { name: colorTheme.label, settings: colorTheme.tokenColors };
this._doUpdateTheme(grammarFactory, this._currentTheme);
}
protected _doUpdateTheme(grammarFactory: TMGrammarFactory, theme: IRawTheme): void {

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