Parcourir la source

Closes #182 - adds heatmap annotations

main
Eric Amodio il y a 7 ans
Parent
révision
b01d7abb62
9 fichiers modifiés avec 156 ajouts et 0 suppressions
  1. +5
    -0
      CHANGELOG.md
  2. +9
    -0
      README.md
  3. +9
    -0
      package.json
  4. +10
    -0
      src/annotations/annotationController.ts
  5. +22
    -0
      src/annotations/annotations.ts
  6. +63
    -0
      src/annotations/heatmapBlameAnnotationProvider.ts
  7. +2
    -0
      src/commands.ts
  8. +1
    -0
      src/commands/common.ts
  9. +35
    -0
      src/commands/toggleFileHeatmap.ts

+ 5
- 0
CHANGELOG.md Voir le fichier

@ -6,6 +6,11 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p
## [Unreleased]
### Added
- Adds on-demand **heatmap annotations** of the whole file -- closes [#182](https://github.com/eamodio/vscode-gitlens/issues/182)
- Displays a `heatmap` (age) indicator near the gutter, which provides an easy, at-a-glance way to tell the age of a line
- Indicator ranges from bright yellow (newer) to dark brown (older)
- Press `Escape` to quickly toggle the annotations off
- Adds `Toggle File Heatmap Annotations` command (`gitlens.toggleFileHeatmap`) to toggle the heatmap annotations on and off
- Adds semi-persistent results for commit operations, via the `Show Commit Details` command (`gitlens.showQuickCommitDetails`) in the `GitLens Results` view -- closes [#237](https://github.com/eamodio/vscode-gitlens/issues/237)
- Adds `Show in Results` option to the commit details quick pick menu to show the commit in the `GitLens Results` view
- Adds `Compare with Index (HEAD)` command (`gitlens.explorers.compareWithHead`) to branch, remote branch, tag, and revision (commit) nodes in the `GitLens` view to compare the current selection with the current index (HEAD) in the `GitLens Results` view

+ 9
- 0
README.md Voir le fichier

@ -93,6 +93,15 @@ While GitLens is highly customizable and provides many [configuration settings](
- Adds a `Toggle Line Blame Annotations` command (`gitlens.toggleLineBlame`) to toggle the current line blame annotations on and off
- Also adds a `Show Line Blame Annotations` command (`gitlens.showLineBlame`)
### Git Heatmap Annotations
- Adds on-demand **heatmap annotations** of the whole file
- Displays a `heatmap` (age) indicator near the gutter, which provides an easy, at-a-glance way to tell the age of a line
- Indicator ranges from bright yellow (newer) to dark brown (older)
- Press `Escape` to quickly toggle the annotations off
- Adds `Toggle File Heatmap Annotations` command (`gitlens.toggleFileHeatmap`) to toggle the heatmap annotations on and off
### Git Recent Changes Annotations
- Adds on-demand, [customizable](#file-recent-changes-annotation-settings) and [themable](#themable-colors), **recent changes annotations** of the whole file

+ 9
- 0
package.json Voir le fichier

@ -1215,6 +1215,11 @@
}
},
{
"command": "gitlens.toggleFileHeatmap",
"title": "Toggle File Heatmap Annotations",
"category": "GitLens"
},
{
"command": "gitlens.toggleFileRecentChanges",
"title": "Toggle Recent File Changes Annotations",
"category": "GitLens",
@ -1677,6 +1682,10 @@
"when": "false"
},
{
"command": "gitlens.toggleFileHeatmap",
"when": "gitlens:activeIsBlameable"
},
{
"command": "gitlens.toggleFileRecentChanges",
"when": "gitlens:activeIsTracked"
},

+ 10
- 0
src/annotations/annotationController.ts Voir le fichier

@ -7,6 +7,7 @@ import { configuration, IConfig, LineHighlightLocations } from '../configuration
import { CommandContext, isTextEditor, setCommandContext } from '../constants';
import { BlameabilityChangeEvent, GitContextTracker, GitService, GitUri } from '../gitService';
import { GutterBlameAnnotationProvider } from './gutterBlameAnnotationProvider';
import { HeatmapBlameAnnotationProvider } from './heatmapBlameAnnotationProvider';
import { HoverBlameAnnotationProvider } from './hoverBlameAnnotationProvider';
import { Keyboard, KeyboardScope, KeyCommand, Keys } from '../keyboard';
import { Logger } from '../logger';
@ -15,6 +16,7 @@ import * as path from 'path';
export enum FileAnnotationType {
Gutter = 'gutter',
Heatmap = 'heatmap',
Hover = 'hover',
RecentChanges = 'recentChanges'
}
@ -343,6 +345,10 @@ export class AnnotationController extends Disposable {
annotationsLabel = 'blame annotations';
break;
case FileAnnotationType.Heatmap:
annotationsLabel = 'heatmap annotations';
break;
case FileAnnotationType.RecentChanges:
annotationsLabel = 'recent changes annotations';
break;
@ -362,6 +368,10 @@ export class AnnotationController extends Disposable {
provider = new GutterBlameAnnotationProvider(this.context, editor, Decorations.blameAnnotation, Decorations.blameHighlight, this.git, gitUri);
break;
case FileAnnotationType.Heatmap:
provider = new HeatmapBlameAnnotationProvider(this.context, editor, Decorations.blameAnnotation, undefined, this.git, gitUri);
break;
case FileAnnotationType.Hover:
provider = new HoverBlameAnnotationProvider(this.context, editor, Decorations.blameAnnotation, Decorations.blameHighlight, this.git, gitUri);
break;

+ 22
- 0
src/annotations/annotations.ts Voir le fichier

@ -207,6 +207,28 @@ export class Annotations {
} as IRenderOptions;
}
static heatmap(commit: GitCommit, now: number, renderOptions: IRenderOptions): DecorationOptions {
const decoration = {
renderOptions: {
before: { ...renderOptions }
} as DecorationInstanceRenderOptions
} as DecorationOptions;
Annotations.applyHeatmap(decoration, commit.date, now);
return decoration;
}
static heatmapRenderOptions(): IRenderOptions {
return {
borderStyle: 'solid',
borderWidth: '0 0 0 2px',
contentText: GlyphChars.ZeroWidthSpace,
height: '100%',
margin: '0 26px -1px 0'
} as IRenderOptions;
}
static hover(commit: GitCommit, renderOptions: IRenderOptions, now: number): DecorationOptions {
const decoration = {
renderOptions: { before: { ...renderOptions } }

+ 63
- 0
src/annotations/heatmapBlameAnnotationProvider.ts Voir le fichier

@ -0,0 +1,63 @@
'use strict';
import { DecorationOptions, Range } from 'vscode';
import { FileAnnotationType } from './annotationController';
import { Annotations } from './annotations';
import { BlameAnnotationProviderBase } from './blameAnnotationProvider';
import { GitBlameCommit } from '../gitService';
import { Logger } from '../logger';
export class HeatmapBlameAnnotationProvider extends BlameAnnotationProviderBase {
async provideAnnotation(shaOrLine?: string | number, type?: FileAnnotationType): Promise<boolean> {
this.annotationType = FileAnnotationType.Heatmap;
const blame = await this.getBlame();
if (blame === undefined) return false;
const start = process.hrtime();
const now = Date.now();
const renderOptions = Annotations.heatmapRenderOptions();
this._decorations = [];
const decorationsMap: { [sha: string]: DecorationOptions | undefined } = Object.create(null);
let commit: GitBlameCommit | undefined;
let heatmap: DecorationOptions | undefined;
for (const l of blame.lines) {
const line = l.line;
heatmap = decorationsMap[l.sha];
if (heatmap !== undefined) {
heatmap = {
...heatmap,
range: new Range(line, 0, line, 0)
} as DecorationOptions;
this._decorations.push(heatmap);
continue;
}
commit = blame.commits.get(l.sha);
if (commit === undefined) continue;
heatmap = Annotations.heatmap(commit, now, renderOptions);
heatmap.range = new Range(line, 0, line, 0);
this._decorations.push(heatmap);
decorationsMap[l.sha] = heatmap;
}
if (this._decorations.length) {
this.editor.setDecorations(this.decoration!, this._decorations);
}
const duration = process.hrtime(start);
Logger.log(`${(duration[0] * 1000) + Math.floor(duration[1] / 1000000)} ms to compute heatmap annotations`);
this.selection(shaOrLine, blame);
return true;
}
}

+ 2
- 0
src/commands.ts Voir le fichier

@ -47,6 +47,7 @@ export * from './commands/stashDelete';
export * from './commands/stashSave';
export * from './commands/toggleCodeLens';
export * from './commands/toggleFileBlame';
export * from './commands/toggleFileHeatmap';
export * from './commands/toggleFileRecentChanges';
export * from './commands/toggleLineBlame';
@ -87,6 +88,7 @@ export function configureCommands(
context.subscriptions.push(new Commands.ShowFileBlameCommand(annotationController));
context.subscriptions.push(new Commands.ShowLineBlameCommand(currentLineController));
context.subscriptions.push(new Commands.ToggleFileBlameCommand(annotationController));
context.subscriptions.push(new Commands.ToggleFileHeatmapCommand(annotationController));
context.subscriptions.push(new Commands.ToggleFileRecentChangesCommand(annotationController));
context.subscriptions.push(new Commands.ToggleLineBlameCommand(currentLineController));
context.subscriptions.push(new Commands.ResetSuppressedWarningsCommand());

+ 1
- 0
src/commands/common.ts Voir le fichier

@ -49,6 +49,7 @@ export enum Commands {
StashSave = 'gitlens.stashSave',
ToggleCodeLens = 'gitlens.toggleCodeLens',
ToggleFileBlame = 'gitlens.toggleFileBlame',
ToggleFileHeatmap = 'gitlens.toggleFileHeatmap',
ToggleFileRecentChanges = 'gitlens.toggleFileRecentChanges',
ToggleLineBlame = 'gitlens.toggleLineBlame'
}

+ 35
- 0
src/commands/toggleFileHeatmap.ts Voir le fichier

@ -0,0 +1,35 @@
'use strict';
import { TextEditor, TextEditorEdit, Uri, window } from 'vscode';
import { AnnotationController, FileAnnotationType } from '../annotations/annotationController';
import { Commands, EditorCommand } from './common';
import { UriComparer } from '../comparers';
import { Logger } from '../logger';
export class ToggleFileHeatmapCommand extends EditorCommand {
constructor(
private readonly annotationController: AnnotationController
) {
super(Commands.ToggleFileHeatmap);
}
async execute(editor: TextEditor, edit: TextEditorEdit, uri?: Uri): Promise<any> {
if (editor === undefined || editor.document.isDirty) return undefined;
// Handle the case where we are focused on a non-editor editor (output, debug console)
if (uri !== undefined && !UriComparer.equals(uri, editor.document.uri)) {
const e = window.visibleTextEditors.find(e => UriComparer.equals(uri, e.document.uri));
if (e !== undefined && !e.document.isDirty) {
editor = e;
}
}
try {
return this.annotationController.toggleAnnotations(editor, FileAnnotationType.Heatmap);
}
catch (ex) {
Logger.error(ex, 'ToggleFileHeatmapCommand');
return window.showErrorMessage(`Unable to toggle heatmap annotations. See output channel for more details`);
}
}
}

Chargement…
Annuler
Enregistrer