Skip to content

Commit 1a7cec1

Browse files
author
Benjamin Pasero
committed
editor history - implement and use history of most recently used editors across all groups
1 parent 59ddc32 commit 1a7cec1

21 files changed

Lines changed: 1511 additions & 356 deletions

File tree

src/vs/base/common/map.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -526,6 +526,14 @@ export class LinkedMap<K, V> {
526526
return this._size;
527527
}
528528

529+
get first(): V | undefined {
530+
return this._head?.value;
531+
}
532+
533+
get last(): V | undefined {
534+
return this._tail?.value;
535+
}
536+
529537
has(key: K): boolean {
530538
return this._map.has(key);
531539
}

src/vs/base/test/common/map.test.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ suite('Map', () => {
1616
map.set('bk', 'bv');
1717
assert.deepStrictEqual(map.keys(), ['ak', 'bk']);
1818
assert.deepStrictEqual(map.values(), ['av', 'bv']);
19+
assert.equal(map.first, 'av');
20+
assert.equal(map.last, 'bv');
1921
});
2022

2123
test('LinkedMap - Touch Old one', () => {

src/vs/workbench/browser/parts/editor/editor.contribution.ts

Lines changed: 113 additions & 46 deletions
Large diffs are not rendered by default.

src/vs/workbench/browser/parts/editor/editorActions.ts

Lines changed: 124 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import { IResourceInput } from 'vs/platform/editor/common/editor';
1515
import { IHistoryService } from 'vs/workbench/services/history/common/history';
1616
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
1717
import { ICommandService } from 'vs/platform/commands/common/commands';
18-
import { CLOSE_EDITOR_COMMAND_ID, NAVIGATE_ALL_EDITORS_GROUP_PREFIX, MOVE_ACTIVE_EDITOR_COMMAND_ID, NAVIGATE_IN_ACTIVE_GROUP_PREFIX, ActiveEditorMoveArguments, SPLIT_EDITOR_LEFT, SPLIT_EDITOR_RIGHT, SPLIT_EDITOR_UP, SPLIT_EDITOR_DOWN, splitEditor, LAYOUT_EDITOR_GROUPS_COMMAND_ID, mergeAllGroups } from 'vs/workbench/browser/parts/editor/editorCommands';
18+
import { CLOSE_EDITOR_COMMAND_ID, NAVIGATE_ALL_EDITORS_BY_APPEARANCE_PREFIX, MOVE_ACTIVE_EDITOR_COMMAND_ID, NAVIGATE_IN_ACTIVE_GROUP_BY_MOST_RECENTLY_USED_PREFIX, ActiveEditorMoveArguments, SPLIT_EDITOR_LEFT, SPLIT_EDITOR_RIGHT, SPLIT_EDITOR_UP, SPLIT_EDITOR_DOWN, splitEditor, LAYOUT_EDITOR_GROUPS_COMMAND_ID, mergeAllGroups, NAVIGATE_ALL_EDITORS_BY_MOST_RECENTLY_USED_PREFIX } from 'vs/workbench/browser/parts/editor/editorCommands';
1919
import { IEditorGroupsService, IEditorGroup, GroupsArrangement, EditorsOrder, GroupLocation, GroupDirection, preferredSideBySideGroupDirection, IFindGroupScope, GroupOrientation, EditorGroupLayout, GroupsOrder } from 'vs/workbench/services/editor/common/editorGroupsService';
2020
import { IEditorService, SIDE_GROUP } from 'vs/workbench/services/editor/common/editorService';
2121
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
@@ -1258,84 +1258,133 @@ export class ClearRecentFilesAction extends Action {
12581258
}
12591259
}
12601260

1261-
export class ShowEditorsInActiveGroupAction extends QuickOpenAction {
1261+
export class ShowEditorsInActiveGroupByMostRecentlyUsedAction extends QuickOpenAction {
12621262

12631263
static readonly ID = 'workbench.action.showEditorsInActiveGroup';
1264-
static readonly LABEL = nls.localize('showEditorsInActiveGroup', "Show Editors in Active Group");
1264+
static readonly LABEL = nls.localize('showEditorsInActiveGroup', "Show Editors in Active Group By Most Recently Used");
12651265

12661266
constructor(
12671267
actionId: string,
12681268
actionLabel: string,
12691269
@IQuickOpenService quickOpenService: IQuickOpenService
12701270
) {
1271-
super(actionId, actionLabel, NAVIGATE_IN_ACTIVE_GROUP_PREFIX, quickOpenService);
1271+
super(actionId, actionLabel, NAVIGATE_IN_ACTIVE_GROUP_BY_MOST_RECENTLY_USED_PREFIX, quickOpenService);
12721272
}
12731273
}
12741274

1275-
export class ShowAllEditorsAction extends QuickOpenAction {
1275+
export class ShowAllEditorsByAppearanceAction extends QuickOpenAction {
12761276

12771277
static readonly ID = 'workbench.action.showAllEditors';
1278-
static readonly LABEL = nls.localize('showAllEditors', "Show All Editors");
1278+
static readonly LABEL = nls.localize('showAllEditors', "Show All Editors By Appearance");
12791279

1280-
constructor(actionId: string, actionLabel: string, @IQuickOpenService quickOpenService: IQuickOpenService) {
1281-
super(actionId, actionLabel, NAVIGATE_ALL_EDITORS_GROUP_PREFIX, quickOpenService);
1280+
constructor(
1281+
actionId: string,
1282+
actionLabel: string,
1283+
@IQuickOpenService quickOpenService: IQuickOpenService
1284+
) {
1285+
super(actionId, actionLabel, NAVIGATE_ALL_EDITORS_BY_APPEARANCE_PREFIX, quickOpenService);
12821286
}
12831287
}
12841288

1285-
export class BaseQuickOpenEditorInGroupAction extends Action {
1289+
export class ShowAllEditorsByMostRecentlyUsedAction extends QuickOpenAction {
1290+
1291+
static readonly ID = 'workbench.action.showAllEditorsByMostRecentlyUsed';
1292+
static readonly LABEL = nls.localize('showAllEditorsByMostRecentlyUsed', "Show All Editors By Most Recently Used");
1293+
1294+
constructor(
1295+
actionId: string,
1296+
actionLabel: string,
1297+
@IQuickOpenService quickOpenService: IQuickOpenService
1298+
) {
1299+
super(actionId, actionLabel, NAVIGATE_ALL_EDITORS_BY_MOST_RECENTLY_USED_PREFIX, quickOpenService);
1300+
}
1301+
}
1302+
1303+
export class BaseQuickOpenEditorAction extends Action {
12861304

12871305
constructor(
12881306
id: string,
12891307
label: string,
1308+
private prefix: string,
12901309
@IQuickOpenService private readonly quickOpenService: IQuickOpenService,
12911310
@IKeybindingService private readonly keybindingService: IKeybindingService
12921311
) {
12931312
super(id, label);
12941313
}
12951314

12961315
run(): Promise<any> {
1297-
const keys = this.keybindingService.lookupKeybindings(this.id);
1316+
const keybindings = this.keybindingService.lookupKeybindings(this.id);
12981317

1299-
this.quickOpenService.show(NAVIGATE_IN_ACTIVE_GROUP_PREFIX, { quickNavigateConfiguration: { keybindings: keys } });
1318+
this.quickOpenService.show(this.prefix, { quickNavigateConfiguration: { keybindings } });
13001319

13011320
return Promise.resolve(true);
13021321
}
13031322
}
13041323

1305-
export class OpenPreviousRecentlyUsedEditorInGroupAction extends BaseQuickOpenEditorInGroupAction {
1324+
export class QuickOpenPreviousRecentlyUsedEditorAction extends BaseQuickOpenEditorAction {
13061325

1307-
static readonly ID = 'workbench.action.openPreviousRecentlyUsedEditorInGroup';
1308-
static readonly LABEL = nls.localize('openPreviousRecentlyUsedEditorInGroup', "Open Previous Recently Used Editor in Group");
1326+
static readonly ID = 'workbench.action.quickOpenPreviousRecentlyUsedEditor';
1327+
static readonly LABEL = nls.localize('quickOpenPreviousRecentlyUsedEditor', "Quick Open Previous Recently Used Editor");
13091328

13101329
constructor(
13111330
id: string,
13121331
label: string,
13131332
@IQuickOpenService quickOpenService: IQuickOpenService,
13141333
@IKeybindingService keybindingService: IKeybindingService
13151334
) {
1316-
super(id, label, quickOpenService, keybindingService);
1335+
super(id, label, NAVIGATE_ALL_EDITORS_BY_MOST_RECENTLY_USED_PREFIX, quickOpenService, keybindingService);
13171336
}
13181337
}
13191338

1320-
export class OpenNextRecentlyUsedEditorInGroupAction extends BaseQuickOpenEditorInGroupAction {
1339+
export class QuickOpenNextRecentlyUsedEditorAction extends BaseQuickOpenEditorAction {
13211340

1322-
static readonly ID = 'workbench.action.openNextRecentlyUsedEditorInGroup';
1323-
static readonly LABEL = nls.localize('openNextRecentlyUsedEditorInGroup', "Open Next Recently Used Editor in Group");
1341+
static readonly ID = 'workbench.action.quickOpenNextRecentlyUsedEditor';
1342+
static readonly LABEL = nls.localize('quickOpenNextRecentlyUsedEditor', "Quick Open Next Recently Used Editor");
1343+
1344+
constructor(
1345+
id: string,
1346+
label: string,
1347+
@IQuickOpenService quickOpenService: IQuickOpenService,
1348+
@IKeybindingService keybindingService: IKeybindingService
1349+
) {
1350+
super(id, label, NAVIGATE_ALL_EDITORS_BY_MOST_RECENTLY_USED_PREFIX, quickOpenService, keybindingService);
1351+
}
1352+
}
1353+
1354+
export class QuickOpenPreviousRecentlyUsedEditorInGroupAction extends BaseQuickOpenEditorAction {
1355+
1356+
static readonly ID = 'workbench.action.quickOpenPreviousRecentlyUsedEditorInGroup';
1357+
static readonly LABEL = nls.localize('quickOpenPreviousRecentlyUsedEditorInGroup', "Quick Open Previous Recently Used Editor in Group");
13241358

13251359
constructor(
13261360
id: string,
13271361
label: string,
13281362
@IQuickOpenService quickOpenService: IQuickOpenService,
13291363
@IKeybindingService keybindingService: IKeybindingService
13301364
) {
1331-
super(id, label, quickOpenService, keybindingService);
1365+
super(id, label, NAVIGATE_IN_ACTIVE_GROUP_BY_MOST_RECENTLY_USED_PREFIX, quickOpenService, keybindingService);
13321366
}
13331367
}
13341368

1335-
export class OpenPreviousEditorFromHistoryAction extends Action {
1369+
export class QuickOpenNextRecentlyUsedEditorInGroupAction extends BaseQuickOpenEditorAction {
1370+
1371+
static readonly ID = 'workbench.action.quickOpenNextRecentlyUsedEditorInGroup';
1372+
static readonly LABEL = nls.localize('quickOpenNextRecentlyUsedEditorInGroup', "Quick Open Next Recently Used Editor in Group");
1373+
1374+
constructor(
1375+
id: string,
1376+
label: string,
1377+
@IQuickOpenService quickOpenService: IQuickOpenService,
1378+
@IKeybindingService keybindingService: IKeybindingService
1379+
) {
1380+
super(id, label, NAVIGATE_IN_ACTIVE_GROUP_BY_MOST_RECENTLY_USED_PREFIX, quickOpenService, keybindingService);
1381+
}
1382+
}
1383+
1384+
export class QuickOpenPreviousEditorFromHistoryAction extends Action {
13361385

13371386
static readonly ID = 'workbench.action.openPreviousEditorFromHistory';
1338-
static readonly LABEL = nls.localize('navigateEditorHistoryByInput', "Open Previous Editor from History");
1387+
static readonly LABEL = nls.localize('navigateEditorHistoryByInput', "Quick Open Previous Editor from History");
13391388

13401389
constructor(
13411390
id: string,
@@ -1360,12 +1409,16 @@ export class OpenNextRecentlyUsedEditorAction extends Action {
13601409
static readonly ID = 'workbench.action.openNextRecentlyUsedEditor';
13611410
static readonly LABEL = nls.localize('openNextRecentlyUsedEditor', "Open Next Recently Used Editor");
13621411

1363-
constructor(id: string, label: string, @IHistoryService private readonly historyService: IHistoryService) {
1412+
constructor(
1413+
id: string,
1414+
label: string,
1415+
@IHistoryService private readonly historyService: IHistoryService
1416+
) {
13641417
super(id, label);
13651418
}
13661419

13671420
run(): Promise<any> {
1368-
this.historyService.forward(true);
1421+
this.historyService.openNextRecentlyUsedEditor();
13691422

13701423
return Promise.resolve();
13711424
}
@@ -1376,12 +1429,58 @@ export class OpenPreviousRecentlyUsedEditorAction extends Action {
13761429
static readonly ID = 'workbench.action.openPreviousRecentlyUsedEditor';
13771430
static readonly LABEL = nls.localize('openPreviousRecentlyUsedEditor', "Open Previous Recently Used Editor");
13781431

1379-
constructor(id: string, label: string, @IHistoryService private readonly historyService: IHistoryService) {
1432+
constructor(
1433+
id: string,
1434+
label: string,
1435+
@IHistoryService private readonly historyService: IHistoryService
1436+
) {
1437+
super(id, label);
1438+
}
1439+
1440+
run(): Promise<any> {
1441+
this.historyService.openPreviouslyUsedEditor();
1442+
1443+
return Promise.resolve();
1444+
}
1445+
}
1446+
1447+
export class OpenNextRecentlyUsedEditorInGroupAction extends Action {
1448+
1449+
static readonly ID = 'workbench.action.openNextRecentlyUsedEditorInGroup';
1450+
static readonly LABEL = nls.localize('openNextRecentlyUsedEditorInGroup', "Open Next Recently Used Editor In Group");
1451+
1452+
constructor(
1453+
id: string,
1454+
label: string,
1455+
@IHistoryService private readonly historyService: IHistoryService,
1456+
@IEditorGroupsService private readonly editorGroupsService: IEditorGroupsService
1457+
) {
1458+
super(id, label);
1459+
}
1460+
1461+
run(): Promise<any> {
1462+
this.historyService.openNextRecentlyUsedEditor(this.editorGroupsService.activeGroup.id);
1463+
1464+
return Promise.resolve();
1465+
}
1466+
}
1467+
1468+
export class OpenPreviousRecentlyUsedEditorInGroupAction extends Action {
1469+
1470+
static readonly ID = 'workbench.action.openPreviousRecentlyUsedEditorInGroup';
1471+
static readonly LABEL = nls.localize('openPreviousRecentlyUsedEditorInGroup', "Open Previous Recently Used Editor In Group");
1472+
1473+
constructor(
1474+
id: string,
1475+
label: string,
1476+
@IHistoryService private readonly historyService: IHistoryService,
1477+
@IEditorGroupsService private readonly editorGroupsService: IEditorGroupsService
1478+
) {
13801479
super(id, label);
13811480
}
13821481

13831482
run(): Promise<any> {
1384-
this.historyService.back(true);
1483+
this.historyService.openPreviouslyUsedEditor(this.editorGroupsService.activeGroup.id);
13851484

13861485
return Promise.resolve();
13871486
}

src/vs/workbench/browser/parts/editor/editorCommands.ts

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,9 @@ export const SPLIT_EDITOR_DOWN = 'workbench.action.splitEditorDown';
4646
export const SPLIT_EDITOR_LEFT = 'workbench.action.splitEditorLeft';
4747
export const SPLIT_EDITOR_RIGHT = 'workbench.action.splitEditorRight';
4848

49-
export const NAVIGATE_ALL_EDITORS_GROUP_PREFIX = 'edt ';
50-
export const NAVIGATE_IN_ACTIVE_GROUP_PREFIX = 'edt active ';
49+
export const NAVIGATE_ALL_EDITORS_BY_APPEARANCE_PREFIX = 'edt ';
50+
export const NAVIGATE_ALL_EDITORS_BY_MOST_RECENTLY_USED_PREFIX = 'edt mru ';
51+
export const NAVIGATE_IN_ACTIVE_GROUP_BY_MOST_RECENTLY_USED_PREFIX = 'edt active ';
5152

5253
export const OPEN_EDITOR_AT_INDEX_COMMAND_ID = 'workbench.action.openEditorAtIndex';
5354

@@ -665,10 +666,6 @@ function registerCloseEditorCommands() {
665666
const editorGroupService = accessor.get(IEditorGroupsService);
666667
const quickOpenService = accessor.get(IQuickOpenService);
667668

668-
if (editorGroupService.count <= 1) {
669-
return quickOpenService.show(NAVIGATE_ALL_EDITORS_GROUP_PREFIX);
670-
}
671-
672669
const commandsContext = getCommandsContext(resourceOrContext, context);
673670
if (commandsContext && typeof commandsContext.groupId === 'number') {
674671
const group = editorGroupService.getGroup(commandsContext.groupId);
@@ -677,7 +674,7 @@ function registerCloseEditorCommands() {
677674
}
678675
}
679676

680-
return quickOpenService.show(NAVIGATE_IN_ACTIVE_GROUP_PREFIX);
677+
return quickOpenService.show(NAVIGATE_IN_ACTIVE_GROUP_BY_MOST_RECENTLY_USED_PREFIX);
681678
}
682679
});
683680

src/vs/workbench/browser/parts/editor/editorGroupView.ts

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ import { hash } from 'vs/base/common/hash';
4949
import { guessMimeTypes } from 'vs/base/common/mime';
5050
import { extname } from 'vs/base/common/resources';
5151
import { Schemas } from 'vs/base/common/network';
52-
import { EditorActivation, EditorOpenContext } from 'vs/platform/editor/common/editor';
52+
import { EditorActivation, EditorOpenContext, IResourceInput } from 'vs/platform/editor/common/editor';
5353
import { IDialogService, IFileDialogService, ConfirmResult } from 'vs/platform/dialogs/common/dialogs';
5454
import { ILogService } from 'vs/platform/log/common/log';
5555

@@ -766,7 +766,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
766766
return this._group.indexOf(editor);
767767
}
768768

769-
isOpened(editor: EditorInput): boolean {
769+
isOpened(editor: EditorInput | IResourceInput): boolean {
770770
return this._group.contains(editor);
771771
}
772772

@@ -783,14 +783,16 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
783783
this._onDidFocus.fire();
784784
}
785785

786-
pinEditor(editor: EditorInput | undefined = this.activeEditor || undefined): void {
787-
if (editor && !this._group.isPinned(editor)) {
786+
pinEditor(candidate: EditorInput | undefined = this.activeEditor || undefined): void {
787+
if (candidate && !this._group.isPinned(candidate)) {
788788

789789
// Update model
790-
this._group.pin(editor);
790+
const editor = this._group.pin(candidate);
791791

792792
// Forward to title control
793-
this.titleAreaControl.pinEditor(editor);
793+
if (editor) {
794+
this.titleAreaControl.pinEditor(editor);
795+
}
794796
}
795797
}
796798

src/vs/workbench/browser/parts/editor/editorPart.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@ export class EditorPart extends Part implements IEditorGroupsService, IEditorGro
240240
const mostRecentActive = coalesce(this.mostRecentActiveGroups.map(groupId => this.getGroup(groupId)));
241241

242242
// there can be groups that got never active, even though they exist. in this case
243-
// make sure to ust append them at the end so that all groups are returned properly
243+
// make sure to just append them at the end so that all groups are returned properly
244244
return distinct([...mostRecentActive, ...this.groups]);
245245

246246
case GroupsOrder.GRID_APPEARANCE:
@@ -544,7 +544,7 @@ export class EditorPart extends Part implements IEditorGroupsService, IEditorGro
544544
this.groupViews.set(groupView.id, groupView);
545545

546546
// Track focus
547-
let groupDisposables = new DisposableStore();
547+
const groupDisposables = new DisposableStore();
548548
groupDisposables.add(groupView.onDidFocus(() => {
549549
this.doSetGroupActive(groupView);
550550
}));

0 commit comments

Comments
 (0)