Comparing the paths of the URI (#208777)

* comparing the paths

* revealing resources for a given original and modified uri pair

* changing comments
This commit is contained in:
Aiday Marlen Kyzy 2024-03-27 17:48:43 +01:00 committed by GitHub
parent 0b448a58a7
commit d469911cbb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 55 additions and 45 deletions

View file

@ -39,17 +39,19 @@ export class Cache<T> {
/**
* Uses a LRU cache to make a given parametrized function cached.
* Caches just the last value.
* The key must be JSON serializable.
*/
export class LRUCachedFunction<TArg, TComputed> {
private lastCache: TComputed | undefined = undefined;
private lastArgKey: string | undefined = undefined;
private lastArgKey: unknown | undefined = undefined;
constructor(private readonly fn: (arg: TArg) => TComputed) {
constructor(
private readonly fn: (arg: TArg) => TComputed,
private readonly _computeKey: (arg: TArg) => unknown = JSON.stringify,
) {
}
public get(arg: TArg): TComputed {
const key = JSON.stringify(arg);
const key = this._computeKey(arg);
if (this.lastArgKey !== key) {
this.lastArgKey = key;
this.lastCache = this.fn(arg);

View file

@ -8,7 +8,7 @@ import { Disposable } from 'vs/base/common/lifecycle';
import { derived, derivedWithStore, observableValue, recomputeInitiallyAndOnChange } from 'vs/base/common/observable';
import { readHotReloadableExport } from 'vs/editor/browser/widget/diffEditor/utils';
import { IMultiDiffEditorModel } from 'vs/editor/browser/widget/multiDiffEditor/model';
import { IMultiDiffEditorViewState, IMultiDiffResource, MultiDiffEditorWidgetImpl } from 'vs/editor/browser/widget/multiDiffEditor/multiDiffEditorWidgetImpl';
import { IMultiDiffEditorViewState, IMultiDiffResourceId, MultiDiffEditorWidgetImpl } from 'vs/editor/browser/widget/multiDiffEditor/multiDiffEditorWidgetImpl';
import { MultiDiffEditorViewModel } from './multiDiffEditorViewModel';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import './colors';
@ -46,7 +46,7 @@ export class MultiDiffEditorWidget extends Disposable {
this._register(recomputeInitiallyAndOnChange(this._widgetImpl));
}
public reveal(resource: IMultiDiffResource, options?: RevealOptions): void {
public reveal(resource: IMultiDiffResourceId, options?: RevealOptions): void {
this._widgetImpl.get().reveal(resource, options);
}

View file

@ -28,6 +28,7 @@ import { ServiceCollection } from 'vs/platform/instantiation/common/serviceColle
import { DiffEditorItemTemplate, TemplateData } from './diffEditorItemTemplate';
import { DocumentDiffItemViewModel, MultiDiffEditorViewModel } from './multiDiffEditorViewModel';
import { ObjectPool } from './objectPool';
import { BugIndicatingError } from 'vs/base/common/errors';
export class MultiDiffEditorWidgetImpl extends Disposable {
private readonly _elements = h('div.monaco-component.multiDiffEditor', [
@ -191,15 +192,15 @@ export class MultiDiffEditorWidgetImpl extends Disposable {
this._scrollableElement.setScrollPosition({ scrollLeft: scrollState.left, scrollTop: scrollState.top });
}
public reveal(resource: IMultiDiffResource, options?: RevealOptions): void {
public reveal(resource: IMultiDiffResourceId, options?: RevealOptions): void {
const viewItems = this._viewItems.get();
let searchCallback: (item: VirtualizedViewItem) => boolean;
if ('original' in resource) {
searchCallback = (item) => item.viewModel.originalUri?.toString() === resource.original.toString();
} else {
searchCallback = (item) => item.viewModel.modifiedUri?.toString() === resource.modified.toString();
const index = viewItems.findIndex(
(item) => item.viewModel.originalUri?.toString() === resource.original?.toString()
&& item.viewModel.modifiedUri?.toString() === resource.modified?.toString()
);
if (index === -1) {
throw new BugIndicatingError('Resource not found in diff editor');
}
const index = viewItems.findIndex(searchCallback);
let scrollTop = 0;
for (let i = 0; i < index; i++) {
scrollTop += viewItems[i].contentHeight.get() + this._spaceBetweenPx;
@ -323,12 +324,12 @@ export interface IMultiDiffEditorOptions extends ITextEditorOptions {
export interface IMultiDiffEditorOptionsViewState {
revealData?: {
resource: IMultiDiffResource;
resource: IMultiDiffResourceId;
range?: IRange;
};
}
export type IMultiDiffResource = { original: URI } | { modified: URI };
export type IMultiDiffResourceId = { original: URI | undefined; modified: URI | undefined };
class VirtualizedViewItem extends Disposable {
private readonly _templateRef = this._register(disposableObservableValue<IReference<DiffEditorItemTemplate> | undefined>(this, undefined));

View file

@ -37,8 +37,9 @@ import { ButtonBar } from 'vs/base/browser/ui/button/button';
import { defaultButtonStyles } from 'vs/platform/theme/browser/defaultStyles';
import { Mutable } from 'vs/base/common/types';
import { IResourceDiffEditorInput } from 'vs/workbench/common/editor';
import { IMultiDiffEditorOptions } from 'vs/editor/browser/widget/multiDiffEditor/multiDiffEditorWidgetImpl';
import { IMultiDiffEditorOptions, IMultiDiffResourceId } from 'vs/editor/browser/widget/multiDiffEditor/multiDiffEditorWidgetImpl';
import { IRange } from 'vs/editor/common/core/range';
import { CachedFunction, LRUCachedFunction } from 'vs/base/common/cache';
const enum State {
Data = 'data',
@ -70,8 +71,6 @@ export class BulkEditPane extends ViewPane {
private _currentResolve?: (edit?: ResourceEdit[]) => void;
private _currentInput?: BulkFileOperations;
private _currentProvider?: BulkEditPreviewProvider;
private _fileOperations?: BulkFileOperation[];
private _resources?: IResourceDiffEditorInput[];
constructor(
options: IViewletViewOptions,
@ -345,12 +344,13 @@ export class BulkEditPane extends ViewPane {
return;
}
const resources = await this._resolveResources(fileOperations);
const result = await this._computeResourceDiffEditorInputs.get(fileOperations);
const resourceId = await result.getResourceDiffEditorInputIdOfOperation(fileElement.edit);
const options: Mutable<IMultiDiffEditorOptions> = {
...e.editorOptions,
viewState: {
revealData: {
resource: { original: fileElement.edit.uri },
resource: resourceId,
range: selection,
}
}
@ -359,49 +359,56 @@ export class BulkEditPane extends ViewPane {
const label = 'Refactor Preview';
this._editorService.openEditor({
multiDiffSource,
resources,
label,
options,
isTransient: true,
description: label
description: label,
resources: result.resources
}, e.sideBySide ? SIDE_GROUP : ACTIVE_GROUP);
}
private async _resolveResources(fileOperations: BulkFileOperation[]): Promise<IResourceDiffEditorInput[]> {
if (this._fileOperations === fileOperations && this._resources) {
return this._resources;
}
const sortedFileOperations = fileOperations.sort(compareBulkFileOperations);
const resources: IResourceDiffEditorInput[] = [];
for (const operation of sortedFileOperations) {
const operationUri = operation.uri;
const previewUri = this._currentProvider!.asPreviewUri(operationUri);
// delete -> show single editor
if (operation.type & BulkFileOperationType.Delete) {
resources.push({
private readonly _computeResourceDiffEditorInputs = new LRUCachedFunction(async (fileOperations: BulkFileOperation[]) => {
const computeDiffEditorInput = new CachedFunction<BulkFileOperation, Promise<IResourceDiffEditorInput>>(async (fileOperation) => {
const fileOperationUri = fileOperation.uri;
const previewUri = this._currentProvider!.asPreviewUri(fileOperationUri);
// delete
if (fileOperation.type & BulkFileOperationType.Delete) {
return {
original: { resource: undefined },
modified: { resource: URI.revive(previewUri) }
});
};
} else {
// rename, create, edits -> show diff editr
}
// rename, create, edits
else {
let leftResource: URI | undefined;
try {
(await this._textModelService.createModelReference(operationUri)).dispose();
leftResource = operationUri;
(await this._textModelService.createModelReference(fileOperationUri)).dispose();
leftResource = fileOperationUri;
} catch {
leftResource = BulkEditPreviewProvider.emptyPreview;
}
resources.push({
return {
original: { resource: URI.revive(leftResource) },
modified: { resource: URI.revive(previewUri) }
});
};
}
});
const sortedFileOperations = fileOperations.slice().sort(compareBulkFileOperations);
const resources: IResourceDiffEditorInput[] = [];
for (const operation of sortedFileOperations) {
resources.push(await computeDiffEditorInput.get(operation));
}
this._fileOperations = fileOperations;
this._resources = resources;
return resources;
}
const getResourceDiffEditorInputIdOfOperation = async (operation: BulkFileOperation): Promise<IMultiDiffResourceId> => {
const resource = await computeDiffEditorInput.get(operation);
return { original: resource.original.resource, modified: resource.modified.resource };
};
return {
resources,
getResourceDiffEditorInputIdOfOperation
};
}, key => key);
private _onContextMenu(e: ITreeContextMenuEvent<any>): void {