Skip to content

Commit d469911

Browse files
authored
Comparing the paths of the URI (microsoft#208777)
* comparing the paths * revealing resources for a given original and modified uri pair * changing comments
1 parent 0b448a5 commit d469911

File tree

4 files changed

+55
-45
lines changed

4 files changed

+55
-45
lines changed

src/vs/base/common/cache.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,17 +39,19 @@ export class Cache<T> {
3939
/**
4040
* Uses a LRU cache to make a given parametrized function cached.
4141
* Caches just the last value.
42-
* The key must be JSON serializable.
4342
*/
4443
export class LRUCachedFunction<TArg, TComputed> {
4544
private lastCache: TComputed | undefined = undefined;
46-
private lastArgKey: string | undefined = undefined;
45+
private lastArgKey: unknown | undefined = undefined;
4746

48-
constructor(private readonly fn: (arg: TArg) => TComputed) {
47+
constructor(
48+
private readonly fn: (arg: TArg) => TComputed,
49+
private readonly _computeKey: (arg: TArg) => unknown = JSON.stringify,
50+
) {
4951
}
5052

5153
public get(arg: TArg): TComputed {
52-
const key = JSON.stringify(arg);
54+
const key = this._computeKey(arg);
5355
if (this.lastArgKey !== key) {
5456
this.lastArgKey = key;
5557
this.lastCache = this.fn(arg);

src/vs/editor/browser/widget/multiDiffEditor/multiDiffEditorWidget.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { Disposable } from 'vs/base/common/lifecycle';
88
import { derived, derivedWithStore, observableValue, recomputeInitiallyAndOnChange } from 'vs/base/common/observable';
99
import { readHotReloadableExport } from 'vs/editor/browser/widget/diffEditor/utils';
1010
import { IMultiDiffEditorModel } from 'vs/editor/browser/widget/multiDiffEditor/model';
11-
import { IMultiDiffEditorViewState, IMultiDiffResource, MultiDiffEditorWidgetImpl } from 'vs/editor/browser/widget/multiDiffEditor/multiDiffEditorWidgetImpl';
11+
import { IMultiDiffEditorViewState, IMultiDiffResourceId, MultiDiffEditorWidgetImpl } from 'vs/editor/browser/widget/multiDiffEditor/multiDiffEditorWidgetImpl';
1212
import { MultiDiffEditorViewModel } from './multiDiffEditorViewModel';
1313
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
1414
import './colors';
@@ -46,7 +46,7 @@ export class MultiDiffEditorWidget extends Disposable {
4646
this._register(recomputeInitiallyAndOnChange(this._widgetImpl));
4747
}
4848

49-
public reveal(resource: IMultiDiffResource, options?: RevealOptions): void {
49+
public reveal(resource: IMultiDiffResourceId, options?: RevealOptions): void {
5050
this._widgetImpl.get().reveal(resource, options);
5151
}
5252

src/vs/editor/browser/widget/multiDiffEditor/multiDiffEditorWidgetImpl.ts

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import { ServiceCollection } from 'vs/platform/instantiation/common/serviceColle
2828
import { DiffEditorItemTemplate, TemplateData } from './diffEditorItemTemplate';
2929
import { DocumentDiffItemViewModel, MultiDiffEditorViewModel } from './multiDiffEditorViewModel';
3030
import { ObjectPool } from './objectPool';
31+
import { BugIndicatingError } from 'vs/base/common/errors';
3132

3233
export class MultiDiffEditorWidgetImpl extends Disposable {
3334
private readonly _elements = h('div.monaco-component.multiDiffEditor', [
@@ -191,15 +192,15 @@ export class MultiDiffEditorWidgetImpl extends Disposable {
191192
this._scrollableElement.setScrollPosition({ scrollLeft: scrollState.left, scrollTop: scrollState.top });
192193
}
193194

194-
public reveal(resource: IMultiDiffResource, options?: RevealOptions): void {
195+
public reveal(resource: IMultiDiffResourceId, options?: RevealOptions): void {
195196
const viewItems = this._viewItems.get();
196-
let searchCallback: (item: VirtualizedViewItem) => boolean;
197-
if ('original' in resource) {
198-
searchCallback = (item) => item.viewModel.originalUri?.toString() === resource.original.toString();
199-
} else {
200-
searchCallback = (item) => item.viewModel.modifiedUri?.toString() === resource.modified.toString();
197+
const index = viewItems.findIndex(
198+
(item) => item.viewModel.originalUri?.toString() === resource.original?.toString()
199+
&& item.viewModel.modifiedUri?.toString() === resource.modified?.toString()
200+
);
201+
if (index === -1) {
202+
throw new BugIndicatingError('Resource not found in diff editor');
201203
}
202-
const index = viewItems.findIndex(searchCallback);
203204
let scrollTop = 0;
204205
for (let i = 0; i < index; i++) {
205206
scrollTop += viewItems[i].contentHeight.get() + this._spaceBetweenPx;
@@ -323,12 +324,12 @@ export interface IMultiDiffEditorOptions extends ITextEditorOptions {
323324

324325
export interface IMultiDiffEditorOptionsViewState {
325326
revealData?: {
326-
resource: IMultiDiffResource;
327+
resource: IMultiDiffResourceId;
327328
range?: IRange;
328329
};
329330
}
330331

331-
export type IMultiDiffResource = { original: URI } | { modified: URI };
332+
export type IMultiDiffResourceId = { original: URI | undefined; modified: URI | undefined };
332333

333334
class VirtualizedViewItem extends Disposable {
334335
private readonly _templateRef = this._register(disposableObservableValue<IReference<DiffEditorItemTemplate> | undefined>(this, undefined));

src/vs/workbench/contrib/bulkEdit/browser/preview/bulkEditPane.ts

Lines changed: 37 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,9 @@ import { ButtonBar } from 'vs/base/browser/ui/button/button';
3737
import { defaultButtonStyles } from 'vs/platform/theme/browser/defaultStyles';
3838
import { Mutable } from 'vs/base/common/types';
3939
import { IResourceDiffEditorInput } from 'vs/workbench/common/editor';
40-
import { IMultiDiffEditorOptions } from 'vs/editor/browser/widget/multiDiffEditor/multiDiffEditorWidgetImpl';
40+
import { IMultiDiffEditorOptions, IMultiDiffResourceId } from 'vs/editor/browser/widget/multiDiffEditor/multiDiffEditorWidgetImpl';
4141
import { IRange } from 'vs/editor/common/core/range';
42+
import { CachedFunction, LRUCachedFunction } from 'vs/base/common/cache';
4243

4344
const enum State {
4445
Data = 'data',
@@ -70,8 +71,6 @@ export class BulkEditPane extends ViewPane {
7071
private _currentResolve?: (edit?: ResourceEdit[]) => void;
7172
private _currentInput?: BulkFileOperations;
7273
private _currentProvider?: BulkEditPreviewProvider;
73-
private _fileOperations?: BulkFileOperation[];
74-
private _resources?: IResourceDiffEditorInput[];
7574

7675
constructor(
7776
options: IViewletViewOptions,
@@ -345,12 +344,13 @@ export class BulkEditPane extends ViewPane {
345344
return;
346345
}
347346

348-
const resources = await this._resolveResources(fileOperations);
347+
const result = await this._computeResourceDiffEditorInputs.get(fileOperations);
348+
const resourceId = await result.getResourceDiffEditorInputIdOfOperation(fileElement.edit);
349349
const options: Mutable<IMultiDiffEditorOptions> = {
350350
...e.editorOptions,
351351
viewState: {
352352
revealData: {
353-
resource: { original: fileElement.edit.uri },
353+
resource: resourceId,
354354
range: selection,
355355
}
356356
}
@@ -359,49 +359,56 @@ export class BulkEditPane extends ViewPane {
359359
const label = 'Refactor Preview';
360360
this._editorService.openEditor({
361361
multiDiffSource,
362-
resources,
363362
label,
364363
options,
365364
isTransient: true,
366-
description: label
365+
description: label,
366+
resources: result.resources
367367
}, e.sideBySide ? SIDE_GROUP : ACTIVE_GROUP);
368368
}
369369

370-
private async _resolveResources(fileOperations: BulkFileOperation[]): Promise<IResourceDiffEditorInput[]> {
371-
if (this._fileOperations === fileOperations && this._resources) {
372-
return this._resources;
373-
}
374-
const sortedFileOperations = fileOperations.sort(compareBulkFileOperations);
375-
const resources: IResourceDiffEditorInput[] = [];
376-
for (const operation of sortedFileOperations) {
377-
const operationUri = operation.uri;
378-
const previewUri = this._currentProvider!.asPreviewUri(operationUri);
379-
// delete -> show single editor
380-
if (operation.type & BulkFileOperationType.Delete) {
381-
resources.push({
370+
private readonly _computeResourceDiffEditorInputs = new LRUCachedFunction(async (fileOperations: BulkFileOperation[]) => {
371+
const computeDiffEditorInput = new CachedFunction<BulkFileOperation, Promise<IResourceDiffEditorInput>>(async (fileOperation) => {
372+
const fileOperationUri = fileOperation.uri;
373+
const previewUri = this._currentProvider!.asPreviewUri(fileOperationUri);
374+
// delete
375+
if (fileOperation.type & BulkFileOperationType.Delete) {
376+
return {
382377
original: { resource: undefined },
383378
modified: { resource: URI.revive(previewUri) }
384-
});
379+
};
385380

386-
} else {
387-
// rename, create, edits -> show diff editr
381+
}
382+
// rename, create, edits
383+
else {
388384
let leftResource: URI | undefined;
389385
try {
390-
(await this._textModelService.createModelReference(operationUri)).dispose();
391-
leftResource = operationUri;
386+
(await this._textModelService.createModelReference(fileOperationUri)).dispose();
387+
leftResource = fileOperationUri;
392388
} catch {
393389
leftResource = BulkEditPreviewProvider.emptyPreview;
394390
}
395-
resources.push({
391+
return {
396392
original: { resource: URI.revive(leftResource) },
397393
modified: { resource: URI.revive(previewUri) }
398-
});
394+
};
399395
}
396+
});
397+
398+
const sortedFileOperations = fileOperations.slice().sort(compareBulkFileOperations);
399+
const resources: IResourceDiffEditorInput[] = [];
400+
for (const operation of sortedFileOperations) {
401+
resources.push(await computeDiffEditorInput.get(operation));
400402
}
401-
this._fileOperations = fileOperations;
402-
this._resources = resources;
403-
return resources;
404-
}
403+
const getResourceDiffEditorInputIdOfOperation = async (operation: BulkFileOperation): Promise<IMultiDiffResourceId> => {
404+
const resource = await computeDiffEditorInput.get(operation);
405+
return { original: resource.original.resource, modified: resource.modified.resource };
406+
};
407+
return {
408+
resources,
409+
getResourceDiffEditorInputIdOfOperation
410+
};
411+
}, key => key);
405412

406413
private _onContextMenu(e: ITreeContextMenuEvent<any>): void {
407414

0 commit comments

Comments
 (0)