git: multiroot content provider

This commit is contained in:
Joao Moreno
2017-08-17 11:17:50 +02:00
parent cf6b77d23e
commit 20b7747ac4
4 changed files with 52 additions and 14 deletions

View File

@@ -8,7 +8,7 @@
import { workspace, Uri, Disposable, Event, EventEmitter, window } from 'vscode';
import { debounce } from './decorators';
import { fromGitUri } from './uri';
import { Repository } from './repository';
import { Model, ModelChangeEvent } from './model';
interface CacheRow {
uri: Uri;
@@ -27,29 +27,53 @@ export class GitContentProvider {
private onDidChangeEmitter = new EventEmitter<Uri>();
get onDidChange(): Event<Uri> { return this.onDidChangeEmitter.event; }
private changedRepositoryRoots = new Set<string>();
private cache: Cache = Object.create(null);
private disposables: Disposable[] = [];
constructor(private repository: Repository) {
constructor(private model: Model) {
this.disposables.push(
repository.onDidChangeRepository(this.eventuallyFireChangeEvents, this),
model.onDidChangeRepository(this.onDidChangeRepository, this),
workspace.registerTextDocumentContentProvider('git', this)
);
setInterval(() => this.cleanup(), FIVE_MINUTES);
}
private onDidChangeRepository({ repository }: ModelChangeEvent): void {
this.changedRepositoryRoots.add(repository.root);
this.eventuallyFireChangeEvents();
}
@debounce(1100)
private eventuallyFireChangeEvents(): void {
this.fireChangeEvents();
}
private fireChangeEvents(): void {
Object.keys(this.cache)
.forEach(key => this.onDidChangeEmitter.fire(this.cache[key].uri));
this.changedRepositoryRoots.clear();
Object.keys(this.cache).forEach(key => {
const uri = this.cache[key].uri;
const fsPath = uri.fsPath;
for (const root of this.changedRepositoryRoots) {
if (fsPath.startsWith(root)) {
this.onDidChangeEmitter.fire(uri);
return;
}
}
});
}
async provideTextDocumentContent(uri: Uri): Promise<string> {
const repository = this.model.getRepository(uri);
if (!repository) {
console.warn('git provideTextDocumentContent: could not find repository');
return '';
}
const cacheKey = uri.toString();
const timestamp = new Date().getTime();
const cacheValue = { uri, timestamp };
@@ -61,12 +85,12 @@ export class GitContentProvider {
if (ref === '~') {
const fileUri = Uri.file(path);
const uriString = fileUri.toString();
const [indexStatus] = this.repository.indexGroup.resourceStates.filter(r => r.original.toString() === uriString);
const [indexStatus] = repository.indexGroup.resourceStates.filter(r => r.original.toString() === uriString);
ref = indexStatus ? '' : 'HEAD';
}
try {
return await this.repository.show(ref, path);
return await repository.show(ref, path);
} catch (err) {
return '';
}