Skip to content

Commit

Permalink
pinned tabs - closing pinned tab should open next non-pinned
Browse files Browse the repository at this point in the history
  • Loading branch information
bpasero committed Sep 10, 2020
1 parent 25081cd commit 6173cf8
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 22 deletions.
31 changes: 30 additions & 1 deletion src/vs/workbench/browser/parts/editor/editorCommands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -478,15 +478,44 @@ function registerSplitEditorCommands() {

function registerCloseEditorCommands() {

// A special handler for "Close Editor" depending on context
// - keybindining: do not close sticky editors, rather open the next non-sticky editor
// - menu: always close editor, even sticky ones
function closeEditorHandler(accessor: ServicesAccessor, forceCloseStickyEditors: boolean, resourceOrContext?: URI | IEditorCommandsContext, context?: IEditorCommandsContext): Promise<unknown> {
const editorGroupsService = accessor.get(IEditorGroupsService);
const editorService = accessor.get(IEditorService);

let keepStickyEditors = true;
if (forceCloseStickyEditors) {
keepStickyEditors = false; // explicitly close sticky editors
} else if (resourceOrContext) {
} else if (resourceOrContext || context) {
keepStickyEditors = false; // we have a context, as such this command was used e.g. from the tab context menu
}

// Without context: skip over sticky editor and select next if active editor is sticky
if (keepStickyEditors && !resourceOrContext && !context) {
const activeGroup = editorGroupsService.activeGroup;
const activeEditor = activeGroup.activeEditor;

if (activeEditor && activeGroup.isSticky(activeEditor)) {

// Open next recently active in same group
const nextNonStickyEditorInGroup = activeGroup.getEditors(EditorsOrder.MOST_RECENTLY_ACTIVE, { excludeSticky: true })[0];
if (nextNonStickyEditorInGroup) {
return activeGroup.openEditor(nextNonStickyEditorInGroup);
}

// Open next recently active across all groups
const nextNonStickyEditorInAllGroups = editorService.getEditors(EditorsOrder.MOST_RECENTLY_ACTIVE, { excludeSticky: true })[0];
if (nextNonStickyEditorInAllGroups) {
return Promise.resolve(editorGroupsService.getGroup(nextNonStickyEditorInAllGroups.groupId)?.openEditor(nextNonStickyEditorInAllGroups.editor));
}
}
}

// With context: proceed to close editors as instructed
const { editors, groups } = getEditorsContext(accessor, resourceOrContext, context);

return Promise.all(groups.map(async group => {
if (group) {
const editorsToClose = coalesce(editors
Expand Down
37 changes: 18 additions & 19 deletions src/vs/workbench/services/editor/browser/editorService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -436,20 +436,27 @@ export class EditorService extends Disposable implements EditorServiceImpl {
return this.getEditors(EditorsOrder.SEQUENTIAL).map(({ editor }) => editor);
}

getEditors(order: EditorsOrder.MOST_RECENTLY_ACTIVE): ReadonlyArray<IEditorIdentifier>;
getEditors(order: EditorsOrder.SEQUENTIAL, options?: { excludeSticky?: boolean }): ReadonlyArray<IEditorIdentifier>;
getEditors(order: EditorsOrder, options?: { excludeSticky?: boolean }): ReadonlyArray<IEditorIdentifier> {
if (order === EditorsOrder.MOST_RECENTLY_ACTIVE) {
return this.editorsObserver.editors;
}
switch (order) {

const editors: IEditorIdentifier[] = [];
// MRU
case EditorsOrder.MOST_RECENTLY_ACTIVE:
if (options?.excludeSticky) {
return this.editorsObserver.editors.filter(({ groupId, editor }) => !this.editorGroupService.getGroup(groupId)?.isSticky(editor));
}

this.editorGroupService.getGroups(GroupsOrder.GRID_APPEARANCE).forEach(group => {
editors.push(...group.getEditors(EditorsOrder.SEQUENTIAL, options).map(editor => ({ editor, groupId: group.id })));
});
return this.editorsObserver.editors;

return editors;
// Sequential
case EditorsOrder.SEQUENTIAL:
const editors: IEditorIdentifier[] = [];

this.editorGroupService.getGroups(GroupsOrder.GRID_APPEARANCE).forEach(group => {
editors.push(...group.getEditors(EditorsOrder.SEQUENTIAL, options).map(editor => ({ editor, groupId: group.id })));
});

return editors;
}
}

get activeEditor(): IEditorInput | undefined {
Expand Down Expand Up @@ -1323,15 +1330,7 @@ export class DelegatingEditorService implements IEditorService {
get editors(): ReadonlyArray<IEditorInput> { return this.editorService.editors; }
get count(): number { return this.editorService.count; }

getEditors(order: EditorsOrder.MOST_RECENTLY_ACTIVE): ReadonlyArray<IEditorIdentifier>;
getEditors(order: EditorsOrder.SEQUENTIAL, options?: { excludeSticky?: boolean }): ReadonlyArray<IEditorIdentifier>;
getEditors(order: EditorsOrder, options?: { excludeSticky?: boolean }): ReadonlyArray<IEditorIdentifier> {
if (order === EditorsOrder.MOST_RECENTLY_ACTIVE) {
return this.editorService.getEditors(order);
}

return this.editorService.getEditors(order, options);
}
getEditors(order: EditorsOrder, options?: { excludeSticky?: boolean }): ReadonlyArray<IEditorIdentifier> { return this.editorService.getEditors(order, options); }

openEditors(editors: IEditorInputWithOptions[], group?: OpenInEditorGroup): Promise<IEditorPane[]>;
openEditors(editors: IResourceEditorInputType[], group?: OpenInEditorGroup): Promise<IEditorPane[]>;
Expand Down
4 changes: 2 additions & 2 deletions src/vs/workbench/services/editor/common/editorService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -175,9 +175,9 @@ export interface IEditorService {
* identifier.
*
* @param order the order of the editors to use
* @param options wether to exclude sticky editors or not
*/
getEditors(order: EditorsOrder.MOST_RECENTLY_ACTIVE): ReadonlyArray<IEditorIdentifier>;
getEditors(order: EditorsOrder.SEQUENTIAL, options?: { excludeSticky?: boolean }): ReadonlyArray<IEditorIdentifier>;
getEditors(order: EditorsOrder, options?: { excludeSticky?: boolean }): ReadonlyArray<IEditorIdentifier>;

/**
* Open an editor in an editor group.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,11 @@ suite('EditorService', () => {
assert.equal(input, sequentialEditorsExcludingSticky[0].editor);
assert.equal(otherInput, sequentialEditorsExcludingSticky[1].editor);

const mruEditorsExcludingSticky = service.getEditors(EditorsOrder.MOST_RECENTLY_ACTIVE, { excludeSticky: true });
assert.equal(mruEditorsExcludingSticky.length, 2);
assert.equal(input, sequentialEditorsExcludingSticky[0].editor);
assert.equal(otherInput, sequentialEditorsExcludingSticky[1].editor);

activeEditorChangeListener.dispose();
visibleEditorChangeListener.dispose();
didCloseEditorListener.dispose();
Expand Down

0 comments on commit 6173cf8

Please sign in to comment.