mirror of
https://github.com/Microsoft/vscode
synced 2024-09-13 13:46:13 +00:00
editors - add and adopt IEditorService#isOpen(resource) for fast lookups of opened editors
This commit is contained in:
parent
f2502971b5
commit
66c09fb60e
|
@ -246,7 +246,7 @@ export class ResourcesDropHandler {
|
|||
}
|
||||
|
||||
// File: ensure the file is not dirty or opened already
|
||||
else if (this.textFileService.isDirty(droppedDirtyEditor.resource) || this.editorService.isOpen(this.editorService.createInput({ resource: droppedDirtyEditor.resource, forceFile: true }))) {
|
||||
else if (this.textFileService.isDirty(droppedDirtyEditor.resource) || this.editorService.isOpen({ resource: droppedDirtyEditor.resource })) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -1075,7 +1075,10 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
|
|||
// Update model and make sure to continue to use the editor we get from
|
||||
// the model. It is possible that the editor was already opened and we
|
||||
// want to ensure that we use the existing instance in that case.
|
||||
const editor = this.group.getEditorByIndex(currentIndex)!;
|
||||
const editor = this._group.getEditorByIndex(currentIndex);
|
||||
if (!editor) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Update model
|
||||
this._group.moveEditor(editor, moveToIndex);
|
||||
|
@ -1278,7 +1281,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
|
|||
return false; // editor must be dirty and not saving
|
||||
}
|
||||
|
||||
if (editor instanceof SideBySideEditorInput && this.isOpened(editor.master)) {
|
||||
if (editor instanceof SideBySideEditorInput && this._group.contains(editor.master)) {
|
||||
return false; // master-side of editor is still opened somewhere else
|
||||
}
|
||||
|
||||
|
|
|
@ -3,15 +3,16 @@
|
|||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { IEditorInput, IEditorInputFactoryRegistry, IEditorIdentifier, GroupIdentifier, Extensions, IEditorPartOptionsChangeEvent, EditorsOrder } from 'vs/workbench/common/editor';
|
||||
import { IEditorInput, IEditorInputFactoryRegistry, IEditorIdentifier, GroupIdentifier, Extensions, IEditorPartOptionsChangeEvent, EditorsOrder, toResource, SideBySideEditor } from 'vs/workbench/common/editor';
|
||||
import { dispose, Disposable, DisposableStore } from 'vs/base/common/lifecycle';
|
||||
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
import { IEditorGroupsService, IEditorGroup, GroupChangeKind, GroupsOrder } from 'vs/workbench/services/editor/common/editorGroupsService';
|
||||
import { coalesce } from 'vs/base/common/arrays';
|
||||
import { LinkedMap, Touch } from 'vs/base/common/map';
|
||||
import { LinkedMap, Touch, ResourceMap } from 'vs/base/common/map';
|
||||
import { equals } from 'vs/base/common/objects';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
|
||||
interface ISerializedEditorsList {
|
||||
entries: ISerializedEditorIdentifier[];
|
||||
|
@ -37,9 +38,10 @@ export class EditorsObserver extends Disposable {
|
|||
|
||||
private readonly keyMap = new Map<GroupIdentifier, Map<IEditorInput, IEditorIdentifier>>();
|
||||
private readonly mostRecentEditorsMap = new LinkedMap<IEditorIdentifier, IEditorIdentifier>();
|
||||
private readonly editorResourcesMap = new ResourceMap<number>();
|
||||
|
||||
private readonly _onDidChange = this._register(new Emitter<void>());
|
||||
readonly onDidChange = this._onDidChange.event;
|
||||
private readonly _onDidMostRecentlyActiveEditorsChange = this._register(new Emitter<void>());
|
||||
readonly onDidMostRecentlyActiveEditorsChange = this._onDidMostRecentlyActiveEditorsChange.event;
|
||||
|
||||
get count(): number {
|
||||
return this.mostRecentEditorsMap.size;
|
||||
|
@ -49,6 +51,10 @@ export class EditorsObserver extends Disposable {
|
|||
return this.mostRecentEditorsMap.values();
|
||||
}
|
||||
|
||||
hasEditor(resource: URI): boolean {
|
||||
return this.editorResourcesMap.has(resource);
|
||||
}
|
||||
|
||||
constructor(
|
||||
@IEditorGroupsService private editorGroupsService: IEditorGroupsService,
|
||||
@IStorageService private readonly storageService: IStorageService
|
||||
|
@ -72,12 +78,12 @@ export class EditorsObserver extends Disposable {
|
|||
// of the new group into our list in LRU order
|
||||
const groupEditorsMru = group.getEditors(EditorsOrder.MOST_RECENTLY_ACTIVE);
|
||||
for (let i = groupEditorsMru.length - 1; i >= 0; i--) {
|
||||
this.addMostRecentEditor(group, groupEditorsMru[i], false /* is not active */);
|
||||
this.addMostRecentEditor(group, groupEditorsMru[i], false /* is not active */, true /* is new */);
|
||||
}
|
||||
|
||||
// Make sure that active editor is put as first if group is active
|
||||
if (this.editorGroupsService.activeGroup === group && group.activeEditor) {
|
||||
this.addMostRecentEditor(group, group.activeEditor, true /* is active */);
|
||||
this.addMostRecentEditor(group, group.activeEditor, true /* is active */, false /* already added before */);
|
||||
}
|
||||
|
||||
// Group Listeners
|
||||
|
@ -92,7 +98,7 @@ export class EditorsObserver extends Disposable {
|
|||
// Group gets active: put active editor as most recent
|
||||
case GroupChangeKind.GROUP_ACTIVE: {
|
||||
if (this.editorGroupsService.activeGroup === group && group.activeEditor) {
|
||||
this.addMostRecentEditor(group, group.activeEditor, true /* is active */);
|
||||
this.addMostRecentEditor(group, group.activeEditor, true /* is active */, false /* editor already opened */);
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -102,7 +108,7 @@ export class EditorsObserver extends Disposable {
|
|||
// if group is active, otherwise second most recent
|
||||
case GroupChangeKind.EDITOR_ACTIVE: {
|
||||
if (e.editor) {
|
||||
this.addMostRecentEditor(group, e.editor, this.editorGroupsService.activeGroup === group);
|
||||
this.addMostRecentEditor(group, e.editor, this.editorGroupsService.activeGroup === group, false /* editor already opened */);
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -114,7 +120,7 @@ export class EditorsObserver extends Disposable {
|
|||
// start to close oldest ones if needed.
|
||||
case GroupChangeKind.EDITOR_OPEN: {
|
||||
if (e.editor) {
|
||||
this.addMostRecentEditor(group, e.editor, false /* is not active */);
|
||||
this.addMostRecentEditor(group, e.editor, false /* is not active */, true /* is new */);
|
||||
this.ensureOpenedEditorsLimit({ groupId: group.id, editor: e.editor }, group.id);
|
||||
}
|
||||
|
||||
|
@ -148,7 +154,7 @@ export class EditorsObserver extends Disposable {
|
|||
}
|
||||
}
|
||||
|
||||
private addMostRecentEditor(group: IEditorGroup, editor: IEditorInput, isActive: boolean): void {
|
||||
private addMostRecentEditor(group: IEditorGroup, editor: IEditorInput, isActive: boolean, isNew: boolean): void {
|
||||
const key = this.ensureKey(group, editor);
|
||||
const mostRecentEditor = this.mostRecentEditorsMap.first;
|
||||
|
||||
|
@ -169,11 +175,39 @@ export class EditorsObserver extends Disposable {
|
|||
this.mostRecentEditorsMap.set(mostRecentEditor, mostRecentEditor, Touch.AsOld /* make first */);
|
||||
}
|
||||
|
||||
// Update in resource map if this is a new editor
|
||||
if (isNew) {
|
||||
this.updateEditorResourcesMap(editor, true);
|
||||
}
|
||||
|
||||
// Event
|
||||
this._onDidChange.fire();
|
||||
this._onDidMostRecentlyActiveEditorsChange.fire();
|
||||
}
|
||||
|
||||
private updateEditorResourcesMap(editor: IEditorInput, add: boolean): void {
|
||||
const resource = toResource(editor, { supportSideBySide: SideBySideEditor.MASTER });
|
||||
if (!resource) {
|
||||
return; // require a resource
|
||||
}
|
||||
|
||||
if (add) {
|
||||
this.editorResourcesMap.set(resource, (this.editorResourcesMap.get(resource) ?? 0) + 1);
|
||||
} else {
|
||||
const counter = this.editorResourcesMap.get(resource) ?? 0;
|
||||
if (counter > 1) {
|
||||
this.editorResourcesMap.set(resource, counter - 1);
|
||||
} else {
|
||||
this.editorResourcesMap.delete(resource);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private removeMostRecentEditor(group: IEditorGroup, editor: IEditorInput): void {
|
||||
|
||||
// Update in resource map
|
||||
this.updateEditorResourcesMap(editor, false);
|
||||
|
||||
// Update in MRU list
|
||||
const key = this.findKey(group, editor);
|
||||
if (key) {
|
||||
|
||||
|
@ -187,7 +221,7 @@ export class EditorsObserver extends Disposable {
|
|||
}
|
||||
|
||||
// Event
|
||||
this._onDidChange.fire();
|
||||
this._onDidMostRecentlyActiveEditorsChange.fire();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -361,7 +395,7 @@ export class EditorsObserver extends Disposable {
|
|||
const group = groups[i];
|
||||
const groupEditorsMru = group.getEditors(EditorsOrder.MOST_RECENTLY_ACTIVE);
|
||||
for (let i = groupEditorsMru.length - 1; i >= 0; i--) {
|
||||
this.addMostRecentEditor(group, groupEditorsMru[i], true /* enforce as active to preserve order */);
|
||||
this.addMostRecentEditor(group, groupEditorsMru[i], true /* enforce as active to preserve order */, true /* is new */);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -392,6 +426,9 @@ export class EditorsObserver extends Disposable {
|
|||
// Make sure key is registered as well
|
||||
const editorIdentifier = this.ensureKey(group, editor);
|
||||
mapValues.push([editorIdentifier, editorIdentifier]);
|
||||
|
||||
// Update in resource map
|
||||
this.updateEditorResourcesMap(editor, true);
|
||||
}
|
||||
|
||||
// Fill map with deserialized values
|
||||
|
|
|
@ -13,7 +13,6 @@ import { IHostService } from 'vs/workbench/services/host/browser/host';
|
|||
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { RunOnceWorker } from 'vs/base/common/async';
|
||||
import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService';
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
|
||||
export class TextFileEditorTracker extends Disposable implements IWorkbenchContribution {
|
||||
|
||||
|
@ -45,7 +44,7 @@ export class TextFileEditorTracker extends Disposable implements IWorkbenchContr
|
|||
|
||||
//#region Text File: Ensure every dirty text and untitled file is opened in an editor
|
||||
|
||||
private readonly ensureDirtyFilesAreOpenedWorker = this._register(new RunOnceWorker<URI>(units => this.ensureDirtyTextFilesAreOpened(units), 250));
|
||||
private readonly ensureDirtyFilesAreOpenedWorker = this._register(new RunOnceWorker<URI>(units => this.ensureDirtyTextFilesAreOpened(units), 50));
|
||||
|
||||
private ensureDirtyTextFilesAreOpened(resources: URI[]): void {
|
||||
this.doEnsureDirtyTextFilesAreOpened(distinct(resources.filter(resource => {
|
||||
|
@ -58,7 +57,7 @@ export class TextFileEditorTracker extends Disposable implements IWorkbenchContr
|
|||
return false; // resource must not be pending to save
|
||||
}
|
||||
|
||||
if (this.editorService.isOpen(this.editorService.createInput({ resource, forceFile: resource.scheme !== Schemas.untitled, forceUntitled: resource.scheme === Schemas.untitled }))) {
|
||||
if (this.editorService.isOpen({ resource })) {
|
||||
return false; // model must not be opened already as file
|
||||
}
|
||||
|
||||
|
|
|
@ -677,7 +677,7 @@ class OpenEditorsDragAndDrop implements IListDragAndDrop<OpenEditor | IEditorGro
|
|||
|
||||
drop(data: IDragAndDropData, targetElement: OpenEditor | IEditorGroup, _targetIndex: number, originalEvent: DragEvent): void {
|
||||
const group = targetElement instanceof OpenEditor ? targetElement.group : targetElement;
|
||||
const index = targetElement instanceof OpenEditor ? targetElement.group.getIndexOfEditor(targetElement.editor) : 0;
|
||||
const index = targetElement instanceof OpenEditor ? targetElement.editorIndex : 0;
|
||||
|
||||
if (data instanceof ElementsDragAndDropData) {
|
||||
const elementsData = data.elements;
|
||||
|
|
|
@ -84,7 +84,7 @@ export class EditorService extends Disposable implements EditorServiceImpl {
|
|||
this.editorGroupService.whenRestored.then(() => this.onEditorsRestored());
|
||||
this.editorGroupService.onDidActiveGroupChange(group => this.handleActiveEditorChange(group));
|
||||
this.editorGroupService.onDidAddGroup(group => this.registerGroupListeners(group as IEditorGroupView));
|
||||
this.editorsObserver.onDidChange(() => this._onDidMostRecentlyActiveEditorsChange.fire());
|
||||
this.editorsObserver.onDidMostRecentlyActiveEditorsChange(() => this._onDidMostRecentlyActiveEditorsChange.fire());
|
||||
|
||||
// Out of workspace file watchers
|
||||
this._register(this.onDidVisibleEditorsChange(() => this.handleVisibleEditorsChange()));
|
||||
|
@ -705,10 +705,20 @@ export class EditorService extends Disposable implements EditorServiceImpl {
|
|||
|
||||
//#region isOpen()
|
||||
|
||||
isOpen(editor: IEditorInput): boolean {
|
||||
isOpen(editor: IEditorInput): boolean;
|
||||
isOpen(editor: IResourceInput): boolean;
|
||||
isOpen(editor: IEditorInput | IResourceInput): boolean {
|
||||
if (editor instanceof EditorInput) {
|
||||
return this.editorGroupService.groups.some(group => group.isOpened(editor));
|
||||
}
|
||||
|
||||
if (editor.resource) {
|
||||
return this.editorsObserver.hasEditor(editor.resource);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region replaceEditors()
|
||||
|
@ -1169,7 +1179,9 @@ export class DelegatingEditorService implements IEditorService {
|
|||
return this.editorService.replaceEditors(editors as IResourceEditorReplacement[] /* TS fail */, group);
|
||||
}
|
||||
|
||||
isOpen(editor: IEditorInput): boolean { return this.editorService.isOpen(editor); }
|
||||
isOpen(editor: IEditorInput): boolean;
|
||||
isOpen(editor: IResourceInput): boolean;
|
||||
isOpen(editor: IEditorInput | IResourceInput): boolean { return this.editorService.isOpen(editor as IResourceInput /* TS fail */); }
|
||||
|
||||
overrideOpenEditor(handler: IOpenEditorOverrideHandler): IDisposable { return this.editorService.overrideOpenEditor(handler); }
|
||||
|
||||
|
|
|
@ -196,7 +196,13 @@ export interface IEditorService {
|
|||
* Find out if the provided editor is opened in any editor group.
|
||||
*
|
||||
* Note: An editor can be opened but not actively visible.
|
||||
*
|
||||
* @param editor the editor to check for being opened. If a
|
||||
* `IResourceInput` is passed in, the resource is checked on
|
||||
* all opened editors. In case of a side by side editor, the
|
||||
* right hand side resource is considered only.
|
||||
*/
|
||||
isOpen(editor: IResourceInput): boolean;
|
||||
isOpen(editor: IEditorInput): boolean;
|
||||
|
||||
/**
|
||||
|
|
|
@ -105,6 +105,7 @@ suite('EditorService', () => {
|
|||
assert.ok(!service.activeTextEditorMode);
|
||||
assert.equal(service.visibleTextEditorWidgets.length, 0);
|
||||
assert.equal(service.isOpen(input), true);
|
||||
assert.equal(service.isOpen({ resource: input.resource }), true);
|
||||
assert.equal(activeEditorChangeEventCounter, 1);
|
||||
assert.equal(visibleEditorChangeEventCounter, 1);
|
||||
|
||||
|
@ -137,7 +138,9 @@ suite('EditorService', () => {
|
|||
assert.equal(otherInput, service.getEditors(EditorsOrder.SEQUENTIAL)[1].editor);
|
||||
assert.equal(service.visibleControls.length, 1);
|
||||
assert.equal(service.isOpen(input), true);
|
||||
assert.equal(service.isOpen({ resource: input.resource }), true);
|
||||
assert.equal(service.isOpen(otherInput), true);
|
||||
assert.equal(service.isOpen({ resource: otherInput.resource }), true);
|
||||
|
||||
assert.equal(activeEditorChangeEventCounter, 4);
|
||||
assert.equal(visibleEditorChangeEventCounter, 4);
|
||||
|
@ -149,6 +152,53 @@ suite('EditorService', () => {
|
|||
part.dispose();
|
||||
});
|
||||
|
||||
test('isOpen() with side by side editor', async () => {
|
||||
const [part, service] = createEditorService();
|
||||
|
||||
const input = new TestFileEditorInput(URI.parse('my://resource-openEditors'), TEST_EDITOR_INPUT_ID);
|
||||
const otherInput = new TestFileEditorInput(URI.parse('my://resource2-openEditors'), TEST_EDITOR_INPUT_ID);
|
||||
const sideBySideInput = new SideBySideEditorInput('sideBySide', '', input, otherInput);
|
||||
|
||||
await part.whenRestored;
|
||||
|
||||
const editor1 = await service.openEditor(sideBySideInput, { pinned: true });
|
||||
assert.equal(part.activeGroup.count, 1);
|
||||
|
||||
assert.equal(service.isOpen(input), false);
|
||||
assert.equal(service.isOpen(otherInput), false);
|
||||
assert.equal(service.isOpen(sideBySideInput), true);
|
||||
assert.equal(service.isOpen({ resource: input.resource }), false);
|
||||
assert.equal(service.isOpen({ resource: otherInput.resource }), true);
|
||||
|
||||
const editor2 = await service.openEditor(input, { pinned: true });
|
||||
assert.equal(part.activeGroup.count, 2);
|
||||
|
||||
assert.equal(service.isOpen(input), true);
|
||||
assert.equal(service.isOpen(otherInput), false);
|
||||
assert.equal(service.isOpen(sideBySideInput), true);
|
||||
assert.equal(service.isOpen({ resource: input.resource }), true);
|
||||
assert.equal(service.isOpen({ resource: otherInput.resource }), true);
|
||||
|
||||
await editor2?.group?.closeEditor(input);
|
||||
assert.equal(part.activeGroup.count, 1);
|
||||
|
||||
assert.equal(service.isOpen(input), false);
|
||||
assert.equal(service.isOpen(otherInput), false);
|
||||
assert.equal(service.isOpen(sideBySideInput), true);
|
||||
assert.equal(service.isOpen({ resource: input.resource }), false);
|
||||
assert.equal(service.isOpen({ resource: otherInput.resource }), true);
|
||||
|
||||
await editor1?.group?.closeEditor(sideBySideInput);
|
||||
|
||||
assert.equal(service.isOpen(input), false);
|
||||
assert.equal(service.isOpen(otherInput), false);
|
||||
assert.equal(service.isOpen(sideBySideInput), false);
|
||||
assert.equal(service.isOpen({ resource: input.resource }), false);
|
||||
assert.equal(service.isOpen({ resource: otherInput.resource }), false);
|
||||
|
||||
part.dispose();
|
||||
});
|
||||
|
||||
test('openEditors() / replaceEditors()', async () => {
|
||||
const [part, service] = createEditorService();
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
import * as assert from 'assert';
|
||||
import { EditorOptions, IEditorInputFactoryRegistry, Extensions as EditorExtensions } from 'vs/workbench/common/editor';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { workbenchInstantiationService, TestStorageService, TestFileEditorInput, registerTestEditor } from 'vs/workbench/test/browser/workbenchTestServices';
|
||||
import { workbenchInstantiationService, TestStorageService, TestFileEditorInput, registerTestEditor, TestEditorPart } from 'vs/workbench/test/browser/workbenchTestServices';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { EditorPart } from 'vs/workbench/browser/parts/editor/editorPart';
|
||||
import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
|
||||
|
@ -34,11 +34,11 @@ suite('EditorsObserver', function () {
|
|||
disposables = [];
|
||||
});
|
||||
|
||||
async function createPart(): Promise<EditorPart> {
|
||||
async function createPart(): Promise<TestEditorPart> {
|
||||
const instantiationService = workbenchInstantiationService();
|
||||
instantiationService.invokeFunction(accessor => Registry.as<IEditorInputFactoryRegistry>(EditorExtensions.EditorInputFactories).start(accessor));
|
||||
|
||||
const part = instantiationService.createInstance(EditorPart);
|
||||
const part = instantiationService.createInstance(TestEditorPart);
|
||||
part.create(document.createElement('div'));
|
||||
part.layout(400, 300);
|
||||
|
||||
|
@ -58,14 +58,14 @@ suite('EditorsObserver', function () {
|
|||
test('basics (single group)', async () => {
|
||||
const [part, observer] = await createEditorObserver();
|
||||
|
||||
let observerChangeListenerCalled = false;
|
||||
const listener = observer.onDidChange(() => {
|
||||
observerChangeListenerCalled = true;
|
||||
let onDidMostRecentlyActiveEditorsChangeCalled = false;
|
||||
const listener = observer.onDidMostRecentlyActiveEditorsChange(() => {
|
||||
onDidMostRecentlyActiveEditorsChangeCalled = true;
|
||||
});
|
||||
|
||||
let currentEditorsMRU = observer.editors;
|
||||
assert.equal(currentEditorsMRU.length, 0);
|
||||
assert.equal(observerChangeListenerCalled, false);
|
||||
assert.equal(onDidMostRecentlyActiveEditorsChangeCalled, false);
|
||||
|
||||
const input1 = new TestFileEditorInput(URI.parse('foo://bar1'), TEST_SERIALIZABLE_EDITOR_INPUT_ID);
|
||||
|
||||
|
@ -75,7 +75,8 @@ suite('EditorsObserver', function () {
|
|||
assert.equal(currentEditorsMRU.length, 1);
|
||||
assert.equal(currentEditorsMRU[0].groupId, part.activeGroup.id);
|
||||
assert.equal(currentEditorsMRU[0].editor, input1);
|
||||
assert.equal(observerChangeListenerCalled, true);
|
||||
assert.equal(onDidMostRecentlyActiveEditorsChangeCalled, true);
|
||||
assert.equal(observer.hasEditor(input1.resource), true);
|
||||
|
||||
const input2 = new TestFileEditorInput(URI.parse('foo://bar2'), TEST_SERIALIZABLE_EDITOR_INPUT_ID);
|
||||
const input3 = new TestFileEditorInput(URI.parse('foo://bar3'), TEST_SERIALIZABLE_EDITOR_INPUT_ID);
|
||||
|
@ -91,6 +92,8 @@ suite('EditorsObserver', function () {
|
|||
assert.equal(currentEditorsMRU[1].editor, input2);
|
||||
assert.equal(currentEditorsMRU[2].groupId, part.activeGroup.id);
|
||||
assert.equal(currentEditorsMRU[2].editor, input1);
|
||||
assert.equal(observer.hasEditor(input2.resource), true);
|
||||
assert.equal(observer.hasEditor(input3.resource), true);
|
||||
|
||||
await part.activeGroup.openEditor(input2, EditorOptions.create({ pinned: true }));
|
||||
|
||||
|
@ -102,8 +105,11 @@ suite('EditorsObserver', function () {
|
|||
assert.equal(currentEditorsMRU[1].editor, input3);
|
||||
assert.equal(currentEditorsMRU[2].groupId, part.activeGroup.id);
|
||||
assert.equal(currentEditorsMRU[2].editor, input1);
|
||||
assert.equal(observer.hasEditor(input1.resource), true);
|
||||
assert.equal(observer.hasEditor(input2.resource), true);
|
||||
assert.equal(observer.hasEditor(input3.resource), true);
|
||||
|
||||
observerChangeListenerCalled = false;
|
||||
onDidMostRecentlyActiveEditorsChangeCalled = false;
|
||||
await part.activeGroup.closeEditor(input1);
|
||||
|
||||
currentEditorsMRU = observer.editors;
|
||||
|
@ -112,11 +118,17 @@ suite('EditorsObserver', function () {
|
|||
assert.equal(currentEditorsMRU[0].editor, input2);
|
||||
assert.equal(currentEditorsMRU[1].groupId, part.activeGroup.id);
|
||||
assert.equal(currentEditorsMRU[1].editor, input3);
|
||||
assert.equal(observerChangeListenerCalled, true);
|
||||
assert.equal(onDidMostRecentlyActiveEditorsChangeCalled, true);
|
||||
assert.equal(observer.hasEditor(input1.resource), false);
|
||||
assert.equal(observer.hasEditor(input2.resource), true);
|
||||
assert.equal(observer.hasEditor(input3.resource), true);
|
||||
|
||||
await part.activeGroup.closeAllEditors();
|
||||
currentEditorsMRU = observer.editors;
|
||||
assert.equal(currentEditorsMRU.length, 0);
|
||||
assert.equal(observer.hasEditor(input1.resource), false);
|
||||
assert.equal(observer.hasEditor(input2.resource), false);
|
||||
assert.equal(observer.hasEditor(input3.resource), false);
|
||||
|
||||
part.dispose();
|
||||
listener.dispose();
|
||||
|
@ -143,6 +155,7 @@ suite('EditorsObserver', function () {
|
|||
assert.equal(currentEditorsMRU[0].editor, input1);
|
||||
assert.equal(currentEditorsMRU[1].groupId, rootGroup.id);
|
||||
assert.equal(currentEditorsMRU[1].editor, input1);
|
||||
assert.equal(observer.hasEditor(input1.resource), true);
|
||||
|
||||
await rootGroup.openEditor(input1, EditorOptions.create({ pinned: true, activation: EditorActivation.ACTIVATE }));
|
||||
|
||||
|
@ -152,6 +165,7 @@ suite('EditorsObserver', function () {
|
|||
assert.equal(currentEditorsMRU[0].editor, input1);
|
||||
assert.equal(currentEditorsMRU[1].groupId, sideGroup.id);
|
||||
assert.equal(currentEditorsMRU[1].editor, input1);
|
||||
assert.equal(observer.hasEditor(input1.resource), true);
|
||||
|
||||
// Opening an editor inactive should not change
|
||||
// the most recent editor, but rather put it behind
|
||||
|
@ -167,6 +181,8 @@ suite('EditorsObserver', function () {
|
|||
assert.equal(currentEditorsMRU[1].editor, input2);
|
||||
assert.equal(currentEditorsMRU[2].groupId, sideGroup.id);
|
||||
assert.equal(currentEditorsMRU[2].editor, input1);
|
||||
assert.equal(observer.hasEditor(input1.resource), true);
|
||||
assert.equal(observer.hasEditor(input2.resource), true);
|
||||
|
||||
await rootGroup.closeAllEditors();
|
||||
|
||||
|
@ -174,11 +190,15 @@ suite('EditorsObserver', function () {
|
|||
assert.equal(currentEditorsMRU.length, 1);
|
||||
assert.equal(currentEditorsMRU[0].groupId, sideGroup.id);
|
||||
assert.equal(currentEditorsMRU[0].editor, input1);
|
||||
assert.equal(observer.hasEditor(input1.resource), true);
|
||||
assert.equal(observer.hasEditor(input2.resource), false);
|
||||
|
||||
await sideGroup.closeAllEditors();
|
||||
|
||||
currentEditorsMRU = observer.editors;
|
||||
assert.equal(currentEditorsMRU.length, 0);
|
||||
assert.equal(observer.hasEditor(input1.resource), false);
|
||||
assert.equal(observer.hasEditor(input2.resource), false);
|
||||
|
||||
part.dispose();
|
||||
});
|
||||
|
@ -204,6 +224,9 @@ suite('EditorsObserver', function () {
|
|||
assert.equal(currentEditorsMRU[1].editor, input2);
|
||||
assert.equal(currentEditorsMRU[2].groupId, rootGroup.id);
|
||||
assert.equal(currentEditorsMRU[2].editor, input1);
|
||||
assert.equal(observer.hasEditor(input1.resource), true);
|
||||
assert.equal(observer.hasEditor(input2.resource), true);
|
||||
assert.equal(observer.hasEditor(input3.resource), true);
|
||||
|
||||
const copiedGroup = part.copyGroup(rootGroup, rootGroup, GroupDirection.RIGHT);
|
||||
copiedGroup.setActive(true);
|
||||
|
@ -222,6 +245,21 @@ suite('EditorsObserver', function () {
|
|||
assert.equal(currentEditorsMRU[4].editor, input2);
|
||||
assert.equal(currentEditorsMRU[5].groupId, rootGroup.id);
|
||||
assert.equal(currentEditorsMRU[5].editor, input1);
|
||||
assert.equal(observer.hasEditor(input1.resource), true);
|
||||
assert.equal(observer.hasEditor(input2.resource), true);
|
||||
assert.equal(observer.hasEditor(input3.resource), true);
|
||||
|
||||
await rootGroup.closeAllEditors();
|
||||
|
||||
assert.equal(observer.hasEditor(input1.resource), true);
|
||||
assert.equal(observer.hasEditor(input2.resource), true);
|
||||
assert.equal(observer.hasEditor(input3.resource), true);
|
||||
|
||||
await copiedGroup.closeAllEditors();
|
||||
|
||||
assert.equal(observer.hasEditor(input1.resource), false);
|
||||
assert.equal(observer.hasEditor(input2.resource), false);
|
||||
assert.equal(observer.hasEditor(input3.resource), false);
|
||||
|
||||
part.dispose();
|
||||
});
|
||||
|
@ -251,6 +289,9 @@ suite('EditorsObserver', function () {
|
|||
assert.equal(currentEditorsMRU[1].editor, input2);
|
||||
assert.equal(currentEditorsMRU[2].groupId, rootGroup.id);
|
||||
assert.equal(currentEditorsMRU[2].editor, input1);
|
||||
assert.equal(observer.hasEditor(input1.resource), true);
|
||||
assert.equal(observer.hasEditor(input2.resource), true);
|
||||
assert.equal(observer.hasEditor(input3.resource), true);
|
||||
|
||||
storage._onWillSaveState.fire({ reason: WillSaveStateReason.SHUTDOWN });
|
||||
|
||||
|
@ -265,7 +306,11 @@ suite('EditorsObserver', function () {
|
|||
assert.equal(currentEditorsMRU[1].editor, input2);
|
||||
assert.equal(currentEditorsMRU[2].groupId, rootGroup.id);
|
||||
assert.equal(currentEditorsMRU[2].editor, input1);
|
||||
assert.equal(observer.hasEditor(input1.resource), true);
|
||||
assert.equal(observer.hasEditor(input2.resource), true);
|
||||
assert.equal(observer.hasEditor(input3.resource), true);
|
||||
|
||||
part.clearState();
|
||||
part.dispose();
|
||||
});
|
||||
|
||||
|
@ -296,6 +341,9 @@ suite('EditorsObserver', function () {
|
|||
assert.equal(currentEditorsMRU[1].editor, input2);
|
||||
assert.equal(currentEditorsMRU[2].groupId, rootGroup.id);
|
||||
assert.equal(currentEditorsMRU[2].editor, input1);
|
||||
assert.equal(observer.hasEditor(input1.resource), true);
|
||||
assert.equal(observer.hasEditor(input2.resource), true);
|
||||
assert.equal(observer.hasEditor(input3.resource), true);
|
||||
|
||||
storage._onWillSaveState.fire({ reason: WillSaveStateReason.SHUTDOWN });
|
||||
|
||||
|
@ -310,7 +358,11 @@ suite('EditorsObserver', function () {
|
|||
assert.equal(currentEditorsMRU[1].editor, input2);
|
||||
assert.equal(currentEditorsMRU[2].groupId, rootGroup.id);
|
||||
assert.equal(currentEditorsMRU[2].editor, input1);
|
||||
assert.equal(restoredObserver.hasEditor(input1.resource), true);
|
||||
assert.equal(restoredObserver.hasEditor(input2.resource), true);
|
||||
assert.equal(restoredObserver.hasEditor(input3.resource), true);
|
||||
|
||||
part.clearState();
|
||||
part.dispose();
|
||||
});
|
||||
|
||||
|
@ -331,6 +383,7 @@ suite('EditorsObserver', function () {
|
|||
assert.equal(currentEditorsMRU.length, 1);
|
||||
assert.equal(currentEditorsMRU[0].groupId, rootGroup.id);
|
||||
assert.equal(currentEditorsMRU[0].editor, input1);
|
||||
assert.equal(observer.hasEditor(input1.resource), true);
|
||||
|
||||
storage._onWillSaveState.fire({ reason: WillSaveStateReason.SHUTDOWN });
|
||||
|
||||
|
@ -339,7 +392,9 @@ suite('EditorsObserver', function () {
|
|||
|
||||
currentEditorsMRU = restoredObserver.editors;
|
||||
assert.equal(currentEditorsMRU.length, 0);
|
||||
assert.equal(restoredObserver.hasEditor(input1.resource), false);
|
||||
|
||||
part.clearState();
|
||||
part.dispose();
|
||||
});
|
||||
|
||||
|
@ -368,6 +423,10 @@ suite('EditorsObserver', function () {
|
|||
assert.equal(rootGroup.isOpened(input2), true);
|
||||
assert.equal(rootGroup.isOpened(input3), true);
|
||||
assert.equal(rootGroup.isOpened(input4), true);
|
||||
assert.equal(observer.hasEditor(input1.resource), false);
|
||||
assert.equal(observer.hasEditor(input2.resource), true);
|
||||
assert.equal(observer.hasEditor(input3.resource), true);
|
||||
assert.equal(observer.hasEditor(input4.resource), true);
|
||||
|
||||
input2.setDirty();
|
||||
part.enforcePartOptions({ limit: { enabled: true, value: 1 } });
|
||||
|
@ -379,6 +438,10 @@ suite('EditorsObserver', function () {
|
|||
assert.equal(rootGroup.isOpened(input2), true); // dirty
|
||||
assert.equal(rootGroup.isOpened(input3), false);
|
||||
assert.equal(rootGroup.isOpened(input4), true);
|
||||
assert.equal(observer.hasEditor(input1.resource), false);
|
||||
assert.equal(observer.hasEditor(input2.resource), true);
|
||||
assert.equal(observer.hasEditor(input3.resource), false);
|
||||
assert.equal(observer.hasEditor(input4.resource), true);
|
||||
|
||||
const input5 = new TestFileEditorInput(URI.parse('foo://bar5'), TEST_EDITOR_INPUT_ID);
|
||||
await sideGroup.openEditor(input5, EditorOptions.create({ pinned: true }));
|
||||
|
@ -388,8 +451,12 @@ suite('EditorsObserver', function () {
|
|||
assert.equal(rootGroup.isOpened(input2), true); // dirty
|
||||
assert.equal(rootGroup.isOpened(input3), false);
|
||||
assert.equal(rootGroup.isOpened(input4), false);
|
||||
|
||||
assert.equal(sideGroup.isOpened(input5), true);
|
||||
assert.equal(observer.hasEditor(input1.resource), false);
|
||||
assert.equal(observer.hasEditor(input2.resource), true);
|
||||
assert.equal(observer.hasEditor(input3.resource), false);
|
||||
assert.equal(observer.hasEditor(input4.resource), false);
|
||||
assert.equal(observer.hasEditor(input5.resource), true);
|
||||
|
||||
observer.dispose();
|
||||
part.dispose();
|
||||
|
@ -415,11 +482,15 @@ suite('EditorsObserver', function () {
|
|||
await rootGroup.openEditor(input3, EditorOptions.create({ pinned: true }));
|
||||
await rootGroup.openEditor(input4, EditorOptions.create({ pinned: true }));
|
||||
|
||||
assert.equal(rootGroup.count, 3);
|
||||
assert.equal(rootGroup.count, 3); // 1 editor got closed due to our limit!
|
||||
assert.equal(rootGroup.isOpened(input1), false);
|
||||
assert.equal(rootGroup.isOpened(input2), true);
|
||||
assert.equal(rootGroup.isOpened(input3), true);
|
||||
assert.equal(rootGroup.isOpened(input4), true);
|
||||
assert.equal(observer.hasEditor(input1.resource), false);
|
||||
assert.equal(observer.hasEditor(input2.resource), true);
|
||||
assert.equal(observer.hasEditor(input3.resource), true);
|
||||
assert.equal(observer.hasEditor(input4.resource), true);
|
||||
|
||||
await sideGroup.openEditor(input1, EditorOptions.create({ pinned: true }));
|
||||
await sideGroup.openEditor(input2, EditorOptions.create({ pinned: true }));
|
||||
|
@ -431,6 +502,10 @@ suite('EditorsObserver', function () {
|
|||
assert.equal(sideGroup.isOpened(input2), true);
|
||||
assert.equal(sideGroup.isOpened(input3), true);
|
||||
assert.equal(sideGroup.isOpened(input4), true);
|
||||
assert.equal(observer.hasEditor(input1.resource), false);
|
||||
assert.equal(observer.hasEditor(input2.resource), true);
|
||||
assert.equal(observer.hasEditor(input3.resource), true);
|
||||
assert.equal(observer.hasEditor(input4.resource), true);
|
||||
|
||||
part.enforcePartOptions({ limit: { enabled: true, value: 1, perEditorGroup: true } });
|
||||
|
||||
|
@ -448,6 +523,11 @@ suite('EditorsObserver', function () {
|
|||
assert.equal(sideGroup.isOpened(input3), false);
|
||||
assert.equal(sideGroup.isOpened(input4), true);
|
||||
|
||||
assert.equal(observer.hasEditor(input1.resource), false);
|
||||
assert.equal(observer.hasEditor(input2.resource), false);
|
||||
assert.equal(observer.hasEditor(input3.resource), false);
|
||||
assert.equal(observer.hasEditor(input4.resource), true);
|
||||
|
||||
observer.dispose();
|
||||
part.dispose();
|
||||
});
|
||||
|
|
|
@ -390,7 +390,7 @@ export class SearchService extends Disposable implements ISearchService {
|
|||
}
|
||||
|
||||
// Skip files that are not opened as text file
|
||||
if (!this.editorService.isOpen(this.editorService.createInput({ resource, forceFile: resource.scheme !== Schemas.untitled, forceUntitled: resource.scheme === Schemas.untitled }))) {
|
||||
if (!this.editorService.isOpen({ resource })) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -623,7 +623,7 @@ export class TestEditorService implements EditorServiceImpl {
|
|||
return [this.editorGroupService.activeGroup, editor as EditorInput, undefined];
|
||||
}
|
||||
openEditors(_editors: any, _group?: any): Promise<IEditor[]> { throw new Error('not implemented'); }
|
||||
isOpen(_editor: IEditorInput): boolean { return false; }
|
||||
isOpen(_editor: IEditorInput | IResourceInput): boolean { return false; }
|
||||
replaceEditors(_editors: any, _group: any) { return Promise.resolve(undefined); }
|
||||
invokeWithinEditorContext<T>(fn: (accessor: ServicesAccessor) => T): T { throw new Error('not implemented'); }
|
||||
createInput(_input: IResourceInput | IUntitledTextResourceInput | IResourceDiffInput | IResourceSideBySideInput): EditorInput { throw new Error('not implemented'); }
|
||||
|
|
Loading…
Reference in a new issue