Merge from vscode a416c77e56ef0314ae00633faa04878151610de8 (#8600)

* Merge from vscode a416c77e56ef0314ae00633faa04878151610de8

* distro

* fix tests

* fix tests
This commit is contained in:
Anthony Dresser
2019-12-07 17:19:16 -08:00
committed by GitHub
parent a7ff238653
commit d614116b63
155 changed files with 1982 additions and 1599 deletions

View File

@@ -819,3 +819,18 @@ export function etag(stat: { mtime: number | undefined, size: number | undefined
return stat.mtime.toString(29) + stat.size.toString(31);
}
export function whenProviderRegistered(file: URI, fileService: IFileService): Promise<void> {
if (fileService.canHandleResource(URI.from({ scheme: file.scheme }))) {
return Promise.resolve();
}
return new Promise((c, e) => {
const disposable = fileService.onDidChangeFileSystemProviderRegistrations(e => {
if (e.scheme === file.scheme && e.added) {
disposable.dispose();
c();
}
});
});
}

View File

@@ -5,12 +5,13 @@
import { ILogService, LogLevel, AbstractLogService, ILoggerService, ILogger } from 'vs/platform/log/common/log';
import { URI } from 'vs/base/common/uri';
import { IFileService } from 'vs/platform/files/common/files';
import { IFileService, whenProviderRegistered } from 'vs/platform/files/common/files';
import { Queue } from 'vs/base/common/async';
import { VSBuffer } from 'vs/base/common/buffer';
import { dirname, joinPath, basename } from 'vs/base/common/resources';
import { Disposable } from 'vs/base/common/lifecycle';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { BufferLogService } from 'vs/platform/log/common/bufferLog';
const MAX_FILE_SIZE = 1024 * 1024 * 5;
@@ -163,6 +164,7 @@ export class FileLoggerService extends Disposable implements ILoggerService {
constructor(
@ILogService private logService: ILogService,
@IInstantiationService private instantiationService: IInstantiationService,
@IFileService private fileService: IFileService,
) {
super();
this._register(logService.onDidChangeLogLevel(level => this.loggers.forEach(logger => logger.setLevel(level))));
@@ -171,8 +173,9 @@ export class FileLoggerService extends Disposable implements ILoggerService {
getLogger(resource: URI): ILogger {
let logger = this.loggers.get(resource.toString());
if (!logger) {
logger = this.instantiationService.createInstance(FileLogService, basename(resource), resource, this.logService.getLevel());
logger = new BufferLogService, this.logService.getLevel();
this.loggers.set(resource.toString(), logger);
whenProviderRegistered(resource, this.fileService).then(() => (<BufferLogService>logger).logger = this.instantiationService.createInstance(FileLogService, basename(resource), resource, this.logService.getLevel()));
}
return logger;
}

View File

@@ -306,8 +306,8 @@ export const editorFindRangeHighlightBorder = registerColor('editor.findRangeHig
*
* Distinct from normal editor find match to allow for better differentiation
*/
export const searchEditorFindMatch = registerColor('searchEditor.findMatchBackground', { light: transparent(editorFindMatchHighlight, 0.5), dark: transparent(editorFindMatchHighlight, 0.5), hc: editorFindMatchHighlight }, nls.localize('searchEditor.queryMatch', "Color of the Search Editor query matches."));
export const searchEditorFindMatchBorder = registerColor('searchEditor.findMatchBorder', { light: transparent(editorFindMatchHighlightBorder, 0.5), dark: transparent(editorFindMatchHighlightBorder, 0.5), hc: editorFindMatchHighlightBorder }, nls.localize('searchEditor.editorFindMatchBorder', "Border color of the Search Editor query matches."));
export const searchEditorFindMatch = registerColor('searchEditor.findMatchBackground', { light: transparent(editorFindMatchHighlight, 0.66), dark: transparent(editorFindMatchHighlight, 0.66), hc: editorFindMatchHighlight }, nls.localize('searchEditor.queryMatch', "Color of the Search Editor query matches."));
export const searchEditorFindMatchBorder = registerColor('searchEditor.findMatchBorder', { light: transparent(editorFindMatchHighlightBorder, 0.66), dark: transparent(editorFindMatchHighlightBorder, 0.66), hc: editorFindMatchHighlightBorder }, nls.localize('searchEditor.editorFindMatchBorder', "Border color of the Search Editor query matches."));
/**
* Editor hover

View File

@@ -320,40 +320,45 @@ export function getTokenClassificationRegistry(): ITokenClassificationRegistry {
return tokenClassificationRegistry;
}
export const comments = registerTokenType('comments', nls.localize('comments', "Style for comments."), [['comment']]);
export const strings = registerTokenType('strings', nls.localize('strings', "Style for strings."), [['string']]);
export const keywords = registerTokenType('keywords', nls.localize('keywords', "Style for keywords."), [['keyword.control']]);
export const numbers = registerTokenType('numbers', nls.localize('numbers', "Style for numbers."), [['constant.numeric']]);
export const regexp = registerTokenType('regexp', nls.localize('regexp', "Style for expressions."), [['constant.regexp']]);
export const operators = registerTokenType('operators', nls.localize('operator', "Style for operators."), [['keyword.operator']]);
// default token types
export const namespaces = registerTokenType('namespaces', nls.localize('namespace', "Style for namespaces."), [['entity.name.namespace']]);
registerTokenType('comment', nls.localize('comment', "Style for comments."), [['comment']]);
registerTokenType('string', nls.localize('string', "Style for strings."), [['string']]);
registerTokenType('keyword', nls.localize('keyword', "Style for keywords."), [['keyword.control']]);
registerTokenType('number', nls.localize('number', "Style for numbers."), [['constant.numeric']]);
registerTokenType('regexp', nls.localize('regexp', "Style for expressions."), [['constant.regexp']]);
registerTokenType('operator', nls.localize('operator', "Style for operators."), [['keyword.operator']]);
export const types = registerTokenType('types', nls.localize('types', "Style for types."), [['entity.name.type'], ['entity.name.class'], ['support.type'], ['support.class']]);
export const structs = registerTokenType('structs', nls.localize('struct', "Style for structs."), [['storage.type.struct']], types);
export const classes = registerTokenType('classes', nls.localize('class', "Style for classes."), [['entity.name.class']], types);
export const interfaces = registerTokenType('interfaces', nls.localize('interface', "Style for interfaces."), undefined, types);
export const enums = registerTokenType('enums', nls.localize('enum', "Style for enums."), undefined, types);
export const parameterTypes = registerTokenType('parameterTypes', nls.localize('parameterType', "Style for parameter types."), undefined, types);
registerTokenType('namespace', nls.localize('namespace', "Style for namespaces."), [['entity.name.namespace']]);
export const functions = registerTokenType('functions', nls.localize('functions', "Style for functions"), [['entity.name.function'], ['support.function']]);
export const macros = registerTokenType('macros', nls.localize('macro', "Style for macros."), undefined, functions);
registerTokenType('type', nls.localize('type', "Style for types."), [['entity.name.type'], ['entity.name.class'], ['support.type'], ['support.class']]);
registerTokenType('struct', nls.localize('struct', "Style for structs."), [['storage.type.struct']], 'type');
registerTokenType('class', nls.localize('class', "Style for classes."), [['entity.name.class']], 'type');
registerTokenType('interface', nls.localize('interface', "Style for interfaces."), undefined, 'type');
registerTokenType('enum', nls.localize('enum', "Style for enums."), undefined, 'type');
registerTokenType('parameterType', nls.localize('parameterType', "Style for parameter types."), undefined, 'type');
export const variables = registerTokenType('variables', nls.localize('variables', "Style for variables."), [['variable'], ['entity.name.variable']]);
export const constants = registerTokenType('constants', nls.localize('constants', "Style for constants."), undefined, variables);
export const parameters = registerTokenType('parameters', nls.localize('parameters', "Style for parameters."), undefined, variables);
export const property = registerTokenType('properties', nls.localize('properties', "Style for properties."), undefined, variables);
registerTokenType('function', nls.localize('function', "Style for functions"), [['entity.name.function'], ['support.function']]);
registerTokenType('macro', nls.localize('macro', "Style for macros."), undefined, 'function');
export const labels = registerTokenType('labels', nls.localize('labels', "Style for labels. "), undefined);
registerTokenType('variable', nls.localize('variable', "Style for variables."), [['variable'], ['entity.name.variable']]);
registerTokenType('constant', nls.localize('constant', "Style for constants."), undefined, 'variable');
registerTokenType('parameter', nls.localize('parameter', "Style for parameters."), undefined, 'variable');
registerTokenType('property', nls.localize('propertie', "Style for properties."), undefined, 'variable');
registerTokenType('label', nls.localize('labels', "Style for labels. "), undefined);
// default token modifiers
registerTokenModifier('declaration', nls.localize('declaration', "Style for all symbol declarations."), undefined);
registerTokenModifier('documentation', nls.localize('documentation', "Style to use for references in documentation."), undefined);
registerTokenModifier('member', nls.localize('member', "Style to use for member functions, variables (fields) and types."), undefined);
registerTokenModifier('static', nls.localize('static', "Style to use for symbols that are static."), undefined);
registerTokenModifier('abstract', nls.localize('abstract', "Style to use for symbols that are abstract."), undefined);
registerTokenModifier('deprecated', nls.localize('deprecated', "Style to use for symbols that are deprecated."), undefined);
registerTokenModifier('modification', nls.localize('modification', "Style to use for write accesses."), undefined);
registerTokenModifier('async', nls.localize('async', "Style to use for symbols that are async."), undefined);
export const m_declaration = registerTokenModifier('declaration', nls.localize('declaration', "Style for all symbol declarations."), undefined);
export const m_documentation = registerTokenModifier('documentation', nls.localize('documentation', "Style to use for references in documentation."), undefined);
export const m_member = registerTokenModifier('member', nls.localize('member', "Style to use for member functions, variables (fields) and types."), undefined);
export const m_static = registerTokenModifier('static', nls.localize('static', "Style to use for symbols that are static."), undefined);
export const m_abstract = registerTokenModifier('abstract', nls.localize('abstract', "Style to use for symbols that are abstract."), undefined);
export const m_deprecated = registerTokenModifier('deprecated', nls.localize('deprecated', "Style to use for symbols that are deprecated."), undefined);
export const m_modification = registerTokenModifier('modification', nls.localize('modification', "Style to use for write accesses."), undefined);
export const m_async = registerTokenModifier('async', nls.localize('async', "Style to use for symbols that are async."), undefined);
function bitCount(u: number) {
// https://blogs.msdn.microsoft.com/jeuge/2005/06/08/bit-fiddling-3/

View File

@@ -18,6 +18,7 @@ import { startsWith } from 'vs/base/common/strings';
import { IFileService } from 'vs/platform/files/common/files';
import { Queue } from 'vs/base/common/async';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { localize } from 'vs/nls';
export interface ISyncPreviewResult {
readonly added: ISyncExtension[];
@@ -26,6 +27,10 @@ export interface ISyncPreviewResult {
readonly remote: ISyncExtension[] | null;
}
interface ILastSyncUserData extends IUserData {
skippedExtensions: ISyncExtension[] | undefined;
}
export class ExtensionsSynchroniser extends Disposable implements ISynchroniser {
private static EXTERNAL_USER_DATA_EXTENSIONS_KEY: string = 'extensions';
@@ -122,14 +127,16 @@ export class ExtensionsSynchroniser extends Disposable implements ISynchroniser
private async doSync(): Promise<void> {
const lastSyncData = await this.getLastSyncUserData();
let remoteData = await this.userDataSyncStoreService.read(ExtensionsSynchroniser.EXTERNAL_USER_DATA_EXTENSIONS_KEY, lastSyncData);
const lastSyncExtensions: ISyncExtension[] | null = lastSyncData ? JSON.parse(lastSyncData.content!) : null;
let skippedExtensions: ISyncExtension[] = lastSyncData ? lastSyncData.skippedExtensions || [] : [];
const lastSyncExtensions: ISyncExtension[] = lastSyncData ? JSON.parse(lastSyncData.content!) : null;
let remoteData = await this.userDataSyncStoreService.read(ExtensionsSynchroniser.EXTERNAL_USER_DATA_EXTENSIONS_KEY, lastSyncData);
const remoteExtensions: ISyncExtension[] = remoteData.content ? JSON.parse(remoteData.content) : null;
const localExtensions = await this.getLocalExtensions();
this.logService.trace('Extensions: Merging remote extensions with local extensions...');
const { added, removed, updated, remote } = this.merge(localExtensions, remoteExtensions, lastSyncExtensions);
const { added, removed, updated, remote } = this.merge(localExtensions, remoteExtensions, lastSyncExtensions, skippedExtensions);
if (!added.length && !removed.length && !updated.length && !remote) {
this.logService.trace('Extensions: No changes found during synchronizing extensions.');
@@ -137,7 +144,7 @@ export class ExtensionsSynchroniser extends Disposable implements ISynchroniser
if (added.length || removed.length || updated.length) {
this.logService.info('Extensions: Updating local extensions...');
await this.updateLocalExtensions(added, removed, updated);
skippedExtensions = await this.updateLocalExtensions(added, removed, updated, skippedExtensions);
}
if (remote) {
@@ -151,7 +158,7 @@ export class ExtensionsSynchroniser extends Disposable implements ISynchroniser
) {
// update last sync
this.logService.info('Extensions: Updating last synchronised extensions...');
await this.updateLastSyncValue(remoteData);
await this.updateLastSyncValue({ ...remoteData, skippedExtensions });
}
}
@@ -161,7 +168,7 @@ export class ExtensionsSynchroniser extends Disposable implements ISynchroniser
* - Overwrite local with remote changes. Removed, Added, Updated.
* - Update remote with those local extension which are newly added or updated or removed and untouched in remote.
*/
private merge(localExtensions: ISyncExtension[], remoteExtensions: ISyncExtension[] | null, lastSyncExtensions: ISyncExtension[] | null): { added: ISyncExtension[], removed: IExtensionIdentifier[], updated: ISyncExtension[], remote: ISyncExtension[] | null } {
private merge(localExtensions: ISyncExtension[], remoteExtensions: ISyncExtension[] | null, lastSyncExtensions: ISyncExtension[] | null, skippedExtensions: ISyncExtension[]): { added: ISyncExtension[], removed: IExtensionIdentifier[], updated: ISyncExtension[], remote: ISyncExtension[] | null } {
const ignoredExtensions = this.configurationService.getValue<string[]>('sync.ignoredExtensions') || [];
// First time sync
if (!remoteExtensions) {
@@ -187,6 +194,7 @@ export class ExtensionsSynchroniser extends Disposable implements ISynchroniser
const remoteExtensionsMap = remoteExtensions.reduce(addExtensionToMap, new Map<string, ISyncExtension>());
const newRemoteExtensionsMap = remoteExtensions.reduce(addExtensionToMap, new Map<string, ISyncExtension>());
const lastSyncExtensionsMap = lastSyncExtensions ? lastSyncExtensions.reduce(addExtensionToMap, new Map<string, ISyncExtension>()) : null;
const skippedExtensionsMap = skippedExtensions.reduce(addExtensionToMap, new Map<string, ISyncExtension>());
const ignoredExtensionsSet = ignoredExtensions.reduce((set, id) => {
const uuid = uuids.get(id.toLowerCase());
return set.add(uuid ? `uuid:${uuid}` : `id:${id.toLowerCase()}`);
@@ -273,8 +281,8 @@ export class ExtensionsSynchroniser extends Disposable implements ISynchroniser
// Locally removed extensions
for (const key of values(baseToLocal.removed)) {
// If not updated in remote
if (!baseToRemote.updated.has(key)) {
// If not skipped and not updated in remote
if (!skippedExtensionsMap.has(key) && !baseToRemote.updated.has(key)) {
newRemoteExtensionsMap.delete(key);
}
}
@@ -308,13 +316,17 @@ export class ExtensionsSynchroniser extends Disposable implements ISynchroniser
return { added, removed, updated };
}
private async updateLocalExtensions(added: ISyncExtension[], removed: IExtensionIdentifier[], updated: ISyncExtension[]): Promise<void> {
private async updateLocalExtensions(added: ISyncExtension[], removed: IExtensionIdentifier[], updated: ISyncExtension[], skippedExtensions: ISyncExtension[]): Promise<ISyncExtension[]> {
const removeFromSkipped: IExtensionIdentifier[] = [];
const addToSkipped: ISyncExtension[] = [];
if (removed.length) {
const installedExtensions = await this.extensionManagementService.getInstalled(ExtensionType.User);
const extensionsToRemove = installedExtensions.filter(({ identifier }) => removed.some(r => areSameExtensions(identifier, r)));
await Promise.all(extensionsToRemove.map(e => {
this.logService.info('Extensions: Removing local extension.', e.identifier.id);
return this.extensionManagementService.uninstall(e);
await Promise.all(extensionsToRemove.map(async extensionToRemove => {
this.logService.info('Extensions: Removing local extension.', extensionToRemove.identifier.id);
await this.extensionManagementService.uninstall(extensionToRemove);
removeFromSkipped.push(extensionToRemove.identifier);
}));
}
@@ -323,18 +335,41 @@ export class ExtensionsSynchroniser extends Disposable implements ISynchroniser
const extension = await this.extensionGalleryService.getCompatibleExtension(e.identifier, e.version);
if (extension) {
this.logService.info('Extensions: Installing local extension.', e.identifier.id, extension.version);
await this.extensionManagementService.installFromGallery(extension);
try {
await this.extensionManagementService.installFromGallery(extension);
removeFromSkipped.push(extension.identifier);
} catch (error) {
addToSkipped.push(e);
this.logService.error(error);
this.logService.info(localize('skip extension', "Skipping synchronising extension {0}", extension.displayName || extension.identifier.id));
}
} else {
addToSkipped.push(e);
}
}));
}
const newSkippedExtensions: ISyncExtension[] = [];
for (const skippedExtension of skippedExtensions) {
if (!removeFromSkipped.some(e => areSameExtensions(e, skippedExtension.identifier))) {
newSkippedExtensions.push(skippedExtension);
}
}
for (const skippedExtension of addToSkipped) {
if (!newSkippedExtensions.some(e => areSameExtensions(e.identifier, skippedExtension.identifier))) {
newSkippedExtensions.push(skippedExtension);
}
}
return newSkippedExtensions;
}
private async getLocalExtensions(): Promise<ISyncExtension[]> {
const installedExtensions = await this.extensionManagementService.getInstalled(ExtensionType.User);
return installedExtensions.map(({ identifier }) => ({ identifier, enabled: true }));
return installedExtensions
.map(({ identifier }) => ({ identifier, enabled: true }));
}
private async getLastSyncUserData(): Promise<IUserData | null> {
private async getLastSyncUserData(): Promise<ILastSyncUserData | null> {
try {
const content = await this.fileService.readFile(this.lastSyncExtensionsResource);
return JSON.parse(content.value.toString());
@@ -343,14 +378,14 @@ export class ExtensionsSynchroniser extends Disposable implements ISynchroniser
}
}
private async updateLastSyncValue(lastSyncUserData: ILastSyncUserData): Promise<void> {
await this.fileService.writeFile(this.lastSyncExtensionsResource, VSBuffer.fromString(JSON.stringify(lastSyncUserData)));
}
private async writeToRemote(extensions: ISyncExtension[], ref: string | null): Promise<IUserData> {
const content = JSON.stringify(extensions);
ref = await this.userDataSyncStoreService.write(ExtensionsSynchroniser.EXTERNAL_USER_DATA_EXTENSIONS_KEY, content, ref);
return { content, ref };
}
private async updateLastSyncValue(remoteUserData: IUserData): Promise<void> {
await this.fileService.writeFile(this.lastSyncExtensionsResource, VSBuffer.fromString(JSON.stringify(remoteUserData)));
}
}

View File

@@ -11,10 +11,10 @@ import { VSBuffer } from 'vs/base/common/buffer';
import { parse, ParseError } from 'vs/base/common/json';
import { localize } from 'vs/nls';
import { Emitter, Event } from 'vs/base/common/event';
import { CancelablePromise, createCancelablePromise, ThrottledDelayer } from 'vs/base/common/async';
import { CancelablePromise, createCancelablePromise } from 'vs/base/common/async';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { URI } from 'vs/base/common/uri';
import { joinPath } from 'vs/base/common/resources';
import { joinPath, dirname } from 'vs/base/common/resources';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { CancellationToken } from 'vs/base/common/cancellation';
import { OS, OperatingSystem } from 'vs/base/common/platform';
@@ -46,7 +46,6 @@ export class KeybindingsSynchroniser extends Disposable implements ISynchroniser
private _onDidChangStatus: Emitter<SyncStatus> = this._register(new Emitter<SyncStatus>());
readonly onDidChangeStatus: Event<SyncStatus> = this._onDidChangStatus.event;
private readonly throttledDelayer: ThrottledDelayer<void>;
private _onDidChangeLocal: Emitter<void> = this._register(new Emitter<void>());
readonly onDidChangeLocal: Event<void> = this._onDidChangeLocal.event;
@@ -62,24 +61,8 @@ export class KeybindingsSynchroniser extends Disposable implements ISynchroniser
) {
super();
this.lastSyncKeybindingsResource = joinPath(this.environmentService.userRoamingDataHome, '.lastSyncKeybindings.json');
this.throttledDelayer = this._register(new ThrottledDelayer<void>(500));
this._register(this.fileService.watch(this.environmentService.keybindingsResource));
this._register(Event.filter(this.fileService.onFileChanges, e => e.contains(this.environmentService.keybindingsResource))(() => this.throttledDelayer.trigger(() => this.onDidChangeKeybindings())));
}
private async onDidChangeKeybindings(): Promise<void> {
const localFileContent = await this.getLocalContent();
const lastSyncData = await this.getLastSyncUserData();
if (localFileContent && lastSyncData) {
if (localFileContent.value.toString() !== lastSyncData.content) {
this._onDidChangeLocal.fire();
return;
}
}
if (!localFileContent || !lastSyncData) {
this._onDidChangeLocal.fire();
return;
}
this._register(this.fileService.watch(dirname(this.environmentService.keybindingsResource)));
this._register(Event.filter(this.fileService.onFileChanges, e => e.contains(this.environmentService.keybindingsResource))(() => this._onDidChangeLocal.fire()));
}
private setStatus(status: SyncStatus): void {

View File

@@ -10,10 +10,10 @@ import { VSBuffer } from 'vs/base/common/buffer';
import { parse, ParseError } from 'vs/base/common/json';
import { localize } from 'vs/nls';
import { Emitter, Event } from 'vs/base/common/event';
import { CancelablePromise, createCancelablePromise, ThrottledDelayer } from 'vs/base/common/async';
import { CancelablePromise, createCancelablePromise } from 'vs/base/common/async';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { URI } from 'vs/base/common/uri';
import { joinPath } from 'vs/base/common/resources';
import { joinPath, dirname } from 'vs/base/common/resources';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { startsWith } from 'vs/base/common/strings';
import { CancellationToken } from 'vs/base/common/cancellation';
@@ -37,7 +37,6 @@ export class SettingsSynchroniser extends Disposable implements ISynchroniser {
private _onDidChangStatus: Emitter<SyncStatus> = this._register(new Emitter<SyncStatus>());
readonly onDidChangeStatus: Event<SyncStatus> = this._onDidChangStatus.event;
private readonly throttledDelayer: ThrottledDelayer<void>;
private _onDidChangeLocal: Emitter<void> = this._register(new Emitter<void>());
readonly onDidChangeLocal: Event<void> = this._onDidChangeLocal.event;
@@ -53,23 +52,8 @@ export class SettingsSynchroniser extends Disposable implements ISynchroniser {
) {
super();
this.lastSyncSettingsResource = joinPath(this.environmentService.userRoamingDataHome, '.lastSyncSettings.json');
this.throttledDelayer = this._register(new ThrottledDelayer<void>(500));
this._register(Event.filter(this.fileService.onFileChanges, e => e.contains(this.environmentService.settingsResource))(() => this.throttledDelayer.trigger(() => this.onDidChangeSettings())));
}
private async onDidChangeSettings(): Promise<void> {
const localFileContent = await this.getLocalFileContent();
const lastSyncData = await this.getLastSyncUserData();
if (localFileContent && lastSyncData) {
if (localFileContent.value.toString() !== lastSyncData.content) {
this._onDidChangeLocal.fire();
return;
}
}
if (!localFileContent || !lastSyncData) {
this._onDidChangeLocal.fire();
return;
}
this._register(this.fileService.watch(dirname(this.environmentService.settingsResource)));
this._register(Event.filter(this.fileService.onFileChanges, e => e.contains(this.environmentService.settingsResource))(() => this._onDidChangeLocal.fire()));
}
private setStatus(status: SyncStatus): void {