Skip to content

Commit acb7f9f

Browse files
committed
Fixes selection not getting restored in blame
Tweaks the blame animation Fixes issues with blame and the active editor
1 parent 1b0d516 commit acb7f9f

File tree

8 files changed

+70
-72
lines changed

8 files changed

+70
-72
lines changed

images/dark/git-icon-progress.svg

Lines changed: 1 addition & 1 deletion
Loading

images/light/git-icon-progress.svg

Lines changed: 1 addition & 1 deletion
Loading

src/annotations/annotationController.ts

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
'use strict';
22
import { Functions, Iterables } from '../system';
33
import { ConfigurationChangeEvent, DecorationRangeBehavior, DecorationRenderOptions, Disposable, Event, EventEmitter, OverviewRulerLane, Progress, ProgressLocation, TextDocument, TextEditor, TextEditorDecorationType, TextEditorViewColumnChangeEvent, ThemeColor, window, workspace } from 'vscode';
4-
import { AnnotationProviderBase, TextEditorCorrelationKey } from './annotationProvider';
4+
import { AnnotationProviderBase, AnnotationStatus, TextEditorCorrelationKey } from './annotationProvider';
55
import { configuration, FileAnnotationType, IConfig, LineHighlightLocations } from '../configuration';
66
import { CommandContext, isTextEditor, setCommandContext } from '../constants';
77
import { Container } from '../container';
@@ -23,11 +23,6 @@ export enum AnnotationClearReason {
2323
DocumentClosed = 'DocumentClosed'
2424
}
2525

