ソースを参照

Fixes selection not getting restored in blame

Tweaks the blame animation
Fixes issues with blame and the active editor
main
Eric Amodio 7年前
コミット
acb7f9f046
8個のファイルの変更70行の追加72行の削除
  1. +1
    -1
      images/dark/git-icon-progress.svg
  2. +1
    -1
      images/light/git-icon-progress.svg
  3. +19
    -20
      src/annotations/annotationController.ts
  4. +33
    -7
      src/annotations/annotationProvider.ts
  5. +9
    -0
      src/commands/clearFileAnnotations.ts
  6. +1
    -1
      src/commands/toggleFileBlame.ts
  7. +3
    -21
      src/commands/toggleFileHeatmap.ts
  8. +3
    -21
      src/commands/toggleFileRecentChanges.ts

+ 1
- 1
images/dark/git-icon-progress.svg ファイルの表示

@ -6,7 +6,7 @@
c0.7,0.3,1.3,0.8,1.9,1.3c2.8,2.7,2.8,7.2,0,10c-2.8,2.7-7.2,2.7-10,0c-2.8-2.8-2.8-7.2,0-10c0.7-0.7,1.5-1.2,2.3-1.5V33.8
c-0.8-0.3-1.6-0.9-2.3-1.5c-2.1-2.1-2.6-5.1-1.5-7.7L29.2,14.2L1.7,41.7c-2.3,2.3-2.3,6.1,0,8.4l40.1,40.1c2.3,2.3,6.1,2.3,8.4,0
l39.9-39.9C92.4,47.9,92.4,44.1,90,41.8z">
<animate attributeName="fill" values="#FFFFFF;#F05133;#FFFFFF" dur="1s" repeatCount="indefinite"/>
<animate attributeName="fill" values="#b27b70;#F05133;#b27b70" dur="0.5s" repeatCount="indefinite"/>
</path>
</g>
</svg>

+ 1
- 1
images/light/git-icon-progress.svg ファイルの表示

@ -6,7 +6,7 @@
c0.7,0.3,1.3,0.8,1.9,1.3c2.8,2.7,2.8,7.2,0,10c-2.8,2.7-7.2,2.7-10,0c-2.8-2.8-2.8-7.2,0-10c0.7-0.7,1.5-1.2,2.3-1.5V33.8
c-0.8-0.3-1.6-0.9-2.3-1.5c-2.1-2.1-2.6-5.1-1.5-7.7L29.2,14.2L1.7,41.7c-2.3,2.3-2.3,6.1,0,8.4l40.1,40.1c2.3,2.3,6.1,2.3,8.4,0
l39.9-39.9C92.4,47.9,92.4,44.1,90,41.8z">
<animate attributeName="fill" values="#000000;#F05133;#000000" dur="1s" repeatCount="indefinite"/>
<animate attributeName="fill" values="#b27b70;#F05133;#b27b70" dur="0.5s" repeatCount="indefinite"/>
</path>
</g>

+ 19
- 20
src/annotations/annotationController.ts ファイルの表示

