diff --git a/src/animatedStatusBar.ts b/src/animatedStatusBar.ts new file mode 100644 index 0000000000..d3d88b664e --- /dev/null +++ b/src/animatedStatusBar.ts @@ -0,0 +1,123 @@ +/*--------------------------------------------------------- + * Copyright (C) Microsoft Corporation. All rights reserved. + *--------------------------------------------------------*/ + +import { + StatusBarItem, + StatusBarAlignment, + Disposable, + window} from "vscode"; + +export function setAnimatedStatusBarMessage(text: string, hideWhenDone: Thenable): Disposable { + let animatedStatusBarItem: AnimatedStatusBarItem = new AnimatedStatusBarItem(text); + animatedStatusBarItem.show(hideWhenDone); + return animatedStatusBarItem; +} + +class AnimatedStatusBarItem implements StatusBarItem { + private readonly animationRate: number; + private statusBarItem: StatusBarItem; + private maxCount: number; + private counter: number; + private baseText: string; + private timerInterval: number; + private elapsedTime: number; + private intervalId: NodeJS.Timer; + private suffixStates: string[]; + + public get alignment(): StatusBarAlignment { + return this.statusBarItem.alignment; + } + + public get priority(): number { + return this.statusBarItem.priority; + } + + public get text(): string { + return this.statusBarItem.text; + } + + public set text(value: string) { + this.statusBarItem.text = value; + } + + public get tooltip(): string { + return this.statusBarItem.tooltip; + } + + public set tooltip(value: string) { + this.statusBarItem.tooltip = value; + } + + public get color(): string { + return this.statusBarItem.color; + } + + public set color(value: string) { + this.statusBarItem.color = value; + } + + public get command(): string { + return this.statusBarItem.command; + } + + public set command(value: string) { + this.statusBarItem.command = value; + } + + constructor(baseText: string, alignment?: StatusBarAlignment, priority?: number) { + this.animationRate = 1; + this.statusBarItem = window.createStatusBarItem(alignment, priority); + this.baseText = baseText; + this.counter = 0; + this.suffixStates = [" ", ". ", ".. ", "..."]; + this.maxCount = this.suffixStates.length; + this.timerInterval = ((1/this.maxCount) * 1000) / this.animationRate; + this.elapsedTime = 0; + } + + public show(hideWhenDone?: Thenable): void { + this.statusBarItem.show(); + this.start(); + if (hideWhenDone !== undefined) { + hideWhenDone.then(() => this.hide()); + } + } + + public hide(): void { + this.stop(); + this.statusBarItem.hide(); + } + + public dispose(): void { + this.statusBarItem.dispose(); + } + + private updateCounter(): void { + this.counter = (this.counter + 1) % this.maxCount; + this.elapsedTime = this.elapsedTime + this.timerInterval; + } + + private updateText(): void { + this.text = this.baseText + this.suffixStates[this.counter]; + } + + private update(): void { + this.updateCounter(); + this.updateText(); + } + + private reset(): void { + this.counter = 0; + this.updateText(); + } + + private start(): void { + this.reset(); + this.intervalId = setInterval(() => this.update(), this.timerInterval); + } + + private stop(): void { + clearInterval(this.intervalId); + } +} \ No newline at end of file diff --git a/src/features/DocumentFormatter.ts b/src/features/DocumentFormatter.ts index a63f91ded5..08d71e2084 100644 --- a/src/features/DocumentFormatter.ts +++ b/src/features/DocumentFormatter.ts @@ -18,6 +18,7 @@ import Window = vscode.window; import { IFeature } from '../feature'; import * as Settings from '../settings'; import * as Utils from '../utils'; +import * as AnimatedStatusBar from '../animatedStatusBar'; export namespace ScriptFileMarkersRequest { export const type: RequestType = { get method(): string { return "powerShell/getScriptFileMarkers"; } }; @@ -110,14 +111,17 @@ class PSDocumentFormattingEditProvider implements DocumentFormattingEditProvider range: Range, options: FormattingOptions, token: CancellationToken): TextEdit[] | Thenable { - return this.executeRulesInOrder(document, range, options, 0); + + let textEdits: Thenable = this.executeRulesInOrder(document, range, options, 0); + AnimatedStatusBar.setAnimatedStatusBarMessage("formatting", textEdits); + return textEdits; } executeRulesInOrder( document: TextDocument, range: Range, options: FormattingOptions, - index: number): Thenable | TextEdit[] { + index: number): Thenable { if (this.languageClient !== null && index < this.ruleOrder.length) { let rule = this.ruleOrder[index]; let uniqueEdits: ScriptRegion[] = []; @@ -172,7 +176,7 @@ class PSDocumentFormattingEditProvider implements DocumentFormattingEditProvider return this.executeRulesInOrder(document, range, options, index + 1); }); } else { - return TextEdit[0]; + return Promise.resolve(TextEdit[0]); } }