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>(); /** * Create a new PijulDecorationProvider instance * @param repository The repository decorations will be provided for */ 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()); } }