Skip to content

Commit

Permalink
Refactors merge editor. (#160116)
Browse files Browse the repository at this point in the history
  • Loading branch information
hediet authored Sep 6, 2022
1 parent 1872bc1 commit 1995346
Show file tree
Hide file tree
Showing 9 changed files with 524 additions and 437 deletions.
33 changes: 31 additions & 2 deletions src/vs/workbench/contrib/mergeEditor/browser/commands/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -186,8 +186,8 @@ export class SetMixedLayoutWithBase extends Action2 {
super({
id: 'merge.mixedLayoutWithBase',
title: {
value: localize('layout.mixedWithBase', 'Mixed Layout With Base'),
original: 'Mixed Layout With Based',
value: localize('layout.mixedWithBase', 'Mixed Layout With Base At Top'),
original: 'Mixed Layout With Based At Top',
},
toggled: ctxMergeEditorLayout.isEqualTo('mixedWithBase'),
menu: [
Expand All @@ -210,6 +210,35 @@ export class SetMixedLayoutWithBase extends Action2 {
}
}

export class SetMixedLayoutWithBaseColumns extends Action2 {
constructor() {
super({
id: 'merge.mixedLayoutWithBaseColumns',
title: {
value: localize('layout.mixedWithBaseColumns', 'Mixed Layout With Base'),
original: 'Mixed Layout With Based',
},
toggled: ctxMergeEditorLayout.isEqualTo('mixedWithBaseColumns'),
menu: [
{
id: MenuId.EditorTitle,
when: ctxIsMergeEditor,
group: '1_merge',
order: 9,
},
],
precondition: ctxIsMergeEditor,
});
}

run(accessor: ServicesAccessor): void {
const { activeEditorPane } = accessor.get(IEditorService);
if (activeEditorPane instanceof MergeEditor) {
activeEditorPane.setLayout('mixedWithBaseColumns');
}
}
}

const mergeEditorCategory: ILocalizedString = {
value: localize('mergeEditor', 'Merge Editor'),
original: 'Merge Editor',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { Registry } from 'vs/platform/registry/common/platform';
import { EditorPaneDescriptor, IEditorPaneRegistry } from 'vs/workbench/browser/editor';
import { Extensions as WorkbenchExtensions, IWorkbenchContributionsRegistry } from 'vs/workbench/common/contributions';
import { EditorExtensions, IEditorFactoryRegistry } from 'vs/workbench/common/editor';
import { AcceptAllInput1, AcceptAllInput2, CompareInput1WithBaseCommand, CompareInput2WithBaseCommand, GoToNextUnhandledConflict, GoToPreviousUnhandledConflict, OpenBaseFile, OpenMergeEditor, OpenResultResource, ResetDirtyConflictsToBaseCommand, ResetToBaseAndAutoMergeCommand, SetColumnLayout, SetMixedLayout, SetMixedLayoutWithBase, ToggleActiveConflictInput1, ToggleActiveConflictInput2 } from 'vs/workbench/contrib/mergeEditor/browser/commands/commands';
import { AcceptAllInput1, AcceptAllInput2, CompareInput1WithBaseCommand, CompareInput2WithBaseCommand, GoToNextUnhandledConflict, GoToPreviousUnhandledConflict, OpenBaseFile, OpenMergeEditor, OpenResultResource, ResetDirtyConflictsToBaseCommand, ResetToBaseAndAutoMergeCommand, SetColumnLayout, SetMixedLayout, SetMixedLayoutWithBase, SetMixedLayoutWithBaseColumns, ToggleActiveConflictInput1, ToggleActiveConflictInput2 } from 'vs/workbench/contrib/mergeEditor/browser/commands/commands';
import { MergeEditorCopyContentsToJSON, MergeEditorSaveContentsToFolder, MergeEditorLoadContentsFromFolder } from 'vs/workbench/contrib/mergeEditor/browser/commands/devCommands';
import { MergeEditorInput } from 'vs/workbench/contrib/mergeEditor/browser/mergeEditorInput';
import { MergeEditor, MergeEditorResolverContribution, MergeEditorOpenHandlerContribution } from 'vs/workbench/contrib/mergeEditor/browser/view/mergeEditor';
Expand Down Expand Up @@ -52,6 +52,7 @@ registerAction2(OpenResultResource);
registerAction2(SetMixedLayout);
registerAction2(SetColumnLayout);
registerAction2(SetMixedLayoutWithBase);
registerAction2(SetMixedLayoutWithBaseColumns);
registerAction2(OpenMergeEditor);
registerAction2(OpenBaseFile);

Expand Down
21 changes: 13 additions & 8 deletions src/vs/workbench/contrib/mergeEditor/browser/view/editorGutter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
*--------------------------------------------------------------------------------------------*/

import { h } from 'vs/base/browser/dom';
import { Disposable, IDisposable } from 'vs/base/common/lifecycle';
import { autorun, IReader, observableFromEvent, observableSignalFromEvent } from 'vs/base/common/observable';
import { Disposable, IDisposable, toDisposable } from 'vs/base/common/lifecycle';
import { autorun, IReader, observableFromEvent, observableSignal, observableSignalFromEvent, transaction } from 'vs/base/common/observable';
import { CodeEditorWidget } from 'vs/editor/browser/widget/codeEditorWidget';
import { LineRange } from 'vs/workbench/contrib/mergeEditor/browser/model/lineRange';

Expand All @@ -22,6 +22,7 @@ export class EditorGutter<T extends IGutterItemInfo = IGutterItemInfo> extends D

private readonly editorOnDidChangeViewZones = observableSignalFromEvent('onDidChangeViewZones', this._editor.onDidChangeViewZones);
private readonly editorOnDidContentSizeChange = observableSignalFromEvent('onDidContentSizeChange', this._editor.onDidContentSizeChange);
private readonly domNodeSizeChanged = observableSignal('domNodeSizeChanged');

constructor(
private readonly _editor: CodeEditorWidget,
Expand All @@ -35,6 +36,15 @@ export class EditorGutter<T extends IGutterItemInfo = IGutterItemInfo> extends D
.root
);

const o = new ResizeObserver(() => {
transaction(tx => {
/** @description ResizeObserver: size changed */
this.domNodeSizeChanged.trigger(tx);
});
});
o.observe(this._domNode);
this._register(toDisposable(() => o.disconnect()));

this._register(autorun('update scroll decoration', (reader) => {
scrollDecoration.className = this.isScrollTopZero.read(reader) ? '' : 'scroll-decoration';
}));
Expand All @@ -49,6 +59,7 @@ export class EditorGutter<T extends IGutterItemInfo = IGutterItemInfo> extends D
return;
}

this.domNodeSizeChanged.read(reader);
this.editorOnDidChangeViewZones.read(reader);
this.editorOnDidContentSizeChange.read(reader);

Expand Down Expand Up @@ -130,12 +141,6 @@ export interface IGutterItemProvider<TItem extends IGutterItemInfo> {
export interface IGutterItemInfo {
id: string;
range: LineRange;
/*
// To accommodate view zones:
offsetInPx: number;
additionalHeightInPx: number;
*/
}

export interface IGutterItemView<T extends IGutterItemInfo> extends IDisposable {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,26 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import { derived } from 'vs/base/common/observable';
import { reset } from 'vs/base/browser/dom';
import { renderLabelWithIcons } from 'vs/base/browser/ui/iconLabel/iconLabels';
import { autorun, derived, IObservable } from 'vs/base/common/observable';
import { EditorExtensionsRegistry, IEditorContributionDescription } from 'vs/editor/browser/editorExtensions';
import { IModelDeltaDecoration, MinimapPosition, OverviewRulerLane } from 'vs/editor/common/model';
import { CodeLensContribution } from 'vs/editor/contrib/codelens/browser/codelensController';
import { localize } from 'vs/nls';
import { MenuId } from 'vs/platform/actions/common/actions';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { applyObservableDecorations } from 'vs/workbench/contrib/mergeEditor/browser/utils';
import { handledConflictMinimapOverViewRulerColor, unhandledConflictMinimapOverViewRulerColor } from 'vs/workbench/contrib/mergeEditor/browser/view/colors';
import { MergeEditorViewModel } from 'vs/workbench/contrib/mergeEditor/browser/view/viewModel';
import { CodeEditorView, createSelectionsAutorun, TitleMenu } from './codeEditorView';

export class BaseCodeEditorView extends CodeEditorView {
constructor(
viewModel: IObservable<MergeEditorViewModel | undefined>,
@IInstantiationService instantiationService: IInstantiationService,
) {
super(instantiationService);

this._register(applyObservableDecorations(this.editor, this.decorations));
super(instantiationService, viewModel);

this._register(
createSelectionsAutorun(this, (baseRange, viewModel) => baseRange)
Expand All @@ -28,6 +31,19 @@ export class BaseCodeEditorView extends CodeEditorView {
this._register(
instantiationService.createInstance(TitleMenu, MenuId.MergeBaseToolbar, this.htmlElements.title)
);

this._register(
autorun('update labels & text model', (reader) => {
const vm = this.viewModel.read(reader);
if (!vm) {
return;
}
this.editor.setModel(vm.model.base);
reset(this.htmlElements.title, ...renderLabelWithIcons(localize('base', 'Base')));
})
);

this._register(applyObservableDecorations(this.editor, this.decorations));
}

private readonly decorations = derived(`base.decorations`, reader => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,33 +3,29 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import { h, reset } from 'vs/base/browser/dom';
import { h } from 'vs/base/browser/dom';
import { IView, IViewSize } from 'vs/base/browser/ui/grid/grid';
import { renderLabelWithIcons } from 'vs/base/browser/ui/iconLabel/iconLabels';
import { ToolBar } from 'vs/base/browser/ui/toolbar/toolbar';
import { IAction } from 'vs/base/common/actions';
import { Emitter, Event } from 'vs/base/common/event';
import { Disposable, IDisposable } from 'vs/base/common/lifecycle';
import { autorun, derived, IObservable, observableFromEvent, observableValue, transaction } from 'vs/base/common/observable';
import { autorun, derived, IObservable, observableFromEvent } from 'vs/base/common/observable';
import { IEditorContributionDescription } from 'vs/editor/browser/editorExtensions';
import { CodeEditorWidget } from 'vs/editor/browser/widget/codeEditorWidget';
import { IEditorOptions } from 'vs/editor/common/config/editorOptions';
import { Range } from 'vs/editor/common/core/range';
import { Selection } from 'vs/editor/common/core/selection';
import { createAndFillInActionBarActions } from 'vs/platform/actions/browser/menuEntryActionViewItem';
import { MenuId, IMenuService } from 'vs/platform/actions/common/actions';
import { IMenuService, MenuId } from 'vs/platform/actions/common/actions';
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
import { Range } from 'vs/editor/common/core/range';
import { Selection } from 'vs/editor/common/core/selection';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { DEFAULT_EDITOR_MAX_DIMENSIONS, DEFAULT_EDITOR_MIN_DIMENSIONS } from 'vs/workbench/browser/parts/editor/editor';
import { InputData } from 'vs/workbench/contrib/mergeEditor/browser/model/mergeEditorModel';
import { setStyle } from 'vs/workbench/contrib/mergeEditor/browser/utils';
import { MergeEditorViewModel } from 'vs/workbench/contrib/mergeEditor/browser/view/viewModel';

export abstract class CodeEditorView extends Disposable {
private readonly _viewModel = observableValue<undefined | MergeEditorViewModel>('viewModel', undefined);
readonly viewModel: IObservable<undefined | MergeEditorViewModel> = this._viewModel;
readonly model = this._viewModel.map(m => /** @description model */ m?.model);
readonly model = this.viewModel.map(m => /** @description model */ m?.model);

protected readonly htmlElements = h('div.code-view', [
h('div.title@header', [
Expand Down Expand Up @@ -98,30 +94,15 @@ export abstract class CodeEditorView extends Disposable {

constructor(
@IInstantiationService
private readonly instantiationService: IInstantiationService
private readonly instantiationService: IInstantiationService,
public readonly viewModel: IObservable<undefined | MergeEditorViewModel>,
) {
super();
}

protected getEditorContributions(): IEditorContributionDescription[] | undefined {
return undefined;
}

public setModel(
viewModel: MergeEditorViewModel,
inputData: InputData
): void {
this.editor.setModel(inputData.textModel);

reset(this.htmlElements.title, ...renderLabelWithIcons(inputData.title || ''));
reset(this.htmlElements.description, ...(inputData.description ? renderLabelWithIcons(inputData.description) : []));
reset(this.htmlElements.detail, ...(inputData.detail ? renderLabelWithIcons(inputData.detail) : []));

transaction(tx => {
/** @description CodeEditorView: Set Model */
this._viewModel.set(viewModel, tx);
});
}
}

export function createSelectionsAutorun(
Expand Down
Loading

0 comments on commit 1995346

Please sign in to comment.