@@ -9,7 +9,7 @@ import { Event, Emitter } from 'vs/base/common/event';
99import * as pfs from 'vs/base/node/pfs' ;
1010import * as errors from 'vs/base/common/errors' ;
1111import * as collections from 'vs/base/common/collections' ;
12- import { Disposable , IDisposable , dispose } from 'vs/base/common/lifecycle' ;
12+ import { Disposable , IDisposable , dispose , toDisposable } from 'vs/base/common/lifecycle' ;
1313import { RunOnceScheduler , Delayer } from 'vs/base/common/async' ;
1414import { FileChangeType , FileChangesEvent , IContent , IFileService } from 'vs/platform/files/common/files' ;
1515import { ConfigurationModel , ConfigurationModelParser } from 'vs/platform/configuration/common/configurationModels' ;
@@ -53,10 +53,19 @@ export class LocalUserConfiguration extends Disposable {
5353
5454 async adopt ( fileService : IFileService ) : Promise < ConfigurationModel | null > {
5555 if ( this . userConfiguration instanceof NodeBasedUserConfiguration ) {
56+ const oldConfigurationModel = this . userConfiguration . getConfigurationModel ( ) ;
5657 this . userConfiguration . dispose ( ) ;
5758 dispose ( this . changeDisposable ) ;
59+
60+ let newConfigurationModel = new ConfigurationModel ( ) ;
5861 this . userConfiguration = this . _register ( new FileServiceBasedUserConfiguration ( this . userConfigurationResource , fileService ) ) ;
5962 this . changeDisposable = this . _register ( this . userConfiguration . onDidChangeConfiguration ( configurationModel => this . _onDidChangeConfiguration . fire ( configurationModel ) ) ) ;
63+ newConfigurationModel = await this . userConfiguration . initialize ( ) ;
64+
65+ const { added, updated, removed } = compare ( oldConfigurationModel , newConfigurationModel ) ;
66+ if ( added . length > 0 || updated . length > 0 || removed . length > 0 ) {
67+ return newConfigurationModel ;
68+ }
6069 }
6170 return null ;
6271 }
@@ -120,6 +129,9 @@ export class FileServiceBasedUserConfiguration extends Disposable {
120129 protected readonly _onDidChangeConfiguration : Emitter < ConfigurationModel > = this . _register ( new Emitter < ConfigurationModel > ( ) ) ;
121130 readonly onDidChangeConfiguration : Event < ConfigurationModel > = this . _onDidChangeConfiguration . event ;
122131
132+ private fileWatcherDisposable : IDisposable = Disposable . None ;
133+ private directoryWatcherDisposable : IDisposable = Disposable . None ;
134+
123135 constructor (
124136 private readonly configurationResource : URI ,
125137 private readonly fileService : IFileService
@@ -128,38 +140,80 @@ export class FileServiceBasedUserConfiguration extends Disposable {
128140
129141 this . _register ( fileService . onFileChanges ( e => this . handleFileEvents ( e ) ) ) ;
130142 this . reloadConfigurationScheduler = this . _register ( new RunOnceScheduler ( ( ) => this . reload ( ) . then ( configurationModel => this . _onDidChangeConfiguration . fire ( configurationModel ) ) , 50 ) ) ;
131- this . _register ( this . fileService . watch ( this . configurationResource ) ) ;
143+ this . _register ( toDisposable ( ( ) => {
144+ this . stopWatchingResource ( ) ;
145+ this . stopWatchingDirectory ( ) ;
146+ } ) ) ;
132147 }
133148
134- initialize ( ) : Promise < ConfigurationModel > {
149+ private watchResource ( ) : void {
150+ this . fileWatcherDisposable = this . fileService . watch ( this . configurationResource ) ;
151+ }
152+
153+ private stopWatchingResource ( ) : void {
154+ this . fileWatcherDisposable . dispose ( ) ;
155+ this . fileWatcherDisposable = Disposable . None ;
156+ }
157+
158+ private watchDirectory ( ) : void {
159+ const directory = resources . dirname ( this . configurationResource ) ;
160+ this . directoryWatcherDisposable = this . fileService . watch ( directory ) ;
161+ }
162+
163+ private stopWatchingDirectory ( ) : void {
164+ this . directoryWatcherDisposable . dispose ( ) ;
165+ this . directoryWatcherDisposable = Disposable . None ;
166+ }
167+
168+ async initialize ( ) : Promise < ConfigurationModel > {
169+ const exists = await this . fileService . exists ( this . configurationResource ) ;
170+ this . onResourceExists ( exists ) ;
135171 return this . reload ( ) ;
136172 }
137173
138- reload ( ) : Promise < ConfigurationModel > {
139- return this . fileService . resolveContent ( this . configurationResource )
140- . then ( content => content . value , ( ) => {
141- // File not found
142- return '' ;
143- } ) . then ( content => {
144- const parser = new ConfigurationModelParser ( this . configurationResource . toString ( ) ) ;
145- parser . parse ( content ) ;
146- return parser . configurationModel ;
147- } ) ;
174+ async reload ( ) : Promise < ConfigurationModel > {
175+ try {
176+ const content = await this . fileService . resolveContent ( this . configurationResource ) ;
177+ const parser = new ConfigurationModelParser ( this . configurationResource . toString ( ) ) ;
178+ parser . parse ( content . value ) ;
179+ return parser . configurationModel ;
180+ } catch ( e ) {
181+ return new ConfigurationModel ( ) ;
182+ }
148183 }
149184
150- private handleFileEvents ( event : FileChangesEvent ) : void {
185+ private async handleFileEvents ( event : FileChangesEvent ) : Promise < void > {
151186 const events = event . changes ;
152187
153188 let affectedByChanges = false ;
154- // Find changes that affect workspace file
155- for ( let i = 0 , len = events . length ; i < len && ! affectedByChanges ; i ++ ) {
156- affectedByChanges = resources . isEqual ( this . configurationResource , events [ i ] . resource ) ;
189+
190+ // Find changes that affect the resource
191+ for ( const event of events ) {
192+ affectedByChanges = resources . isEqual ( this . configurationResource , event . resource ) ;
193+ if ( affectedByChanges ) {
194+ if ( event . type === FileChangeType . ADDED ) {
195+ this . onResourceExists ( true ) ;
196+ } else if ( event . type === FileChangeType . DELETED ) {
197+ this . onResourceExists ( false ) ;
198+ }
199+ break ;
200+ }
157201 }
158202
159203 if ( affectedByChanges ) {
160204 this . reloadConfigurationScheduler . schedule ( ) ;
161205 }
162206 }
207+
208+ private onResourceExists ( exists : boolean ) : void {
209+ if ( exists ) {
210+ this . stopWatchingDirectory ( ) ;
211+ this . watchResource ( ) ;
212+ } else {
213+ this . stopWatchingResource ( ) ;
214+ this . watchDirectory ( ) ;
215+ }
216+ }
163217}
164218
165219class CachedUserConfiguration extends Disposable {
0 commit comments