From 310a54758137800e7e4490807cb0acef22810801 Mon Sep 17 00:00:00 2001 From: Eric Amodio Date: Mon, 13 Feb 2017 01:44:54 -0500 Subject: [PATCH] Adds setting to control blame annotation highlight Fixes #24 --- README.md | 1 + package.json | 11 +++++ src/blameActiveLineController.ts | 6 +-- src/blameAnnotationController.ts | 84 ++++++++++++++++++++++++++++++-- src/blameAnnotationProvider.ts | 36 ++------------ src/configuration.ts | 1 + src/gitProvider.ts | 6 +-- 7 files changed, 103 insertions(+), 42 deletions(-) diff --git a/README.md b/README.md index af06d9d..fb9033a 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,7 @@ Provides Git CodeLens information (most recent commit, # of authors), on-demand |Name | Description |-----|------------ |`gitlens.blame.annotation.style`|Specifies the style of the blame annotations. `compact` - groups annotations to limit the repetition and also adds author and date when possible. `expanded` - shows an annotation on every line +|`gitlens.blame.annotation.highlight`|Specifies whether and how to highlight blame annotations. `none` - no highlight. `gutter` - adds a gutter icon. `line` - adds a full-line highlight. `both` - adds both `gutter` and `line` highlights |`gitlens.blame.annotation.sha`|Specifies whether the commit sha will be shown in the blame annotations. Applies only to the `expanded` & `trailing` annotation styles |`gitlens.blame.annotation.author`|Specifies whether the committer will be shown in the blame annotations. Applies only to the `expanded` & `trailing` annotation styles |`gitlens.blame.annotation.date`|Specifies whether the commit date will be shown in the blame annotations. Applies only to the `expanded` & `trailing` annotation styles diff --git a/package.json b/package.json index 3de380a..bdd95a5 100644 --- a/package.json +++ b/package.json @@ -52,6 +52,17 @@ ], "description": "Specifies the style of the blame annotations. `compact` - groups annotations to limit the repetition and also adds author and date when possible. `expanded` - shows an annotation before every line. `trailing` - shows an annotation after every line" }, + "gitlens.blame.annotation.highlight": { + "type": "string", + "default": "both", + "enum": [ + "none", + "gutter", + "line", + "both" + ], + "description": "Specifies whether and how to highlight blame annotations. `none` - no highlight. `gutter` - adds a gutter icon. `line` - adds a full-line highlight. `both` - adds both `gutter` and `line` highlights" + }, "gitlens.blame.annotation.sha": { "type": "boolean", "default": true, diff --git a/src/blameActiveLineController.ts b/src/blameActiveLineController.ts index 025dfed..559294f 100644 --- a/src/blameActiveLineController.ts +++ b/src/blameActiveLineController.ts @@ -33,11 +33,11 @@ export default class BlameActiveLineController extends Disposable { this._updateBlameDebounced = Functions.debounce(this._updateBlame, 50); - this._onConfigure(); + this._onConfigurationChanged(); const subscriptions: Disposable[] = []; - subscriptions.push(workspace.onDidChangeConfiguration(this._onConfigure, this)); + subscriptions.push(workspace.onDidChangeConfiguration(this._onConfigurationChanged, this)); subscriptions.push(git.onDidRemoveCacheEntry(this._onRemoveCacheEntry, this)); this._disposable = Disposable.from(...subscriptions); @@ -51,7 +51,7 @@ export default class BlameActiveLineController extends Disposable { this._disposable && this._disposable.dispose(); } - private _onConfigure() { + private _onConfigurationChanged() { const config = workspace.getConfiguration('').get('gitlens'); let changed: boolean = false; diff --git a/src/blameAnnotationController.ts b/src/blameAnnotationController.ts index 6e171da..3f15960 100644 --- a/src/blameAnnotationController.ts +++ b/src/blameAnnotationController.ts @@ -1,28 +1,40 @@ 'use strict'; import { Functions } from './system'; -import { Disposable, ExtensionContext, TextDocument, TextEditor, TextEditorViewColumnChangeEvent, window, workspace } from 'vscode'; +import { DecorationRenderOptions, Disposable, ExtensionContext, OverviewRulerLane, TextDocument, TextEditor, TextEditorDecorationType, TextEditorViewColumnChangeEvent, window, workspace } from 'vscode'; import { BlameAnnotationProvider } from './blameAnnotationProvider'; import { TextDocumentComparer, TextEditorComparer } from './comparers'; -// import { IAdvancedConfig } from './configuration'; +import { IBlameConfig } from './configuration'; import GitProvider from './gitProvider'; import { Logger } from './logger'; import WhitespaceController from './whitespaceController'; +export const blameDecoration: TextEditorDecorationType = window.createTextEditorDecorationType({ + before: { + margin: '0 1.75em 0 0' + }, + after: { + margin: '0 0 0 4em' + } +} as DecorationRenderOptions); + +export let highlightDecoration: TextEditorDecorationType; + export default class BlameAnnotationController extends Disposable { private _annotationProviders: Map = new Map(); private _blameAnnotationsDisposable: Disposable; + private _config: IBlameConfig; private _disposable: Disposable; private _whitespaceController: WhitespaceController | undefined; constructor(private context: ExtensionContext, private git: GitProvider) { super(() => this.dispose()); - this._onConfigure(); + this._onConfigurationChanged(); const subscriptions: Disposable[] = []; - subscriptions.push(workspace.onDidChangeConfiguration(this._onConfigure, this)); + subscriptions.push(workspace.onDidChangeConfiguration(this._onConfigurationChanged, this)); this._disposable = Disposable.from(...subscriptions); } @@ -35,7 +47,7 @@ export default class BlameAnnotationController extends Disposable { this._disposable && this._disposable.dispose(); } - private _onConfigure() { + private _onConfigurationChanged() { let toggleWhitespace = workspace.getConfiguration('gitlens.advanced.toggleWhitespace').get('enabled'); if (!toggleWhitespace) { // Until https://github.com/Microsoft/vscode/issues/11485 is fixed we need to toggle whitespace for non-monospace fonts and ligatures @@ -50,6 +62,68 @@ export default class BlameAnnotationController extends Disposable { this._whitespaceController.dispose(); this._whitespaceController = undefined; } + + const config = workspace.getConfiguration('gitlens').get('blame'); + + if (config.annotation.highlight !== (this._config && this._config.annotation.highlight)) { + highlightDecoration && highlightDecoration.dispose(); + + switch (config.annotation.highlight) { + case 'none': + highlightDecoration = undefined; + break; + + case 'gutter': + highlightDecoration = window.createTextEditorDecorationType({ + dark: { + gutterIconPath: this.context.asAbsolutePath('images/blame-dark.svg'), + overviewRulerColor: 'rgba(255, 255, 255, 0.75)' + }, + light: { + gutterIconPath: this.context.asAbsolutePath('images/blame-light.svg'), + overviewRulerColor: 'rgba(0, 0, 0, 0.75)' + }, + gutterIconSize: 'contain', + overviewRulerLane: OverviewRulerLane.Right + }); + break; + + case 'line': + highlightDecoration = window.createTextEditorDecorationType({ + dark: { + backgroundColor: 'rgba(255, 255, 255, 0.15)', + overviewRulerColor: 'rgba(255, 255, 255, 0.75)' + }, + light: { + backgroundColor: 'rgba(0, 0, 0, 0.15)', + overviewRulerColor: 'rgba(0, 0, 0, 0.75)' + }, + overviewRulerLane: OverviewRulerLane.Right, + isWholeLine: true + }); + break; + + case 'both': + highlightDecoration = window.createTextEditorDecorationType({ + dark: { + backgroundColor: 'rgba(255, 255, 255, 0.15)', + gutterIconPath: this.context.asAbsolutePath('images/blame-dark.svg'), + overviewRulerColor: 'rgba(255, 255, 255, 0.75)' + }, + light: { + backgroundColor: 'rgba(0, 0, 0, 0.15)', + gutterIconPath: this.context.asAbsolutePath('images/blame-light.svg'), + overviewRulerColor: 'rgba(0, 0, 0, 0.75)' + }, + gutterIconSize: 'contain', + overviewRulerLane: OverviewRulerLane.Right, + isWholeLine: true + }); + break; + } + } + + this._config = config; } async clear(column: number) { diff --git a/src/blameAnnotationProvider.ts b/src/blameAnnotationProvider.ts index ab8221b..5156313 100644 --- a/src/blameAnnotationProvider.ts +++ b/src/blameAnnotationProvider.ts @@ -1,23 +1,13 @@ 'use strict'; import { Iterables } from './system'; -import { DecorationInstanceRenderOptions, DecorationOptions, DecorationRenderOptions, Disposable, ExtensionContext, OverviewRulerLane, Range, TextDocument, TextEditor, TextEditorDecorationType, TextEditorSelectionChangeEvent, window, workspace } from 'vscode'; +import { DecorationInstanceRenderOptions, DecorationOptions, Disposable, ExtensionContext, Range, TextDocument, TextEditor, TextEditorSelectionChangeEvent, window, workspace } from 'vscode'; import BlameAnnotationFormatter, { BlameAnnotationFormat, cssIndent, defaultShaLength, defaultAuthorLength } from './blameAnnotationFormatter'; +import { blameDecoration, highlightDecoration } from './blameAnnotationController'; import { TextDocumentComparer } from './comparers'; import { BlameAnnotationStyle, IBlameConfig } from './configuration'; import GitProvider, { GitUri, IGitBlame } from './gitProvider'; import WhitespaceController from './whitespaceController'; -const blameDecoration: TextEditorDecorationType = window.createTextEditorDecorationType({ - before: { - margin: '0 1.75em 0 0' - }, - after: { - margin: '0 0 0 4em' - } -} as DecorationRenderOptions); - -let highlightDecoration: TextEditorDecorationType; - export class BlameAnnotationProvider extends Disposable { public document: TextDocument; @@ -30,24 +20,6 @@ export class BlameAnnotationProvider extends Disposable { constructor(context: ExtensionContext, private git: GitProvider, private whitespaceController: WhitespaceController | undefined, public editor: TextEditor) { super(() => this.dispose()); - if (!highlightDecoration) { - highlightDecoration = window.createTextEditorDecorationType({ - dark: { - backgroundColor: 'rgba(255, 255, 255, 0.15)', - gutterIconPath: context.asAbsolutePath('images/blame-dark.svg'), - overviewRulerColor: 'rgba(255, 255, 255, 0.75)' - }, - light: { - backgroundColor: 'rgba(0, 0, 0, 0.15)', - gutterIconPath: context.asAbsolutePath('images/blame-light.svg'), - overviewRulerColor: 'rgba(0, 0, 0, 0.75)' - }, - gutterIconSize: 'contain', - overviewRulerLane: OverviewRulerLane.Right, - isWholeLine: true - }); - } - this.document = this.editor.document; this._uri = GitUri.fromUri(this.document.uri, this.git); @@ -65,7 +37,7 @@ export class BlameAnnotationProvider extends Disposable { async dispose() { if (this.editor) { this.editor.setDecorations(blameDecoration, []); - this.editor.setDecorations(highlightDecoration, []); + highlightDecoration && this.editor.setDecorations(highlightDecoration, []); } // HACK: Until https://github.com/Microsoft/vscode/issues/11485 is fixed -- restore whitespace @@ -123,6 +95,8 @@ export class BlameAnnotationProvider extends Disposable { } private _setSelection(blame: IGitBlame, shaOrLine?: string | number) { + if (!highlightDecoration) return; + const offset = this._uri.offset; let sha: string; diff --git a/src/configuration.ts b/src/configuration.ts index db8b957..cc6641d 100644 --- a/src/configuration.ts +++ b/src/configuration.ts @@ -11,6 +11,7 @@ export const BlameAnnotationStyle = { export interface IBlameConfig { annotation: { style: BlameAnnotationStyle; + highlight: 'none' | 'gutter' | 'line' | 'both'; sha: boolean; author: boolean; date: 'off' | 'relative' | 'absolute'; diff --git a/src/gitProvider.ts b/src/gitProvider.ts index 40a5aac..e36127f 100644 --- a/src/gitProvider.ts +++ b/src/gitProvider.ts @@ -70,11 +70,11 @@ export default class GitProvider extends Disposable { this._repoPath = context.workspaceState.get(WorkspaceState.RepoPath) as string; - this._onConfigure(); + this._onConfigurationChanged(); const subscriptions: Disposable[] = []; - subscriptions.push(workspace.onDidChangeConfiguration(this._onConfigure, this)); + subscriptions.push(workspace.onDidChangeConfiguration(this._onConfigurationChanged, this)); this._disposable = Disposable.from(...subscriptions); } @@ -99,7 +99,7 @@ export default class GitProvider extends Disposable { return !!this._gitCache; } - private _onConfigure() { + private _onConfigurationChanged() { const config = workspace.getConfiguration().get('gitlens'); const codeLensChanged = !Objects.areEquivalent(config.codeLens, this.config && this.config.codeLens);