122
123
constructor(
125
>
configFolder: string,
126
>
logPrefix: string,
127
>
fileService: IFileService,
128
>
workspaceContextService: IWorkspaceContextService,
129
>
private readonly _logService: ILogService,
130
>
) {
131
>
super();
132
>
133
>
const settingsDirs = observableFromEvent(
134
>
this,
135
>
workspaceContextService.onDidChangeWorkspaceFolders,
136
>
() => workspaceContextService.getWorkspace().folders.map(f => f.uri.path ? joinPath(f.uri, configFolder) : joinPath(f.uri.with({ path: '/' }), configFolder)),
137
>
);
138
>
139
>
const watcherStore = this._register(new DisposableStore());
140
>
this._register(autorun(reader => {
141
>
const dirs = settingsDirs.read(reader);
142
>
watcherStore.clear();
143
>
144
>
// Coalesce rapid file-change events into a single read.
145
>
const scheduler = new RunOnceScheduler(() => this._readSettings(dirs, logPrefix, fileService), 100);
146
>
watcherStore.add(scheduler);
147
>
148
>
for (const dir of dirs) {
149
>
const watcher = fileService.createWatcher(dir, { recursive: false, excludes: [] });
150
>
watcherStore.add(watcher);
151
>
watcherStore.add(watcher.onDidChange(e => {
152
if (e.affects(joinPath(dir, SETTINGS_FILENAME)) || e.affects(joinPath(dir, SETTINGS_LOCAL_FILENAME))) {
153
scheduler.schedule();
154
}
156
>
}
157
>
158
>
// Perform initial read immediately.
159
>
this._readSettings(dirs, logPrefix, fileService);
160
>
}));
161
>
}
162
163
private async _readSettings(dirs: readonly URI[], logPrefix: string, fileService: IFileService): Promise<void> {
165
>
const mergedEnabled = new Map<string, boolean>();
166
>
167
>
for (const dir of dirs) {
168
>
const sharedUri = joinPath(dir, SETTINGS_FILENAME);
169
>
const localUri = joinPath(dir, SETTINGS_LOCAL_FILENAME);
170
>
171
>
for (const uri of [sharedUri, localUri]) {
172
>
try {
173
>
const content = await fileService.readFile(uri);
174
const json = parseJSONC(content.value.toString());
175
177
continue;
178
}