diff --git a/extensions/javascript/src/features/packageJSONContribution.ts b/extensions/javascript/src/features/packageJSONContribution.ts index 25f26865f57..573b8b1608f 100644 --- a/extensions/javascript/src/features/packageJSONContribution.ts +++ b/extensions/javascript/src/features/packageJSONContribution.ts @@ -67,7 +67,7 @@ export class PackageJSONContribution implements IJSONContribution { let name = keys[0]; let insertText = new SnippetString().appendText(JSON.stringify(name)); if (addValue) { - insertText.appendText(': ').appendPlaceholder('*'); + insertText.appendText(': "').appendPlaceholder('').appendText('"'); if (!isLast) { insertText.appendText(','); } @@ -99,7 +99,7 @@ export class PackageJSONContribution implements IJSONContribution { this.mostDependedOn.forEach((name) => { let insertText = new SnippetString().appendText(JSON.stringify(name)); if (addValue) { - insertText.appendText(': ').appendPlaceholder('*'); + insertText.appendText(': "').appendPlaceholder('').appendText('"'); if (!isLast) { insertText.appendText(','); } diff --git a/extensions/typescript/npm-shrinkwrap.json b/extensions/typescript/npm-shrinkwrap.json index 6861979ba1a..f68512bf919 100644 --- a/extensions/typescript/npm-shrinkwrap.json +++ b/extensions/typescript/npm-shrinkwrap.json @@ -13,9 +13,9 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-4.3.6.tgz" }, "typescript": { - "version": "2.1.5-insiders.20161220", - "from": "typescript@2.1.5-insiders.20161220", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.1.5-insiders.20161220.tgz" + "version": "2.1.5-insiders.20161229", + "from": "typescript@2.1.5-insiders.20161229", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.1.5-insiders.20161229.tgz" }, "vscode-extension-telemetry": { "version": "0.0.5", diff --git a/extensions/typescript/package.json b/extensions/typescript/package.json index 634b2558847..201ddf039de 100644 --- a/extensions/typescript/package.json +++ b/extensions/typescript/package.json @@ -14,7 +14,7 @@ "semver": "4.3.6", "vscode-extension-telemetry": "^0.0.5", "vscode-nls": "^2.0.1", - "typescript": "2.1.5-insiders.20161220" + "typescript": "2.1.5-insiders.20161229" }, "devDependencies": { "@types/semver": "^5.3.30" diff --git a/extensions/typescript/src/features/completionItemProvider.ts b/extensions/typescript/src/features/completionItemProvider.ts index 4b48085f3a6..65a725816fa 100644 --- a/extensions/typescript/src/features/completionItemProvider.ts +++ b/extensions/typescript/src/features/completionItemProvider.ts @@ -34,10 +34,12 @@ class MyCompletionItem extends CompletionItem { // We convert to 0-based indexing. this.textEdit = TextEdit.replace(new Range(span.start.line - 1, span.start.offset - 1, span.end.line - 1, span.end.offset - 1), entry.name); } else { + // Try getting longer, prefix based range for completions that span words + const wordRange = document.getWordRangeAtPosition(position); const text = document.getText(new Range(position.line, Math.max(0, position.character - entry.name.length), position.line, position.character)).toLowerCase(); const entryName = entry.name.toLowerCase(); for (let i = entryName.length; i >= 0; --i) { - if (text.endsWith(entryName.substr(0, i))) { + if (text.endsWith(entryName.substr(0, i)) && (!wordRange || wordRange.start.character > position.character - i)) { this.range = new Range(position.line, Math.max(0, position.character - i), position.line, position.character); break; } diff --git a/src/vs/base/common/arrays.ts b/src/vs/base/common/arrays.ts index 7c6db6d75d8..2eb260b91bb 100644 --- a/src/vs/base/common/arrays.ts +++ b/src/vs/base/common/arrays.ts @@ -13,19 +13,6 @@ export function tail(array: T[], n: number = 0): T { return array[array.length - (1 + n)]; } -/** - * Iterates the provided array and allows to remove - * elements while iterating. - */ -export function forEach(array: T[], callback: (element: T, remove: Function) => void): void { - for (var i = 0, len = array.length; i < len; i++) { - callback(array[i], function () { - array.splice(i, 1); - i--; len--; - }); - } -} - export function equals(one: T[], other: T[], itemEquals: (a: T, b: T) => boolean = (a, b) => a === b): boolean { if (one.length !== other.length) { return false; @@ -105,29 +92,6 @@ export function top(array: T[], compare: (a: T, b: T) => number, n: number): return result; } -export function merge(arrays: T[][], hashFn?: (element: T) => string): T[] { - const result = new Array(); - if (!hashFn) { - for (let i = 0, len = arrays.length; i < len; i++) { - result.push.apply(result, arrays[i]); - } - } else { - const map: { [k: string]: boolean } = {}; - for (let i = 0; i < arrays.length; i++) { - for (let j = 0; j < arrays[i].length; j++) { - let element = arrays[i][j], - hash = hashFn(element); - - if (!map.hasOwnProperty(hash)) { - map[hash] = true; - result.push(element); - } - } - } - } - return result; -} - /** * @returns a new array with all undefined or null values removed. The original array is not modified at all. */ @@ -139,24 +103,6 @@ export function coalesce(array: T[]): T[] { return array.filter(e => !!e); } -/** - * @returns true if the given item is contained in the array. - */ -export function contains(array: T[], item: T): boolean { - return array.indexOf(item) >= 0; -} - -/** - * Swaps the elements in the array for the provided positions. - */ -export function swap(array: any[], pos1: number, pos2: number): void { - const element1 = array[pos1]; - const element2 = array[pos2]; - - array[pos1] = element2; - array[pos2] = element1; -} - /** * Moves the element in the array for the provided positions. */ @@ -283,4 +229,4 @@ export function insert(array: T[], element: T): () => void { array.splice(index, 1); } }; -} \ No newline at end of file +} diff --git a/src/vs/base/parts/tree/browser/tree.css b/src/vs/base/parts/tree/browser/tree.css index 2d2f61abc41..d9aaa763cd5 100644 --- a/src/vs/base/parts/tree/browser/tree.css +++ b/src/vs/base/parts/tree/browser/tree.css @@ -64,7 +64,7 @@ /* Expansion */ -.monaco-tree .monaco-tree-rows > .monaco-tree-row.has-children > .content:before { +.monaco-tree .monaco-tree-rows.show-twisties > .monaco-tree-row.has-children > .content:before { content: ' '; position: absolute; display: block; @@ -75,7 +75,7 @@ left: -16px; } -.monaco-tree .monaco-tree-rows > .monaco-tree-row.expanded > .content:before { +.monaco-tree .monaco-tree-rows.show-twisties > .monaco-tree-row.expanded > .content:before { background-image: url('expanded.svg'); } @@ -109,11 +109,11 @@ .vs-dark .monaco-tree-wrapper.drop-target, .vs-dark .monaco-tree .monaco-tree-row.drop-target { background-color: #383B3D !important; color: inherit !important; } -.vs-dark .monaco-tree .monaco-tree-rows > .monaco-tree-row.has-children > .content:before { +.vs-dark .monaco-tree .monaco-tree-rows.show-twisties > .monaco-tree-row.has-children > .content:before { background-image: url('collapsed-dark.svg'); } -.vs-dark .monaco-tree .monaco-tree-rows > .monaco-tree-row.expanded > .content:before { +.vs-dark .monaco-tree .monaco-tree-rows.show-twisties > .monaco-tree-row.expanded > .content:before { background-image: url('expanded-dark.svg'); } @@ -131,11 +131,11 @@ .hc-black .monaco-tree .monaco-tree-wrapper.drop-target, .hc-black .monaco-tree .monaco-tree-rows > .monaco-tree-row.drop-target { background: none !important; border: 1px dashed #f38518; } -.hc-black .monaco-tree .monaco-tree-rows > .monaco-tree-row.has-children > .content:before { +.hc-black .monaco-tree .monaco-tree-rows.show-twisties > .monaco-tree-row.has-children > .content:before { background-image: url('collapsed-hc.svg'); } -.hc-black .monaco-tree .monaco-tree-rows > .monaco-tree-row.expanded > .content:before { +.hc-black .monaco-tree .monaco-tree-rows.show-twisties > .monaco-tree-row.expanded > .content:before { background-image: url('expanded-hc.svg'); } diff --git a/src/vs/base/parts/tree/browser/tree.ts b/src/vs/base/parts/tree/browser/tree.ts index fc122b48b41..b59f4b267cc 100644 --- a/src/vs/base/parts/tree/browser/tree.ts +++ b/src/vs/base/parts/tree/browser/tree.ts @@ -634,6 +634,7 @@ export interface ITreeConfiguration { export interface ITreeOptions { twistiePixels?: number; + showTwistie?: boolean; indentPixels?: number; verticalScrollMode?: ScrollbarVisibility; alwaysFocused?: boolean; diff --git a/src/vs/base/parts/tree/browser/treeImpl.ts b/src/vs/base/parts/tree/browser/treeImpl.ts index 3ea5c7251b1..3e8879bdb90 100644 --- a/src/vs/base/parts/tree/browser/treeImpl.ts +++ b/src/vs/base/parts/tree/browser/treeImpl.ts @@ -64,6 +64,7 @@ export class Tree extends Events.EventEmitter implements _.ITree { this.options = options; this.options.twistiePixels = typeof this.options.twistiePixels === 'number' ? this.options.twistiePixels : 32; + this.options.showTwistie = this.options.showTwistie === false ? false : true; this.options.indentPixels = typeof this.options.indentPixels === 'number' ? this.options.indentPixels : 12; this.options.alwaysFocused = this.options.alwaysFocused === true ? true : false; this.options.useShadows = this.options.useShadows === false ? false : true; diff --git a/src/vs/base/parts/tree/browser/treeView.ts b/src/vs/base/parts/tree/browser/treeView.ts index 2d9a815f57c..4fa1b9b7afd 100644 --- a/src/vs/base/parts/tree/browser/treeView.ts +++ b/src/vs/base/parts/tree/browser/treeView.ts @@ -504,6 +504,9 @@ export class TreeView extends HeightMap { this.rowsContainer = document.createElement('div'); this.rowsContainer.className = 'monaco-tree-rows'; + if (context.options.showTwistie) { + this.rowsContainer.className += ' show-twisties'; + } var focusTracker = DOM.trackFocus(this.domNode); focusTracker.addFocusListener(() => this.onFocus()); diff --git a/src/vs/editor/common/services/bulkEdit.ts b/src/vs/editor/common/services/bulkEdit.ts index 4f3bc62ce2d..90c3ae98474 100644 --- a/src/vs/editor/common/services/bulkEdit.ts +++ b/src/vs/editor/common/services/bulkEdit.ts @@ -5,7 +5,7 @@ 'use strict'; import * as nls from 'vs/nls'; -import { merge } from 'vs/base/common/arrays'; +import { flatten } from 'vs/base/common/arrays'; import { IStringDictionary, forEach, values } from 'vs/base/common/collections'; import { IDisposable, dispose, IReference } from 'vs/base/common/lifecycle'; import URI from 'vs/base/common/uri'; @@ -59,7 +59,7 @@ class ChangeRecorder { return { stop: () => { stop.dispose(); }, hasChanged: (resource: URI) => !!changes[resource.toString()], - allChanges: () => merge(values(changes)) + allChanges: () => flatten(values(changes)) }; } } diff --git a/src/vs/editor/contrib/referenceSearch/browser/referencesWidget.ts b/src/vs/editor/contrib/referenceSearch/browser/referencesWidget.ts index 1b9e43d20aa..6dccbb348b3 100644 --- a/src/vs/editor/contrib/referenceSearch/browser/referencesWidget.ts +++ b/src/vs/editor/contrib/referenceSearch/browser/referencesWidget.ts @@ -50,8 +50,8 @@ class DecorationsManager implements IDisposable { private _callOnDispose: IDisposable[] = []; private _callOnModelChange: IDisposable[] = []; - constructor(private editor: ICodeEditor, private model: ReferencesModel) { - this._callOnDispose.push(this.editor.onDidChangeModel(() => this._onModelChanged())); + constructor(private _editor: ICodeEditor, private _model: ReferencesModel) { + this._callOnDispose.push(this._editor.onDidChangeModel(() => this._onModelChanged())); this._onModelChanged(); } @@ -62,30 +62,25 @@ class DecorationsManager implements IDisposable { } private _onModelChanged(): void { - - this.removeDecorations(); this._callOnModelChange = dispose(this._callOnModelChange); - - var model = this.editor.getModel(); - if (!model) { - return; - } - - for (var i = 0, len = this.model.groups.length; i < len; i++) { - if (this.model.groups[i].uri.toString() === model.uri.toString()) { - this._addDecorations(this.model.groups[i]); - return; + const model = this._editor.getModel(); + if (model) { + for (const ref of this._model.groups) { + if (ref.uri.toString() === model.uri.toString()) { + this._addDecorations(ref); + return; + } } } } private _addDecorations(reference: FileReferences): void { - this._callOnModelChange.push(this.editor.getModel().onDidChangeDecorations((event) => this._onDecorationChanged(event))); + this._callOnModelChange.push(this._editor.getModel().onDidChangeDecorations((event) => this._onDecorationChanged(event))); - this.editor.changeDecorations(accessor => { + this._editor.changeDecorations(accessor => { - var newDecorations: editorCommon.IModelDeltaDecoration[] = []; - var newDecorationsActualIndex: number[] = []; + const newDecorations: editorCommon.IModelDeltaDecoration[] = []; + const newDecorationsActualIndex: number[] = []; for (let i = 0, len = reference.children.length; i < len; i++) { let oneReference = reference.children[i]; @@ -99,26 +94,25 @@ class DecorationsManager implements IDisposable { newDecorationsActualIndex.push(i); } - var decorations = accessor.deltaDecorations([], newDecorations); - - for (var i = 0; i < decorations.length; i++) { + const decorations = accessor.deltaDecorations([], newDecorations); + for (let i = 0; i < decorations.length; i++) { this._decorations.set(decorations[i], reference.children[newDecorationsActualIndex[i]]); } }); } private _onDecorationChanged(event: editorCommon.IModelDecorationsChangedEvent): void { - var changedDecorations = event.changedDecorations, + const changedDecorations = event.changedDecorations, toRemove: string[] = []; - for (var i = 0, len = changedDecorations.length; i < len; i++) { + for (let i = 0, len = changedDecorations.length; i < len; i++) { let reference = this._decorations.get(changedDecorations[i]); if (!reference) { continue; } - var newRange = this.editor.getModel().getDecorationRange(changedDecorations[i]), - ignore = false; + const newRange = this._editor.getModel().getDecorationRange(changedDecorations[i]); + let ignore = false; if (Range.equalsRange(newRange, reference.range)) { continue; @@ -127,8 +121,8 @@ class DecorationsManager implements IDisposable { ignore = true; } else { - var lineLength = reference.range.endColumn - reference.range.startColumn, - newLineLength = newRange.endColumn - newRange.startColumn; + const lineLength = reference.range.endColumn - reference.range.startColumn; + const newLineLength = newRange.endColumn - newRange.startColumn; if (lineLength !== newLineLength) { ignore = true; @@ -143,7 +137,7 @@ class DecorationsManager implements IDisposable { } } - this.editor.changeDecorations((accessor) => { + this._editor.changeDecorations((accessor) => { for (let i = 0, len = toRemove.length; i < len; i++) { delete this._decorations[toRemove[i]]; } @@ -152,7 +146,7 @@ class DecorationsManager implements IDisposable { } public removeDecorations(): void { - this.editor.changeDecorations(accessor => { + this._editor.changeDecorations(accessor => { this._decorations.forEach((value, key) => { accessor.removeDecoration(key); }); diff --git a/src/vs/editor/contrib/suggest/common/snippetCompletion.ts b/src/vs/editor/contrib/suggest/common/snippetCompletion.ts index 8174b7aa8b7..d50d71e7fcb 100644 --- a/src/vs/editor/contrib/suggest/common/snippetCompletion.ts +++ b/src/vs/editor/contrib/suggest/common/snippetCompletion.ts @@ -17,23 +17,32 @@ interface ISnippetPick extends IPickOpenEntry { snippet: ISnippet; } -class NameAndLangId { +class Args { - static fromArg(arg: any): NameAndLangId { + static fromUser(arg: any): Args { if (typeof arg !== 'object') { - return new NameAndLangId(undefined, undefined); + return Args._empty; + } + let {snippet, name, langId} = arg; + if (typeof snippet !== 'string') { + snippet = undefined; } - let {name, langId} = arg; if (typeof name !== 'string') { name = undefined; } if (typeof langId !== 'string') { langId = undefined; } - return new NameAndLangId(name, langId); + return new Args(snippet, name, langId); } - private constructor(public readonly name: string, public readonly langId: string) { + private static _empty = new Args(undefined, undefined, undefined); + + private constructor( + public readonly snippet: string, + public readonly name: string, + public readonly langId: string + ) { } @@ -59,13 +68,24 @@ class InsertSnippetAction extends EditorAction { const quickOpenService = accessor.get(IQuickOpenService); const {lineNumber, column} = editor.getPosition(); - let {name, langId} = NameAndLangId.fromArg(arg); - - if (!langId) { - langId = editor.getModel().getModeIdAtPosition(lineNumber, column); - } + let {snippet, name, langId} = Args.fromUser(arg); return new TPromise((resolve, reject) => { + + if (snippet) { + return resolve({ + codeSnippet: snippet, + description: undefined, + name: undefined, + owner: undefined, + prefix: undefined + }); + } + + if (!langId) { + langId = editor.getModel().getModeIdAtPosition(lineNumber, column); + } + if (name) { // take selected snippet Registry.as(Extensions.Snippets).visitSnippets(langId, snippet => { diff --git a/src/vs/platform/actions/common/menuService.ts b/src/vs/platform/actions/common/menuService.ts index 575df57988c..729428af7ba 100644 --- a/src/vs/platform/actions/common/menuService.ts +++ b/src/vs/platform/actions/common/menuService.ts @@ -50,7 +50,7 @@ class Menu implements IMenu { this._extensionService.onReady().then(_ => { const menuItems = MenuRegistry.getMenuItems(id); - const keysFilter: { [key: string]: boolean } = Object.create(null); + const keysFilter = new Set(); let group: MenuItemGroup; menuItems.sort(Menu._compareMenuItems); @@ -71,7 +71,7 @@ class Menu implements IMenu { // subscribe to context changes this._disposables.push(this._contextKeyService.onDidChangeContext(keys => { for (let k of keys) { - if (keysFilter[k]) { + if (keysFilter.has(k)) { this._onDidChange.fire(); return; } @@ -110,10 +110,10 @@ class Menu implements IMenu { return result; } - private static _fillInKbExprKeys(exp: ContextKeyExpr, set: { [k: string]: boolean }): void { + private static _fillInKbExprKeys(exp: ContextKeyExpr, set: Set): void { if (exp) { for (let key of exp.keys()) { - set[key] = true; + set.add(key); } } } diff --git a/src/vs/platform/commands/common/commands.ts b/src/vs/platform/commands/common/commands.ts index 2960eaa7f15..7ad7588bbca 100644 --- a/src/vs/platform/commands/common/commands.ts +++ b/src/vs/platform/commands/common/commands.ts @@ -51,7 +51,7 @@ function isCommand(thing: any): thing is ICommand { export const CommandsRegistry: ICommandRegistry = new class implements ICommandRegistry { - private _commands: { [id: string]: ICommand | ICommand[] } = Object.create(null); + private _commands = new Map(); registerCommand(id: string, commandOrDesc: ICommandHandler | ICommand): IDisposable { @@ -86,18 +86,18 @@ export const CommandsRegistry: ICommandRegistry = new class implements ICommandR } // find a place to store the command - const commandOrArray = this._commands[id]; + const commandOrArray = this._commands.get(id); if (commandOrArray === void 0) { - this._commands[id] = command; + this._commands.set(id, command); } else if (Array.isArray(commandOrArray)) { commandOrArray.unshift(command); } else { - this._commands[id] = [command, commandOrArray]; + this._commands.set(id, [command, commandOrArray]); } return { dispose: () => { - const commandOrArray = this._commands[id]; + const commandOrArray = this._commands.get(id); if (Array.isArray(commandOrArray)) { // remove from array, remove array // if last element removed @@ -105,19 +105,19 @@ export const CommandsRegistry: ICommandRegistry = new class implements ICommandR if (idx >= 0) { commandOrArray.splice(idx, 1); if (commandOrArray.length === 0) { - delete this._commands[id]; + this._commands.delete(id); } } } else if (isCommand(commandOrArray)) { // remove from map - delete this._commands[id]; + this._commands.delete(id); } } }; } getCommand(id: string): ICommand { - const commandOrArray = this._commands[id]; + const commandOrArray = this._commands.get(id); if (Array.isArray(commandOrArray)) { return commandOrArray[0]; } else { @@ -127,9 +127,9 @@ export const CommandsRegistry: ICommandRegistry = new class implements ICommandR getCommands(): ICommandsMap { const result: ICommandsMap = Object.create(null); - for (let id in this._commands) { - result[id] = this.getCommand(id); - } + this._commands.forEach((value, key) => { + result[key] = this.getCommand(key); + }); return result; } }; @@ -139,4 +139,4 @@ export const NullCommandService: ICommandService = { executeCommand() { return TPromise.as(undefined); } -}; \ No newline at end of file +}; diff --git a/src/vs/workbench/api/node/extHost.api.impl.ts b/src/vs/workbench/api/node/extHost.api.impl.ts index 4516bdd249a..6d8ad575681 100644 --- a/src/vs/workbench/api/node/extHost.api.impl.ts +++ b/src/vs/workbench/api/node/extHost.api.impl.ts @@ -466,7 +466,7 @@ function createExtensionPathIndex(extensionService: ExtHostExtensionService): TP function defineAPI(factory: IExtensionApiFactory, extensionPaths: TrieMap): void { // each extension is meant to get its own api implementation - const extApiImpl: { [id: string]: typeof vscode } = Object.create(null); + const extApiImpl = new Map(); let defaultApiImpl: typeof vscode; const node_module = require.__$__nodeRequire('module'); @@ -479,9 +479,10 @@ function defineAPI(factory: IExtensionApiFactory, extensionPaths: TrieMap(); private _proxy: MainThreadCommandsShape; private _extHostEditors: ExtHostEditors; private _converter: CommandsConverter; @@ -52,15 +52,15 @@ export class ExtHostCommands extends ExtHostCommandsShape { throw new Error('invalid id'); } - if (this._commands[id]) { + if (this._commands.has(id)) { throw new Error('command with id already exists'); } - this._commands[id] = { callback, thisArg, description }; + this._commands.set(id, { callback, thisArg, description }); this._proxy.$registerCommand(id); return new extHostTypes.Disposable(() => { - if (delete this._commands[id]) { + if (this._commands.delete(id)) { this._proxy.$unregisterCommand(id); } }); @@ -68,7 +68,7 @@ export class ExtHostCommands extends ExtHostCommandsShape { executeCommand(id: string, ...args: any[]): Thenable { - if (this._commands[id]) { + if (this._commands.has(id)) { // we stay inside the extension host and support // to pass any kind of parameters around return this.$executeContributedCommand(id, ...args); @@ -97,7 +97,7 @@ export class ExtHostCommands extends ExtHostCommandsShape { } $executeContributedCommand(id: string, ...args: any[]): Thenable { - let command = this._commands[id]; + let command = this._commands.get(id); if (!command) { return TPromise.wrapError(`Contributed command '${id}' does not exist.`); } @@ -139,12 +139,12 @@ export class ExtHostCommands extends ExtHostCommandsShape { $getContributedCommandHandlerDescriptions(): TPromise<{ [id: string]: string | ICommandHandlerDescription }> { const result: { [id: string]: string | ICommandHandlerDescription } = Object.create(null); - for (let id in this._commands) { - let {description} = this._commands[id]; + this._commands.forEach((command, id) => { + let {description} = command; if (description) { result[id] = description; } - } + }); return TPromise.as(result); } } @@ -212,4 +212,4 @@ export class CommandsConverter { return this._commands.executeCommand(actualCmd.command, ...actualCmd.arguments); } -} \ No newline at end of file +} diff --git a/src/vs/workbench/api/node/extHostDiagnostics.ts b/src/vs/workbench/api/node/extHostDiagnostics.ts index f4a44d77ed7..4285991a3a8 100644 --- a/src/vs/workbench/api/node/extHostDiagnostics.ts +++ b/src/vs/workbench/api/node/extHostDiagnostics.ts @@ -15,13 +15,13 @@ import { DiagnosticSeverity } from './extHostTypes'; export class DiagnosticCollection implements vscode.DiagnosticCollection { - private static _maxDiagnosticsPerFile: number = 250; + private static readonly _maxDiagnosticsPerFile: number = 250; + + private readonly _name: string; - private _name: string; private _proxy: MainThreadDiagnosticsShape; - private _isDisposed = false; - private _data: { [uri: string]: vscode.Diagnostic[] } = Object.create(null); + private _data = new Map(); constructor(name: string, proxy: MainThreadDiagnosticsShape) { this._name = name; @@ -66,7 +66,7 @@ export class DiagnosticCollection implements vscode.DiagnosticCollection { } // update single row - this._data[first.toString()] = diagnostics; + this._data.set(first.toString(), diagnostics); toSync = [first]; } else if (Array.isArray(first)) { @@ -83,19 +83,19 @@ export class DiagnosticCollection implements vscode.DiagnosticCollection { for (const {tuple} of sortedTuples) { const [uri, diagnostics] = tuple; if (!lastUri || uri.toString() !== lastUri.toString()) { - if (lastUri && this._data[lastUri.toString()].length === 0) { - delete this._data[lastUri.toString()]; + if (lastUri && this._data.get(lastUri.toString()).length === 0) { + this._data.delete(lastUri.toString()); } lastUri = uri; toSync.push(uri); - this._data[uri.toString()] = []; + this._data.set(uri.toString(), []); } if (!diagnostics) { // [Uri, undefined] means clear this - this._data[uri.toString()].length = 0; + this._data.get(uri.toString()).length = 0; } else { - this._data[uri.toString()].push(...diagnostics); + this._data.get(uri.toString()).push(...diagnostics); } } } @@ -104,7 +104,7 @@ export class DiagnosticCollection implements vscode.DiagnosticCollection { const entries: [URI, IMarkerData[]][] = []; for (let uri of toSync) { let marker: IMarkerData[]; - let diagnostics = this._data[uri.toString()]; + let diagnostics = this._data.get(uri.toString()); if (diagnostics) { // no more than 250 diagnostics per file @@ -144,27 +144,27 @@ export class DiagnosticCollection implements vscode.DiagnosticCollection { delete(uri: vscode.Uri): void { this._checkDisposed(); - delete this._data[uri.toString()]; + this._data.delete(uri.toString()); this._proxy.$changeMany(this.name, [[uri, undefined]]); } clear(): void { this._checkDisposed(); - this._data = Object.create(null); + this._data.clear(); this._proxy.$clear(this.name); } forEach(callback: (uri: URI, diagnostics: vscode.Diagnostic[], collection: DiagnosticCollection) => any, thisArg?: any): void { this._checkDisposed(); - for (let key in this._data) { + this._data.forEach((value, key) => { let uri = URI.parse(key); callback.apply(thisArg, [uri, this.get(uri), this]); - } + }); } get(uri: URI): vscode.Diagnostic[] { this._checkDisposed(); - let result = this._data[uri.toString()]; + let result = this._data.get(uri.toString()); if (Array.isArray(result)) { return Object.freeze(result.slice(0)); } @@ -172,7 +172,7 @@ export class DiagnosticCollection implements vscode.DiagnosticCollection { has(uri: URI): boolean { this._checkDisposed(); - return Array.isArray(this._data[uri.toString()]); + return Array.isArray(this._data.get(uri.toString())); } private _checkDisposed() { diff --git a/src/vs/workbench/api/node/extHostDocuments.ts b/src/vs/workbench/api/node/extHostDocuments.ts index 7b9eaf556da..6b18fc8b951 100644 --- a/src/vs/workbench/api/node/extHostDocuments.ts +++ b/src/vs/workbench/api/node/extHostDocuments.ts @@ -20,16 +20,14 @@ import { asWinJsPromise } from 'vs/base/common/async'; import { getWordAtText, ensureValidWordDefinition } from 'vs/editor/common/model/wordHelper'; import { MainContext, MainThreadDocumentsShape, ExtHostDocumentsShape, IModelAddedData } from './extHost.protocol'; -const _modeId2WordDefinition: { - [modeId: string]: RegExp; -} = Object.create(null); +const _modeId2WordDefinition = new Map(); function setWordDefinitionFor(modeId: string, wordDefinition: RegExp): void { - _modeId2WordDefinition[modeId] = wordDefinition; + _modeId2WordDefinition.set(modeId, wordDefinition); } function getWordDefinitionFor(modeId: string): RegExp { - return _modeId2WordDefinition[modeId]; + return _modeId2WordDefinition.get(modeId); } export class ExtHostDocuments extends ExtHostDocumentsShape { @@ -48,9 +46,9 @@ export class ExtHostDocuments extends ExtHostDocumentsShape { private _onDidSaveDocumentEventEmitter: Emitter; public onDidSaveDocument: Event; - private _documentData: { [modelUri: string]: ExtHostDocumentData; }; - private _documentLoader: { [modelUri: string]: TPromise }; - private _documentContentProviders: { [handle: number]: vscode.TextDocumentContentProvider; }; + private _documentData = new Map(); + private _documentLoader = new Map>(); + private _documentContentProviders = new Map(); private _proxy: MainThreadDocumentsShape; @@ -69,17 +67,11 @@ export class ExtHostDocuments extends ExtHostDocumentsShape { this._onDidSaveDocumentEventEmitter = new Emitter(); this.onDidSaveDocument = this._onDidSaveDocumentEventEmitter.event; - - this._documentData = Object.create(null); - this._documentLoader = Object.create(null); - this._documentContentProviders = Object.create(null); } public getAllDocumentData(): ExtHostDocumentData[] { const result: ExtHostDocumentData[] = []; - for (let key in this._documentData) { - result.push(this._documentData[key]); - } + this._documentData.forEach(data => result.push(data)); return result; } @@ -87,7 +79,7 @@ export class ExtHostDocuments extends ExtHostDocumentsShape { if (!resource) { return; } - const data = this._documentData[resource.toString()]; + const data = this._documentData.get(resource.toString()); if (data) { return data; } @@ -95,21 +87,21 @@ export class ExtHostDocuments extends ExtHostDocumentsShape { public ensureDocumentData(uri: URI): TPromise { - let cached = this._documentData[uri.toString()]; + let cached = this._documentData.get(uri.toString()); if (cached) { return TPromise.as(cached); } - let promise = this._documentLoader[uri.toString()]; + let promise = this._documentLoader.get(uri.toString()); if (!promise) { promise = this._proxy.$tryOpenDocument(uri).then(() => { - delete this._documentLoader[uri.toString()]; - return this._documentData[uri.toString()]; + this._documentLoader.delete(uri.toString()); + return this._documentData.get(uri.toString()); }, err => { - delete this._documentLoader[uri.toString()]; + this._documentLoader.delete(uri.toString()); return TPromise.wrapError(err); }); - this._documentLoader[uri.toString()] = promise; + this._documentLoader.set(uri.toString(), promise); } return promise; @@ -122,13 +114,13 @@ export class ExtHostDocuments extends ExtHostDocumentsShape { const handle = ExtHostDocuments._handlePool++; - this._documentContentProviders[handle] = provider; + this._documentContentProviders.set(handle, provider); this._proxy.$registerTextContentProvider(handle, scheme); let subscription: IDisposable; if (typeof provider.onDidChange === 'function') { subscription = provider.onDidChange(uri => { - if (this._documentData[uri.toString()]) { + if (this._documentData.has(uri.toString())) { this.$provideTextDocumentContent(handle, uri).then(value => { return this._proxy.$onVirtualDocumentChange(uri, value); }, onUnexpectedError); @@ -136,7 +128,7 @@ export class ExtHostDocuments extends ExtHostDocumentsShape { }); } return new Disposable(() => { - if (delete this._documentContentProviders[handle]) { + if (this._documentContentProviders.delete(handle)) { this._proxy.$unregisterTextContentProvider(handle); } if (subscription) { @@ -147,7 +139,7 @@ export class ExtHostDocuments extends ExtHostDocumentsShape { } $provideTextDocumentContent(handle: number, uri: URI): TPromise { - const provider = this._documentContentProviders[handle]; + const provider = this._documentContentProviders.get(handle); if (!provider) { return TPromise.wrapError(`unsupported uri-scheme: ${uri.scheme}`); } @@ -157,15 +149,15 @@ export class ExtHostDocuments extends ExtHostDocumentsShape { public $acceptModelAdd(initData: IModelAddedData): void { let data = new ExtHostDocumentData(this._proxy, initData.url, initData.value.lines, initData.value.EOL, initData.modeId, initData.versionId, initData.isDirty); let key = data.document.uri.toString(); - if (this._documentData[key]) { + if (this._documentData.has(key)) { throw new Error('Document `' + key + '` already exists.'); } - this._documentData[key] = data; + this._documentData.set(key, data); this._onDidAddDocumentEventEmitter.fire(data.document); } public $acceptModelModeChanged(strURL: string, oldModeId: string, newModeId: string): void { - let data = this._documentData[strURL]; + let data = this._documentData.get(strURL); // Treat a mode change as a remove + add @@ -175,33 +167,33 @@ export class ExtHostDocuments extends ExtHostDocumentsShape { } public $acceptModelSaved(strURL: string): void { - let data = this._documentData[strURL]; + let data = this._documentData.get(strURL); data._acceptIsDirty(false); this._onDidSaveDocumentEventEmitter.fire(data.document); } public $acceptModelDirty(strURL: string): void { - let document = this._documentData[strURL]; + let document = this._documentData.get(strURL); document._acceptIsDirty(true); } public $acceptModelReverted(strURL: string): void { - let document = this._documentData[strURL]; + let document = this._documentData.get(strURL); document._acceptIsDirty(false); } public $acceptModelRemoved(strURL: string): void { - if (!this._documentData[strURL]) { + if (!this._documentData.has(strURL)) { throw new Error('Document `' + strURL + '` does not exist.'); } - let data = this._documentData[strURL]; - delete this._documentData[strURL]; + let data = this._documentData.get(strURL); + this._documentData.delete(strURL); this._onDidRemoveDocumentEventEmitter.fire(data.document); data.dispose(); } public $acceptModelChanged(strURL: string, events: editorCommon.IModelContentChangedEvent2[], isDirty: boolean): void { - let data = this._documentData[strURL]; + let data = this._documentData.get(strURL); data._acceptIsDirty(isDirty); data.onEvents(events); this._onDidChangeDocumentEventEmitter.fire({ diff --git a/src/vs/workbench/api/node/extHostEditors.ts b/src/vs/workbench/api/node/extHostEditors.ts index 7556f5a818a..7f1b0e57cd5 100644 --- a/src/vs/workbench/api/node/extHostEditors.ts +++ b/src/vs/workbench/api/node/extHostEditors.ts @@ -30,7 +30,7 @@ export class ExtHostEditors extends ExtHostEditorsShape { public onDidChangeTextEditorViewColumn: Event; private _onDidChangeTextEditorViewColumn: Emitter; - private _editors: { [id: string]: ExtHostTextEditor }; + private _editors: Map; private _proxy: MainThreadEditorsShape; private _onDidChangeActiveTextEditor: Emitter; private _onDidChangeVisibleTextEditors: Emitter; @@ -56,17 +56,17 @@ export class ExtHostEditors extends ExtHostEditorsShape { this._proxy = threadService.get(MainContext.MainThreadEditors); this._onDidChangeActiveTextEditor = new Emitter(); this._onDidChangeVisibleTextEditors = new Emitter(); - this._editors = Object.create(null); + this._editors = new Map(); this._visibleEditorIds = []; } getActiveTextEditor(): vscode.TextEditor { - return this._editors[this._activeEditorId]; + return this._editors.get(this._activeEditorId); } getVisibleTextEditors(): vscode.TextEditor[] { - return this._visibleEditorIds.map(id => this._editors[id]); + return this._visibleEditorIds.map(id => this._editors.get(id)); } get onDidChangeActiveTextEditor(): Event { @@ -79,7 +79,7 @@ export class ExtHostEditors extends ExtHostEditorsShape { showTextDocument(document: vscode.TextDocument, column: vscode.ViewColumn, preserveFocus: boolean): TPromise { return this._proxy.$tryShowTextDocument(document.uri, TypeConverters.fromViewColumn(column), preserveFocus).then(id => { - let editor = this._editors[id]; + let editor = this._editors.get(id); if (editor) { return editor; } else { @@ -97,11 +97,11 @@ export class ExtHostEditors extends ExtHostEditorsShape { $acceptTextEditorAdd(data: ITextEditorAddData): void { let document = this._extHostDocuments.getDocumentData(data.document); let newEditor = new ExtHostTextEditor(this._proxy, data.id, document, data.selections.map(TypeConverters.toSelection), data.options, TypeConverters.toViewColumn(data.editorPosition)); - this._editors[data.id] = newEditor; + this._editors.set(data.id, newEditor); } $acceptOptionsChanged(id: string, opts: IResolvedTextEditorConfiguration): void { - let editor = this._editors[id]; + let editor = this._editors.get(id); editor._acceptOptions(opts); this._onDidChangeTextEditorOptions.fire({ textEditor: editor, @@ -112,7 +112,7 @@ export class ExtHostEditors extends ExtHostEditorsShape { $acceptSelectionsChanged(id: string, event: ISelectionChangeEvent): void { const kind = TextEditorSelectionChangeKind.fromValue(event.source); const selections = event.selections.map(TypeConverters.toSelection); - const textEditor = this._editors[id]; + const textEditor = this._editors.get(id); textEditor._acceptSelections(selections); this._onDidChangeTextEditorSelection.fire({ textEditor, @@ -145,7 +145,7 @@ export class ExtHostEditors extends ExtHostEditorsShape { $acceptEditorPositionData(data: ITextEditorPositionData): void { for (let id in data) { - let textEditor = this._editors[id]; + let textEditor = this._editors.get(id); let viewColumn = TypeConverters.toViewColumn(data[id]); if (textEditor.viewColumn !== viewColumn) { textEditor._acceptViewColumn(viewColumn); @@ -165,9 +165,9 @@ export class ExtHostEditors extends ExtHostEditorsShape { this.$acceptActiveEditorAndVisibleEditors(this._activeEditorId, newVisibleEditors); } - let editor = this._editors[id]; + let editor = this._editors.get(id); editor.dispose(); - delete this._editors[id]; + this._editors.delete(id); } } diff --git a/src/vs/workbench/api/node/extHostHeapService.ts b/src/vs/workbench/api/node/extHostHeapService.ts index c993ae4ecba..62c38b8528a 100644 --- a/src/vs/workbench/api/node/extHostHeapService.ts +++ b/src/vs/workbench/api/node/extHostHeapService.ts @@ -10,20 +10,20 @@ export class ExtHostHeapService extends ExtHostHeapServiceShape { private static _idPool = 0; - private _data: { [n: number]: any } = Object.create(null); + private _data = new Map(); keep(obj: any): number { const id = ExtHostHeapService._idPool++; - this._data[id] = obj; + this._data.set(id, obj); return id; } delete(id: number): boolean { - return this._data[id]; + return this._data.delete(id); } get(id: number): T { - return this._data[id]; + return this._data.get(id); } $onGarbageCollection(ids: number[]): void { @@ -31,4 +31,4 @@ export class ExtHostHeapService extends ExtHostHeapServiceShape { this.delete(id); } } -} \ No newline at end of file +} diff --git a/src/vs/workbench/api/node/extHostLanguageFeatures.ts b/src/vs/workbench/api/node/extHostLanguageFeatures.ts index 038eb9e0138..38706f8abb2 100644 --- a/src/vs/workbench/api/node/extHostLanguageFeatures.ts +++ b/src/vs/workbench/api/node/extHostLanguageFeatures.ts @@ -624,7 +624,7 @@ export class ExtHostLanguageFeatures extends ExtHostLanguageFeaturesShape { private _commands: ExtHostCommands; private _heapService: ExtHostHeapService; private _diagnostics: ExtHostDiagnostics; - private _adapter: { [handle: number]: Adapter } = Object.create(null); + private _adapter = new Map(); constructor( threadService: IThreadService, @@ -643,7 +643,7 @@ export class ExtHostLanguageFeatures extends ExtHostLanguageFeaturesShape { private _createDisposable(handle: number): Disposable { return new Disposable(() => { - delete this._adapter[handle]; + this._adapter.delete(handle); this._proxy.$unregister(handle); }); } @@ -653,7 +653,7 @@ export class ExtHostLanguageFeatures extends ExtHostLanguageFeaturesShape { } private _withAdapter(handle: number, ctor: { new (...args: any[]): A }, callback: (adapter: A) => TPromise): TPromise { - let adapter = this._adapter[handle]; + let adapter = this._adapter.get(handle); if (!(adapter instanceof ctor)) { return TPromise.wrapError(new Error('no adapter found')); } @@ -664,7 +664,7 @@ export class ExtHostLanguageFeatures extends ExtHostLanguageFeaturesShape { registerDocumentSymbolProvider(selector: vscode.DocumentSelector, provider: vscode.DocumentSymbolProvider): vscode.Disposable { const handle = this._nextHandle(); - this._adapter[handle] = new OutlineAdapter(this._documents, provider); + this._adapter.set(handle, new OutlineAdapter(this._documents, provider)); this._proxy.$registerOutlineSupport(handle, selector); return this._createDisposable(handle); } @@ -679,7 +679,7 @@ export class ExtHostLanguageFeatures extends ExtHostLanguageFeaturesShape { const handle = this._nextHandle(); const eventHandle = typeof provider.onDidChangeCodeLenses === 'function' ? this._nextHandle() : undefined; - this._adapter[handle] = new CodeLensAdapter(this._documents, this._commands.converter, this._heapService, provider); + this._adapter.set(handle, new CodeLensAdapter(this._documents, this._commands.converter, this._heapService, provider)); this._proxy.$registerCodeLensSupport(handle, selector, eventHandle); let result = this._createDisposable(handle); @@ -703,7 +703,7 @@ export class ExtHostLanguageFeatures extends ExtHostLanguageFeaturesShape { registerDefinitionProvider(selector: vscode.DocumentSelector, provider: vscode.DefinitionProvider): vscode.Disposable { const handle = this._nextHandle(); - this._adapter[handle] = new DefinitionAdapter(this._documents, provider); + this._adapter.set(handle, new DefinitionAdapter(this._documents, provider)); this._proxy.$registerDeclaractionSupport(handle, selector); return this._createDisposable(handle); } @@ -716,7 +716,7 @@ export class ExtHostLanguageFeatures extends ExtHostLanguageFeaturesShape { registerHoverProvider(selector: vscode.DocumentSelector, provider: vscode.HoverProvider): vscode.Disposable { const handle = this._nextHandle(); - this._adapter[handle] = new HoverAdapter(this._documents, provider); + this._adapter.set(handle, new HoverAdapter(this._documents, provider)); this._proxy.$registerHoverProvider(handle, selector); return this._createDisposable(handle); } @@ -729,7 +729,7 @@ export class ExtHostLanguageFeatures extends ExtHostLanguageFeaturesShape { registerDocumentHighlightProvider(selector: vscode.DocumentSelector, provider: vscode.DocumentHighlightProvider): vscode.Disposable { const handle = this._nextHandle(); - this._adapter[handle] = new DocumentHighlightAdapter(this._documents, provider); + this._adapter.set(handle, new DocumentHighlightAdapter(this._documents, provider)); this._proxy.$registerDocumentHighlightProvider(handle, selector); return this._createDisposable(handle); } @@ -742,7 +742,7 @@ export class ExtHostLanguageFeatures extends ExtHostLanguageFeaturesShape { registerReferenceProvider(selector: vscode.DocumentSelector, provider: vscode.ReferenceProvider): vscode.Disposable { const handle = this._nextHandle(); - this._adapter[handle] = new ReferenceAdapter(this._documents, provider); + this._adapter.set(handle, new ReferenceAdapter(this._documents, provider)); this._proxy.$registerReferenceSupport(handle, selector); return this._createDisposable(handle); } @@ -755,7 +755,7 @@ export class ExtHostLanguageFeatures extends ExtHostLanguageFeaturesShape { registerCodeActionProvider(selector: vscode.DocumentSelector, provider: vscode.CodeActionProvider): vscode.Disposable { const handle = this._nextHandle(); - this._adapter[handle] = new QuickFixAdapter(this._documents, this._commands.converter, this._diagnostics, this._heapService, provider); + this._adapter.set(handle, new QuickFixAdapter(this._documents, this._commands.converter, this._diagnostics, this._heapService, provider)); this._proxy.$registerQuickFixSupport(handle, selector); return this._createDisposable(handle); } @@ -768,7 +768,7 @@ export class ExtHostLanguageFeatures extends ExtHostLanguageFeaturesShape { registerDocumentFormattingEditProvider(selector: vscode.DocumentSelector, provider: vscode.DocumentFormattingEditProvider): vscode.Disposable { const handle = this._nextHandle(); - this._adapter[handle] = new DocumentFormattingAdapter(this._documents, provider); + this._adapter.set(handle, new DocumentFormattingAdapter(this._documents, provider)); this._proxy.$registerDocumentFormattingSupport(handle, selector); return this._createDisposable(handle); } @@ -779,7 +779,7 @@ export class ExtHostLanguageFeatures extends ExtHostLanguageFeaturesShape { registerDocumentRangeFormattingEditProvider(selector: vscode.DocumentSelector, provider: vscode.DocumentRangeFormattingEditProvider): vscode.Disposable { const handle = this._nextHandle(); - this._adapter[handle] = new RangeFormattingAdapter(this._documents, provider); + this._adapter.set(handle, new RangeFormattingAdapter(this._documents, provider)); this._proxy.$registerRangeFormattingSupport(handle, selector); return this._createDisposable(handle); } @@ -790,7 +790,7 @@ export class ExtHostLanguageFeatures extends ExtHostLanguageFeaturesShape { registerOnTypeFormattingEditProvider(selector: vscode.DocumentSelector, provider: vscode.OnTypeFormattingEditProvider, triggerCharacters: string[]): vscode.Disposable { const handle = this._nextHandle(); - this._adapter[handle] = new OnTypeFormattingAdapter(this._documents, provider); + this._adapter.set(handle, new OnTypeFormattingAdapter(this._documents, provider)); this._proxy.$registerOnTypeFormattingSupport(handle, selector, triggerCharacters); return this._createDisposable(handle); } @@ -803,7 +803,7 @@ export class ExtHostLanguageFeatures extends ExtHostLanguageFeaturesShape { registerWorkspaceSymbolProvider(provider: vscode.WorkspaceSymbolProvider): vscode.Disposable { const handle = this._nextHandle(); - this._adapter[handle] = new NavigateTypeAdapter(provider, this._heapService); + this._adapter.set(handle, new NavigateTypeAdapter(provider, this._heapService)); this._proxy.$registerNavigateTypeSupport(handle); return this._createDisposable(handle); } @@ -820,7 +820,7 @@ export class ExtHostLanguageFeatures extends ExtHostLanguageFeaturesShape { registerRenameProvider(selector: vscode.DocumentSelector, provider: vscode.RenameProvider): vscode.Disposable { const handle = this._nextHandle(); - this._adapter[handle] = new RenameAdapter(this._documents, provider); + this._adapter.set(handle, new RenameAdapter(this._documents, provider)); this._proxy.$registerRenameSupport(handle, selector); return this._createDisposable(handle); } @@ -833,7 +833,7 @@ export class ExtHostLanguageFeatures extends ExtHostLanguageFeaturesShape { registerCompletionItemProvider(selector: vscode.DocumentSelector, provider: vscode.CompletionItemProvider, triggerCharacters: string[]): vscode.Disposable { const handle = this._nextHandle(); - this._adapter[handle] = new SuggestAdapter(this._documents, this._commands.converter, this._heapService, provider); + this._adapter.set(handle, new SuggestAdapter(this._documents, this._commands.converter, this._heapService, provider)); this._proxy.$registerSuggestSupport(handle, selector, triggerCharacters); return this._createDisposable(handle); } @@ -850,7 +850,7 @@ export class ExtHostLanguageFeatures extends ExtHostLanguageFeaturesShape { registerSignatureHelpProvider(selector: vscode.DocumentSelector, provider: vscode.SignatureHelpProvider, triggerCharacters: string[]): vscode.Disposable { const handle = this._nextHandle(); - this._adapter[handle] = new SignatureHelpAdapter(this._documents, provider); + this._adapter.set(handle, new SignatureHelpAdapter(this._documents, provider)); this._proxy.$registerSignatureHelpProvider(handle, selector, triggerCharacters); return this._createDisposable(handle); } @@ -863,7 +863,7 @@ export class ExtHostLanguageFeatures extends ExtHostLanguageFeaturesShape { registerDocumentLinkProvider(selector: vscode.DocumentSelector, provider: vscode.DocumentLinkProvider): vscode.Disposable { const handle = this._nextHandle(); - this._adapter[handle] = new LinkProviderAdapter(this._documents, provider); + this._adapter.set(handle, new LinkProviderAdapter(this._documents, provider)); this._proxy.$registerDocumentLinkProvider(handle, selector); return this._createDisposable(handle); } diff --git a/src/vs/workbench/api/node/extHostTypes.ts b/src/vs/workbench/api/node/extHostTypes.ts index cc30c8ef508..e7b26461e60 100644 --- a/src/vs/workbench/api/node/extHostTypes.ts +++ b/src/vs/workbench/api/node/extHostTypes.ts @@ -465,7 +465,7 @@ export class Uri extends URI { } export class WorkspaceEdit { private _values: [Uri, TextEdit[]][] = []; - private _index: { [uri: string]: number } = Object.create(null); + private _index = new Map(); replace(uri: Uri, range: Range, newText: string): void { let edit = new TextEdit(range, newText); @@ -486,21 +486,21 @@ export class WorkspaceEdit { } has(uri: Uri): boolean { - return typeof this._index[uri.toString()] !== 'undefined'; + return this._index.has(uri.toString()); } set(uri: Uri, edits: TextEdit[]): void { - let idx = this._index[uri.toString()]; + const idx = this._index.get(uri.toString()); if (typeof idx === 'undefined') { let newLen = this._values.push([uri, edits]); - this._index[uri.toString()] = newLen - 1; + this._index.set(uri.toString(), newLen - 1); } else { this._values[idx][1] = edits; } } get(uri: Uri): TextEdit[] { - let idx = this._index[uri.toString()]; + let idx = this._index.get(uri.toString()); return typeof idx !== 'undefined' && this._values[idx][1]; } diff --git a/src/vs/workbench/parts/files/browser/media/collapsed-dark.svg b/src/vs/workbench/parts/files/browser/media/collapsed-dark.svg new file mode 100755 index 00000000000..cf5c3641aa7 --- /dev/null +++ b/src/vs/workbench/parts/files/browser/media/collapsed-dark.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/vs/workbench/parts/files/browser/media/collapsed-hc.svg b/src/vs/workbench/parts/files/browser/media/collapsed-hc.svg new file mode 100644 index 00000000000..145c763338f --- /dev/null +++ b/src/vs/workbench/parts/files/browser/media/collapsed-hc.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/vs/workbench/parts/files/browser/media/collapsed.svg b/src/vs/workbench/parts/files/browser/media/collapsed.svg new file mode 100755 index 00000000000..3a63808c358 --- /dev/null +++ b/src/vs/workbench/parts/files/browser/media/collapsed.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/vs/workbench/parts/files/browser/media/expanded-dark.svg b/src/vs/workbench/parts/files/browser/media/expanded-dark.svg new file mode 100755 index 00000000000..73d41e63990 --- /dev/null +++ b/src/vs/workbench/parts/files/browser/media/expanded-dark.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/vs/workbench/parts/files/browser/media/expanded-hc.svg b/src/vs/workbench/parts/files/browser/media/expanded-hc.svg new file mode 100644 index 00000000000..d38d4abc89e --- /dev/null +++ b/src/vs/workbench/parts/files/browser/media/expanded-hc.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/vs/workbench/parts/files/browser/media/expanded.svg b/src/vs/workbench/parts/files/browser/media/expanded.svg new file mode 100755 index 00000000000..75f73adbb02 --- /dev/null +++ b/src/vs/workbench/parts/files/browser/media/expanded.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/vs/workbench/parts/files/browser/media/explorerviewlet.css b/src/vs/workbench/parts/files/browser/media/explorerviewlet.css index 275207a4063..7429a126d46 100644 --- a/src/vs/workbench/parts/files/browser/media/explorerviewlet.css +++ b/src/vs/workbench/parts/files/browser/media/explorerviewlet.css @@ -48,6 +48,48 @@ visibility: hidden; } +.explorer-folders-view .monaco-tree-row > .content { + display: inline-block; +} + +.explorer-folders-view .monaco-tree-row::before { + /* svg icons rendered as background image */ + background-size: 16px; + background-position: left center; + background-repeat: no-repeat; + padding-right: 6px; + width: 16px; + height: 22px; + display: inline-block; + vertical-align: top; + content: ' '; +} + +.explorer-folders-view .monaco-tree-row.has-children.expanded::before { + background-image: url("expanded.svg"); +} + +.explorer-folders-view .monaco-tree-row.has-children::before { + display: inline-block; + background-image: url("collapsed.svg"); +} + +.vs-dark .explorer-folders-view .monaco-tree-row.has-children.expanded::before { + background-image: url("expanded-dark.svg"); +} + +.vs-dark .explorer-folders-view .monaco-tree-row.has-children::before { + background-image: url("collapsed-dark.svg"); +} + +.hc-black .explorer-folders-view .monaco-tree-row.has-children.expanded::before { + background-image: url("expanded-hc.svg"); +} + +.hc-black .explorer-folders-view .monaco-tree-row.has-children::before { + background-image: url("collapsed-hc.svg"); +} + .explorer-viewlet .explorer-open-editors .monaco-tree .monaco-tree-row:hover > .content .monaco-action-bar, .explorer-viewlet .explorer-open-editors .monaco-tree.focused .monaco-tree-row.focused > .content .monaco-action-bar, .explorer-viewlet .explorer-open-editors .monaco-tree .monaco-tree-row > .content.dirty > .monaco-action-bar { diff --git a/src/vs/workbench/parts/files/browser/views/explorerView.ts b/src/vs/workbench/parts/files/browser/views/explorerView.ts index 5e2c1722675..b56e240c784 100644 --- a/src/vs/workbench/parts/files/browser/views/explorerView.ts +++ b/src/vs/workbench/parts/files/browser/views/explorerView.ts @@ -330,7 +330,9 @@ export class ExplorerView extends CollapsibleViewletView { accessibilityProvider }, { autoExpandSingleChildren: true, - ariaLabel: nls.localize('treeAriaLabel', "Files Explorer") + ariaLabel: nls.localize('treeAriaLabel', "Files Explorer"), + twistiePixels: 16, + showTwistie: false }); this.toDispose.push(lifecycle.toDisposable(() => renderer.dispose())); diff --git a/src/vs/workbench/services/themes/electron-browser/themeService.ts b/src/vs/workbench/services/themes/electron-browser/themeService.ts index 521268516b3..e44edd872ba 100644 --- a/src/vs/workbench/services/themes/electron-browser/themeService.ts +++ b/src/vs/workbench/services/themes/electron-browser/themeService.ts @@ -481,6 +481,10 @@ function _loadIconThemeDocument(fileSetPath: string): TPromise {