From 9edf629c3b865d84d4468b1f210f209e71f97647 Mon Sep 17 00:00:00 2001 From: Eric Amodio Date: Mon, 6 Feb 2017 14:59:08 -0500 Subject: [PATCH] Reworks the design of hover annotations Combines activeline annotation settings --- package.json | 14 +++++--- src/blameAnnotationFormatter.ts | 30 +++++----------- src/blameAnnotationProvider.ts | 7 ++-- src/blameStatusBarController.ts | 63 ++++++++++++++++++++++++--------- src/configuration.ts | 4 +-- 5 files changed, 69 insertions(+), 49 deletions(-) diff --git a/package.json b/package.json index 0468073..efc6933 100644 --- a/package.json +++ b/package.json @@ -77,10 +77,16 @@ "default": false, "description": "Specifies whether the commit message will be shown in the blame annotations. Applies only to the `expanded` & `trailing` annotation styles" }, - "gitlens.blame.annotation.activeLine.enabled": { - "type": "boolean", - "default": true, - "description": "Specifies whether to show a trailing blame annotation (sha and commit message) of the active line" + "gitlens.blame.annotation.activeLine": { + "type": "string", + "default": "both", + "enum": [ + "off", + "inline", + "hover", + "both" + ], + "description": "Specifies whether and how to show blame annotations on the active line. `off` - no annotation. `inline` - adds a trailing annotation to the active line. `hover` - adds hover annotation to the active line. `both` - adds both `inline` and `hover` annotations" }, "gitlens.codeLens.visibility": { "type": "string", diff --git a/src/blameAnnotationFormatter.ts b/src/blameAnnotationFormatter.ts index 87d5258..189b8fc 100644 --- a/src/blameAnnotationFormatter.ts +++ b/src/blameAnnotationFormatter.ts @@ -1,6 +1,6 @@ 'use strict'; import { IBlameConfig } from './configuration'; -import { GitCommit, IGitBlame, IGitCommitLine } from './gitProvider'; +import { GitCommit, IGitCommitLine } from './gitProvider'; import * as moment from 'moment'; export const defaultShaLength = 8; @@ -50,38 +50,24 @@ export default class BlameAnnotationFormatter { return message; } - static getAnnotationHover(config: IBlameConfig, line: IGitCommitLine, commit: GitCommit, blame?: IGitBlame): string | Array { + static getAnnotationHover(config: IBlameConfig, line: IGitCommitLine, commit: GitCommit): string | Array { + const message = commit.message.replace(/\n/g, '\n\n'); if (commit.isUncommitted) { - let previous = blame && blame.commits.get(commit.previousSha); - if (previous) { - return [ - 'Uncommitted changes', - `_${previous.sha}_ - ${previous.message}`, - `${previous.author}, ${moment(previous.date).format('MMMM Do, YYYY h:MMa')}` - ]; - } - - return [ - 'Uncommitted changes', - `_${line.previousSha}_` - ]; + return `\`${'0'.repeat(8)}\`   __Uncommitted changes__ \n\n > ${message}`; } - return [ - `_${commit.sha}_ - ${commit.message}`, - `${commit.author}, ${moment(commit.date).format('MMMM Do, YYYY h:MMa')}` - ]; + return `\`${commit.sha}\`   __${commit.author}__, ${moment(commit.date).fromNow()} _(${moment(commit.date).format('MMMM Do, YYYY h:MMa')})_ \n\n > ${message}`; } - static getAuthorAndDate(config: IBlameConfig, commit: GitCommit, format?: string/*, truncate: boolean = false*/, force: boolean = false) { + static getAuthorAndDate(config: IBlameConfig, commit: GitCommit, format?: string, force: boolean = false) { if (!force && !config.annotation.author && (!config.annotation.date || config.annotation.date === 'off')) return ''; if (!config.annotation.author) { - return this.getDate(config, commit, format); //, truncate); + return this.getDate(config, commit, format); } if (!config.annotation.date || config.annotation.date === 'off') { - return this.getAuthor(config, commit); //, truncate ? defaultAuthorLength : 0); + return this.getAuthor(config, commit); } return `${this.getAuthor(config, commit)}, ${this.getDate(config, commit, format)}`; diff --git a/src/blameAnnotationProvider.ts b/src/blameAnnotationProvider.ts index 7c7cb51..351c842 100644 --- a/src/blameAnnotationProvider.ts +++ b/src/blameAnnotationProvider.ts @@ -167,8 +167,6 @@ export class BlameAnnotationProvider extends Disposable { color = l.previousSha ? '#999999' : '#6b6b6b'; } - const hoverMessage = BlameAnnotationFormatter.getAnnotationHover(this._config, l, commit, blame); - let gutter = ''; if (lastSha !== l.sha) { count = -1; @@ -192,6 +190,8 @@ export class BlameAnnotationProvider extends Disposable { } } + const hoverMessage = BlameAnnotationFormatter.getAnnotationHover(this._config, l, commit); + // Escape single quotes because for some reason that breaks the ::before or ::after element gutter = gutter.replace(/\'/g, '\\\''); @@ -274,11 +274,10 @@ export class BlameAnnotationProvider extends Disposable { } } - const hoverMessage = BlameAnnotationFormatter.getAnnotationHover(this._config, l, commit, blame); - const format = trailing ? BlameAnnotationFormat.Unconstrained : BlameAnnotationFormat.Constrained; // Escape single quotes because for some reason that breaks the ::before or ::after element const gutter = BlameAnnotationFormatter.getAnnotation(this._config, commit, format).replace(/\'/g, '\\\''); + const hoverMessage = BlameAnnotationFormatter.getAnnotationHover(this._config, l, commit); let renderOptions: DecorationInstanceRenderOptions; if (trailing) { diff --git a/src/blameStatusBarController.ts b/src/blameStatusBarController.ts index 8f10465..cb8e8af 100644 --- a/src/blameStatusBarController.ts +++ b/src/blameStatusBarController.ts @@ -72,7 +72,7 @@ export default class BlameStatusBarController extends Disposable { if (!Objects.areEquivalent(config.blame.annotation.activeLine, this._config && this._config.blame.annotation.activeLine)) { changed = true; - if (!config.blame.annotation.activeLine.enabled && this._editor) { + if (config.blame.annotation.activeLine !== 'off' && this._editor) { this._editor.setDecorations(activeLineDecoration, []); } } @@ -81,7 +81,7 @@ export default class BlameStatusBarController extends Disposable { if (!changed) return; - let trackActiveLine = config.statusBar.enabled || config.blame.annotation.activeLine.enabled; + let trackActiveLine = config.statusBar.enabled || config.blame.annotation.activeLine !== 'off'; if (trackActiveLine && !this._activeEditorLineDisposable) { const subscriptions: Disposable[] = []; @@ -176,7 +176,7 @@ export default class BlameStatusBarController extends Disposable { this._statusBarItem && this._statusBarItem.hide(); } - show(commit: GitCommit, blameLine: IGitCommitLine, editor: TextEditor) { + async show(commit: GitCommit, blameLine: IGitCommitLine, editor: TextEditor) { if (this._config.statusBar.enabled) { this._statusBarItem.text = `$(git-commit) ${commit.author}, ${moment(commit.date).fromNow()}`; @@ -204,7 +204,7 @@ export default class BlameStatusBarController extends Disposable { this._statusBarItem.show(); } - if (this._config.blame.annotation.activeLine.enabled) { + if (this._config.blame.annotation.activeLine !== 'off') { const offset = this._uri.offset; const config = { @@ -218,20 +218,51 @@ export default class BlameStatusBarController extends Disposable { // Escape single quotes because for some reason that breaks the ::before or ::after element const annotation = BlameAnnotationFormatter.getAnnotation(config, commit, BlameAnnotationFormat.Unconstrained).replace(/\'/g, '\\\''); - const hoverMessage = BlameAnnotationFormatter.getAnnotationHover(config, blameLine, commit); - const decorationOptions = { - range: editor.document.validateRange(new Range(blameLine.line + offset, 1000000, blameLine.line + offset, 1000000)), - hoverMessage: hoverMessage, - renderOptions: { - after: { - color: 'rgba(153, 153, 153, 0.3)', - contentText: annotation - } - } as DecorationInstanceRenderOptions - } as DecorationOptions; + // Get the full commit message -- since blame only returns the summary + let logCommit: GitCommit; + if (!commit.isUncommitted) { + const log = await this.git.getLogForFile(this._uri.fsPath, commit.sha, this._uri.repoPath, undefined, 1); + logCommit = log && log.commits.get(commit.sha); + } + const hoverMessage = BlameAnnotationFormatter.getAnnotationHover(config, blameLine, logCommit || commit); - editor.setDecorations(activeLineDecoration, [decorationOptions]); + let decorationOptions: DecorationOptions; + switch (this._config.blame.annotation.activeLine) { + case 'both': + decorationOptions = { + range: editor.document.validateRange(new Range(blameLine.line + offset, 0, blameLine.line + offset, 1000000)), + hoverMessage: hoverMessage, + renderOptions: { + after: { + color: 'rgba(153, 153, 153, 0.3)', + contentText: annotation + } + } as DecorationInstanceRenderOptions + } as DecorationOptions; + break; + + case 'inline': + decorationOptions = { + range: editor.document.validateRange(new Range(blameLine.line + offset, 1000000, blameLine.line + offset, 1000000)), + renderOptions: { + after: { + color: 'rgba(153, 153, 153, 0.3)', + contentText: annotation + } + } as DecorationInstanceRenderOptions + } as DecorationOptions; + break; + + case 'hover': + decorationOptions = { + range: editor.document.validateRange(new Range(blameLine.line + offset, 0, blameLine.line + offset, 1000000)), + hoverMessage: hoverMessage + } as DecorationOptions; + break; + } + + decorationOptions && editor.setDecorations(activeLineDecoration, [decorationOptions]); } } } \ No newline at end of file diff --git a/src/configuration.ts b/src/configuration.ts index 040e4f9..906d0d8 100644 --- a/src/configuration.ts +++ b/src/configuration.ts @@ -15,9 +15,7 @@ export interface IBlameConfig { author: boolean; date: 'off' | 'relative' | 'absolute'; message: boolean; - activeLine: { - enabled: boolean; - }; + activeLine: 'off' | 'inline' | 'hover' | 'both'; }; }