@@ -42,8 +42,9 @@ import { URI } from '../../../../base/common/uri.js';
4242import { basename } from '../../../../base/common/resources.js' ;
4343import { ICompressibleTreeRenderer } from '../../../../base/browser/ui/tree/objectTree.js' ;
4444import { ICompressedTreeNode } from '../../../../base/browser/ui/tree/compressedObjectTreeModel.js' ;
45- import { ITreeCompressionDelegate } from '../../../../base/browser/ui/tree/asyncDataTree.js' ;
45+ import { IAsyncDataTreeViewState , ITreeCompressionDelegate } from '../../../../base/browser/ui/tree/asyncDataTree.js' ;
4646import { Codicon } from '../../../../base/common/codicons.js' ;
47+ import { IStorageService , StorageScope , StorageTarget } from '../../../../platform/storage/common/storage.js' ;
4748
4849type TreeElement = ISCMRepository | SCMArtifactGroupTreeElement | SCMArtifactTreeElement | IResourceNode < SCMArtifactTreeElement , SCMArtifactGroupTreeElement > ;
4950
@@ -394,13 +395,18 @@ export class SCMRepositoriesViewPane extends ViewPane {
394395 @IConfigurationService configurationService : IConfigurationService ,
395396 @IOpenerService openerService : IOpenerService ,
396397 @IThemeService themeService : IThemeService ,
397- @IHoverService hoverService : IHoverService
398+ @IHoverService hoverService : IHoverService ,
399+ @IStorageService private readonly storageService : IStorageService
398400 ) {
399401 super ( { ...options , titleMenuId : MenuId . SCMSourceControlTitle } , keybindingService , contextMenuService , configurationService , contextKeyService , viewDescriptorService , instantiationService , openerService , themeService , hoverService ) ;
400402
401403 this . visibleCountObs = observableConfigValue ( 'scm.repositories.visible' , 10 , this . configurationService ) ;
402404 this . providerCountBadgeObs = observableConfigValue < 'hidden' | 'auto' | 'visible' > ( 'scm.providerCountBadge' , 'hidden' , this . configurationService ) ;
403405
406+ this . storageService . onWillSaveState ( ( ) => {
407+ this . storeTreeViewState ( ) ;
408+ } , this , this . _store ) ;
409+
404410 this . _register ( this . updateChildrenThrottler ) ;
405411 }
406412
@@ -416,7 +422,8 @@ export class SCMRepositoriesViewPane extends ViewPane {
416422 treeContainer . classList . toggle ( 'auto-provider-counts' , providerCountBadge === 'auto' ) ;
417423 } ) ) ;
418424
419- this . createTree ( treeContainer ) ;
425+ const viewState = this . loadTreeViewState ( ) ;
426+ this . createTree ( treeContainer , viewState ) ;
420427
421428 this . onDidChangeBodyVisibility ( async visible => {
422429 if ( ! visible ) {
@@ -426,7 +433,7 @@ export class SCMRepositoriesViewPane extends ViewPane {
426433
427434 this . treeOperationSequencer . queue ( async ( ) => {
428435 // Initial rendering
429- await this . tree . setInput ( this . scmViewService ) ;
436+ await this . tree . setInput ( this . scmViewService , viewState ) ;
430437
431438 // scm.repositories.visible setting
432439 this . visibilityDisposables . add ( autorun ( reader => {
@@ -461,6 +468,17 @@ export class SCMRepositoriesViewPane extends ViewPane {
461468 for ( const repository of this . scmService . repositories ) {
462469 this . onDidAddRepository ( repository ) ;
463470 }
471+
472+ // Expand repository if there is only one
473+ this . visibilityDisposables . add ( autorun ( async reader => {
474+ const explorerEnabledConfig = this . scmViewService . explorerEnabledConfig . read ( reader ) ;
475+ const didFinishLoadingRepositories = this . scmViewService . didFinishLoadingRepositories . read ( reader ) ;
476+
477+ if ( viewState === undefined && explorerEnabledConfig && didFinishLoadingRepositories && this . scmViewService . repositories . length === 1 ) {
478+ await this . treeOperationSequencer . queue ( ( ) =>
479+ this . tree . expand ( this . scmViewService . repositories [ 0 ] ) ) ;
480+ }
481+ } ) ) ;
464482 } ) ;
465483 } , this , this . _store ) ;
466484 }
@@ -475,7 +493,7 @@ export class SCMRepositoriesViewPane extends ViewPane {
475493 this . tree . domFocus ( ) ;
476494 }
477495
478- private createTree ( container : HTMLElement ) : void {
496+ private createTree ( container : HTMLElement , viewState ?: IAsyncDataTreeViewState ) : void {
479497 this . treeIdentityProvider = new RepositoryTreeIdentityProvider ( ) ;
480498 this . treeDataSource = this . instantiationService . createInstance ( RepositoryTreeDataSource ) ;
481499 this . _register ( this . treeDataSource ) ;
@@ -504,7 +522,10 @@ export class SCMRepositoriesViewPane extends ViewPane {
504522 }
505523
506524 // Explorer mode
507- if ( isSCMArtifactNode ( e ) ) {
525+ if ( viewState ?. expanded && ( isSCMRepository ( e ) || isSCMArtifactGroupTreeElement ( e ) || isSCMArtifactTreeElement ( e ) ) ) {
526+ // Only expand repositories/artifact groups/artifacts that were expanded before
527+ return viewState . expanded . indexOf ( this . treeIdentityProvider . getId ( e ) ) === - 1 ;
528+ } else if ( isSCMArtifactNode ( e ) ) {
508529 // Only expand artifact folders as they are compressed by default
509530 return ! ( e . childrenCount === 1 && Iterable . first ( e . children ) ?. element === undefined ) ;
510531 } else {
@@ -773,6 +794,26 @@ export class SCMRepositoriesViewPane extends ViewPane {
773794 } ) ;
774795 }
775796
797+ private loadTreeViewState ( ) : IAsyncDataTreeViewState | undefined {
798+ const storageViewState = this . storageService . get ( 'scm.repositoriesViewState' , StorageScope . WORKSPACE ) ;
799+ if ( ! storageViewState ) {
800+ return undefined ;
801+ }
802+
803+ try {
804+ const treeViewState = JSON . parse ( storageViewState ) ;
805+ return treeViewState ;
806+ } catch {
807+ return undefined ;
808+ }
809+ }
810+
811+ private storeTreeViewState ( ) : void {
812+ if ( this . tree ) {
813+ this . storageService . store ( 'scm.repositoriesViewState' , JSON . stringify ( this . tree . getViewState ( ) ) , StorageScope . WORKSPACE , StorageTarget . MACHINE ) ;
814+ }
815+ }
816+
776817 override dispose ( ) : void {
777818 this . visibilityDisposables . dispose ( ) ;
778819 super . dispose ( ) ;
0 commit comments