@@ -18,7 +18,7 @@ import paths = require('vs/base/common/paths');
1818import uri from 'vs/base/common/uri' ;
1919import strings = require( 'vs/base/common/strings' ) ;
2020import { IResourceInput } from 'vs/platform/editor/common/editor' ;
21- import { Workspace } from ' vs/platform/workspace/common/workspace' ;
21+ import { IWorkspace , Workspace } from " vs/platform/workspace/common/workspace" ;
2222import { WorkspaceConfigurationService } from 'vs/workbench/services/configuration/node/configuration' ;
2323import { realpath , stat } from 'vs/base/node/pfs' ;
2424import { EnvironmentService } from 'vs/platform/environment/node/environmentService' ;
@@ -95,47 +95,45 @@ function toInputs(paths: IPath[], isUntitledFile?: boolean): IResourceInput[] {
9595}
9696
9797function openWorkbench ( configuration : IWindowConfiguration , options : IOptions ) : TPromise < void > {
98- return getWorkspace ( configuration ) . then ( workspace => {
98+ return resolveWorkspace ( configuration ) . then ( workspace => {
9999 const environmentService = new EnvironmentService ( configuration , configuration . execPath ) ;
100100 const workspaceConfigurationService = new WorkspaceConfigurationService ( environmentService , workspace ) ;
101101 const timerService = new TimerService ( ( < any > window ) . MonacoEnvironment . timers as IInitData , ! workspaceConfigurationService . hasWorkspace ( ) ) ;
102-
103- return createStorageService ( configuration , environmentService ) . then ( storageService => {
104-
105- // Since the configuration service is one of the core services that is used in so many places, we initialize it
106- // right before startup of the workbench shell to have its data ready for consumers
107- return workspaceConfigurationService . initialize ( ) . then ( ( ) => {
108- timerService . beforeDOMContentLoaded = Date . now ( ) ;
109-
110- return domContentLoaded ( ) . then ( ( ) => {
111- timerService . afterDOMContentLoaded = Date . now ( ) ;
112-
113- // Open Shell
114- timerService . beforeWorkbenchOpen = Date . now ( ) ;
115- const shell = new WorkbenchShell ( document . body , {
116- contextService : workspaceConfigurationService ,
117- configurationService : workspaceConfigurationService ,
118- environmentService,
119- timerService,
120- storageService
121- } , configuration , options ) ;
122- shell . open ( ) ;
123-
124- // Inform user about loading issues from the loader
125- ( < any > self ) . require . config ( {
126- onError : ( err : any ) => {
127- if ( err . errorCode === 'load' ) {
128- shell . onUnexpectedError ( loaderError ( err ) ) ;
129- }
102+ const storageService = createStorageService ( workspace , configuration , environmentService ) ;
103+
104+ // Since the configuration service is one of the core services that is used in so many places, we initialize it
105+ // right before startup of the workbench shell to have its data ready for consumers
106+ return workspaceConfigurationService . initialize ( ) . then ( ( ) => {
107+ timerService . beforeDOMContentLoaded = Date . now ( ) ;
108+
109+ return domContentLoaded ( ) . then ( ( ) => {
110+ timerService . afterDOMContentLoaded = Date . now ( ) ;
111+
112+ // Open Shell
113+ timerService . beforeWorkbenchOpen = Date . now ( ) ;
114+ const shell = new WorkbenchShell ( document . body , {
115+ contextService : workspaceConfigurationService ,
116+ configurationService : workspaceConfigurationService ,
117+ environmentService,
118+ timerService,
119+ storageService
120+ } , configuration , options ) ;
121+ shell . open ( ) ;
122+
123+ // Inform user about loading issues from the loader
124+ ( < any > self ) . require . config ( {
125+ onError : ( err : any ) => {
126+ if ( err . errorCode === 'load' ) {
127+ shell . onUnexpectedError ( loaderError ( err ) ) ;
130128 }
131- } ) ;
129+ }
132130 } ) ;
133131 } ) ;
134132 } ) ;
135133 } ) ;
136134}
137135
138- function getWorkspace ( configuration : IWindowConfiguration ) : TPromise < Workspace > {
136+ function resolveWorkspace ( configuration : IWindowConfiguration ) : TPromise < Workspace > {
139137 if ( ! configuration . workspacePath ) {
140138 return TPromise . as ( null ) ;
141139 }
@@ -153,42 +151,36 @@ function getWorkspace(configuration: IWindowConfiguration): TPromise<Workspace>
153151 // update config
154152 configuration . workspacePath = realWorkspacePath ;
155153
156- const workspaceResource = uri . file ( realWorkspacePath ) ;
157- const folderName = path . basename ( realWorkspacePath ) || realWorkspacePath ;
158-
159- return new Workspace ( workspaceResource , folderName ) ;
154+ // resolve ctime of workspace
155+ return stat ( realWorkspacePath ) . then ( folderStat => new Workspace (
156+ uri . file ( realWorkspacePath ) ,
157+ platform . isLinux ? folderStat . ino : folderStat . birthtime . getTime ( ) // On Linux, birthtime is ctime, so we cannot use it! We use the ino instead!
158+ ) ) ;
160159 } , error => {
161160 errors . onUnexpectedError ( error ) ;
162161
163162 return null ; // treat invalid paths as empty workspace
164163 } ) ;
165164}
166165
167- function createStorageService ( configuration : IWindowConfiguration , environmentService : IEnvironmentService ) : TPromise < IStorageService > {
168- let workspaceStatPromise : TPromise < fs . Stats > = TPromise . as ( null ) ;
169- if ( configuration . workspacePath ) {
170- workspaceStatPromise = stat ( configuration . workspacePath ) ;
166+ function createStorageService ( workspace : IWorkspace , configuration : IWindowConfiguration , environmentService : IEnvironmentService ) : IStorageService {
167+ let id : IWorkspaceStorageIdentifier ;
168+ if ( workspace ) {
169+ id = { resource : workspace . resource , uid : workspace . ctime } ;
170+ } else if ( configuration . backupPath ) {
171+ // if we do not have a workspace open, we need to find another identifier for the window to store
172+ // workspace UI state. if we have a backup path in the configuration we can use that because this
173+ // will be a unique identifier per window that is stable between restarts as long as there are
174+ // dirty files in the workspace.
175+ // We use basename() to produce a short identifier, we do not need the full path. We use a custom
176+ // scheme so that we can later distinguish these identifiers from the workspace one.
177+ id = { resource : uri . from ( { path : path . basename ( configuration . backupPath ) , scheme : 'empty' } ) } ;
171178 }
172179
173- return workspaceStatPromise . then ( stat => {
174- let id : IWorkspaceStorageIdentifier ;
175- if ( stat ) {
176- id = { resource : uri . file ( configuration . workspacePath ) , uid : platform . isLinux ? stat . ino : stat . birthtime . getTime ( ) } ;
177- } else if ( configuration . backupPath ) {
178- // if we do not have a workspace open, we need to find another identifier for the window to store
179- // workspace UI state. if we have a backup path in the configuration we can use that because this
180- // will be a unique identifier per window that is stable between restarts as long as there are
181- // dirty files in the workspace.
182- // We use basename() to produce a short identifier, we do not need the full path. We use a custom
183- // scheme so that we can later distinguish these identifiers from the workspace one.
184- id = { resource : uri . from ( { path : path . basename ( configuration . backupPath ) , scheme : 'empty' } ) } ;
185- }
180+ const disableStorage = ! ! environmentService . extensionTestsPath ; // never keep any state when running extension tests!
181+ const storage = disableStorage ? inMemoryLocalStorageInstance : window . localStorage ;
186182
187- const disableStorage = ! ! environmentService . extensionTestsPath ; // never keep any state when running extension tests!
188- const storage = disableStorage ? inMemoryLocalStorageInstance : window . localStorage ;
189-
190- return new StorageService ( storage , storage , id ) ;
191- } ) ;
183+ return new StorageService ( storage , storage , id ) ;
192184}
193185
194186function loaderError ( err : Error ) : Error {
0 commit comments