@ -1,7 +1,7 @@
'use strict';
import { Functions, Iterables } from '../system';
import { ConfigurationChangeEvent, DecorationRangeBehavior, DecorationRenderOptions, Disposable, Event, EventEmitter, OverviewRulerLane, Progress, ProgressLocation, TextDocument, TextEditor, TextEditorDecorationType, TextEditorViewColumnChangeEvent, ThemeColor, window, workspace } from 'vscode';
import { AnnotationProviderBase, TextEditorCorrelationKey } from './annotationProvider';
import { AnnotationProviderBase, AnnotationStatus, TextEditorCorrelationKey } from './annotationProvider';
import { configuration, FileAnnotationType, IConfig, LineHighlightLocations } from '../configuration';
import { CommandContext, isTextEditor, setCommandContext } from '../constants';
import { Container } from '../container';
@ -23,11 +23,6 @@ export enum AnnotationClearReason {
DocumentClosed = 'DocumentClosed'
}
enum AnnotationStatus {
Computing = 'computing',
Computed = 'computed'
}
export const Decorations = {
blameAnnotation: window.createTextEditorDecorationType({
isWholeLine: true,
@ -49,6 +44,7 @@ export class AnnotationController extends Disposable {
private _annotationsDisposable: Disposable | undefined;
private _annotationProviders: Map<TextEditorCorrelationKey, AnnotationProviderBase> = new Map();
private _disposable: Disposable;
private _editor: TextEditor | undefined;
private _keyboardScope: KeyboardScope | undefined = undefined;
constructor() {
@ -174,6 +170,7 @@ export class AnnotationController extends Disposable {
private onActiveTextEditorChanged(editor: TextEditor | undefined) {
if (editor !== undefined && !isTextEditor(editor)) return;
this._editor = editor;
// Logger.log('AnnotationController.onActiveTextEditorChanged', editor && editor.document.uri.fsPath);
const provider = this.getProvider(editor);
@ -182,7 +179,7 @@ export class AnnotationController extends Disposable {
this.detachKeyboardHook();
}
else {
setCommandContext(CommandContext.AnnotationStatus, AnnotationStatus.Computed);
setCommandContext(CommandContext.AnnotationStatus, provider.status);
this.attachKeyboardHook();
}
}
@ -262,6 +259,7 @@ export class AnnotationController extends Disposable {
async showAnnotations(editor: TextEditor | undefined, type: FileAnnotationType, shaOrLine?: string | number): Promise<boolean> {
if (editor === undefined) return false; // || editor.viewColumn === undefined) return false;
this._editor = editor;
const trackedDocument = await Container.tracker.getOrAdd(editor.document);
if (!trackedDocument.isBlameable) return false;
@ -272,19 +270,20 @@ export class AnnotationController extends Disposable {
return true;
}
return window.withProgress({ location: ProgressLocation.Window }, async (progress: Progress<{ message: string }>) => {
const active = editor === window.activeTextEditor;
await setCommandContext(CommandContext.AnnotationStatus, active ? AnnotationStatus.Computing : undefined);
const provider = await window.withProgress({ location: ProgressLocation.Window }, async (progress: Progress<{ message: string }>) => {
await setCommandContext(CommandContext.AnnotationStatus, AnnotationStatus.Computing);
const computingAnnotations = this.showAnnotationsCore(currentProvider, editor, type, shaOrLine, progress);
const result = await computingAnnotations;
const provider = await computingAnnotations;
if (active) {
await setCommandContext(CommandContext.AnnotationStatus, result ? AnnotationStatus.Computed : undefined);
if (editor === this._editor) {
await setCommandContext(CommandContext.AnnotationStatus, provider && provider.status);
}
return computingAnnotations;
});
return provider !== undefined;
}
async toggleAnnotations(editor: TextEditor | undefined, type: FileAnnotationType, shaOrLine?: string | number): Promise<boolean> {
@ -310,7 +309,7 @@ export class AnnotationController extends Disposable {
this._keyboardScope = await Container.keyboard.beginScope({
escape: {
onDidPressKey: async (key: Keys) => {
const e = window.activeTextEditor;
const e = this._editor;
if (e === undefined) return undefined;
await this.clear(e, AnnotationClearReason.User);
@ -330,7 +329,7 @@ export class AnnotationController extends Disposable {
this._annotationProviders.delete(key);
await provider.dispose();
if (key === AnnotationProviderBase.getCorrelationKey(window.activeTextEditor)) {
if (this._annotationProviders.size === 0 || key === AnnotationProviderBase.getCorrelationKey(this._editor)) {
await setCommandContext(CommandContext.AnnotationStatus, undefined);
await this.detachKeyboardHook();
}
@ -352,7 +351,7 @@ export class AnnotationController extends Disposable {
this._keyboardScope = undefined;
}
private async showAnnotationsCore(currentProvider: AnnotationProviderBase | undefined, editor: TextEditor, type: FileAnnotationType, shaOrLine?: string | number, progress?: Progress<{ message: string}>): Promise<boolean> {
private async showAnnotationsCore(currentProvider: AnnotationProviderBase | undefined, editor: TextEditor, type: FileAnnotationType, shaOrLine?: string | number, progress?: Progress<{ message: string}>): Promise<AnnotationProviderBase | undefined> {
if (progress !== undefined) {
let annotationsLabel = 'annotations';
switch (type) {
@ -396,7 +395,7 @@ export class AnnotationController extends Disposable {
provider = new RecentChangesAnnotationProvider(editor, trackedDocument, undefined, Decorations.recentChangesHighlight!);
break;
}
if (provider === undefined || !(await provider.validate())) return false;
if (provider === undefined || !(await provider.validate())) return undefined;
if (currentProvider !== undefined) {
await this.clearCore(currentProvider.correlationKey, AnnotationClearReason.User);
@ -408,7 +407,7 @@ export class AnnotationController extends Disposable {
this._annotationsDisposable = Disposable.from(
window.onDidChangeActiveTextEditor(Functions.debounce(this.onActiveTextEditorChanged, 50), this),
window.onDidChangeTextEditorViewColumn(this.onTextEditorViewColumnChanged, this),
window.onDidChangeVisibleTextEditors(this.onVisibleTextEditorsChanged, this),
window.onDidChangeVisibleTextEditors(Functions.debounce(this.onVisibleTextEditorsChanged, 50), this),
workspace.onDidCloseTextDocument(this.onTextDocumentClosed, this),
Container.tracker.onDidChangeBlameState(this.onBlameStateChanged, this),
Container.tracker.onDidChangeDirtyState(this.onDirtyStateChanged, this)
@ -418,9 +417,9 @@ export class AnnotationController extends Disposable {
this._annotationProviders.set(provider.correlationKey, provider);
if (await provider.provideAnnotation(shaOrLine)) {
this._onDidToggleAnnotations.fire();
return true;
return provider;
}
return false;
return undefined;
}
}

+ 33
- 7
src/annotations/annotationProvider.ts ファイルの表示

@ -3,8 +3,14 @@ import { Functions } from '../system';
import { DecorationOptions, Disposable, Range, TextDocument, TextEditor, TextEditorDecorationType, TextEditorSelectionChangeEvent, Uri, window } from 'vscode';
import { FileAnnotationType } from '../configuration';
import { TextDocumentComparer } from '../comparers';
import { CommandContext, setCommandContext } from '../constants';
import { GitDocumentState, TrackedDocument } from '../trackers/documentTracker';
export enum AnnotationStatus {
Computing = 'computing',
Computed = 'computed'
}
export type TextEditorCorrelationKey = string;
export abstract class AnnotationProviderBase extends Disposable {
@ -13,9 +19,10 @@ export abstract class AnnotationProviderBase extends Disposable {
return editor !== undefined ? (editor as any).id : '';
}
public annotationType: FileAnnotationType;
public correlationKey: TextEditorCorrelationKey;
public document: TextDocument;
annotationType: FileAnnotationType;
correlationKey: TextEditorCorrelationKey;
document: TextDocument;
status: AnnotationStatus | undefined;
protected decorations: DecorationOptions[] | undefined;
protected disposable: Disposable;
@ -61,6 +68,7 @@ export abstract class AnnotationProviderBase extends Disposable {
protected additionalDecorations: { decoration: TextEditorDecorationType, ranges: Range[] }[] | undefined;
async clear() {
this.status = undefined;
if (this.editor === undefined) return;
if (this.decoration !== undefined) {
@ -110,10 +118,15 @@ export abstract class AnnotationProviderBase extends Disposable {
await this.provideAnnotation(this.editor === undefined ? undefined : this.editor.selection.active.line);
}
restore(editor: TextEditor, force: boolean = false) {
async restore(editor: TextEditor) {
// If the editor isn't disposed then we don't need to do anything
// Explicitly check for `false`
if (!force && (this.editor as any)._disposed === false) return;
if ((this.editor as any)._disposed === false) return;
this.status = AnnotationStatus.Computing;
if (editor === window.activeTextEditor) {
await setCommandContext(CommandContext.AnnotationStatus, this.status);
}
this.editor = editor;
this.correlationKey = AnnotationProviderBase.getCorrelationKey(editor);
@ -128,10 +141,23 @@ export abstract class AnnotationProviderBase extends Disposable {
}
}
}
this.status = AnnotationStatus.Computed;
if (editor === window.activeTextEditor) {
await setCommandContext(CommandContext.AnnotationStatus, this.status);
await this.selection(editor.selection.active.line);
}
}
provideAnnotation(shaOrLine?: string | number): Promise<boolean> {
return this.onProvideAnnotation(shaOrLine);
async provideAnnotation(shaOrLine?: string | number): Promise<boolean> {
this.status = AnnotationStatus.Computing;
if (await this.onProvideAnnotation(shaOrLine)) {
this.status = AnnotationStatus.Computed;
return true;
}
this.status = undefined;
return false;
}
abstract async onProvideAnnotation(shaOrLine?: string | number): Promise<boolean>;

+ 9
- 0
src/commands/clearFileAnnotations.ts ファイルの表示

@ -1,6 +1,7 @@
'use strict';
import { TextEditor, TextEditorEdit, Uri, window } from 'vscode';
import { Commands, EditorCommand } from './common';
import { UriComparer } from '../comparers';
import { Container } from '../container';
import { Logger } from '../logger';
@ -13,6 +14,14 @@ export class ClearFileAnnotationsCommand extends EditorCommand {
async execute(editor: TextEditor, edit: TextEditorEdit, uri?: Uri): Promise<any> {
if (editor === undefined) 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) {
editor = e;
}
}
try {
return Container.annotations.clear(editor);
}

+ 1
- 1
src/commands/toggleFileBlame.ts ファイルの表示

@ -37,7 +37,7 @@ export class ToggleFileBlameCommand extends EditorCommand {
}
catch (ex) {
Logger.error(ex, 'ToggleFileBlameCommand');
return window.showErrorMessage(`Unable to toggle file blame annotations. See output channel for more details`);
return window.showErrorMessage(`Unable to toggle file ${args.type} annotations. See output channel for more details`);
}
}
}

+ 3
- 21
src/commands/toggleFileHeatmap.ts ファイルの表示

@ -1,10 +1,8 @@
'use strict';
import { TextEditor, TextEditorEdit, Uri, window } from 'vscode';
import { commands, TextEditor, TextEditorEdit, Uri } from 'vscode';
import { ToggleFileBlameCommandArgs } from '../commands';
import { Commands, EditorCommand } from './common';
import { UriComparer } from '../comparers';
import { FileAnnotationType } from '../configuration';
import { Container } from '../container';
import { Logger } from '../logger';
export class ToggleFileHeatmapCommand extends EditorCommand {
@ -13,22 +11,6 @@ export class ToggleFileHeatmapCommand extends EditorCommand {
}
async execute(editor: TextEditor, edit: TextEditorEdit, uri?: Uri): Promise<any> {
if (editor === undefined) 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) {
editor = e;
}
}
try {
return Container.annotations.toggleAnnotations(editor, FileAnnotationType.Heatmap);
}
catch (ex) {
Logger.error(ex, 'ToggleFileHeatmapCommand');
return window.showErrorMessage(`Unable to toggle heatmap annotations. See output channel for more details`);
}
commands.executeCommand(Commands.ToggleFileBlame, uri, { type: FileAnnotationType.Heatmap } as ToggleFileBlameCommandArgs);
}
}

+ 3
- 21
src/commands/toggleFileRecentChanges.ts ファイルの表示

@ -1,10 +1,8 @@
'use strict';
import { TextEditor, TextEditorEdit, Uri, window } from 'vscode';
import { commands, TextEditor, TextEditorEdit, Uri } from 'vscode';
import { ToggleFileBlameCommandArgs } from '../commands';
import { Commands, EditorCommand } from './common';
import { UriComparer } from '../comparers';
import { FileAnnotationType } from '../configuration';
import { Container } from '../container';
import { Logger } from '../logger';
export class ToggleFileRecentChangesCommand extends EditorCommand {
@ -13,22 +11,6 @@ export class ToggleFileRecentChangesCommand extends EditorCommand {
}
async execute(editor: TextEditor, edit: TextEditorEdit, uri?: Uri): Promise<any> {
if (editor === undefined) 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) {
editor = e;
}
}
try {
return Container.annotations.toggleAnnotations(editor, FileAnnotationType.RecentChanges);
}
catch (ex) {
Logger.error(ex, 'ToggleFileRecentChangesCommand');
return window.showErrorMessage(`Unable to toggle recent file changes annotations. See output channel for more details`);
}
commands.executeCommand(Commands.ToggleFileBlame, uri, { type: FileAnnotationType.RecentChanges } as ToggleFileBlameCommandArgs);
}
}

読み込み中…
キャンセル
保存