import * as vscode from 'vscode'; const spinnerFrames = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏']; export class StatusDisplay implements vscode.Disposable { public packageName?: string; private i = 0; private statusBarItem: vscode.StatusBarItem; private command: string; private timer?: NodeJS.Timeout; constructor(command: string) { this.statusBarItem = vscode.window.createStatusBarItem( vscode.StatusBarAlignment.Left, 10, ); this.command = command; this.statusBarItem.hide(); } public show() { this.packageName = undefined; this.timer = this.timer || setInterval(() => { if (this.packageName) { this.statusBarItem!.text = `cargo ${this.command} [${ this.packageName }] ${this.frame()}`; } else { this.statusBarItem!.text = `cargo ${ this.command } ${this.frame()}`; } }, 300); this.statusBarItem.show(); } public hide() { if (this.timer) { clearInterval(this.timer); this.timer = undefined; } this.statusBarItem.hide(); } public dispose() { if (this.timer) { clearInterval(this.timer); this.timer = undefined; } this.statusBarItem.dispose(); } public handleProgressNotification(params: ProgressParams) { const { token, value } = params; if (token !== "rustAnalyzer/cargoWatcher") { return; } console.log("Got progress notification", token, value) switch (value.kind) { case "begin": this.show(); break; case "report": if (value.message) { this.packageName = value.message; } break; case "end": this.hide(); break; } } private frame() { return spinnerFrames[(this.i = ++this.i % spinnerFrames.length)]; } } // FIXME: Replace this once vscode-languageclient is updated to LSP 3.15 interface ProgressParams { token: string value: WorkDoneProgress } enum WorkDoneProgressKind { Begin = "begin", Report = "report", End = "end" } interface WorkDoneProgress { kind: WorkDoneProgressKind, message?: string cancelable?: boolean percentage?: string }