diff --git a/extensions/git/src/commands.ts b/extensions/git/src/commands.ts index 554165f476c..dc1774aea46 100644 --- a/extensions/git/src/commands.ts +++ b/extensions/git/src/commands.ts @@ -556,7 +556,7 @@ export class CommandCenter { @command('git.stage') async stage(...resourceStates: SourceControlResourceState[]): Promise { - if (resourceStates.length === 0 || !(resourceStates[0].resourceUri instanceof Uri)) { + if (resourceStates.length === 0 || (resourceStates[0] && !(resourceStates[0].resourceUri instanceof Uri))) { const resource = this.getSCMResource(); if (!resource) { @@ -733,7 +733,7 @@ export class CommandCenter { @command('git.unstage') async unstage(...resourceStates: SourceControlResourceState[]): Promise { - if (resourceStates.length === 0 || !(resourceStates[0].resourceUri instanceof Uri)) { + if (resourceStates.length === 0 || (resourceStates[0] && !(resourceStates[0].resourceUri instanceof Uri))) { const resource = this.getSCMResource(); if (!resource) { @@ -799,7 +799,7 @@ export class CommandCenter { @command('git.clean') async clean(...resourceStates: SourceControlResourceState[]): Promise { - if (resourceStates.length === 0 || !(resourceStates[0].resourceUri instanceof Uri)) { + if (resourceStates.length === 0 || (resourceStates[0] && !(resourceStates[0].resourceUri instanceof Uri))) { const resource = this.getSCMResource(); if (!resource) { @@ -1406,7 +1406,7 @@ export class CommandCenter { @command('git.ignore') async ignore(...resourceStates: SourceControlResourceState[]): Promise { - if (resourceStates.length === 0 || !(resourceStates[0].resourceUri instanceof Uri)) { + if (resourceStates.length === 0 || (resourceStates[0] && !(resourceStates[0].resourceUri instanceof Uri))) { const resource = this.getSCMResource(); if (!resource) { diff --git a/src/vs/workbench/api/node/extHostSCM.ts b/src/vs/workbench/api/node/extHostSCM.ts index 7ffe2da7829..36ae0131eb1 100644 --- a/src/vs/workbench/api/node/extHostSCM.ts +++ b/src/vs/workbench/api/node/extHostSCM.ts @@ -13,7 +13,7 @@ import { asWinJsPromise } from 'vs/base/common/async'; import { IExtensionDescription } from 'vs/platform/extensions/common/extensions'; import { ExtHostCommands } from 'vs/workbench/api/node/extHostCommands'; import { MainContext, MainThreadSCMShape, SCMRawResource, SCMRawResourceSplice, SCMRawResourceSplices, IMainContext } from './extHost.protocol'; -import { sortedDiff } from 'vs/base/common/arrays'; +import { sortedDiff, Splice } from 'vs/base/common/arrays'; import { comparePaths } from 'vs/base/common/comparers'; import * as vscode from 'vscode'; @@ -158,7 +158,6 @@ class ExtHostSourceControlResourceGroup implements vscode.SourceControlResourceG private _resourceHandlePool: number = 0; private _resourceStates: vscode.SourceControlResourceState[] = []; - private _resourceStatesRollingDisposables: { (): void }[] = []; private _resourceStatesMap: Map = new Map(); private _resourceStatesCommandsMap: Map = new Map(); @@ -221,65 +220,63 @@ class ExtHostSourceControlResourceGroup implements vscode.SourceControlResourceG _takeResourceStateSnapshot(): SCMRawResourceSplice[] { const snapshot = [...this._resourceStates].sort(compareResourceStates); const diffs = sortedDiff(this._resourceSnapshot, snapshot, compareResourceStates); - const handlesToDelete: number[] = []; - const splices = diffs.map(diff => { - const { start, deleteCount } = diff; - const handles: number[] = []; + const splices = diffs.map>(diff => { + const inserted = diff.inserted.map(r => { + const handle = this._resourceHandlePool++; + this._resourceStatesMap.set(handle, r); - const rawResources = diff.inserted - .map(r => { - const handle = this._resourceHandlePool++; - this._resourceStatesMap.set(handle, r); - handles.push(handle); + const sourceUri = r.resourceUri.toString(); + const iconPath = getIconPath(r.decorations); + const lightIconPath = r.decorations && getIconPath(r.decorations.light) || iconPath; + const darkIconPath = r.decorations && getIconPath(r.decorations.dark) || iconPath; + const icons: string[] = []; - const sourceUri = r.resourceUri.toString(); - const iconPath = getIconPath(r.decorations); - const lightIconPath = r.decorations && getIconPath(r.decorations.light) || iconPath; - const darkIconPath = r.decorations && getIconPath(r.decorations.dark) || iconPath; - const icons: string[] = []; + if (r.command) { + this._resourceStatesCommandsMap.set(handle, r.command); + } - if (r.command) { - this._resourceStatesCommandsMap.set(handle, r.command); - } + if (lightIconPath || darkIconPath) { + icons.push(lightIconPath); + } - if (lightIconPath || darkIconPath) { - icons.push(lightIconPath); - } + if (darkIconPath !== lightIconPath) { + icons.push(darkIconPath); + } - if (darkIconPath !== lightIconPath) { - icons.push(darkIconPath); - } + const tooltip = (r.decorations && r.decorations.tooltip) || ''; + const strikeThrough = r.decorations && !!r.decorations.strikeThrough; + const faded = r.decorations && !!r.decorations.faded; - const tooltip = (r.decorations && r.decorations.tooltip) || ''; - const strikeThrough = r.decorations && !!r.decorations.strikeThrough; - const faded = r.decorations && !!r.decorations.faded; + const source = r.decorations && r.decorations.source || undefined; + const letter = r.decorations && r.decorations.letter || undefined; + const color = r.decorations && r.decorations.color || undefined; - const source = r.decorations && r.decorations.source || undefined; - const letter = r.decorations && r.decorations.letter || undefined; - const color = r.decorations && r.decorations.color || undefined; + const rawResource = [handle, sourceUri, icons, tooltip, strikeThrough, faded, source, letter, color] as SCMRawResource; - return [handle, sourceUri, icons, tooltip, strikeThrough, faded, source, letter, color] as SCMRawResource; - }); + return { rawResource, handle }; + }); - handlesToDelete.push(...this._handlesSnapshot.splice(start, deleteCount, ...handles)); - - return [start, deleteCount, rawResources] as SCMRawResourceSplice; + return { start: diff.start, deleteCount: diff.deleteCount, inserted }; }); - const disposable = () => handlesToDelete.forEach(handle => { - this._resourceStatesMap.delete(handle); - this._resourceStatesCommandsMap.delete(handle); - }); + const rawResourceSplices = splices + .map(({ start, deleteCount, inserted }) => [start, deleteCount, inserted.map(i => i.rawResource)] as SCMRawResourceSplice); - this._resourceStatesRollingDisposables.push(disposable); + const reverseSplices = splices.reverse(); - while (this._resourceStatesRollingDisposables.length >= 10) { - this._resourceStatesRollingDisposables.shift()(); + for (const { start, deleteCount, inserted } of reverseSplices) { + const handles = inserted.map(i => i.handle); + const handlesToDelete = this._handlesSnapshot.splice(start, deleteCount, ...handles); + + for (const handle of handlesToDelete) { + this._resourceStatesMap.delete(handle); + this._resourceStatesCommandsMap.delete(handle); + } } this._resourceSnapshot = snapshot; - return splices; + return rawResourceSplices; } dispose(): void {