import * as vscode from 'vscode';
-import * as lc from 'vscode-languageclient';
+import * as lc from 'vscode-languageclient/node';
+import * as ra from './lsp_ext';
import { Config } from './config';
-import { createClient, configToServerOptions } from './client';
+import { createClient } from './client';
import { isRustEditor, RustEditor } from './util';
+import { ServerStatusParams } from './lsp_ext';
export class Ctx {
private constructor(
private readonly extCtx: vscode.ExtensionContext,
readonly client: lc.LanguageClient,
readonly serverPath: string,
+ readonly statusBar: vscode.StatusBarItem,
) {
}
- static async create(config: Config, extCtx: vscode.ExtensionContext, serverPath: string): Promise<Ctx> {
- const client = await createClient(config, serverPath);
- const res = new Ctx(config, extCtx, client, serverPath);
+ static async create(
+ config: Config,
+ extCtx: vscode.ExtensionContext,
+ serverPath: string,
+ cwd: string,
+ ): Promise<Ctx> {
+ const client = createClient(serverPath, cwd, config.serverExtraEnv);
+
+ const statusBar = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left);
+ extCtx.subscriptions.push(statusBar);
+ statusBar.text = "rust-analyzer";
+ statusBar.tooltip = "ready";
+ statusBar.show();
+
+ const res = new Ctx(config, extCtx, client, serverPath, statusBar);
+
res.pushCleanup(client.start());
await client.onReady();
- client.onRequest('workspace/configuration', _ => [configToServerOptions(config)]);
+ client.onNotification(ra.serverStatus, (params) => res.setServerStatus(params));
return res;
}
return this.extCtx.subscriptions;
}
+ setServerStatus(status: ServerStatusParams) {
+ this.statusBar.tooltip = status.message ?? "Ready";
+ let icon = "";
+ switch (status.health) {
+ case "ok":
+ this.statusBar.color = undefined;
+ break;
+ case "warning":
+ this.statusBar.tooltip += "\nClick to reload."
+ this.statusBar.command = "rust-analyzer.reloadWorkspace";
+ this.statusBar.color = new vscode.ThemeColor("notificationsWarningIcon.foreground");
+ icon = "$(warning) ";
+ break;
+ case "error":
+ this.statusBar.tooltip += "\nClick to reload."
+ this.statusBar.command = "rust-analyzer.reloadWorkspace";
+ this.statusBar.color = new vscode.ThemeColor("notificationsErrorIcon.foreground");
+ icon = "$(error) ";
+ break;
+ }
+ if (!status.quiescent) icon = "$(sync~spin) ";
+ this.statusBar.text = `${icon} rust-analyzer`;
+ }
+
pushCleanup(d: Disposable) {
this.extCtx.subscriptions.push(d);
}