Skip to content

Commit 021a5b8

Browse files
committed
Fixes #71 - blame invalid on external edit
1 parent f1042de commit 021a5b8

File tree

2 files changed

+36
-2
lines changed

2 files changed

+36
-2
lines changed

src/blameAnnotationController.ts

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
'use strict';
22
import { Functions } from './system';
3-
import { DecorationRenderOptions, Disposable, Event, EventEmitter, ExtensionContext, OverviewRulerLane, TextDocument, TextEditor, TextEditorDecorationType, TextEditorViewColumnChangeEvent, window, workspace } from 'vscode';
3+
import { DecorationRenderOptions, Disposable, Event, EventEmitter, ExtensionContext, OverviewRulerLane, TextDocument, TextDocumentChangeEvent, TextEditor, TextEditorDecorationType, TextEditorViewColumnChangeEvent, window, workspace } from 'vscode';
44
import { BlameAnnotationProvider } from './blameAnnotationProvider';
55
import { TextDocumentComparer, TextEditorComparer } from './comparers';
66
import { IBlameConfig } from './configuration';
@@ -176,6 +176,7 @@ export class BlameAnnotationController extends Disposable {
176176

177177
subscriptions.push(window.onDidChangeVisibleTextEditors(Functions.debounce(this._onVisibleTextEditorsChanged, 100), this));
178178
subscriptions.push(window.onDidChangeTextEditorViewColumn(this._onTextEditorViewColumnChanged, this));
179+
subscriptions.push(workspace.onDidChangeTextDocument(this._onTextDocumentChanged, this));
179180
subscriptions.push(workspace.onDidCloseTextDocument(this._onTextDocumentClosed, this));
180181
subscriptions.push(this.gitContextTracker.onDidBlameabilityChange(this._onBlameabilityChanged, this));
181182

@@ -217,6 +218,23 @@ export class BlameAnnotationController extends Disposable {
217218
}
218219
}
219220

221+
private _onTextDocumentChanged(e: TextDocumentChangeEvent) {
222+
for (const [key, p] of this._annotationProviders) {
223+
if (!TextDocumentComparer.equals(p.document, e.document)) continue;
224+
225+
// We have to defer because isDirty is not reliable inside this event
226+
setTimeout(() => {
227+
// If the document is dirty all is fine, just kick out since the GitContextTracker will handle it
228+
if (e.document.isDirty) return;
229+
230+
// If the document isn't dirty, it is very likely this event was triggered by an outside edit of this document
231+
// Which means the document has been reloaded and the blame annotations have been removed, so we need to update (clear) our state tracking
232+
Logger.log('TextDocumentChanged:', `Clear blame annotations for column ${key}`);
233+
this.clear(key);
234+
}, 1);
235+
}
236+
}
237+
220238
private _onTextDocumentClosed(e: TextDocument) {
221239
for (const [key, p] of this._annotationProviders) {
222240
if (!TextDocumentComparer.equals(p.document, e)) continue;

src/gitService.ts

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
'use strict';
22
import { Iterables, Objects } from './system';
3-
import { Disposable, Event, EventEmitter, ExtensionContext, FileSystemWatcher, languages, Location, Position, Range, TextDocument, TextEditor, Uri, workspace } from 'vscode';
3+
import { Disposable, Event, EventEmitter, ExtensionContext, FileSystemWatcher, languages, Location, Position, Range, TextDocument, TextDocumentChangeEvent, TextEditor, Uri, workspace } from 'vscode';
44
import { CommandContext, setCommandContext } from './commands';
55
import { CodeLensVisibility, IConfig } from './configuration';
66
import { DocumentSchemes, ExtensionKey } from './constants';
@@ -166,6 +166,7 @@ export class GitService extends Disposable {
166166
const disposables: Disposable[] = [];
167167

168168
disposables.push(workspace.onDidCloseTextDocument(d => this._removeCachedEntry(d, RemoveCacheReason.DocumentClosed)));
169+
disposables.push(workspace.onDidChangeTextDocument(this._onTextDocumentChanged, this));
169170
disposables.push(workspace.onDidSaveTextDocument(d => this._removeCachedEntry(d, RemoveCacheReason.DocumentSaved)));
170171
disposables.push(this._fsWatcher.onDidChange(this._onGitChanged, this));
171172

@@ -208,6 +209,21 @@ export class GitService extends Disposable {
208209
this.config = cfg;
209210
}
210211

212+
private _onTextDocumentChanged(e: TextDocumentChangeEvent) {
213+
if (!this.UseCaching) return;
214+
if (e.document.uri.scheme !== DocumentSchemes.File) return;
215+
216+
// We have to defer because isDirty is not reliable inside this event
217+
setTimeout(() => {
218+
// If the document is dirty all is fine, we'll just wait for the save before clearing our cache
219+
if (e.document.isDirty) return;
220+
221+
// If the document isn't dirty, it is very likely this event was triggered by an outside edit of this document
222+
// Which means the document has been reloaded and we should clear our cache for it
223+
this._removeCachedEntry(e.document, RemoveCacheReason.DocumentSaved);
224+
}, 1);
225+
}
226+
211227
private _onGitChanged() {
212228
this._gitCache.clear();
213229

0 commit comments

Comments
 (0)