mirror of
https://github.com/microsoft/vscode.git
synced 2026-04-23 18:19:12 +01:00
git: multiroot content provider
This commit is contained in:
@@ -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 '';
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user