Skip to content

Commit

Permalink
Adds paused blame indication in the status bar blame
Browse files Browse the repository at this point in the history
Refactors document & line tracking for Git annotations
Consolidated into GitDocumentTracker, TrackedGitDocument, and GitLineTracker to simplify the code
  • Loading branch information
eamodio committed Jan 15, 2024
1 parent 310606b commit e522866
Show file tree
Hide file tree
Showing 23 changed files with 505 additions and 522 deletions.
5 changes: 2 additions & 3 deletions src/annotations/annotationProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ import type { FileAnnotationType } from '../config';
import type { Container } from '../container';
import { setContext } from '../system/context';
import { Logger } from '../system/logger';
import type { GitDocumentState } from '../trackers/gitDocumentTracker';
import type { TrackedDocument } from '../trackers/trackedDocument';
import type { TrackedGitDocument } from '../trackers/trackedDocument';
import type { Decoration } from './annotations';

export type AnnotationStatus = 'computing' | 'computed';
Expand Down Expand Up @@ -34,7 +33,7 @@ export abstract class AnnotationProviderBase<TContext extends AnnotationContext
protected readonly container: Container,
public readonly annotationType: FileAnnotationType,
editor: TextEditor,
protected readonly trackedDocument: TrackedDocument<GitDocumentState>,
protected readonly trackedDocument: TrackedGitDocument,
) {
this.editor = editor;

Expand Down
5 changes: 2 additions & 3 deletions src/annotations/blameAnnotationProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ import type { GitCommit } from '../git/models/commit';
import { changesMessage, detailsMessage } from '../hovers/hovers';
import { configuration } from '../system/configuration';
import { log } from '../system/decorators/log';
import type { GitDocumentState } from '../trackers/gitDocumentTracker';
import type { TrackedDocument } from '../trackers/trackedDocument';
import type { TrackedGitDocument } from '../trackers/trackedDocument';
import { AnnotationProviderBase } from './annotationProvider';
import type { ComputedHeatmap } from './annotations';
import { getHeatmapColors } from './annotations';
Expand All @@ -24,7 +23,7 @@ export abstract class BlameAnnotationProviderBase extends AnnotationProviderBase
container: Container,
annotationType: FileAnnotationType,
editor: TextEditor,
trackedDocument: TrackedDocument<GitDocumentState>,
trackedDocument: TrackedGitDocument,
) {
super(container, annotationType, editor, trackedDocument);

Expand Down
23 changes: 11 additions & 12 deletions src/annotations/fileAnnotationController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ import type {
DocumentDirtyIdleTriggerEvent,
DocumentDirtyStateChangeEvent,
} from '../trackers/documentTracker';
import type { GitDocumentState } from '../trackers/gitDocumentTracker';
import type { AnnotationContext, AnnotationProviderBase, TextEditorCorrelationKey } from './annotationProvider';
import { getEditorCorrelationKey } from './annotationProvider';
import type { ChangesAnnotationContext } from './gutterChangesAnnotationProvider';
Expand Down Expand Up @@ -195,7 +194,7 @@ export class FileAnnotationController implements Disposable {
}
}

