import { Disposable, Event, EventEmitter, FileDecoration, FileDecorationProvider, Uri, window } from 'vscode';
import { Repository } from './repository';
import { PijulResourceGroup } from './resource';
/**
* A decoration provider which tells VS Code how to decorate the files in a Pijul repository
*/
export class PijulDecorationProvider implements FileDecorationProvider {
private readonly onDidChangeDecorationsEmitter = new EventEmitter<Uri[]>();
readonly onDidChangeFileDecorations: Event<Uri[]> = this.onDidChangeDecorationsEmitter.event;
private readonly disposables: Disposable[] = [];
private decorations = new Map<string, FileDecoration>();
constructor (private readonly repository: Repository) {
this.disposables.push(
window.registerFileDecorationProvider(this),
repository.onDidRefreshStatus(this.onDidRefreshStatus, this)
);
}
/**
* Event listener that is triggered when the Pijul repo state is refreshed
*/
private onDidRefreshStatus (): void {
const newDecorations = new Map<string, FileDecoration>();
this.collectDecorationData(this.repository.changedGroup, newDecorations);
this.collectDecorationData(this.repository.untrackedGroup, newDecorations);
const uris = new Set([...this.decorations.keys()].concat([...newDecorations.keys()]));
this.decorations = newDecorations;
this.onDidChangeDecorationsEmitter.fire([...uris.values()].map(value => Uri.parse(value, true)));
}
/**
* Take the decoration data from each item in a resource group and add it to the decorationMap
* @param group The resource group decoration data will be taken from
* @param decorationMap The decoration map the decoration data will be added to
*/
private collectDecorationData (group: PijulResourceGroup, decorationMap: Map<string, FileDecoration>): void {
for (const resource of group.resourceStates) {
// TODO: Better handling of moves
decorationMap.set(resource.resourceUri.toString(), resource.resourceDecoration);
}
}
/**
* Interface function which provides decorations to VS Code by looking up the file
* URI in the decoration map.
* @param uri The URI of the file VS Code is looking up decorations for
*/
provideFileDecoration (uri: Uri): FileDecoration | undefined {
return this.decorations.get(uri.toString());
}
/**
* Dispose of all of the disposable resources
*/
dispose (): void {
this.disposables.forEach(d => d.dispose());
}
}