This commit is contained in:
Aiday Marlen Kyzy
2024-02-13 17:51:04 +01:00
parent 0776d4f78f
commit 5f33bf34ce
6 changed files with 61 additions and 34 deletions
@@ -44,8 +44,8 @@ export class MultiDiffEditorWidget extends Disposable {
this._register(recomputeInitiallyAndOnChange(this._widgetImpl));
}
public scrollTo(uri: URI): void {
this._widgetImpl.get().scrollTo(uri);
public reveal(resource: { original: URI } | { modified: URI }, lineNumber: number): void {
this._widgetImpl.get().reveal(resource, lineNumber);
}
public createViewModel(model: IMultiDiffEditorModel): MultiDiffEditorViewModel {
@@ -25,6 +25,7 @@ import { ISelection, Selection } from 'vs/editor/common/core/selection';
import { URI } from 'vs/base/common/uri';
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
import { IDiffEditor } from 'vs/editor/common/editorCommon';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
export class MultiDiffEditorWidgetImpl extends Disposable {
private readonly _elements = h('div.monaco-component.multiDiffEditor', [
@@ -104,6 +105,7 @@ export class MultiDiffEditorWidgetImpl extends Disposable {
private readonly _workbenchUIElementFactory: IWorkbenchUIElementFactory,
@IContextKeyService private readonly _parentContextKeyService: IContextKeyService,
@IInstantiationService private readonly _parentInstantiationService: IInstantiationService,
@IConfigurationService private readonly _configurationService: IConfigurationService,
) {
super();
@@ -186,10 +188,20 @@ export class MultiDiffEditorWidgetImpl extends Disposable {
this._scrollableElement.setScrollPosition({ scrollLeft: scrollState.left, scrollTop: scrollState.top });
}
public scrollTo(originalUri: URI): void {
public reveal(resource: IMultiDiffResource, lineNumber: number): void {
const viewItems = this._viewItems.get();
const index = viewItems?.findIndex(item => item.viewModel.originalUri?.toString() === originalUri.toString());
let scrollTop = 0;
let searchCallback: (item: VirtualizedViewItem) => boolean;
if (isMultiDiffOriginalResourceUri(resource)) {
searchCallback = (item) => item.viewModel.originalUri?.toString() === resource.original.toString();
} else {
searchCallback = (item) => item.viewModel.modifiedUri?.toString() === resource.modified.toString();
}
const index = viewItems.findIndex(searchCallback);
const scrollTopWithinItem = (lineNumber - 1) * this._configurationService.getValue<number>('editor.lineHeight');
// todo@aiday-mar: need to find the actual scroll top given the line number specific to the original or modified uri
// following does not neccessarily correspond to the appropriate scroll top within the editor
const maxScroll = viewItems[index].template.get()?.maxScroll.get().maxScroll;
let scrollTop = (maxScroll && scrollTopWithinItem < maxScroll) ? scrollTopWithinItem : 0;
for (let i = 0; i < index; i++) {
scrollTop += viewItems[i].contentHeight.get() + this._spaceBetweenPx;
}
@@ -289,6 +301,20 @@ interface IMultiDiffDocState {
selections?: ISelection[];
}
interface IMultiDiffOriginalResource {
original: URI;
}
interface IMultiDiffModifiedResource {
modified: URI;
}
function isMultiDiffOriginalResourceUri(obj: any): obj is IMultiDiffOriginalResource {
return 'original' in obj && obj.original instanceof URI;
}
type IMultiDiffResource = IMultiDiffOriginalResource | IMultiDiffModifiedResource;
class VirtualizedViewItem extends Disposable {
private readonly _templateRef = this._register(disposableObservableValue<IReference<DiffEditorItemTemplate> | undefined>(this, undefined));
+5
View File
@@ -505,6 +505,11 @@ export interface IResourceMultiDiffEditorInput extends IBaseUntypedEditorInput {
* If not set, the resources are dynamically derived from the {@link multiDiffSource}.
*/
readonly resources?: IResourceDiffEditorInput[];
/**
* Reveal the following resource on open
*/
readonly revealResource?: IResourceDiffEditorInput;
}
export type IResourceMergeEditorInputSide = (IResourceEditorInput | ITextResourceEditorInput) & { detail?: string };
@@ -11,7 +11,7 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti
import { IThemeService } from 'vs/platform/theme/common/themeService';
import { localize } from 'vs/nls';
import { DisposableStore } from 'vs/base/common/lifecycle';
import { BulkEditPreviewProvider, BulkFileOperations, BulkFileOperationType } from 'vs/workbench/contrib/bulkEdit/browser/preview/bulkEditPreview';
import { BulkEditPreviewProvider, BulkFileOperation, BulkFileOperations, BulkFileOperationType } from 'vs/workbench/contrib/bulkEdit/browser/preview/bulkEditPreview';
import { ILabelService } from 'vs/platform/label/common/label';
import { ITextModelService } from 'vs/editor/common/services/resolverService';
import { URI } from 'vs/base/common/uri';
@@ -36,8 +36,7 @@ import { ResourceEdit } from 'vs/editor/browser/services/bulkEditService';
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 { IEditorService } from 'vs/workbench/services/editor/common/editorService';
import { MultiDiffEditor } from 'vs/workbench/contrib/multiDiffEditor/browser/multiDiffEditor';
import { ACTIVE_GROUP, IEditorService, SIDE_GROUP } from 'vs/workbench/services/editor/common/editorService';
import { IResourceDiffEditorInput } from 'vs/workbench/common/editor';
const enum State {
@@ -69,7 +68,8 @@ export class BulkEditPane extends ViewPane {
private _currentResolve?: (edit?: ResourceEdit[]) => void;
private _currentInput?: BulkFileOperations;
private _currentProvider?: BulkEditPreviewProvider;
private _multiDiffEditor?: MultiDiffEditor;
private _fileOperations?: BulkFileOperation[];
private _resources?: IResourceDiffEditorInput[];
constructor(
options: IViewletViewOptions,
@@ -98,11 +98,6 @@ export class BulkEditPane extends ViewPane {
this._ctxHasCategories = BulkEditPane.ctxHasCategories.bindTo(contextKeyService);
this._ctxGroupByFile = BulkEditPane.ctxGroupByFile.bindTo(contextKeyService);
this._ctxHasCheckedChanges = BulkEditPane.ctxHasCheckedChanges.bindTo(contextKeyService);
this._disposables.add(this._editorService.onDidCloseEditor((e) => {
if (this._multiDiffEditor && e.editor === this._multiDiffEditor.input && e.groupId === this._multiDiffEditor.group?.id) {
this._multiDiffEditor = undefined;
}
}));
}
override dispose(): void {
@@ -281,10 +276,6 @@ export class BulkEditPane extends ViewPane {
this._currentInput = undefined;
this._setState(State.Message);
this._sessionDisposables.clear();
if (this._multiDiffEditor && this._multiDiffEditor.input && this._multiDiffEditor.group) {
this._editorService.closeEditor({ editor: this._multiDiffEditor.input, groupId: this._multiDiffEditor.group.id });
this._multiDiffEditor = undefined;
}
}
toggleChecked() {
@@ -347,12 +338,26 @@ export class BulkEditPane extends ViewPane {
return;
}
if (this._multiDiffEditor) {
// Multi diff editor already visible
this._multiDiffEditor.scrollTo(fileElement.edit.uri);
return;
let resources: IResourceDiffEditorInput[];
if (this._fileOperations === fileOperations && this._resources) {
resources = this._resources;
} else {
resources = await this._getResources(fileOperations);
}
const revealResource = resources.find(r => r.original.resource!.toString() === fileElement.edit.uri.toString());
const multiDiffSource = URI.from({ scheme: 'refactor-preview' });
const label = 'Refactor Preview';
this._editorService.openEditor({
multiDiffSource,
revealResource,
resources,
label,
description: label,
options,
}, e.sideBySide ? SIDE_GROUP : ACTIVE_GROUP);
}
private async _getResources(fileOperations: BulkFileOperation[]): Promise<IResourceDiffEditorInput[]> {
const resources: IResourceDiffEditorInput[] = [];
for (const operation of fileOperations) {
const operationUri = operation.uri;
@@ -379,15 +384,7 @@ export class BulkEditPane extends ViewPane {
});
}
}
const multiDiffSource = URI.from({ scheme: 'refactor-preview' });
const label = 'Refactor Preview';
this._multiDiffEditor = await this._editorService.openEditor({
multiDiffSource,
resources,
label,
description: label,
options,
}) as MultiDiffEditor;
return resources;
}
private _onContextMenu(e: ITreeContextMenuEvent<any>): void {
@@ -72,8 +72,8 @@ export class MultiDiffEditor extends AbstractEditorWithViewState<IMultiDiffEdito
}));
}
public scrollTo(uri: URI): void {
this._multiDiffEditorWidget?.scrollTo(uri);
public reveal(resource: { original: URI } | { modified: URI }, lineNumber: number): void {
this._multiDiffEditorWidget?.reveal(resource, lineNumber);
}
override async setInput(input: MultiDiffEditorInput, options: IEditorOptions | undefined, context: IEditorOpenContext, token: CancellationToken): Promise<void> {
@@ -236,7 +236,6 @@ export interface IEditorService {
* Open an editor in an editor group.
*
* @param editor the editor to open
* @param options the options to use for the editor
* @param group the target group. If unspecified, the editor will open in the currently
* active group. Use `SIDE_GROUP` to open the editor in a new editor group to the side
* of the currently active group.