26-
enum AnnotationStatus {
27-
Computing = 'computing',
28-
Computed = 'computed'
29-
}
30-
3126
export const Decorations = {
3227
blameAnnotation: window.createTextEditorDecorationType({
3328
isWholeLine: true,
@@ -49,6 +44,7 @@ export class AnnotationController extends Disposable {
4944
private _annotationsDisposable: Disposable | undefined;
5045
private _annotationProviders: Map<TextEditorCorrelationKey, AnnotationProviderBase> = new Map();
5146
private _disposable: Disposable;
47+
private _editor: TextEditor | undefined;
5248
private _keyboardScope: KeyboardScope | undefined = undefined;
5349

5450
constructor() {
@@ -174,6 +170,7 @@ export class AnnotationController extends Disposable {
174170
private onActiveTextEditorChanged(editor: TextEditor | undefined) {
175171
if (editor !== undefined && !isTextEditor(editor)) return;
176172

173+
this._editor = editor;
177174
// Logger.log('AnnotationController.onActiveTextEditorChanged', editor && editor.document.uri.fsPath);
178175

179176
const provider = this.getProvider(editor);
@@ -182,7 +179,7 @@ export class AnnotationController extends Disposable {
182179
this.detachKeyboardHook();
183180
}
184181
else {
185-
setCommandContext(CommandContext.AnnotationStatus, AnnotationStatus.Computed);
182+
setCommandContext(CommandContext.AnnotationStatus, provider.status);
186183
this.attachKeyboardHook();
187184
}
188185
}
@@ -262,6 +259,7 @@ export class AnnotationController extends Disposable {
262259

263260
async showAnnotations(editor: TextEditor | undefined, type: FileAnnotationType, shaOrLine?: string | number): Promise<boolean> {
264261
if (editor === undefined) return false; // || editor.viewColumn === undefined) return false;
262+
this._editor = editor;
265263

266264
const trackedDocument = await Container.tracker.getOrAdd(editor.document);
267265
if (!trackedDocument.isBlameable) return false;
@@ -272,19 +270,20 @@ export class AnnotationController extends Disposable {
272270
return true;
273271
}
274272

275-
return window.withProgress({ location: ProgressLocation.Window }, async (progress: Progress<{ message: string }>) => {
276-
const active = editor === window.activeTextEditor;
277-
await setCommandContext(CommandContext.AnnotationStatus, active ? AnnotationStatus.Computing : undefined);
273+
const provider = await window.withProgress({ location: ProgressLocation.Window }, async (progress: Progress<{ message: string }>) => {
274+
await setCommandContext(CommandContext.AnnotationStatus, AnnotationStatus.Computing);
278275

279276
const computingAnnotations = this.showAnnotationsCore(currentProvider, editor, type, shaOrLine, progress);
280-
const result = await computingAnnotations;
277+
const provider = await computingAnnotations;
281278

282-
if (active) {
283-
await setCommandContext(CommandContext.AnnotationStatus, result ? AnnotationStatus.Computed : undefined);
279+
if (editor === this._editor) {
280+
await setCommandContext(CommandContext.AnnotationStatus, provider && provider.status);
284281
}
285282

286283
return computingAnnotations;
287284
});
285+
286+
return provider !== undefined;
288287
}
289288

290289
async toggleAnnotations(editor: TextEditor | undefined, type: FileAnnotationType, shaOrLine?: string | number): Promise<boolean> {
@@ -310,7 +309,7 @@ export class AnnotationController extends Disposable {
310309
this._keyboardScope = await Container.keyboard.beginScope({
311310
escape: {
312311
onDidPressKey: async (key: Keys) => {
313-
const e = window.activeTextEditor;
312+
const e = this._editor;
314313
if (e === undefined) return undefined;
315314

316315
await this.clear(e, AnnotationClearReason.User);
@@ -330,7 +329,7 @@ export class AnnotationController extends Disposable {
330329
this._annotationProviders.delete(key);
331330
await provider.dispose();
332331

333-
if (key === AnnotationProviderBase.getCorrelationKey(window.activeTextEditor)) {
332+
if (this._annotationProviders.size === 0 || key === AnnotationProviderBase.getCorrelationKey(this._editor)) {
334333
await setCommandContext(CommandContext.AnnotationStatus, undefined);
335334
await this.detachKeyboardHook();
336335
}
@@ -352,7 +351,7 @@ export class AnnotationController extends Disposable {
352351
this._keyboardScope = undefined;
353352
}
354353

355-
private async showAnnotationsCore(currentProvider: AnnotationProviderBase | undefined, editor: TextEditor, type: FileAnnotationType, shaOrLine?: string | number, progress?: Progress<{ message: string}>): Promise<boolean> {
354+
private async showAnnotationsCore(currentProvider: AnnotationProviderBase | undefined, editor: TextEditor, type: FileAnnotationType, shaOrLine?: string | number, progress?: Progress<{ message: string}>): Promise<AnnotationProviderBase | undefined> {
356355
if (progress !== undefined) {
357356
let annotationsLabel = 'annotations';
358357
switch (type) {
@@ -396,7 +395,7 @@ export class AnnotationController extends Disposable {
396395
provider = new RecentChangesAnnotationProvider(editor, trackedDocument, undefined, Decorations.recentChangesHighlight!);
397396
break;
398397
}
399-
if (provider === undefined || !(await provider.validate())) return false;
398+
if (provider === undefined || !(await provider.validate())) return undefined;
400399

401400
if (currentProvider !== undefined) {
402401
await this.clearCore(currentProvider.correlationKey, AnnotationClearReason.User);
@@ -408,7 +407,7 @@ export class AnnotationController extends Disposable {
408407
this._annotationsDisposable = Disposable.from(
409408
window.onDidChangeActiveTextEditor(Functions.debounce(this.onActiveTextEditorChanged, 50), this),
410409
window.onDidChangeTextEditorViewColumn(this.onTextEditorViewColumnChanged, this),
411-
window.onDidChangeVisibleTextEditors(this.onVisibleTextEditorsChanged, this),
410+
window.onDidChangeVisibleTextEditors(Functions.debounce(this.onVisibleTextEditorsChanged, 50), this),
412411
workspace.onDidCloseTextDocument(this.onTextDocumentClosed, this),
413412
Container.tracker.onDidChangeBlameState(this.onBlameStateChanged, this),
414413
Container.tracker.onDidChangeDirtyState(this.onDirtyStateChanged, this)
@@ -418,9 +417,9 @@ export class AnnotationController extends Disposable {
418417
this._annotationProviders.set(provider.correlationKey, provider);
419418
if (await provider.provideAnnotation(shaOrLine)) {
420419
this._onDidToggleAnnotations.fire();
421-
return true;
420+
return provider;
422421
}
423422

424-
return false;
423+
return undefined;
425424
}
426425
}

src/annotations/annotationProvider.ts

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,14 @@ import { Functions } from '../system';
33
import { DecorationOptions, Disposable, Range, TextDocument, TextEditor, TextEditorDecorationType, TextEditorSelectionChangeEvent, Uri, window } from 'vscode';
44
import { FileAnnotationType } from '../configuration';
55
import { TextDocumentComparer } from '../comparers';
6+
import { CommandContext, setCommandContext } from '../constants';
67
import { GitDocumentState, TrackedDocument } from '../trackers/documentTracker';
78

9+
export enum AnnotationStatus {
10+
Computing = 'computing',
11+
Computed = 'computed'
12+
}
13+
814
export type TextEditorCorrelationKey = string;
915

1016
export abstract class AnnotationProviderBase extends Disposable {
@@ -13,9 +19,10 @@ export abstract class AnnotationProviderBase extends Disposable {
1319
return editor !== undefined ? (editor as any).id : '';
1420
}
1521

16-
public annotationType: FileAnnotationType;
17-
public correlationKey: TextEditorCorrelationKey;
18-
public document: TextDocument;
22+
annotationType: FileAnnotationType;
23+
correlationKey: TextEditorCorrelationKey;
24+
document: TextDocument;
25+
status: AnnotationStatus | undefined;
1926

2027
protected decorations: DecorationOptions[] | undefined;
2128
protected disposable: Disposable;
@@ -61,6 +68,7 @@ export abstract class AnnotationProviderBase extends Disposable {
6168
protected additionalDecorations: { decoration: TextEditorDecorationType, ranges: Range[] }[] | undefined;
6269

6370
async clear() {
71+
this.status = undefined;
6472
if (this.editor === undefined) return;
6573

6674
if (this.decoration !== undefined) {
@@ -110,10 +118,15 @@ export abstract class AnnotationProviderBase extends Disposable {
110118
await this.provideAnnotation(this.editor === undefined ? undefined : this.editor.selection.active.line);
111119
}
112120

113-
restore(editor: TextEditor, force: boolean = false) {
121+
async restore(editor: TextEditor) {
114122
// If the editor isn't disposed then we don't need to do anything
115123
// Explicitly check for `false`
116-
if (!force && (this.editor as any)._disposed === false) return;
124+
if ((this.editor as any)._disposed === false) return;
125+
126+
this.status = AnnotationStatus.Computing;
127+
if (editor === window.activeTextEditor) {
128+
await setCommandContext(CommandContext.AnnotationStatus, this.status);
129+
}
117130

118131
this.editor = editor;
119132
this.correlationKey = AnnotationProviderBase.getCorrelationKey(editor);
@@ -128,10 +141,23 @@ export abstract class AnnotationProviderBase extends Disposable {
128141
}
129142
}
130143
}
144+
145+
this.status = AnnotationStatus.Computed;
146+
if (editor === window.activeTextEditor) {
147+
await setCommandContext(CommandContext.AnnotationStatus, this.status);
148+
await this.selection(editor.selection.active.line);
149+
}
131150
}
132151

133-
provideAnnotation(shaOrLine?: string | number): Promise<boolean> {
134-
return this.onProvideAnnotation(shaOrLine);
152+
async provideAnnotation(shaOrLine?: string | number): Promise<boolean> {
153+
this.status = AnnotationStatus.Computing;
154+
if (await this.onProvideAnnotation(shaOrLine)) {
155+
this.status = AnnotationStatus.Computed;
156+
return true;
157+
}
158+
159+
this.status = undefined;
160+
return false;
135161
}
136162

137163
abstract async onProvideAnnotation(shaOrLine?: string | number): Promise<boolean>;

src/commands/clearFileAnnotations.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
'use strict';
22
import { TextEditor, TextEditorEdit, Uri, window } from 'vscode';
33
import { Commands, EditorCommand } from './common';
4+
import { UriComparer } from '../comparers';
45
import { Container } from '../container';
56
import { Logger } from '../logger';
67

@@ -13,6 +14,14 @@ export class ClearFileAnnotationsCommand extends EditorCommand {
1314
async execute(editor: TextEditor, edit: TextEditorEdit, uri?: Uri): Promise<any> {
1415
if (editor === undefined) return undefined;
1516

17+
// Handle the case where we are focused on a non-editor editor (output, debug console)
18+
if (uri !== undefined && !UriComparer.equals(uri, editor.document.uri)) {
19+
const e = window.visibleTextEditors.find(e => UriComparer.equals(uri, e.document.uri));
20+
if (e !== undefined) {
21+
editor = e;
22+
}
23+
}
24+
1625
try {
1726
return Container.annotations.clear(editor);
1827
}

src/commands/toggleFileBlame.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ export class ToggleFileBlameCommand extends EditorCommand {
3737
}
3838
catch (ex) {
3939
Logger.error(ex, 'ToggleFileBlameCommand');
40-
return window.showErrorMessage(`Unable to toggle file blame annotations. See output channel for more details`);
40+
return window.showErrorMessage(`Unable to toggle file ${args.type} annotations. See output channel for more details`);
4141
}
4242
}
4343
}

src/commands/toggleFileHeatmap.ts

Lines changed: 3 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
'use strict';
2-
import { TextEditor, TextEditorEdit, Uri, window } from 'vscode';
2+
import { commands, TextEditor, TextEditorEdit, Uri } from 'vscode';
3+
import { ToggleFileBlameCommandArgs } from '../commands';
34
import { Commands, EditorCommand } from './common';
4-
import { UriComparer } from '../comparers';
55
import { FileAnnotationType } from '../configuration';
6-
import { Container } from '../container';
7-
import { Logger } from '../logger';
86

97
export class ToggleFileHeatmapCommand extends EditorCommand {
108

@@ -13,22 +11,6 @@ export class ToggleFileHeatmapCommand extends EditorCommand {
1311
}
1412

1513
async execute(editor: TextEditor, edit: TextEditorEdit, uri?: Uri): Promise<any> {
16-
if (editor === undefined) return undefined;
17-
18-
// Handle the case where we are focused on a non-editor editor (output, debug console)
19-
if (uri !== undefined && !UriComparer.equals(uri, editor.document.uri)) {
20-
const e = window.visibleTextEditors.find(e => UriComparer.equals(uri, e.document.uri));
21-
if (e !== undefined) {
22-
editor = e;
23-
}
24-
}
25-
26-
try {
27-
return Container.annotations.toggleAnnotations(editor, FileAnnotationType.Heatmap);
28-
}
29-
catch (ex) {
30-
Logger.error(ex, 'ToggleFileHeatmapCommand');
31-
return window.showErrorMessage(`Unable to toggle heatmap annotations. See output channel for more details`);
32-
}
14+
commands.executeCommand(Commands.ToggleFileBlame, uri, { type: FileAnnotationType.Heatmap } as ToggleFileBlameCommandArgs);
3315
}
3416
}
Lines changed: 3 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
'use strict';
2-
import { TextEditor, TextEditorEdit, Uri, window } from 'vscode';
2+
import { commands, TextEditor, TextEditorEdit, Uri } from 'vscode';
3+
import { ToggleFileBlameCommandArgs } from '../commands';
34
import { Commands, EditorCommand } from './common';
4-
import { UriComparer } from '../comparers';
55
import { FileAnnotationType } from '../configuration';
6-
import { Container } from '../container';
7-
import { Logger } from '../logger';
86

97
export class ToggleFileRecentChangesCommand extends EditorCommand {
108

@@ -13,22 +11,6 @@ export class ToggleFileRecentChangesCommand extends EditorCommand {
1311
}
1412

1513
async execute(editor: TextEditor, edit: TextEditorEdit, uri?: Uri): Promise<any> {
16-
if (editor === undefined) return undefined;
17-
18-
// Handle the case where we are focused on a non-editor editor (output, debug console)
19-
if (uri !== undefined && !UriComparer.equals(uri, editor.document.uri)) {
20-
const e = window.visibleTextEditors.find(e => UriComparer.equals(uri, e.document.uri));
21-
if (e !== undefined) {
22-
editor = e;
23-
}
24-
}
25-
26-
try {
27-
return Container.annotations.toggleAnnotations(editor, FileAnnotationType.RecentChanges);
28-
}
29-
catch (ex) {
30-
Logger.error(ex, 'ToggleFileRecentChangesCommand');
31-
return window.showErrorMessage(`Unable to toggle recent file changes annotations. See output channel for more details`);
32-
}
14+
commands.executeCommand(Commands.ToggleFileBlame, uri, { type: FileAnnotationType.RecentChanges } as ToggleFileBlameCommandArgs);
3315
}
3416
}

0 commit comments

Comments
 (0)