diff --git a/packages/git/src/browser/git-decoration-provider.ts b/packages/git/src/browser/git-decoration-provider.ts index c4ab65596cc99..94c1e1406057e 100644 --- a/packages/git/src/browser/git-decoration-provider.ts +++ b/packages/git/src/browser/git-decoration-provider.ts @@ -14,41 +14,55 @@ // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 // ***************************************************************************** -import { inject, injectable } from '@theia/core/shared/inversify'; +import { inject, injectable, postConstruct } from '@theia/core/shared/inversify'; import { GitFileChange, GitFileStatus, GitStatusChangeEvent } from '../common'; import { CancellationToken, Emitter, Event } from '@theia/core/lib/common'; import { Decoration, DecorationsProvider } from '@theia/core/lib/browser/decorations-service'; import { GitRepositoryTracker } from './git-repository-tracker'; import URI from '@theia/core/lib/common/uri'; +import { GitConfiguration, GitPreferences } from './git-preferences'; +import { PreferenceChangeEvent } from '@theia/core/lib/browser'; @injectable() export class GitDecorationProvider implements DecorationsProvider { + @inject(GitPreferences) protected readonly preferences: GitPreferences; + @inject(GitRepositoryTracker) protected readonly gitRepositoryTracker: GitRepositoryTracker; + + protected decorationsEnabled: boolean; + protected colorsEnabled: boolean; + + protected decorations = new Map(); + protected uris = new Set(); + private readonly onDidChangeDecorationsEmitter = new Emitter(); readonly onDidChange: Event = this.onDidChangeDecorationsEmitter.event; - private decorations = new Map(); + @postConstruct() + protected init(): void { + this.decorationsEnabled = this.preferences['git.decorations.enabled']; + this.colorsEnabled = this.preferences['git.decorations.colors']; + this.gitRepositoryTracker.onGitEvent((event: GitStatusChangeEvent | undefined) => this.handleGitEvent(event)); + this.preferences.onPreferenceChanged((event: PreferenceChangeEvent) => this.handlePreferenceChange(event)); + } - constructor(@inject(GitRepositoryTracker) protected readonly gitRepositoryTracker: GitRepositoryTracker) { - this.gitRepositoryTracker.onGitEvent((event: GitStatusChangeEvent | undefined) => { - this.onGitEvent(event); - }); + protected async handleGitEvent(event: GitStatusChangeEvent | undefined): Promise { + this.updateDecorations(event); + this.triggerDecorationChange(); } - private async onGitEvent(event: GitStatusChangeEvent | undefined): Promise { + protected updateDecorations(event?: GitStatusChangeEvent): void { if (!event) { return; } - const newDecorations = new Map(); this.collectDecorationData(event.status.changes, newDecorations); - const uris = new Set([...this.decorations.keys()].concat([...newDecorations.keys()])); + this.uris = new Set([...this.decorations.keys()].concat([...newDecorations.keys()])); this.decorations = newDecorations; - this.onDidChangeDecorationsEmitter.fire(Array.from(uris, value => new URI(value))); } - private collectDecorationData(changes: GitFileChange[], bucket: Map): void { + protected collectDecorationData(changes: GitFileChange[], bucket: Map): void { changes.forEach(change => { const color = GitFileStatus.getColor(change.status, change.staged); bucket.set(change.uri, { @@ -61,7 +75,48 @@ export class GitDecorationProvider implements DecorationsProvider { } provideDecorations(uri: URI, token: CancellationToken): Decoration | Promise | undefined { - return this.decorations.get(uri.toString()); + if (this.decorationsEnabled) { + const decoration = this.decorations.get(uri.toString()); + if (decoration && !this.colorsEnabled) { + // Remove decoration color if disabled. + return { + ...decoration, + colorId: undefined + }; + } + return decoration; + } + return undefined; } + + protected handlePreferenceChange(event: PreferenceChangeEvent): void { + const { preferenceName, newValue } = event; + let updateDecorations = false; + if (preferenceName === 'git.decorations.enabled') { + updateDecorations = true; + const decorationsEnabled = !!newValue; + if (this.decorationsEnabled !== decorationsEnabled) { + this.decorationsEnabled = decorationsEnabled; + } + } + if (preferenceName === 'git.decorations.colors') { + updateDecorations = true; + const colorsEnabled = !!newValue; + if (this.colorsEnabled !== colorsEnabled) { + this.colorsEnabled = colorsEnabled; + } + } + if (updateDecorations) { + this.triggerDecorationChange(); + } + } + + /** + * Notify that the provider has been updated to trigger a re-render of decorations. + */ + protected triggerDecorationChange(): void { + this.onDidChangeDecorationsEmitter.fire(Array.from(this.uris, value => new URI(value))); + } + } diff --git a/packages/git/src/browser/git-preferences.ts b/packages/git/src/browser/git-preferences.ts index 48e7bec6fab7a..3afbed8d4e41d 100644 --- a/packages/git/src/browser/git-preferences.ts +++ b/packages/git/src/browser/git-preferences.ts @@ -31,7 +31,7 @@ export const GitConfigSchema: PreferenceSchema = { 'git.decorations.colors': { 'type': 'boolean', 'description': nls.localize('theia/git/gitDecorationsColors', 'Use color decoration in the navigator.'), - 'default': false + 'default': true }, 'git.editor.decorations.enabled': { 'type': 'boolean',