mirror of
https://github.com/ckaczor/vscode-gitlens.git
synced 2026-01-15 09:35:42 -05:00
122 lines
5.0 KiB
TypeScript
122 lines
5.0 KiB
TypeScript
'use strict';
|
|
import { Strings } from '../system';
|
|
import { DecorationOptions, Range } from 'vscode';
|
|
import { FileAnnotationType } from './annotationController';
|
|
import { Annotations, endOfLineIndex } from './annotations';
|
|
import { BlameAnnotationProviderBase } from './blameAnnotationProvider';
|
|
import { GlyphChars } from '../constants';
|
|
import { GitBlameCommit, ICommitFormatOptions } from '../gitService';
|
|
|
|
export class GutterBlameAnnotationProvider extends BlameAnnotationProviderBase {
|
|
|
|
async provideAnnotation(shaOrLine?: string | number, type?: FileAnnotationType): Promise<boolean> {
|
|
this.annotationType = FileAnnotationType.Gutter;
|
|
|
|
const blame = await this.getBlame(true);
|
|
if (blame === undefined) return false;
|
|
|
|
// console.time('Computing blame annotations...');
|
|
|
|
const cfg = this._config.annotations.file.gutter;
|
|
|
|
// Precalculate the formatting options so we don't need to do it on each iteration
|
|
const tokenOptions = Strings.getTokensFromTemplate(cfg.format)
|
|
.reduce((map, token) => {
|
|
map[token.key] = token.options as ICommitFormatOptions;
|
|
return map;
|
|
}, {} as { [token: string]: ICommitFormatOptions });
|
|
|
|
const options: ICommitFormatOptions = {
|
|
dateFormat: cfg.dateFormat === null ? this._config.defaultDateFormat : cfg.dateFormat,
|
|
tokenOptions: tokenOptions
|
|
};
|
|
|
|
const now = Date.now();
|
|
const offset = this.uri.offset;
|
|
const renderOptions = Annotations.gutterRenderOptions(this._config.theme, cfg.heatmap);
|
|
const dateFormat = this._config.defaultDateFormat;
|
|
const separateLines = this._config.theme.annotations.file.gutter.separateLines;
|
|
|
|
const decorations: DecorationOptions[] = [];
|
|
const document = this.document;
|
|
|
|
let commit: GitBlameCommit | undefined;
|
|
let compacted = false;
|
|
let details: DecorationOptions | undefined;
|
|
let gutter: DecorationOptions | undefined;
|
|
let previousSha: string | undefined;
|
|
|
|
for (const l of blame.lines) {
|
|
commit = blame.commits.get(l.sha);
|
|
if (commit === undefined) continue;
|
|
|
|
const line = l.line + offset;
|
|
|
|
if (previousSha === l.sha) {
|
|
// Use a shallow copy of the previous decoration options
|
|
gutter = { ...gutter } as DecorationOptions;
|
|
if (cfg.compact && !compacted) {
|
|
// Since we are wiping out the contextText make sure to copy the objects
|
|
gutter.renderOptions = { ...gutter.renderOptions };
|
|
gutter.renderOptions.before = {
|
|
...gutter.renderOptions.before,
|
|
...{ contentText: GlyphChars.Space.repeat(Strings.getWidth(gutter.renderOptions!.before!.contentText!)) }
|
|
};
|
|
|
|
if (separateLines) {
|
|
gutter.renderOptions.dark = { ...gutter.renderOptions.dark };
|
|
gutter.renderOptions.dark.before = { ...gutter.renderOptions.dark.before, ...{ textDecoration: 'none' } };
|
|
gutter.renderOptions.light = { ...gutter.renderOptions.light };
|
|
gutter.renderOptions.light.before = { ...gutter.renderOptions.light.before, ...{ textDecoration: 'none' } };
|
|
}
|
|
|
|
compacted = true;
|
|
}
|
|
|
|
const endIndex = document.lineAt(line).firstNonWhitespaceCharacterIndex;
|
|
gutter.range = new Range(line, 0, line, endIndex);
|
|
decorations.push(gutter);
|
|
|
|
if (details !== undefined) {
|
|
details = { ...details } as DecorationOptions;
|
|
details.range = cfg.hover.wholeLine
|
|
? document.validateRange(new Range(line, 0, line, endOfLineIndex))
|
|
: gutter.range;
|
|
decorations.push(details);
|
|
}
|
|
|
|
continue;
|
|
}
|
|
|
|
compacted = false;
|
|
previousSha = l.sha;
|
|
|
|
gutter = Annotations.gutter(commit, cfg.format, options, renderOptions);
|
|
|
|
if (cfg.heatmap.enabled) {
|
|
Annotations.applyHeatmap(gutter, commit.date, now);
|
|
}
|
|
|
|
const endIndex = document.lineAt(line).firstNonWhitespaceCharacterIndex;
|
|
gutter.range = new Range(line, 0, line, endIndex);
|
|
decorations.push(gutter);
|
|
|
|
if (cfg.hover.details) {
|
|
details = Annotations.detailsHover(commit, dateFormat);
|
|
details.range = cfg.hover.wholeLine
|
|
? document.validateRange(new Range(line, 0, line, endOfLineIndex))
|
|
: gutter.range;
|
|
decorations.push(details);
|
|
}
|
|
}
|
|
|
|
if (decorations.length) {
|
|
this.editor.setDecorations(this.decoration!, decorations);
|
|
}
|
|
|
|
// console.timeEnd('Computing blame annotations...');
|
|
|
|
this.selection(shaOrLine, blame);
|
|
return true;
|
|
}
|
|
} |