aboutsummaryrefslogtreecommitdiff
path: root/editors/code/src/status_display.ts
diff options
context:
space:
mode:
Diffstat (limited to 'editors/code/src/status_display.ts')
-rw-r--r--editors/code/src/status_display.ts115
1 files changed, 115 insertions, 0 deletions
diff --git a/editors/code/src/status_display.ts b/editors/code/src/status_display.ts
new file mode 100644
index 000000000..08cdc8bdf
--- /dev/null
+++ b/editors/code/src/status_display.ts
@@ -0,0 +1,115 @@
1import * as vscode from 'vscode';
2
3import { Ctx } from './ctx';
4
5const spinnerFrames = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
6
7export function activateStatusDisplay(ctx: Ctx) {
8 const statusDisplay = new StatusDisplay(ctx.config.cargoWatchOptions.command);
9 ctx.pushCleanup(statusDisplay);
10 ctx.onDidRestart(client => {
11 client.onNotification('$/progress', params => statusDisplay.handleProgressNotification(params));
12 });
13}
14
15class StatusDisplay implements vscode.Disposable {
16 packageName?: string;
17
18 private i = 0;
19 private statusBarItem: vscode.StatusBarItem;
20 private command: string;
21 private timer?: NodeJS.Timeout;
22
23 constructor(command: string) {
24 this.statusBarItem = vscode.window.createStatusBarItem(
25 vscode.StatusBarAlignment.Left,
26 10,
27 );
28 this.command = command;
29 this.statusBarItem.hide();
30 }
31
32 show() {
33 this.packageName = undefined;
34
35 this.timer =
36 this.timer ||
37 setInterval(() => {
38 if (this.packageName) {
39 this.statusBarItem!.text = `cargo ${this.command} [${
40 this.packageName
41 }] ${this.frame()}`;
42 } else {
43 this.statusBarItem!.text = `cargo ${
44 this.command
45 } ${this.frame()}`;
46 }
47 }, 300);
48
49 this.statusBarItem.show();
50 }
51
52 hide() {
53 if (this.timer) {
54 clearInterval(this.timer);
55 this.timer = undefined;
56 }
57
58 this.statusBarItem.hide();
59 }
60
61 dispose() {
62 if (this.timer) {
63 clearInterval(this.timer);
64 this.timer = undefined;
65 }
66
67 this.statusBarItem.dispose();
68 }
69
70 handleProgressNotification(params: ProgressParams) {
71 const { token, value } = params;
72 if (token !== 'rustAnalyzer/cargoWatcher') {
73 return;
74 }
75
76 switch (value.kind) {
77 case 'begin':
78 this.show();
79 break;
80
81 case 'report':
82 if (value.message) {
83 this.packageName = value.message;
84 }
85 break;
86
87 case 'end':
88 this.hide();
89 break;
90 }
91 }
92
93 private frame() {
94 return spinnerFrames[(this.i = ++this.i % spinnerFrames.length)];
95 }
96}
97
98// FIXME: Replace this once vscode-languageclient is updated to LSP 3.15
99interface ProgressParams {
100 token: string;
101 value: WorkDoneProgress;
102}
103
104enum WorkDoneProgressKind {
105 Begin = 'begin',
106 Report = 'report',
107 End = 'end',
108}
109
110interface WorkDoneProgress {
111 kind: WorkDoneProgressKind;
112 message?: string;
113 cancelable?: boolean;
114 percentage?: string;
115}