editors - fix side by side editor matching logic (#132651)

上级 aa93eefe
......@@ -3,7 +3,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { GroupIdentifier, IWorkbenchEditorConfiguration, IEditorInput, IEditorIdentifier, IEditorCloseEvent, IEditorPartOptions, IEditorPartOptionsChangeEvent } from 'vs/workbench/common/editor';
import { GroupIdentifier, IWorkbenchEditorConfiguration, IEditorInput, IEditorIdentifier, IEditorCloseEvent, IEditorPartOptions, IEditorPartOptionsChangeEvent, SideBySideEditor } from 'vs/workbench/common/editor';
import { IEditorGroup, GroupDirection, IAddGroupOptions, IMergeGroupOptions, GroupsOrder, GroupsArrangement } from 'vs/workbench/services/editor/common/editorGroupsService';
import { IDisposable } from 'vs/base/common/lifecycle';
import { Dimension } from 'vs/base/browser/dom';
......@@ -184,7 +184,17 @@ export interface IInternalEditorTitleControlOptions {
skipTitleUpdate?: boolean;
}
export interface IInternalEditorOpenOptions extends IInternalEditorTitleControlOptions { }
export interface IInternalEditorOpenOptions extends IInternalEditorTitleControlOptions {
/**
* Whether to consider a side by side editor as matching
* when figuring out if the editor to open is already
* opened or not. By default, side by side editors will
* not be considered as matching, even if the editor is
* opened in one of the sides.
*/
supportSideBySide?: SideBySideEditor.ANY | SideBySideEditor.BOTH;
}
export interface IInternalEditorCloseOptions extends IInternalEditorTitleControlOptions {
......
......@@ -4,8 +4,8 @@
*--------------------------------------------------------------------------------------------*/
import 'vs/css!./media/editorgroupview';
import { EditorGroupModel, IEditorOpenOptions, EditorCloseEvent, ISerializedEditorGroupModel, isSerializedEditorGroupModel, SideBySideMatchingStrategy } from 'vs/workbench/common/editor/editorGroupModel';
import { GroupIdentifier, CloseDirection, IEditorCloseEvent, ActiveEditorDirtyContext, IEditorPane, EditorGroupEditorsCountContext, SaveReason, IEditorPartOptionsChangeEvent, EditorsOrder, IVisibleEditorPane, ActiveEditorStickyContext, ActiveEditorPinnedContext, EditorResourceAccessor, IEditorMoveEvent, EditorInputCapabilities, IEditorOpenEvent, IUntypedEditorInput, DEFAULT_EDITOR_ASSOCIATION, ActiveEditorGroupLockedContext, IEditorInput } from 'vs/workbench/common/editor';
import { EditorGroupModel, IEditorOpenOptions, EditorCloseEvent, ISerializedEditorGroupModel, isSerializedEditorGroupModel } from 'vs/workbench/common/editor/editorGroupModel';
import { GroupIdentifier, CloseDirection, IEditorCloseEvent, ActiveEditorDirtyContext, IEditorPane, EditorGroupEditorsCountContext, SaveReason, IEditorPartOptionsChangeEvent, EditorsOrder, IVisibleEditorPane, ActiveEditorStickyContext, ActiveEditorPinnedContext, EditorResourceAccessor, IEditorMoveEvent, EditorInputCapabilities, IEditorOpenEvent, IUntypedEditorInput, DEFAULT_EDITOR_ASSOCIATION, ActiveEditorGroupLockedContext, IEditorInput, SideBySideEditor } from 'vs/workbench/common/editor';
import { EditorInput } from 'vs/workbench/common/editor/editorInput';
import { SideBySideEditorInput } from 'vs/workbench/common/editor/sideBySideEditorInput';
import { Event, Emitter, Relay } from 'vs/base/common/event';
......@@ -613,8 +613,8 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
private canDispose(editor: IEditorInput): boolean {
for (const groupView of this.accessor.groups) {
if (groupView instanceof EditorGroupView && groupView.model.contains(editor, {
strictEquals: true, // only if this input is not shared across editor groups
supportSideBySide: SideBySideMatchingStrategy.ANY_SIDE // include any side of an opened side by side editor
strictEquals: true, // only if this input is not shared across editor groups
supportSideBySide: SideBySideEditor.ANY // include any side of an opened side by side editor
})) {
return false;
}
......@@ -948,7 +948,12 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
//#region openEditor()
async openEditor(editor: EditorInput, options?: IEditorOptions): Promise<IEditorPane | undefined> {
return this.doOpenEditor(editor, options);
return this.doOpenEditor(editor, options, {
// Allow to match on a side-by-side editor when same
// editor is opened on both sides. In that case we
// do not want to open a new editor but reuse that one.
supportSideBySide: SideBySideEditor.BOTH
});
}
private async doOpenEditor(editor: EditorInput, options?: IEditorOptions, internalOptions?: IInternalEditorOpenOptions): Promise<IEditorPane | undefined> {
......@@ -968,7 +973,8 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
index: options ? options.index : undefined,
pinned: options?.sticky || !this.accessor.partOptions.enablePreview || editor.isDirty() || (options?.pinned ?? typeof options?.index === 'number' /* unless specified, prefer to pin when opening with index */) || (typeof options?.index === 'number' && this.model.isSticky(options.index)),
sticky: options?.sticky || (typeof options?.index === 'number' && this.model.isSticky(options.index)),
active: this.count === 0 || !options || !options.inactive
active: this.count === 0 || !options || !options.inactive,
supportSideBySide: internalOptions?.supportSideBySide
};
if (options?.sticky && typeof options?.index === 'number' && !this.model.isSticky(options.index)) {
......@@ -1202,7 +1208,14 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
return null;
}
await this.openEditor(firstEditor.editor, firstEditor.options);
const openEditorsOptions: IInternalEditorOpenOptions = {
// Allow to match on a side-by-side editor when same
// editor is opened on both sides. In that case we
// do not want to open a new editor but reuse that one.
supportSideBySide: SideBySideEditor.BOTH
};
await this.doOpenEditor(firstEditor.editor, firstEditor.options, openEditorsOptions);
// Open the other ones inactive
const inactiveEditors = editorsToOpen.slice(1);
......@@ -1214,6 +1227,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
pinned: true,
index: startingIndex + index
}, {
...openEditorsOptions,
// optimization: update the title control later
// https://github.com/microsoft/vscode/issues/130634
skipTitleUpdate: true
......@@ -1471,7 +1485,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
ignoreError: internalOptions?.fromError
};
this.openEditor(nextActiveEditor, options);
this.doOpenEditor(nextActiveEditor, options);
}
// Otherwise we are empty, so clear from editor control and send event
......@@ -1598,7 +1612,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
else {
// Switch to editor that we want to handle and confirm to save/revert
await this.openEditor(editor);
await this.doOpenEditor(editor);
// Let editor handle confirmation if implemented
if (typeof editor.confirm === 'function') {
......@@ -1821,7 +1835,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
for (const { editor, replacement, forceReplaceDirty, options } of inactiveReplacements) {
// Open inactive editor
await this.openEditor(replacement, options);
await this.doOpenEditor(replacement, options);
// Close replaced inactive editor unless they match
if (!editor.matches(replacement)) {
......@@ -1842,7 +1856,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
if (activeReplacement) {
// Open replacement as active editor
const openEditorResult = this.openEditor(activeReplacement.replacement, activeReplacement.options);
const openEditorResult = this.doOpenEditor(activeReplacement.replacement, activeReplacement.options);
// Close replaced active editor unless they match
if (!activeReplacement.editor.matches(activeReplacement.replacement)) {
......
......@@ -952,7 +952,8 @@ export interface IEditorPartOptionsChangeEvent {
export enum SideBySideEditor {
PRIMARY = 1,
SECONDARY = 2,
BOTH = 3
BOTH = 3,
ANY = 4
}
export interface IEditorResourceAccessorOptions {
......@@ -990,7 +991,7 @@ class EditorResourceAccessorImpl {
* such, the original URI and the canonical URI can be different.
*/
getOriginalUri(editor: IEditorInput | IUntypedEditorInput | undefined | null): URI | undefined;
getOriginalUri(editor: IEditorInput | IUntypedEditorInput | undefined | null, options: IEditorResourceAccessorOptions & { supportSideBySide?: SideBySideEditor.PRIMARY | SideBySideEditor.SECONDARY }): URI | undefined;
getOriginalUri(editor: IEditorInput | IUntypedEditorInput | undefined | null, options: IEditorResourceAccessorOptions & { supportSideBySide?: SideBySideEditor.PRIMARY | SideBySideEditor.SECONDARY | SideBySideEditor.ANY }): URI | undefined;
getOriginalUri(editor: IEditorInput | IUntypedEditorInput | undefined | null, options: IEditorResourceAccessorOptions & { supportSideBySide: SideBySideEditor.BOTH }): URI | { primary?: URI, secondary?: URI } | undefined;
getOriginalUri(editor: IEditorInput | IUntypedEditorInput | undefined | null, options?: IEditorResourceAccessorOptions): URI | { primary?: URI, secondary?: URI } | undefined {
if (!editor) {
......@@ -1006,6 +1007,8 @@ class EditorResourceAccessorImpl {
primary: this.getOriginalUri(primary, { filterByScheme: options.filterByScheme }),
secondary: this.getOriginalUri(secondary, { filterByScheme: options.filterByScheme })
};
} else if (options?.supportSideBySide === SideBySideEditor.ANY) {
return this.getOriginalUri(primary, { filterByScheme: options.filterByScheme }) ?? this.getOriginalUri(secondary, { filterByScheme: options.filterByScheme });
}
editor = options.supportSideBySide === SideBySideEditor.PRIMARY ? primary : secondary;
......@@ -1051,7 +1054,7 @@ class EditorResourceAccessorImpl {
* such, the original URI and the canonical URI can be different.
*/
getCanonicalUri(editor: IEditorInput | IUntypedEditorInput | undefined | null): URI | undefined;
getCanonicalUri(editor: IEditorInput | IUntypedEditorInput | undefined | null, options: IEditorResourceAccessorOptions & { supportSideBySide?: SideBySideEditor.PRIMARY | SideBySideEditor.SECONDARY }): URI | undefined;
getCanonicalUri(editor: IEditorInput | IUntypedEditorInput | undefined | null, options: IEditorResourceAccessorOptions & { supportSideBySide?: SideBySideEditor.PRIMARY | SideBySideEditor.SECONDARY | SideBySideEditor.ANY }): URI | undefined;
getCanonicalUri(editor: IEditorInput | IUntypedEditorInput | undefined | null, options: IEditorResourceAccessorOptions & { supportSideBySide: SideBySideEditor.BOTH }): URI | { primary?: URI, secondary?: URI } | undefined;
getCanonicalUri(editor: IEditorInput | IUntypedEditorInput | undefined | null, options?: IEditorResourceAccessorOptions): URI | { primary?: URI, secondary?: URI } | undefined {
if (!editor) {
......@@ -1067,6 +1070,8 @@ class EditorResourceAccessorImpl {
primary: this.getCanonicalUri(primary, { filterByScheme: options.filterByScheme }),
secondary: this.getCanonicalUri(secondary, { filterByScheme: options.filterByScheme })
};
} else if (options?.supportSideBySide === SideBySideEditor.ANY) {
return this.getCanonicalUri(primary, { filterByScheme: options.filterByScheme }) ?? this.getCanonicalUri(secondary, { filterByScheme: options.filterByScheme });
}
editor = options.supportSideBySide === SideBySideEditor.PRIMARY ? primary : secondary;
......
......@@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import { Event, Emitter } from 'vs/base/common/event';
import { IEditorFactoryRegistry, IEditorIdentifier, IEditorCloseEvent, GroupIdentifier, IEditorInput, EditorsOrder, EditorExtensions, IUntypedEditorInput } from 'vs/workbench/common/editor';
import { IEditorFactoryRegistry, IEditorIdentifier, IEditorCloseEvent, GroupIdentifier, IEditorInput, EditorsOrder, EditorExtensions, IUntypedEditorInput, SideBySideEditor } from 'vs/workbench/common/editor';
import { EditorInput } from 'vs/workbench/common/editor/editorInput';
import { SideBySideEditorInput } from 'vs/workbench/common/editor/sideBySideEditorInput';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
......@@ -34,6 +34,7 @@ export interface IEditorOpenOptions {
sticky?: boolean;
active?: boolean;
readonly index?: number;
readonly supportSideBySide?: SideBySideEditor.ANY | SideBySideEditor.BOTH;
}
export interface IEditorOpenResult {
......@@ -61,28 +62,14 @@ export function isSerializedEditorGroupModel(group?: unknown): group is ISeriali
return !!(candidate && typeof candidate === 'object' && Array.isArray(candidate.editors) && Array.isArray(candidate.mru));
}
export enum SideBySideMatchingStrategy {
/**
* Consider an editor to match a side by side
* editor if any of the two sides match.
*/
ANY_SIDE = 1,
/**
* Consider an editor to match a side by side
* editor if both sides match.
*/
BOTH_SIDES
}
export interface IMatchOptions {
/**
* Whether to support side by side editors when
* considering a match.
* Whether to consider a side by side editor as matching.
* By default, side by side editors will not be considered
* as matching, even if the editor is opened in one of the sides.
*/
supportSideBySide?: SideBySideMatchingStrategy;
supportSideBySide?: SideBySideEditor.ANY | SideBySideEditor.BOTH;
/**
* Only consider an editor to match when the
......@@ -220,13 +207,7 @@ export class EditorGroupModel extends Disposable {
const makePinned = options?.pinned || options?.sticky;
const makeActive = options?.active || !this.activeEditor || (!makePinned && this.matches(this.preview, this.activeEditor));
const existingEditorAndIndex = this.findEditor(candidate, {
// Allow to match on a side-by-side editor when same
// editor is opened on both sides. In that case we
// do not want to open a new editor but reuse that one.
// For: https://github.com/microsoft/vscode/issues/36700
supportSideBySide: SideBySideMatchingStrategy.BOTH_SIDES
});
const existingEditorAndIndex = this.findEditor(candidate, options);
// New editor
if (!existingEditorAndIndex) {
......@@ -725,17 +706,27 @@ export class EditorGroupModel extends Disposable {
}
indexOf(candidate: IEditorInput | null, editors = this.editors, options?: IMatchOptions): number {
if (!candidate) {
return -1;
}
for (let i = 0; i < editors.length; i++) {
if (this.matches(editors[i], candidate, options)) {
return i;
let index = -1;
if (candidate) {
for (let i = 0; i < editors.length; i++) {
const editor = editors[i];
if (this.matches(editor, candidate, options)) {
// If we are to support side by side matching, it is possible that
// a better direct match is found later. As such, we continue finding
// a matching editor and prefer that match over the side by side one.
if (options?.supportSideBySide && editor instanceof SideBySideEditorInput && !(candidate instanceof SideBySideEditorInput)) {
index = i;
} else {
index = i;
break;
}
}
}
}
return -1;
return index;
}
private findEditor(candidate: EditorInput | null, options?: IMatchOptions): [EditorInput, number /* index */] | undefined {
......@@ -764,12 +755,12 @@ export class EditorGroupModel extends Disposable {
if (options?.supportSideBySide && editor instanceof SideBySideEditorInput && !(candidate instanceof SideBySideEditorInput)) {
switch (options.supportSideBySide) {
case SideBySideMatchingStrategy.ANY_SIDE:
case SideBySideEditor.ANY:
if (this.matches(editor.primary, candidate, options) || this.matches(editor.secondary, candidate, options)) {
return true;
}
break;
case SideBySideMatchingStrategy.BOTH_SIDES:
case SideBySideEditor.BOTH:
if (this.matches(editor.primary, candidate, options) && this.matches(editor.secondary, candidate, options)) {
return true;
}
......
......@@ -14,6 +14,7 @@ import { MockScopableContextKeyService } from 'vs/platform/keybinding/test/commo
import { ConfirmResult } from 'vs/platform/dialogs/common/dialogs';
import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { SideBySideEditorInput } from 'vs/workbench/common/editor/sideBySideEditorInput';
suite('EditorGroupsService', () => {
......@@ -23,7 +24,7 @@ suite('EditorGroupsService', () => {
const disposables = new DisposableStore();
setup(() => {
disposables.add(registerTestEditor(TEST_EDITOR_ID, [new SyncDescriptor(TestFileEditorInput)], TEST_EDITOR_INPUT_ID));
disposables.add(registerTestEditor(TEST_EDITOR_ID, [new SyncDescriptor(TestFileEditorInput), new SyncDescriptor(SideBySideEditorInput)], TEST_EDITOR_INPUT_ID));
});
teardown(() => {
......@@ -1143,6 +1144,27 @@ suite('EditorGroupsService', () => {
assert.strictEqual(group.getEditorByIndex(4), input8);
});
test('replaceEditors - should be able to replace when side by side editor is involved with same input side by side', async () => {
const [part] = await createPart();
const group = part.activeGroup;
assert.strictEqual(group.isEmpty, true);
const input = new TestFileEditorInput(URI.file('foo/bar'), TEST_EDITOR_INPUT_ID);
const sideBySideInput = new SideBySideEditorInput(undefined, undefined, input, input);
await group.openEditor(input);
assert.strictEqual(group.count, 1);
assert.strictEqual(group.getEditorByIndex(0), input);
await group.replaceEditors([{ editor: input, replacement: sideBySideInput }]);
assert.strictEqual(group.count, 1);
assert.strictEqual(group.getEditorByIndex(0), sideBySideInput);
await group.replaceEditors([{ editor: sideBySideInput, replacement: input }]);
assert.strictEqual(group.count, 1);
assert.strictEqual(group.getEditorByIndex(0), input);
});
test('find editors', async () => {
const [part] = await createPart();
const group = part.activeGroup;
......
......@@ -152,6 +152,7 @@ suite('Workbench editor utils', () => {
assert.strictEqual(EditorResourceAccessor.getCanonicalUri(untitled)!.toString(), untitled.resource.toString());
assert.strictEqual(EditorResourceAccessor.getCanonicalUri(untitled, { supportSideBySide: SideBySideEditor.PRIMARY })!.toString(), untitled.resource.toString());
assert.strictEqual(EditorResourceAccessor.getCanonicalUri(untitled, { supportSideBySide: SideBySideEditor.ANY })!.toString(), untitled.resource.toString());
assert.strictEqual(EditorResourceAccessor.getCanonicalUri(untitled, { supportSideBySide: SideBySideEditor.SECONDARY })!.toString(), untitled.resource.toString());
assert.strictEqual(EditorResourceAccessor.getCanonicalUri(untitled, { supportSideBySide: SideBySideEditor.BOTH })!.toString(), untitled.resource.toString());
assert.strictEqual(EditorResourceAccessor.getCanonicalUri(untitled, { filterByScheme: Schemas.untitled })!.toString(), untitled.resource.toString());
......@@ -160,6 +161,7 @@ suite('Workbench editor utils', () => {
assert.strictEqual(EditorResourceAccessor.getOriginalUri(untitled)!.toString(), untitled.resource.toString());
assert.strictEqual(EditorResourceAccessor.getOriginalUri(untitled, { supportSideBySide: SideBySideEditor.PRIMARY })!.toString(), untitled.resource.toString());
assert.strictEqual(EditorResourceAccessor.getOriginalUri(untitled, { supportSideBySide: SideBySideEditor.ANY })!.toString(), untitled.resource.toString());
assert.strictEqual(EditorResourceAccessor.getOriginalUri(untitled, { supportSideBySide: SideBySideEditor.SECONDARY })!.toString(), untitled.resource.toString());
assert.strictEqual(EditorResourceAccessor.getOriginalUri(untitled, { supportSideBySide: SideBySideEditor.BOTH })!.toString(), untitled.resource.toString());
assert.strictEqual(EditorResourceAccessor.getOriginalUri(untitled, { filterByScheme: Schemas.untitled })!.toString(), untitled.resource.toString());
......@@ -170,6 +172,7 @@ suite('Workbench editor utils', () => {
assert.strictEqual(EditorResourceAccessor.getCanonicalUri(file)!.toString(), file.resource.toString());
assert.strictEqual(EditorResourceAccessor.getCanonicalUri(file, { supportSideBySide: SideBySideEditor.PRIMARY })!.toString(), file.resource.toString());
assert.strictEqual(EditorResourceAccessor.getCanonicalUri(file, { supportSideBySide: SideBySideEditor.ANY })!.toString(), file.resource.toString());
assert.strictEqual(EditorResourceAccessor.getCanonicalUri(file, { supportSideBySide: SideBySideEditor.SECONDARY })!.toString(), file.resource.toString());
assert.strictEqual(EditorResourceAccessor.getCanonicalUri(file, { supportSideBySide: SideBySideEditor.BOTH })!.toString(), file.resource.toString());
assert.strictEqual(EditorResourceAccessor.getCanonicalUri(file, { filterByScheme: Schemas.file })!.toString(), file.resource.toString());
......@@ -178,6 +181,7 @@ suite('Workbench editor utils', () => {
assert.strictEqual(EditorResourceAccessor.getOriginalUri(file)!.toString(), file.resource.toString());
assert.strictEqual(EditorResourceAccessor.getOriginalUri(file, { supportSideBySide: SideBySideEditor.PRIMARY })!.toString(), file.resource.toString());
assert.strictEqual(EditorResourceAccessor.getOriginalUri(file, { supportSideBySide: SideBySideEditor.ANY })!.toString(), file.resource.toString());
assert.strictEqual(EditorResourceAccessor.getOriginalUri(file, { supportSideBySide: SideBySideEditor.SECONDARY })!.toString(), file.resource.toString());
assert.strictEqual(EditorResourceAccessor.getOriginalUri(file, { supportSideBySide: SideBySideEditor.BOTH })!.toString(), file.resource.toString());
assert.strictEqual(EditorResourceAccessor.getOriginalUri(file, { filterByScheme: Schemas.file })!.toString(), file.resource.toString());
......@@ -250,6 +254,7 @@ suite('Workbench editor utils', () => {
assert.strictEqual(EditorResourceAccessor.getCanonicalUri(untitled)!.toString(), untitled.resource?.toString());
assert.strictEqual(EditorResourceAccessor.getCanonicalUri(untitled, { supportSideBySide: SideBySideEditor.PRIMARY })!.toString(), untitled.resource?.toString());
assert.strictEqual(EditorResourceAccessor.getCanonicalUri(untitled, { supportSideBySide: SideBySideEditor.ANY })!.toString(), untitled.resource?.toString());
assert.strictEqual(EditorResourceAccessor.getCanonicalUri(untitled, { supportSideBySide: SideBySideEditor.SECONDARY })!.toString(), untitled.resource?.toString());
assert.strictEqual(EditorResourceAccessor.getCanonicalUri(untitled, { supportSideBySide: SideBySideEditor.BOTH })!.toString(), untitled.resource?.toString());
assert.strictEqual(EditorResourceAccessor.getCanonicalUri(untitled, { filterByScheme: Schemas.untitled })!.toString(), untitled.resource?.toString());
......@@ -258,6 +263,7 @@ suite('Workbench editor utils', () => {
assert.strictEqual(EditorResourceAccessor.getOriginalUri(untitled)!.toString(), untitled.resource?.toString());
assert.strictEqual(EditorResourceAccessor.getOriginalUri(untitled, { supportSideBySide: SideBySideEditor.PRIMARY })!.toString(), untitled.resource?.toString());
assert.strictEqual(EditorResourceAccessor.getOriginalUri(untitled, { supportSideBySide: SideBySideEditor.ANY })!.toString(), untitled.resource?.toString());
assert.strictEqual(EditorResourceAccessor.getOriginalUri(untitled, { supportSideBySide: SideBySideEditor.SECONDARY })!.toString(), untitled.resource?.toString());
assert.strictEqual(EditorResourceAccessor.getOriginalUri(untitled, { supportSideBySide: SideBySideEditor.BOTH })!.toString(), untitled.resource?.toString());
assert.strictEqual(EditorResourceAccessor.getOriginalUri(untitled, { filterByScheme: Schemas.untitled })!.toString(), untitled.resource?.toString());
......@@ -270,6 +276,7 @@ suite('Workbench editor utils', () => {
assert.strictEqual(EditorResourceAccessor.getCanonicalUri(file)!.toString(), file.resource.toString());
assert.strictEqual(EditorResourceAccessor.getCanonicalUri(file, { supportSideBySide: SideBySideEditor.PRIMARY })!.toString(), file.resource.toString());
assert.strictEqual(EditorResourceAccessor.getCanonicalUri(file, { supportSideBySide: SideBySideEditor.ANY })!.toString(), file.resource.toString());
assert.strictEqual(EditorResourceAccessor.getCanonicalUri(file, { supportSideBySide: SideBySideEditor.SECONDARY })!.toString(), file.resource.toString());
assert.strictEqual(EditorResourceAccessor.getCanonicalUri(file, { supportSideBySide: SideBySideEditor.BOTH })!.toString(), file.resource.toString());
assert.strictEqual(EditorResourceAccessor.getCanonicalUri(file, { filterByScheme: Schemas.file })!.toString(), file.resource.toString());
......@@ -278,6 +285,7 @@ suite('Workbench editor utils', () => {
assert.strictEqual(EditorResourceAccessor.getOriginalUri(file)!.toString(), file.resource.toString());
assert.strictEqual(EditorResourceAccessor.getOriginalUri(file, { supportSideBySide: SideBySideEditor.PRIMARY })!.toString(), file.resource.toString());
assert.strictEqual(EditorResourceAccessor.getOriginalUri(file, { supportSideBySide: SideBySideEditor.ANY })!.toString(), file.resource.toString());
assert.strictEqual(EditorResourceAccessor.getOriginalUri(file, { supportSideBySide: SideBySideEditor.SECONDARY })!.toString(), file.resource.toString());
assert.strictEqual(EditorResourceAccessor.getOriginalUri(file, { supportSideBySide: SideBySideEditor.BOTH })!.toString(), file.resource.toString());
assert.strictEqual(EditorResourceAccessor.getOriginalUri(file, { filterByScheme: Schemas.file })!.toString(), file.resource.toString());
......
......@@ -4,8 +4,8 @@
*--------------------------------------------------------------------------------------------*/
import * as assert from 'assert';
import { EditorGroupModel, ISerializedEditorGroupModel, EditorCloseEvent, SideBySideMatchingStrategy } from 'vs/workbench/common/editor/editorGroupModel';
import { EditorExtensions, IEditorFactoryRegistry, IFileEditorInput, IEditorSerializer, CloseDirection, EditorsOrder, IResourceDiffEditorInput, IResourceSideBySideEditorInput } from 'vs/workbench/common/editor';
import { EditorGroupModel, ISerializedEditorGroupModel, EditorCloseEvent } from 'vs/workbench/common/editor/editorGroupModel';
import { EditorExtensions, IEditorFactoryRegistry, IFileEditorInput, IEditorSerializer, CloseDirection, EditorsOrder, IResourceDiffEditorInput, IResourceSideBySideEditorInput, SideBySideEditor } from 'vs/workbench/common/editor';
import { URI } from 'vs/base/common/uri';
import { TestLifecycleService, workbenchInstantiationService } from 'vs/workbench/test/browser/workbenchTestServices';
import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService';
......@@ -324,7 +324,7 @@ suite('EditorGroupModel', () => {
assert.strictEqual(res.editor, sideBySideInputSame);
assert.strictEqual(res.isNew, true);
res = group.openEditor(input1, { pinned: true, active: true });
res = group.openEditor(input1, { pinned: true, active: true, supportSideBySide: SideBySideEditor.BOTH });
assert.strictEqual(res.editor, sideBySideInputSame);
assert.strictEqual(res.isNew, false);
......@@ -338,6 +338,24 @@ suite('EditorGroupModel', () => {
assert.strictEqual(res.isNew, true);
});
test('indexOf() - prefers direct matching editor over side by side matching one', () => {
const group = createEditorGroupModel();
const input1 = new TestFileEditorInput('testInput', URI.file('fake1'));
const sideBySideInput = new SideBySideEditorInput(undefined, undefined, input1, input1);
group.openEditor(sideBySideInput, { pinned: true, active: true });
assert.strictEqual(group.indexOf(sideBySideInput), 0);
assert.strictEqual(group.indexOf(input1), -1);
assert.strictEqual(group.indexOf(input1, undefined, { supportSideBySide: SideBySideEditor.BOTH }), 0);
assert.strictEqual(group.indexOf(input1, undefined, { supportSideBySide: SideBySideEditor.ANY }), 0);
group.openEditor(input1, { pinned: true, active: true });
assert.strictEqual(group.indexOf(input1), 1);
assert.strictEqual(group.indexOf(input1, undefined, { supportSideBySide: SideBySideEditor.BOTH }), 1);
assert.strictEqual(group.indexOf(input1, undefined, { supportSideBySide: SideBySideEditor.ANY }), 1);
});
test('contains() - untyped', function () {
const group = createEditorGroupModel();
const instantiationService = workbenchInstantiationService();
......@@ -376,12 +394,12 @@ suite('EditorGroupModel', () => {
assert.strictEqual(group.contains(untypedInput1), true);
assert.strictEqual(group.contains(untypedInput1, { strictEquals: true }), false);
assert.strictEqual(group.contains(untypedInput1, { supportSideBySide: SideBySideMatchingStrategy.ANY_SIDE }), true);
assert.strictEqual(group.contains(untypedInput1, { supportSideBySide: SideBySideMatchingStrategy.BOTH_SIDES }), true);
assert.strictEqual(group.contains(untypedInput1, { supportSideBySide: SideBySideEditor.ANY }), true);
assert.strictEqual(group.contains(untypedInput1, { supportSideBySide: SideBySideEditor.BOTH }), true);
assert.strictEqual(group.contains(untypedInput2), false);
assert.strictEqual(group.contains(untypedInput2, { strictEquals: true }), false);
assert.strictEqual(group.contains(untypedInput2, { supportSideBySide: SideBySideMatchingStrategy.ANY_SIDE }), false);
assert.strictEqual(group.contains(untypedInput2, { supportSideBySide: SideBySideMatchingStrategy.BOTH_SIDES }), false);
assert.strictEqual(group.contains(untypedInput2, { supportSideBySide: SideBySideEditor.ANY }), false);
assert.strictEqual(group.contains(untypedInput2, { supportSideBySide: SideBySideEditor.BOTH }), false);
assert.strictEqual(group.contains(untypedDiffInput1), false);
assert.strictEqual(group.contains(untypedDiffInput2), false);
......@@ -409,8 +427,8 @@ suite('EditorGroupModel', () => {
group.closeEditor(input1);
assert.strictEqual(group.contains(untypedInput1), false);
assert.strictEqual(group.contains(untypedInput1, { supportSideBySide: SideBySideMatchingStrategy.ANY_SIDE }), true);
assert.strictEqual(group.contains(untypedInput1, { supportSideBySide: SideBySideMatchingStrategy.BOTH_SIDES }), false);
assert.strictEqual(group.contains(untypedInput1, { supportSideBySide: SideBySideEditor.ANY }), true);
assert.strictEqual(group.contains(untypedInput1, { supportSideBySide: SideBySideEditor.BOTH }), false);
assert.strictEqual(group.contains(untypedInput2), true);
assert.strictEqual(group.contains(untypedDiffInput1), true);
assert.strictEqual(group.contains(untypedDiffInput2), true);
......@@ -418,45 +436,45 @@ suite('EditorGroupModel', () => {
group.closeEditor(input2);
assert.strictEqual(group.contains(untypedInput1), false);
assert.strictEqual(group.contains(untypedInput1, { supportSideBySide: SideBySideMatchingStrategy.ANY_SIDE }), true);
assert.strictEqual(group.contains(untypedInput1, { supportSideBySide: SideBySideEditor.ANY }), true);
assert.strictEqual(group.contains(untypedInput2), false);
assert.strictEqual(group.contains(untypedInput2, { supportSideBySide: SideBySideMatchingStrategy.ANY_SIDE }), true);
assert.strictEqual(group.contains(untypedInput2, { supportSideBySide: SideBySideEditor.ANY }), true);
assert.strictEqual(group.contains(untypedDiffInput1), true);
assert.strictEqual(group.contains(untypedDiffInput2), true);
group.closeEditor(diffInput1);
assert.strictEqual(group.contains(untypedInput1), false);
assert.strictEqual(group.contains(untypedInput1, { supportSideBySide: SideBySideMatchingStrategy.ANY_SIDE }), true);
assert.strictEqual(group.contains(untypedInput1, { supportSideBySide: SideBySideEditor.ANY }), true);
assert.strictEqual(group.contains(untypedInput2), false);
assert.strictEqual(group.contains(untypedInput2, { supportSideBySide: SideBySideMatchingStrategy.ANY_SIDE }), true);
assert.strictEqual(group.contains(untypedInput2, { supportSideBySide: SideBySideEditor.ANY }), true);
assert.strictEqual(group.contains(untypedDiffInput1), false);
assert.strictEqual(group.contains(untypedDiffInput2), true);
group.closeEditor(diffInput2);
assert.strictEqual(group.contains(untypedInput1), false);
assert.strictEqual(group.contains(untypedInput1, { supportSideBySide: SideBySideMatchingStrategy.ANY_SIDE }), false);
assert.strictEqual(group.contains(untypedInput1, { supportSideBySide: SideBySideEditor.ANY }), false);
assert.strictEqual(group.contains(untypedInput2), false);
assert.strictEqual(group.contains(untypedInput2, { supportSideBySide: SideBySideMatchingStrategy.ANY_SIDE }), false);
assert.strictEqual(group.contains(untypedInput2, { supportSideBySide: SideBySideEditor.ANY }), false);
assert.strictEqual(group.contains(untypedDiffInput1), false);
assert.strictEqual(group.contains(untypedDiffInput2), false);
assert.strictEqual(group.count, 0);
group.openEditor(sideBySideInputSame, { pinned: true, active: true });
assert.strictEqual(group.contains(untypedSideBySideInputSame), true);
assert.strictEqual(group.contains(untypedInput1, { supportSideBySide: SideBySideMatchingStrategy.ANY_SIDE }), true);
assert.strictEqual(group.contains(untypedInput1, { supportSideBySide: SideBySideMatchingStrategy.BOTH_SIDES }), true);
assert.strictEqual(group.contains(untypedInput1, { supportSideBySide: SideBySideMatchingStrategy.ANY_SIDE, strictEquals: true }), false);
assert.strictEqual(group.contains(untypedInput1, { supportSideBySide: SideBySideMatchingStrategy.BOTH_SIDES, strictEquals: true }), false);
assert.strictEqual(group.contains(untypedInput1, { supportSideBySide: SideBySideEditor.ANY }), true);
assert.strictEqual(group.contains(untypedInput1, { supportSideBySide: SideBySideEditor.BOTH }), true);
assert.strictEqual(group.contains(untypedInput1, { supportSideBySide: SideBySideEditor.ANY, strictEquals: true }), false);
assert.strictEqual(group.contains(untypedInput1, { supportSideBySide: SideBySideEditor.BOTH, strictEquals: true }), false);
group.closeEditor(sideBySideInputSame);
assert.strictEqual(group.count, 0);
group.openEditor(sideBySideInputDifferent, { pinned: true, active: true });
assert.strictEqual(group.contains(untypedSideBySideInputDifferent), true);
assert.strictEqual(group.contains(untypedInput1, { supportSideBySide: SideBySideMatchingStrategy.ANY_SIDE }), true);
assert.strictEqual(group.contains(untypedInput1, { supportSideBySide: SideBySideMatchingStrategy.BOTH_SIDES }), false);
assert.strictEqual(group.contains(untypedInput1, { supportSideBySide: SideBySideEditor.ANY }), true);
assert.strictEqual(group.contains(untypedInput1, { supportSideBySide: SideBySideEditor.BOTH }), false);
});
test('contains()', () => {
......@@ -476,10 +494,10 @@ suite('EditorGroupModel', () => {
assert.strictEqual(group.contains(input1), true);
assert.strictEqual(group.contains(input1, { strictEquals: true }), true);
assert.strictEqual(group.contains(input1, { supportSideBySide: SideBySideMatchingStrategy.ANY_SIDE }), true);
assert.strictEqual(group.contains(input1, { supportSideBySide: SideBySideEditor.ANY }), true);
assert.strictEqual(group.contains(input2), false);
assert.strictEqual(group.contains(input2, { strictEquals: true }), false);
assert.strictEqual(group.contains(input2, { supportSideBySide: SideBySideMatchingStrategy.ANY_SIDE }), false);
assert.strictEqual(group.contains(input2, { supportSideBySide: SideBySideEditor.ANY }), false);
assert.strictEqual(group.contains(diffInput1), false);
assert.strictEqual(group.contains(diffInput2), false);
......@@ -507,7 +525,7 @@ suite('EditorGroupModel', () => {
group.closeEditor(input1);
assert.strictEqual(group.contains(input1), false);
assert.strictEqual(group.contains(input1, { supportSideBySide: SideBySideMatchingStrategy.ANY_SIDE }), true);
assert.strictEqual(group.contains(input1, { supportSideBySide: SideBySideEditor.ANY }), true);
assert.strictEqual(group.contains(input2), true);
assert.strictEqual(group.contains(diffInput1), true);
assert.strictEqual(group.contains(diffInput2), true);
......@@ -515,27 +533,27 @@ suite('EditorGroupModel', () => {
group.closeEditor(input2);
assert.strictEqual(group.contains(input1), false);
assert.strictEqual(group.contains(input1, { supportSideBySide: SideBySideMatchingStrategy.ANY_SIDE }), true);
assert.strictEqual(group.contains(input1, { supportSideBySide: SideBySideEditor.ANY }), true);
assert.strictEqual(group.contains(input2), false);
assert.strictEqual(group.contains(input2, { supportSideBySide: SideBySideMatchingStrategy.ANY_SIDE }), true);
assert.strictEqual(group.contains(input2, { supportSideBySide: SideBySideEditor.ANY }), true);
assert.strictEqual(group.contains(diffInput1), true);
assert.strictEqual(group.contains(diffInput2), true);
group.closeEditor(diffInput1);
assert.strictEqual(group.contains(input1), false);
assert.strictEqual(group.contains(input1, { supportSideBySide: SideBySideMatchingStrategy.ANY_SIDE }), true);
assert.strictEqual(group.contains(input1, { supportSideBySide: SideBySideEditor.ANY }), true);
assert.strictEqual(group.contains(input2), false);
assert.strictEqual(group.contains(input2, { supportSideBySide: SideBySideMatchingStrategy.ANY_SIDE }), true);
assert.strictEqual(group.contains(input2, { supportSideBySide: SideBySideEditor.ANY }), true);
assert.strictEqual(group.contains(diffInput1), false);
assert.strictEqual(group.contains(diffInput2), true);
group.closeEditor(diffInput2);
assert.strictEqual(group.contains(input1), false);
assert.strictEqual(group.contains(input1, { supportSideBySide: SideBySideMatchingStrategy.ANY_SIDE }), false);
assert.strictEqual(group.contains(input1, { supportSideBySide: SideBySideEditor.ANY }), false);
assert.strictEqual(group.contains(input2), false);
assert.strictEqual(group.contains(input2, { supportSideBySide: SideBySideMatchingStrategy.ANY_SIDE }), false);
assert.strictEqual(group.contains(input2, { supportSideBySide: SideBySideEditor.ANY }), false);
assert.strictEqual(group.contains(diffInput1), false);
assert.strictEqual(group.contains(diffInput2), false);
......@@ -555,20 +573,20 @@ suite('EditorGroupModel', () => {
group.openEditor(sideBySideInputSame, { pinned: true, active: true });
assert.strictEqual(group.contains(sideBySideInputSame), true);
assert.strictEqual(group.contains(input1, { supportSideBySide: SideBySideMatchingStrategy.ANY_SIDE }), true);
assert.strictEqual(group.contains(input1, { supportSideBySide: SideBySideMatchingStrategy.BOTH_SIDES }), true);
assert.strictEqual(group.contains(input1, { supportSideBySide: SideBySideMatchingStrategy.ANY_SIDE, strictEquals: true }), true);
assert.strictEqual(group.contains(input1, { supportSideBySide: SideBySideMatchingStrategy.BOTH_SIDES, strictEquals: true }), true);
assert.strictEqual(group.contains(input1, { supportSideBySide: SideBySideEditor.ANY }), true);
assert.strictEqual(group.contains(input1, { supportSideBySide: SideBySideEditor.BOTH }), true);
assert.strictEqual(group.contains(input1, { supportSideBySide: SideBySideEditor.ANY, strictEquals: true }), true);
assert.strictEqual(group.contains(input1, { supportSideBySide: SideBySideEditor.BOTH, strictEquals: true }), true);
group.closeEditor(sideBySideInputSame);
assert.strictEqual(group.count, 0);
group.openEditor(sideBySideInputDifferent, { pinned: true, active: true });
assert.strictEqual(group.contains(sideBySideInputDifferent), true);
assert.strictEqual(group.contains(input1, { supportSideBySide: SideBySideMatchingStrategy.ANY_SIDE }), true);
assert.strictEqual(group.contains(input1, { supportSideBySide: SideBySideMatchingStrategy.ANY_SIDE, strictEquals: true }), true);
assert.strictEqual(group.contains(input1, { supportSideBySide: SideBySideMatchingStrategy.BOTH_SIDES }), false);
assert.strictEqual(group.contains(input1, { supportSideBySide: SideBySideMatchingStrategy.BOTH_SIDES, strictEquals: true }), false);
assert.strictEqual(group.contains(input1, { supportSideBySide: SideBySideEditor.ANY }), true);
assert.strictEqual(group.contains(input1, { supportSideBySide: SideBySideEditor.ANY, strictEquals: true }), true);
assert.strictEqual(group.contains(input1, { supportSideBySide: SideBySideEditor.BOTH }), false);
assert.strictEqual(group.contains(input1, { supportSideBySide: SideBySideEditor.BOTH, strictEquals: true }), false);
});
test('group serialization', function () {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册