diff --git a/CHANGELOG.md b/CHANGELOG.md index 3597dd0..575e98c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,9 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p ## [Unreleased] ### Fixed - Fixes [#207](https://github.com/eamodio/vscode-gitlens/issues/207) - Applying and deleting stashes suddenly stopped working +- Fixes [#205](https://github.com/eamodio/vscode-gitlens/issues/205) - Toggle Line Blame Annotations disappeared after last update - Fixes [#203](https://github.com/eamodio/vscode-gitlens/issues/203) - Open Changed Files is broken +- Fixes [#176](https://github.com/eamodio/vscode-gitlens/issues/176) - Line annotations some times mess with white space ## [6.1.1] - 2017-11-17 ### Fixed diff --git a/src/currentLineController.ts b/src/currentLineController.ts index dae410c..f625220 100644 --- a/src/currentLineController.ts +++ b/src/currentLineController.ts @@ -1,5 +1,5 @@ 'use strict'; -import { Functions } from './system'; +import { Functions, IDeferred } from './system'; import { CancellationToken, ConfigurationChangeEvent, debug, DecorationRangeBehavior, DecorationRenderOptions, Disposable, ExtensionContext, Hover, HoverProvider, languages, Position, Range, StatusBarAlignment, StatusBarItem, TextDocument, TextEditor, TextEditorDecorationType, TextEditorSelectionChangeEvent, window } from 'vscode'; import { AnnotationController, FileAnnotationType } from './annotations/annotationController'; import { Annotations, endOfLineIndex } from './annotations/annotations'; @@ -36,7 +36,7 @@ export class CurrentLineController extends Disposable { private _isAnnotating: boolean = false; private _statusBarItem: StatusBarItem | undefined; private _trackCurrentLineDisposable: Disposable | undefined; - private _updateBlameDebounced: (line: number, editor: TextEditor) => Promise; + private _updateBlameDebounced: ((line: number, editor: TextEditor) => Promise) & IDeferred; private _uri: GitUri; constructor( @@ -138,17 +138,23 @@ export class CurrentLineController extends Disposable { } private onBlameabilityChanged(e: BlameabilityChangeEvent) { - if (!this._blameable && !e.blameable) return; + // Make sure this is for the editor we are tracking + if (!TextEditorComparer.equals(this._editor, e.editor)) return; + + if (!this._blameable && !e.blameable) { + this._updateBlameDebounced.cancel(); + + return; + } this._blameable = e.blameable; if (!e.blameable || this._editor === undefined) { - this.clear(e.editor); + this._updateBlameDebounced.cancel(); + this.updateBlame(this._currentLine.line, e.editor!); + return; } - // Make sure this is for the editor we are tracking - if (!TextEditorComparer.equals(this._editor, e.editor)) return; - this._updateBlameDebounced(this._editor.selection.active.line, this._editor); } @@ -215,8 +221,12 @@ export class CurrentLineController extends Disposable { // Since blame information isn't valid when there are unsaved changes -- don't show any status if (this._blameable && line >= 0) { const blameLine = await this.git.getBlameForLine(this._uri, line); - commitLine = blameLine === undefined ? undefined : blameLine.line; - commit = blameLine === undefined ? undefined : blameLine.commit; + + // Make sure we are still blameable after the await + if (this._blameable) { + commitLine = blameLine === undefined ? undefined : blameLine.line; + commit = blameLine === undefined ? undefined : blameLine.commit; + } } this._currentLine.commit = commit; @@ -255,14 +265,14 @@ export class CurrentLineController extends Disposable { this.clearAnnotations(this._editor); - if (editor === undefined || !this.isEditorBlameable(editor)) { - this.clear(editor); + this._blameable = this.isEditorBlameable(editor); + if (!this._blameable || editor === undefined) { + this.updateBlame(this._currentLine.line, editor!); this._editor = undefined; return; } - this._blameable = editor !== undefined && editor.document !== undefined && !editor.document.isDirty; this._editor = editor; this._uri = await GitUri.fromUri(editor.document.uri, this.git); diff --git a/src/git/gitContextTracker.ts b/src/git/gitContextTracker.ts index 851d142..54eee74 100644 --- a/src/git/gitContextTracker.ts +++ b/src/git/gitContextTracker.ts @@ -1,5 +1,5 @@ 'use strict'; -import { Functions } from '../system'; +import { Functions, IDeferred } from '../system'; import { ConfigurationChangeEvent, Disposable, Event, EventEmitter, TextDocumentChangeEvent, TextEditor, window, workspace } from 'vscode'; import { TextDocumentComparer } from '../comparers'; import { configuration } from '../configuration'; @@ -44,16 +44,19 @@ export class GitContextTracker extends Disposable { private readonly _context: Context = { state: { dirty: false } }; private readonly _disposable: Disposable; private _listenersDisposable: Disposable | undefined; + private _onDirtyStateChangedDebounced: ((dirty: boolean) => void) & IDeferred; constructor( private readonly git: GitService ) { super(() => this.dispose()); + this._onDirtyStateChangedDebounced = Functions.debounce(this.onDirtyStateChanged, 250); + this._disposable = Disposable.from( workspace.onDidChangeConfiguration(this.onConfigurationChanged, this) ); - this.onConfigurationChanged(configuration.initializingChangeEvent); + this.onConfigurationChanged(configuration.initializingChangeEvent); } dispose() { @@ -75,7 +78,7 @@ export class GitContextTracker extends Disposable { if (enabled) { this._listenersDisposable = Disposable.from( window.onDidChangeActiveTextEditor(Functions.debounce(this.onActiveTextEditorChanged, 50), this), - workspace.onDidChangeTextDocument(Functions.debounce(this.onTextDocumentChanged, 50), this), + workspace.onDidChangeTextDocument(this.onTextDocumentChanged, this), this.git.onDidBlameFail(this.onBlameFailed, this), this.git.onDidChange(this.onGitChanged, this) ); @@ -102,6 +105,11 @@ export class GitContextTracker extends Disposable { this.updateBlameability(BlameabilityChangeReason.BlameFailed, false); } + private onDirtyStateChanged(dirty: boolean) { + this._context.state.dirty = dirty; + this.updateBlameability(BlameabilityChangeReason.DocumentChanged); + } + private onGitChanged(e: GitChangeEvent) { if (e.reason !== GitChangeReason.Repositories) return; @@ -116,13 +124,25 @@ export class GitContextTracker extends Disposable { private onTextDocumentChanged(e: TextDocumentChangeEvent) { if (this._context.editor === undefined || !TextDocumentComparer.equals(this._context.editor.document, e.document)) return; + const dirty = e.document.isDirty; + // If we haven't changed state, kick out - if (this._context.state.dirty === e.document.isDirty) return; + if (dirty === this._context.state.dirty) { + this._onDirtyStateChangedDebounced.cancel(); - // Logger.log('GitContextTracker.onTextDocumentChanged', 'Dirty state changed', e); + return; + } - this._context.state.dirty = e.document.isDirty; - this.updateBlameability(BlameabilityChangeReason.DocumentChanged); + // Logger.log('GitContextTracker.onTextDocumentChanged', `Dirty(${dirty}) state changed`); + + if (dirty) { + this._onDirtyStateChangedDebounced.cancel(); + this.onDirtyStateChanged(dirty); + + return; + } + + this._onDirtyStateChangedDebounced(dirty); } private async updateContext(reason: BlameabilityChangeReason, editor: TextEditor | undefined, force: boolean = false) {