diff --git a/src/vs/workbench/parts/markers/browser/markersFileDecorations.ts b/src/vs/workbench/parts/markers/browser/markersFileDecorations.ts index 2a9a05a17a2254eca06f5d01a216ed8585022fc8..c12f87e110fef9ba7129df55a8adf3c44e6bf955 100644 --- a/src/vs/workbench/parts/markers/browser/markersFileDecorations.ts +++ b/src/vs/workbench/parts/markers/browser/markersFileDecorations.ts @@ -74,8 +74,8 @@ class MarkersFileDecorations implements IWorkbenchContribution { } private _updateEnablement(): void { - let value = this._configurationService.getConfiguration<{ showOnFiles: boolean }>('problems'); - if (value) { + let value = this._configurationService.getConfiguration<{ fileDecorations: { enabled: boolean } }>('problems'); + if (value.fileDecorations.enabled) { const provider = new MarkersDecorationsProvider(this._markerService); this._provider = this._decorationsService.registerDecortionsProvider(provider); } else if (this._provider) { diff --git a/src/vs/workbench/parts/markers/browser/markersWorkbenchContributions.ts b/src/vs/workbench/parts/markers/browser/markersWorkbenchContributions.ts index 45e7ca37718c0e9a7946629e521de16100b6ba5d..b3dbb71466953f03deb1add01366736884a1a0ca 100644 --- a/src/vs/workbench/parts/markers/browser/markersWorkbenchContributions.ts +++ b/src/vs/workbench/parts/markers/browser/markersWorkbenchContributions.ts @@ -56,8 +56,8 @@ export function registerContributions(): void { 'order': 101, 'type': 'object', 'properties': { - 'problems.showOnFiles': { - 'description': localize('markers.showOnFile', "Show Errors & Warnings in the file explorer."), + 'problems.fileDecorations.enabled': { + 'description': localize('markers.showOnFile', "Show Errors & Warnings on files and folder."), 'type': 'boolean', 'default': true } diff --git a/src/vs/workbench/parts/scm/electron-browser/scm.contribution.ts b/src/vs/workbench/parts/scm/electron-browser/scm.contribution.ts index 93da15cee6991658af761ca9ca555a58aca6d17c..9510db9af9eded5bc1cd4111fdb44e396cf1dc4c 100644 --- a/src/vs/workbench/parts/scm/electron-browser/scm.contribution.ts +++ b/src/vs/workbench/parts/scm/electron-browser/scm.contribution.ts @@ -19,6 +19,7 @@ import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/edi import { StatusUpdater, StatusBarController } from './scmActivity'; import { FileDecorations } from './scmFileDecorations'; import { SCMViewlet } from 'vs/workbench/parts/scm/electron-browser/scmViewlet'; +import { IConfigurationRegistry, Extensions } from 'vs/platform/configuration/common/configurationRegistry'; class OpenSCMViewletAction extends ToggleViewletAction { @@ -64,3 +65,17 @@ Registry.as(WorkbenchActionExtensions.WorkbenchActions 'View: Show SCM', localize('view', "View") ); + + +Registry.as(Extensions.Configuration).registerConfiguration({ + 'id': 'scm', + 'order': 101, + 'type': 'object', + 'properties': { + 'scm.fileDecorations.enabled': { + 'description': localize('scm.fileDecorations.enabled', "Show source control status on files and folders"), + 'type': 'boolean', + 'default': true + } + } +}); diff --git a/src/vs/workbench/parts/scm/electron-browser/scmFileDecorations.ts b/src/vs/workbench/parts/scm/electron-browser/scmFileDecorations.ts index 03aacefc1901d1306b9a891410b0a1dd664249be..332577c07a047e3c73bd0c3a066c48b57e6b4a8d 100644 --- a/src/vs/workbench/parts/scm/electron-browser/scmFileDecorations.ts +++ b/src/vs/workbench/parts/scm/electron-browser/scmFileDecorations.ts @@ -12,6 +12,7 @@ import { ISCMService, ISCMRepository, ISCMProvider, ISCMResource } from 'vs/work import URI from 'vs/base/common/uri'; import Severity from 'vs/base/common/severity'; import Event, { Emitter } from 'vs/base/common/event'; +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; class SCMDecorationsProvider implements IDecorationsProvider { @@ -32,6 +33,7 @@ class SCMDecorationsProvider implements IDecorationsProvider { dispose(): void { this._disposable.dispose(); + this._data.clear(); } private _updateGroups(): void { @@ -67,18 +69,17 @@ class SCMDecorationsProvider implements IDecorationsProvider { export class FileDecorations implements IWorkbenchContribution { - private readonly _disposables: IDisposable[]; - private readonly _providers = new Map(); + private _providers = new Map(); + private _configListener: IDisposable; + private _repoListeners: IDisposable[]; constructor( @IResourceDecorationsService private _decorationsService: IResourceDecorationsService, + @IConfigurationService private _configurationService: IConfigurationService, @ISCMService private _scmService: ISCMService, ) { - this._scmService.repositories.forEach(this._onDidAddRepository, this); - this._disposables = [ - this._scmService.onDidAddRepository(this._onDidAddRepository, this), - this._scmService.onDidRemoveRepository(this._onDidRemoveRepository, this), - ]; + this._configListener = this._configurationService.onDidUpdateConfiguration(this._update, this); + this._update(); } getId(): string { @@ -86,7 +87,23 @@ export class FileDecorations implements IWorkbenchContribution { } dispose(): void { - dispose(this._disposables); + this._providers.forEach(value => dispose(value)); + dispose(this._repoListeners); + dispose(this._configListener, this._configListener); + } + + private _update(): void { + const value = this._configurationService.getConfiguration<{ fileDecorations: { enabled: boolean } }>('scm'); + if (value.fileDecorations.enabled) { + this._scmService.repositories.forEach(this._onDidAddRepository, this); + this._repoListeners = [ + this._scmService.onDidAddRepository(this._onDidAddRepository, this), + this._scmService.onDidRemoveRepository(this._onDidRemoveRepository, this) + ]; + } else { + this._providers.forEach(value => dispose(value)); + this._repoListeners = dispose(this._repoListeners); + } } private _onDidAddRepository(repo: ISCMRepository): void { diff --git a/src/vs/workbench/services/decorations/browser/decorationsService.ts b/src/vs/workbench/services/decorations/browser/decorationsService.ts index 6fdc51d1749505d41735106b7f0a7bad3acdf999..99437905107a03d12fb9c70794c49b6114166687 100644 --- a/src/vs/workbench/services/decorations/browser/decorationsService.ts +++ b/src/vs/workbench/services/decorations/browser/decorationsService.ts @@ -6,7 +6,7 @@ import URI from 'vs/base/common/uri'; import Severity from 'vs/base/common/severity'; -import Event, { Emitter, debounceEvent } from 'vs/base/common/event'; +import Event, { Emitter, debounceEvent, any } from 'vs/base/common/event'; import { IResourceDecorationsService, IResourceDecoration, IResourceDecorationChangeEvent, IDecorationsProvider } from './decorations'; import { TernarySearchTree } from 'vs/base/common/map'; import { IDisposable } from 'vs/base/common/lifecycle'; @@ -61,6 +61,10 @@ class DecorationProviderWrapper { this._data.clear(); } + knowsAbout(uri: URI): boolean { + return Boolean(this._data.get(uri.toString())) || Boolean(this._data.findSuperstr(uri.toString())); + } + getOrRetrieve(uri: URI, includeChildren: boolean, callback: (data: IResourceDecoration) => void): void { const key = uri.toString(); const item = this._data.get(key); @@ -110,22 +114,28 @@ export class FileDecorationsService implements IResourceDecorationsService { _serviceBrand: any; private readonly _data = new LinkedList(); - private readonly _onDidChangeFileDecoration = new Emitter(); - - readonly onDidChangeDecorations: Event = debounceEvent( - this._onDidChangeFileDecoration.event, - FileDecorationChangeEvent.debouncer + private readonly _onDidChangeDecorationsDelayed = new Emitter(); + private readonly _onDidChangeDecorations = new Emitter(); + + readonly onDidChangeDecorations: Event = any( + this._onDidChangeDecorations.event, + debounceEvent( + this._onDidChangeDecorationsDelayed.event, + FileDecorationChangeEvent.debouncer + ) ); registerDecortionsProvider(provider: IDecorationsProvider): IDisposable { - const wrapper = new DecorationProviderWrapper(provider, this._onDidChangeFileDecoration); + const wrapper = new DecorationProviderWrapper(provider, this._onDidChangeDecorationsDelayed); const remove = this._data.push(wrapper); - // fire for all return { dispose: () => { - wrapper.dispose(); + // fire event that says 'yes' for any resource + // known to this provider. then dispose and remove it. remove(); + this._onDidChangeDecorations.fire({ affectsResource: uri => wrapper.knowsAbout(uri) }); + wrapper.dispose(); } }; }