private onBlameStateChanged(e: DocumentBlameStateChangeEvent<GitDocumentState>) {
private onBlameStateChanged(e: DocumentBlameStateChangeEvent) {
const editor = window.activeTextEditor;
if (editor == null) return;

Expand All @@ -211,7 +210,7 @@ export class FileAnnotationController implements Disposable {
void this.clear(editor, 'BlameabilityChanged');
}

private onDirtyIdleTriggered(e: DocumentDirtyIdleTriggerEvent<GitDocumentState>) {
private onDirtyIdleTriggered(e: DocumentDirtyIdleTriggerEvent) {
if (!e.document.isBlameable || !configuration.get('experimental.allowAnnotationsWhenDirty')) return;

const editor = window.activeTextEditor;
Expand All @@ -220,7 +219,7 @@ export class FileAnnotationController implements Disposable {
this.restore(editor);
}

private onDirtyStateChanged(e: DocumentDirtyStateChangeEvent<GitDocumentState>) {
private onDirtyStateChanged(e: DocumentDirtyStateChangeEvent) {
for (const [key, p] of this._annotationProviders) {
if (!e.document.is(p.editor.document)) continue;

Expand Down Expand Up @@ -296,8 +295,8 @@ export class FileAnnotationController implements Disposable {
const provider = this.getProvider(editor);
if (provider == null) return undefined;

const trackedDocument = await this.container.tracker.get(editor!.document);
if (trackedDocument == null || !trackedDocument.isBlameable) return undefined;
const trackedDocument = await this.container.documentTracker.get(editor!.document);
if (!trackedDocument?.isBlameable) return undefined;

return provider.annotationType;
}
Expand Down Expand Up @@ -355,7 +354,7 @@ export class FileAnnotationController implements Disposable {
if (editor == null) return false; // || editor.viewColumn == null) return false;
this._editor = editor;

const trackedDocument = await this.container.tracker.getOrAdd(editor.document);
const trackedDocument = await this.container.documentTracker.getOrAdd(editor.document);
if (!trackedDocument.isBlameable) return false;

const currentProvider = this.getProvider(editor);
Expand Down Expand Up @@ -402,7 +401,7 @@ export class FileAnnotationController implements Disposable {
on?: boolean,
): Promise<boolean> {
if (editor != null && this._toggleModes.get(type) === 'file') {
const trackedDocument = await this.container.tracker.getOrAdd(editor.document);
const trackedDocument = await this.container.documentTracker.getOrAdd(editor.document);
if ((type === 'changes' && !trackedDocument.isTracked) || !trackedDocument.isBlameable) {
return false;
}
Expand Down Expand Up @@ -521,7 +520,7 @@ export class FileAnnotationController implements Disposable {
// Allows pressing escape to exit the annotations
await this.attachKeyboardHook();

const trackedDocument = await this.container.tracker.getOrAdd(editor.document);
const trackedDocument = await this.container.documentTracker.getOrAdd(editor.document);

let provider: AnnotationProviderBase | undefined = undefined;
switch (type) {
Expand Down Expand Up @@ -561,9 +560,9 @@ export class FileAnnotationController implements Disposable {
window.onDidChangeTextEditorViewColumn(this.onTextEditorViewColumnChanged, this),
window.onDidChangeVisibleTextEditors(debounce(this.onVisibleTextEditorsChanged, 50), this),
workspace.onDidCloseTextDocument(this.onTextDocumentClosed, this),
this.container.tracker.onDidChangeBlameState(this.onBlameStateChanged, this),
this.container.tracker.onDidChangeDirtyState(this.onDirtyStateChanged, this),
this.container.tracker.onDidTriggerDirtyIdle(this.onDirtyIdleTriggered, this),
this.container.documentTracker.onDidChangeBlameState(this.onBlameStateChanged, this),
this.container.documentTracker.onDidChangeDirtyState(this.onDirtyStateChanged, this),
this.container.documentTracker.onDidTriggerDirtyIdle(this.onDirtyIdleTriggered, this),
registerCommand('gitlens.annotations.nextChange', () => this.nextChange()),
registerCommand('gitlens.annotations.previousChange', () => this.previousChange()),
);
Expand Down
5 changes: 2 additions & 3 deletions src/annotations/gutterBlameAnnotationProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@ import { getLogScope } from '../system/logger.scope';
import { maybeStopWatch } from '../system/stopwatch';
import type { TokenOptions } from '../system/string';
import { getTokensFromTemplate, getWidth } from '../system/string';
import type { GitDocumentState } from '../trackers/gitDocumentTracker';
import type { TrackedDocument } from '../trackers/trackedDocument';
import type { TrackedGitDocument } from '../trackers/trackedDocument';
import type { AnnotationContext, AnnotationState } from './annotationProvider';
import { applyHeatmap, getGutterDecoration, getGutterRenderOptions } from './annotations';
import { BlameAnnotationProviderBase } from './blameAnnotationProvider';
Expand All @@ -24,7 +23,7 @@ import { Decorations } from './fileAnnotationController';
const maxSmallIntegerV8 = 2 ** 30; // Max number that can be stored in V8's smis (small integers)

export class GutterBlameAnnotationProvider extends BlameAnnotationProviderBase {
constructor(container: Container, editor: TextEditor, trackedDocument: TrackedDocument<GitDocumentState>) {
constructor(container: Container, editor: TextEditor, trackedDocument: TrackedGitDocument) {
super(container, 'blame', editor, trackedDocument);
}

Expand Down
5 changes: 2 additions & 3 deletions src/annotations/gutterChangesAnnotationProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@ import { log } from '../system/decorators/log';
import { getLogScope } from '../system/logger.scope';
import { getSettledValue } from '../system/promise';
import { maybeStopWatch } from '../system/stopwatch';
import type { GitDocumentState } from '../trackers/gitDocumentTracker';
import type { TrackedDocument } from '../trackers/trackedDocument';
import type { TrackedGitDocument } from '../trackers/trackedDocument';
import type { AnnotationContext, AnnotationState } from './annotationProvider';
import { AnnotationProviderBase } from './annotationProvider';
import type { Decoration } from './annotations';
Expand All @@ -28,7 +27,7 @@ export class GutterChangesAnnotationProvider extends AnnotationProviderBase<Chan
private sortedHunkStarts: number[] | undefined;
private state: { commit: GitCommit | undefined; diffs: GitDiffFile[] } | undefined;

constructor(container: Container, editor: TextEditor, trackedDocument: TrackedDocument<GitDocumentState>) {
constructor(container: Container, editor: TextEditor, trackedDocument: TrackedGitDocument) {
super(container, 'changes', editor, trackedDocument);
}

Expand Down
5 changes: 2 additions & 3 deletions src/annotations/gutterHeatmapBlameAnnotationProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,14 @@ import type { GitCommit } from '../git/models/commit';
import { log } from '../system/decorators/log';
import { getLogScope } from '../system/logger.scope';
import { maybeStopWatch } from '../system/stopwatch';
import type { GitDocumentState } from '../trackers/gitDocumentTracker';
import type { TrackedDocument } from '../trackers/trackedDocument';
import type { TrackedGitDocument } from '../trackers/trackedDocument';
import type { AnnotationContext, AnnotationState } from './annotationProvider';
import type { Decoration } from './annotations';
import { addOrUpdateGutterHeatmapDecoration } from './annotations';
import { BlameAnnotationProviderBase } from './blameAnnotationProvider';

export class GutterHeatmapBlameAnnotationProvider extends BlameAnnotationProviderBase {
constructor(container: Container, editor: TextEditor, trackedDocument: TrackedDocument<GitDocumentState>) {
constructor(container: Container, editor: TextEditor, trackedDocument: TrackedGitDocument) {
super(container, 'heatmap', editor, trackedDocument);
}

Expand Down
9 changes: 4 additions & 5 deletions src/annotations/lineAnnotationController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@ import { Logger } from '../system/logger';
import { getLogScope, setLogScopeExit } from '../system/logger.scope';
import { getSettledValue } from '../system/promise';
import { isTextEditor } from '../system/utils';
import type { GitLineState } from '../trackers/gitLineTracker';
import type { LinesChangeEvent } from '../trackers/lineTracker';
import type { LinesChangeEvent, LineState } from '../trackers/lineTracker';
import { getInlineDecoration } from './annotations';

const annotationDecoration: TextEditorDecorationType = window.createTextEditorDecorationType({
Expand Down Expand Up @@ -153,7 +152,7 @@ export class LineAnnotationController implements Disposable {

private getPullRequestsForLines(
repoPath: string,
lines: Map<number, GitLineState>,
lines: Map<number, LineState>,
): Map<string, Promise<PullRequest | undefined>> {
const prs = new Map<string, Promise<PullRequest | undefined>>();
if (lines.size === 0) return prs;
Expand Down Expand Up @@ -205,7 +204,7 @@ export class LineAnnotationController implements Disposable {
return;
}

const trackedDocument = await this.container.tracker.getOrAdd(editor.document);
const trackedDocument = await this.container.documentTracker.getOrAdd(editor.document);
if (!trackedDocument.isBlameable && this.suspended) {
if (scope != null) {
scope.exitDetails = ` ${GlyphChars.Dot} Skipped because the ${
Expand Down Expand Up @@ -242,7 +241,7 @@ export class LineAnnotationController implements Disposable {
let uncommittedOnly = true;

const commitPromises = new Map<string, Promise<void>>();
const lines = new Map<number, GitLineState>();
const lines = new Map<number, LineState>();
for (const selection of selections) {
const state = this.container.lineTracker.getState(selection.active);
if (state?.commit == null) {
Expand Down
16 changes: 6 additions & 10 deletions src/codelens/codeLensController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import { setContext } from '../system/context';
import { once } from '../system/event';
import { Logger } from '../system/logger';
import type { DocumentBlameStateChangeEvent, DocumentDirtyIdleTriggerEvent } from '../trackers/documentTracker';
import type { GitDocumentState } from '../trackers/gitDocumentTracker';

export class GitCodeLensController implements Disposable {
private _canToggle: boolean = false;
Expand Down Expand Up @@ -49,22 +48,19 @@ export class GitCodeLensController implements Disposable {
}
}

private onBlameStateChanged(e: DocumentBlameStateChangeEvent<GitDocumentState>) {
private onBlameStateChanged(e: DocumentBlameStateChangeEvent) {
// Only reset if we have saved, since the CodeLens won't naturally be re-rendered
if (this._provider == null || !e.blameable) return;

Logger.log('Blame state changed; resetting CodeLens provider');
this._provider.reset('saved');
this._provider.reset();
}

private onDirtyIdleTriggered(e: DocumentDirtyIdleTriggerEvent<GitDocumentState>) {
private onDirtyIdleTriggered(e: DocumentDirtyIdleTriggerEvent) {
if (this._provider == null || !e.document.isBlameable) return;

const maxLines = configuration.get('advanced.blame.sizeThresholdAfterEdit');
if (maxLines > 0 && e.document.lineCount > maxLines) return;

Logger.log('Dirty idle triggered; resetting CodeLens provider');
this._provider.reset('idle');
this._provider.reset();
}

toggleCodeLens() {
Expand Down Expand Up @@ -95,8 +91,8 @@ export class GitCodeLensController implements Disposable {
this._provider = new GitCodeLensProvider(this.container);
this._providerDisposable = Disposable.from(
languages.registerCodeLensProvider(GitCodeLensProvider.selector, this._provider),
this.container.tracker.onDidChangeBlameState(this.onBlameStateChanged, this),
this.container.tracker.onDidTriggerDirtyIdle(this.onDirtyIdleTriggered, this),
this.container.documentTracker.onDidChangeBlameState(this.onBlameStateChanged, this),
this.container.documentTracker.onDidTriggerDirtyIdle(this.onDirtyIdleTriggered, this),
);
}
}
17 changes: 5 additions & 12 deletions src/codelens/codeLensProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,28 +91,21 @@ export class GitCodeLensProvider implements CodeLensProvider {

constructor(private readonly container: Container) {}

reset(_reason?: 'idle' | 'saved') {
reset() {
this._onDidChangeCodeLenses.fire();
}

async provideCodeLenses(document: TextDocument, token: CancellationToken): Promise<CodeLens[]> {
// Since we can't currently blame edited virtual documents, don't even attempt anything if dirty
if (document.isDirty && isVirtualUri(document.uri)) return [];

const trackedDocument = await this.container.tracker.getOrAdd(document);
const trackedDocument = await this.container.documentTracker.getOrAdd(document);
if (!trackedDocument.isBlameable) return [];

let dirty = false;
if (document.isDirty) {
// Only allow dirty blames if we are idle
if (trackedDocument.isDirtyIdle) {
const maxLines = configuration.get('advanced.blame.sizeThresholdAfterEdit');
if (maxLines > 0 && document.lineCount > maxLines) {
dirty = true;
}
} else {
dirty = true;
}
// Only allow dirty blames if we are idle
if (document.isDirty && !trackedDocument.isDirtyIdle) {
dirty = true;
}

const cfg = configuration.get('codeLens', document);
Expand Down
20 changes: 10 additions & 10 deletions src/container.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@ import type { Storage } from './system/storage';
import { TelemetryService } from './telemetry/telemetry';
import { UsageTracker } from './telemetry/usageTracker';
import { GitTerminalLinkProvider } from './terminal/linkProvider';
import { GitDocumentTracker } from './trackers/gitDocumentTracker';
import { GitLineTracker } from './trackers/gitLineTracker';
import { GitDocumentTracker } from './trackers/documentTracker';
import { LineTracker } from './trackers/lineTracker';
import { DeepLinkService } from './uris/deepLinks/deepLinkService';
import { UriService } from './uris/uriService';
import { BranchesView } from './views/branchesView';
Expand Down Expand Up @@ -221,8 +221,8 @@ export class Container {
this._disposables.push((this._deepLinks = new DeepLinkService(this)));

this._disposables.push((this._actionRunners = new ActionRunners(this)));
this._disposables.push((this._tracker = new GitDocumentTracker(this)));
this._disposables.push((this._lineTracker = new GitLineTracker(this)));
this._disposables.push((this._documentTracker = new GitDocumentTracker(this)));
this._disposables.push((this._lineTracker = new LineTracker(this, this._documentTracker)));
this._disposables.push((this._keyboard = new Keyboard()));
this._disposables.push((this._vsls = new VslsController(this)));
this._disposables.push((this._eventBus = new EventBus()));
Expand Down Expand Up @@ -454,6 +454,11 @@ export class Container {
return this._deepLinks;
}

private readonly _documentTracker: GitDocumentTracker;
get documentTracker() {
return this._documentTracker;
}

@memoize()
get env(): Environment {
if (this.prereleaseOrDebugging) {
Expand Down Expand Up @@ -595,7 +600,7 @@ export class Container {
return this._lineHoverController;
}

private readonly _lineTracker: GitLineTracker;
private readonly _lineTracker: LineTracker;
get lineTracker() {
return this._lineTracker;
}
Expand Down Expand Up @@ -694,11 +699,6 @@ export class Container {
return this._timelineView;
}

private readonly _tracker: GitDocumentTracker;
get tracker() {
return this._tracker;
}

private readonly _uri: UriService;
get uri() {
return this._uri;
Expand Down

0 comments on commit e522866

Please sign in to comment.