Browse Source

Fixes tracked document refresh on repo discovery

main
Eric Amodio 1 year ago
parent
commit
f664445296
4 changed files with 34 additions and 50 deletions
  1. +2
    -2
      src/env/node/git/localGitProvider.ts
  2. +1
    -1
      src/plus/github/githubGitProvider.ts
  3. +21
    -37
      src/trackers/documentTracker.ts
  4. +10
    -10
      src/trackers/trackedDocument.ts

+ 2
- 2
src/env/node/git/localGitProvider.ts View File

@ -1488,7 +1488,7 @@ export class LocalGitProvider implements GitProvider, Disposable {
errorMessage: msg,
};
document.state.setBlame(key, value);
document.setBlameFailure();
document.setBlameFailure(ex);
if (ex instanceof BlameIgnoreRevsFileError) {
void window.showErrorMessage(ex.friendlyMessage);
@ -1574,7 +1574,7 @@ export class LocalGitProvider implements GitProvider, Disposable {
errorMessage: msg,
};
document.state.setBlame(key, value);
document.setBlameFailure();
document.setBlameFailure(ex);
if (ex instanceof BlameIgnoreRevsFileError) {
void window.showErrorMessage(ex.friendlyMessage);

+ 1
- 1
src/plus/github/githubGitProvider.ts View File

@ -676,7 +676,7 @@ export class GitHubGitProvider implements GitProvider, Disposable {
};
document.state.setBlame(key, value);
document.setBlameFailure();
document.setBlameFailure(ex);
return emptyPromise as Promise<GitBlame>;
}

+ 21
- 37
src/trackers/documentTracker.ts View File

@ -18,11 +18,9 @@ import type { RepositoryChangeEvent } from '../git/models/repository';
import { RepositoryChange, RepositoryChangeComparisonMode } from '../git/models/repository';
import { configuration } from '../system/configuration';
import { setContext } from '../system/context';
import { debug } from '../system/decorators/log';
import { once } from '../system/event';
import type { Deferrable } from '../system/function';
import { debounce } from '../system/function';
import { filter, join, map } from '../system/iterable';
import { findTextDocument, isActiveDocument, isTextEditor } from '../system/utils';
import { TrackedDocument } from './trackedDocument';
@ -140,7 +138,7 @@ export class DocumentTracker implements Disposable {
e != null &&
(configuration.changed(e, 'blame.ignoreWhitespace') || configuration.changed(e, 'advanced.caching.enabled'))
) {
this.reset('config');
void this.refreshDocuments();
}
if (configuration.changed(e, 'advanced.blame.delayAfterEdit')) {
@ -150,11 +148,10 @@ export class DocumentTracker implements Disposable {
}
private onRepositoriesChanged(e: RepositoriesChangeEvent) {
this.reset(
'repository',
e.added.length ? new Set<string>(e.added.map(r => r.path)) : undefined,
e.removed.length ? new Set<string>(e.removed.map(r => r.path)) : undefined,
);
void this.refreshDocuments({
addedOrChangedRepoPaths: e.added.length ? new Set<string>(e.added.map(r => r.path)) : undefined,
removedRepoPaths: e.removed.length ? new Set<string>(e.removed.map(r => r.path)) : undefined,
});
}
private onRepositoryChanged(e: RepositoryChangeEvent) {
@ -167,7 +164,7 @@ export class DocumentTracker implements Disposable {
RepositoryChangeComparisonMode.Any,
)
) {
this.reset('repository', new Set([e.repository.path]));
void this.refreshDocuments({ addedOrChangedRepoPaths: new Set([e.repository.path]) });
}
}
@ -176,7 +173,7 @@ export class DocumentTracker implements Disposable {
if (!this.container.git.supportedSchemes.has(scheme)) return;
const doc = await (this._documentMap.get(e.document) ?? this.addCore(e.document));
doc.reset('document');
doc.refresh('doc-changed');
const dirty = e.document.isDirty;
const editor = window.activeTextEditor;
@ -340,14 +337,14 @@ export class DocumentTracker implements Disposable {
}
private async remove(document: TextDocument, tracked?: TrackedDocument<T>): Promise<void> {
let promise;
let docPromise;
if (tracked != null) {
promise = this._documentMap.get(document);
docPromise = this._documentMap.get(document);
}
this._documentMap.delete(document);
(tracked ?? (await promise))?.dispose();
(tracked ?? (await docPromise))?.dispose();
}
private _dirtyIdleTriggeredDebounced: Deferrable<(e: DocumentDirtyIdleTriggerEvent<T>) => void> | undefined;
@ -388,30 +385,17 @@ export class DocumentTracker implements Disposable {
this._dirtyStateChangedDebounced(e);
}
@debug<DocumentTracker<T>['reset']>({
args: {
1: c => (c != null ? join(c, ',') : ''),
2: r => (r != null ? join(r, ',') : ''),
},
})
private reset(reason: 'config' | 'repository', changedRepoPaths?: Set<string>, removedRepoPaths?: Set<string>) {
void Promise.allSettled(
map(
filter(this._documentMap, ([key]) => typeof key === 'string'),
async ([, promise]) => {
const doc = await promise;
if (removedRepoPaths?.has(doc.uri.repoPath!)) {
void this.remove(doc.document, doc);
return;
}
if (changedRepoPaths == null || changedRepoPaths.has(doc.uri.repoPath!)) {
doc.reset(reason);
}
},
),
);
private async refreshDocuments(changed?: {
addedOrChangedRepoPaths?: Set<string>;
removedRepoPaths?: Set<string>;
}) {
for await (const doc of this._documentMap.values()) {
if (changed?.removedRepoPaths?.has(doc.uri.repoPath!)) {
void this.remove(doc.document, doc);
} else if (changed == null || changed?.addedOrChangedRepoPaths?.has(doc.uri.repoPath!)) {
doc.refresh('repo-changed');
}
}
}
}

+ 10
- 10
src/trackers/trackedDocument.ts View File

@ -70,7 +70,7 @@ export class TrackedDocument implements Disposable {
}
get isBlameable() {
return this._blameFailed ? false : this._isTracked;
return this._blameFailed != null ? false : this._isTracked;
}
private _isDirtyIdle: boolean = false;
@ -110,12 +110,12 @@ export class TrackedDocument implements Disposable {
}
private _updateDebounced:
| Deferrable<({ forceBlameChange }?: { forceBlameChange?: boolean | undefined }) => Promise<void>>
| Deferrable<(options?: { forceBlameChange?: boolean | undefined }) => Promise<void>>
| undefined;
reset(reason: 'config' | 'document' | 'repository') {
refresh(reason: 'doc-changed' | 'repo-changed') {
this._requiresUpdate = true;
this._blameFailed = false;
this._blameFailed = undefined;
this._isDirtyIdle = false;
if (this.state != null) {
@ -123,7 +123,7 @@ export class TrackedDocument implements Disposable {
Logger.log(`Reset state for '${this.document.uri.toString(true)}', reason=${reason}`);
}
if (reason === 'repository' && isActiveDocument(this.document)) {
if (reason === 'repo-changed' && isActiveDocument(this.document)) {
if (this._updateDebounced == null) {
this._updateDebounced = debounce(this.update.bind(this), 250);
}
@ -132,11 +132,11 @@ export class TrackedDocument implements Disposable {
}
}
private _blameFailed: boolean = false;
setBlameFailure() {
private _blameFailed: Error | undefined;
setBlameFailure(ex: Error) {
const wasBlameable = this.isBlameable;
this._blameFailed = true;
this._blameFailed = ex;
if (wasBlameable && isActiveDocument(this.document)) {
void this.update({ forceBlameChange: true });
@ -152,7 +152,7 @@ export class TrackedDocument implements Disposable {
}
private _requiresUpdate: boolean = true;
async update({ forceBlameChange }: { forceBlameChange?: boolean } = {}) {
async update(options?: { forceBlameChange?: boolean }) {
this._requiresUpdate = false;
if (this._disposed || this._uri == null) {
@ -166,7 +166,7 @@ export class TrackedDocument implements Disposable {
// Caches these before the awaits
const active = getEditorIfActive(this.document);
const wasBlameable = forceBlameChange ? undefined : this.isBlameable;
const wasBlameable = options?.forceBlameChange ? undefined : this.isBlameable;
const repo = this.container.git.getRepository(this._uri);
if (repo == null) {

Loading…
Cancel
Save