33 * Licensed under the MIT License. See License.txt in the project root for license information.
44 *--------------------------------------------------------------------------------------------*/
55
6- import { IEditorInput , IEditorInputFactoryRegistry , IEditorIdentifier , GroupIdentifier , Extensions , IEditorPartOptionsChangeEvent , EditorsOrder } from 'vs/workbench/common/editor' ;
6+ import { IEditorInput , IEditorInputFactoryRegistry , IEditorIdentifier , GroupIdentifier , Extensions , IEditorPartOptionsChangeEvent , EditorsOrder , toResource , SideBySideEditor } from 'vs/workbench/common/editor' ;
77import { dispose , Disposable , DisposableStore } from 'vs/base/common/lifecycle' ;
88import { IStorageService , StorageScope } from 'vs/platform/storage/common/storage' ;
99import { Registry } from 'vs/platform/registry/common/platform' ;
1010import { Event , Emitter } from 'vs/base/common/event' ;
1111import { IEditorGroupsService , IEditorGroup , GroupChangeKind , GroupsOrder } from 'vs/workbench/services/editor/common/editorGroupsService' ;
1212import { coalesce } from 'vs/base/common/arrays' ;
13- import { LinkedMap , Touch } from 'vs/base/common/map' ;
13+ import { LinkedMap , Touch , ResourceMap } from 'vs/base/common/map' ;
1414import { equals } from 'vs/base/common/objects' ;
15+ import { URI } from 'vs/base/common/uri' ;
1516
1617interface ISerializedEditorsList {
1718 entries : ISerializedEditorIdentifier [ ] ;
@@ -37,9 +38,10 @@ export class EditorsObserver extends Disposable {
3738
3839 private readonly keyMap = new Map < GroupIdentifier , Map < IEditorInput , IEditorIdentifier > > ( ) ;
3940 private readonly mostRecentEditorsMap = new LinkedMap < IEditorIdentifier , IEditorIdentifier > ( ) ;
41+ private readonly editorResourcesMap = new ResourceMap < number > ( ) ;
4042
41- private readonly _onDidChange = this . _register ( new Emitter < void > ( ) ) ;
42- readonly onDidChange = this . _onDidChange . event ;
43+ private readonly _onDidMostRecentlyActiveEditorsChange = this . _register ( new Emitter < void > ( ) ) ;
44+ readonly onDidMostRecentlyActiveEditorsChange = this . _onDidMostRecentlyActiveEditorsChange . event ;
4345
4446 get count ( ) : number {
4547 return this . mostRecentEditorsMap . size ;
@@ -49,6 +51,10 @@ export class EditorsObserver extends Disposable {
4951 return this . mostRecentEditorsMap . values ( ) ;
5052 }
5153
54+ hasEditor ( resource : URI ) : boolean {
55+ return this . editorResourcesMap . has ( resource ) ;
56+ }
57+
5258 constructor (
5359 @IEditorGroupsService private editorGroupsService : IEditorGroupsService ,
5460 @IStorageService private readonly storageService : IStorageService
@@ -72,12 +78,12 @@ export class EditorsObserver extends Disposable {
7278 // of the new group into our list in LRU order
7379 const groupEditorsMru = group . getEditors ( EditorsOrder . MOST_RECENTLY_ACTIVE ) ;
7480 for ( let i = groupEditorsMru . length - 1 ; i >= 0 ; i -- ) {
75- this . addMostRecentEditor ( group , groupEditorsMru [ i ] , false /* is not active */ ) ;
81+ this . addMostRecentEditor ( group , groupEditorsMru [ i ] , false /* is not active */ , true /* is new */ ) ;
7682 }
7783
7884 // Make sure that active editor is put as first if group is active
7985 if ( this . editorGroupsService . activeGroup === group && group . activeEditor ) {
80- this . addMostRecentEditor ( group , group . activeEditor , true /* is active */ ) ;
86+ this . addMostRecentEditor ( group , group . activeEditor , true /* is active */ , false /* already added before */ ) ;
8187 }
8288
8389 // Group Listeners
@@ -92,7 +98,7 @@ export class EditorsObserver extends Disposable {
9298 // Group gets active: put active editor as most recent
9399 case GroupChangeKind . GROUP_ACTIVE : {
94100 if ( this . editorGroupsService . activeGroup === group && group . activeEditor ) {
95- this . addMostRecentEditor ( group , group . activeEditor , true /* is active */ ) ;
101+ this . addMostRecentEditor ( group , group . activeEditor , true /* is active */ , false /* editor already opened */ ) ;
96102 }
97103
98104 break ;
@@ -102,7 +108,7 @@ export class EditorsObserver extends Disposable {
102108 // if group is active, otherwise second most recent
103109 case GroupChangeKind . EDITOR_ACTIVE : {
104110 if ( e . editor ) {
105- this . addMostRecentEditor ( group , e . editor , this . editorGroupsService . activeGroup === group ) ;
111+ this . addMostRecentEditor ( group , e . editor , this . editorGroupsService . activeGroup === group , false /* editor already opened */ ) ;
106112 }
107113
108114 break ;
@@ -114,7 +120,7 @@ export class EditorsObserver extends Disposable {
114120 // start to close oldest ones if needed.
115121 case GroupChangeKind . EDITOR_OPEN : {
116122 if ( e . editor ) {
117- this . addMostRecentEditor ( group , e . editor , false /* is not active */ ) ;
123+ this . addMostRecentEditor ( group , e . editor , false /* is not active */ , true /* is new */ ) ;
118124 this . ensureOpenedEditorsLimit ( { groupId : group . id , editor : e . editor } , group . id ) ;
119125 }
120126
@@ -148,7 +154,7 @@ export class EditorsObserver extends Disposable {
148154 }
149155 }
150156
151- private addMostRecentEditor ( group : IEditorGroup , editor : IEditorInput , isActive : boolean ) : void {
157+ private addMostRecentEditor ( group : IEditorGroup , editor : IEditorInput , isActive : boolean , isNew : boolean ) : void {
152158 const key = this . ensureKey ( group , editor ) ;
153159 const mostRecentEditor = this . mostRecentEditorsMap . first ;
154160
@@ -169,11 +175,39 @@ export class EditorsObserver extends Disposable {
169175 this . mostRecentEditorsMap . set ( mostRecentEditor , mostRecentEditor , Touch . AsOld /* make first */ ) ;
170176 }
171177
178+ // Update in resource map if this is a new editor
179+ if ( isNew ) {
180+ this . updateEditorResourcesMap ( editor , true ) ;
181+ }
182+
172183 // Event
173- this . _onDidChange . fire ( ) ;
184+ this . _onDidMostRecentlyActiveEditorsChange . fire ( ) ;
185+ }
186+
187+ private updateEditorResourcesMap ( editor : IEditorInput , add : boolean ) : void {
188+ const resource = toResource ( editor , { supportSideBySide : SideBySideEditor . MASTER } ) ;
189+ if ( ! resource ) {
190+ return ; // require a resource
191+ }
192+
193+ if ( add ) {
194+ this . editorResourcesMap . set ( resource , ( this . editorResourcesMap . get ( resource ) ?? 0 ) + 1 ) ;
195+ } else {
196+ const counter = this . editorResourcesMap . get ( resource ) ?? 0 ;
197+ if ( counter > 1 ) {
198+ this . editorResourcesMap . set ( resource , counter - 1 ) ;
199+ } else {
200+ this . editorResourcesMap . delete ( resource ) ;
201+ }
202+ }
174203 }
175204
176205 private removeMostRecentEditor ( group : IEditorGroup , editor : IEditorInput ) : void {
206+
207+ // Update in resource map
208+ this . updateEditorResourcesMap ( editor , false ) ;
209+
210+ // Update in MRU list
177211 const key = this . findKey ( group , editor ) ;
178212 if ( key ) {
179213
@@ -187,7 +221,7 @@ export class EditorsObserver extends Disposable {
187221 }
188222
189223 // Event
190- this . _onDidChange . fire ( ) ;
224+ this . _onDidMostRecentlyActiveEditorsChange . fire ( ) ;
191225 }
192226 }
193227
@@ -361,7 +395,7 @@ export class EditorsObserver extends Disposable {
361395 const group = groups [ i ] ;
362396 const groupEditorsMru = group . getEditors ( EditorsOrder . MOST_RECENTLY_ACTIVE ) ;
363397 for ( let i = groupEditorsMru . length - 1 ; i >= 0 ; i -- ) {
364- this . addMostRecentEditor ( group , groupEditorsMru [ i ] , true /* enforce as active to preserve order */ ) ;
398+ this . addMostRecentEditor ( group , groupEditorsMru [ i ] , true /* enforce as active to preserve order */ , true /* is new */ ) ;
365399 }
366400 }
367401 }
@@ -392,6 +426,9 @@ export class EditorsObserver extends Disposable {
392426 // Make sure key is registered as well
393427 const editorIdentifier = this . ensureKey ( group , editor ) ;
394428 mapValues . push ( [ editorIdentifier , editorIdentifier ] ) ;
429+
430+ // Update in resource map
431+ this . updateEditorResourcesMap ( editor , true ) ;
395432 }
396433
397434 // Fill map with deserialized values
0 commit comments