Unnamed repository; edit this file 'description' to name the repository.
Add a 'open server logs' button to the error notification
Lukas Wirth 2023-01-23
parent 84239a1 · commit b9fe5af
-rw-r--r--crates/rust-analyzer/src/config.rs4
-rw-r--r--crates/rust-analyzer/src/lsp_ext.rs7
-rw-r--r--crates/rust-analyzer/src/lsp_utils.rs50
-rw-r--r--docs/dev/lsp-extensions.md2
-rw-r--r--editors/code/src/client.ts1
-rw-r--r--editors/code/src/ctx.ts5
-rw-r--r--editors/code/src/lsp_ext.ts1
7 files changed, 58 insertions, 12 deletions
diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs
index c4d9ad7dff..8ea161dbdc 100644
--- a/crates/rust-analyzer/src/config.rs
+++ b/crates/rust-analyzer/src/config.rs
@@ -989,6 +989,10 @@ impl Config {
self.experimental("codeActionGroup")
}
+ pub fn open_server_logs(&self) -> bool {
+ self.experimental("openServerLogs")
+ }
+
pub fn server_status_notification(&self) -> bool {
self.experimental("serverStatusNotification")
}
diff --git a/crates/rust-analyzer/src/lsp_ext.rs b/crates/rust-analyzer/src/lsp_ext.rs
index b117acd1b0..08b2c837de 100644
--- a/crates/rust-analyzer/src/lsp_ext.rs
+++ b/crates/rust-analyzer/src/lsp_ext.rs
@@ -151,6 +151,13 @@ impl Notification for ClearFlycheck {
const METHOD: &'static str = "rust-analyzer/clearFlycheck";
}
+pub enum OpenServerLogs {}
+
+impl Notification for OpenServerLogs {
+ type Params = ();
+ const METHOD: &'static str = "rust-analyzer/openServerLogs";
+}
+
#[derive(Deserialize, Serialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct RunFlycheckParams {
diff --git a/crates/rust-analyzer/src/lsp_utils.rs b/crates/rust-analyzer/src/lsp_utils.rs
index dcaee92857..baa77a005e 100644
--- a/crates/rust-analyzer/src/lsp_utils.rs
+++ b/crates/rust-analyzer/src/lsp_utils.rs
@@ -2,12 +2,13 @@
use std::{mem, ops::Range, sync::Arc};
use lsp_server::Notification;
+use lsp_types::request::Request;
use crate::{
from_proto,
global_state::GlobalState,
line_index::{LineEndings, LineIndex, PositionEncoding},
- LspError,
+ lsp_ext, LspError,
};
pub(crate) fn invalid_params_error(message: String) -> LspError {
@@ -46,20 +47,47 @@ impl GlobalState {
/// If `additional_info` is [`Some`], appends a note to the notification telling to check the logs.
/// This will always log `message` + `additional_info` to the server's error log.
pub(crate) fn show_and_log_error(&mut self, message: String, additional_info: Option<String>) {
- let mut message = message;
match additional_info {
Some(additional_info) => {
- tracing::error!("{}\n\n{}", &message, &additional_info);
- if tracing::enabled!(tracing::Level::ERROR) {
- message.push_str("\n\nCheck the server logs for additional info.");
+ tracing::error!("{}:\n{}", &message, &additional_info);
+ match self.config.open_server_logs() && tracing::enabled!(tracing::Level::ERROR) {
+ true => self.send_request::<lsp_types::request::ShowMessageRequest>(
+ lsp_types::ShowMessageRequestParams {
+ typ: lsp_types::MessageType::ERROR,
+ message,
+ actions: Some(vec![lsp_types::MessageActionItem {
+ title: "Open server logs".to_owned(),
+ properties: Default::default(),
+ }]),
+ },
+ |this, resp| {
+ let lsp_server::Response { error: None, result: Some(result), .. } = resp
+ else { return };
+ if let Ok(Some(_item)) = crate::from_json::<
+ <lsp_types::request::ShowMessageRequest as lsp_types::request::Request>::Result,
+ >(
+ lsp_types::request::ShowMessageRequest::METHOD, &result
+ ) {
+ this.send_notification::<lsp_ext::OpenServerLogs>(());
+ }
+ },
+ ),
+ false => self.send_notification::<lsp_types::notification::ShowMessage>(
+ lsp_types::ShowMessageParams {
+ typ: lsp_types::MessageType::ERROR,
+ message,
+ },
+ ),
}
}
- None => tracing::error!("{}", &message),
- }
+ None => {
+ tracing::error!("{}", &message);
- self.send_notification::<lsp_types::notification::ShowMessage>(
- lsp_types::ShowMessageParams { typ: lsp_types::MessageType::ERROR, message },
- )
+ self.send_notification::<lsp_types::notification::ShowMessage>(
+ lsp_types::ShowMessageParams { typ: lsp_types::MessageType::ERROR, message },
+ );
+ }
+ }
}
/// rust-analyzer is resilient -- if it fails, this doesn't usually affect
@@ -77,7 +105,7 @@ impl GlobalState {
let from_source_build = option_env!("POKE_RA_DEVS").is_some();
let profiling_enabled = std::env::var("RA_PROFILE").is_ok();
if from_source_build || profiling_enabled {
- self.show_message(lsp_types::MessageType::ERROR, message)
+ self.show_and_log_error(message, None);
}
}
diff --git a/docs/dev/lsp-extensions.md b/docs/dev/lsp-extensions.md
index 0f24ddbbc0..a794e86618 100644
--- a/docs/dev/lsp-extensions.md
+++ b/docs/dev/lsp-extensions.md
@@ -1,5 +1,5 @@
<!---
-lsp_ext.rs hash: d296ce1226e3568d
+lsp_ext.rs hash: ec29403e67dfd15b
If you need to change the above hash to make the test pass, please check if you
need to adjust this doc as well and ping this issue:
diff --git a/editors/code/src/client.ts b/editors/code/src/client.ts
index 1fbe9d4ea0..9335e9abb3 100644
--- a/editors/code/src/client.ts
+++ b/editors/code/src/client.ts
@@ -316,6 +316,7 @@ class ExperimentalFeatures implements lc.StaticFeature {
caps.hoverActions = true;
caps.serverStatusNotification = true;
caps.colorDiagnosticOutput = true;
+ caps.openServerLogs = true;
caps.commands = {
commands: [
"rust-analyzer.runSingle",
diff --git a/editors/code/src/ctx.ts b/editors/code/src/ctx.ts
index d6cee5c8fc..1860924c6d 100644
--- a/editors/code/src/ctx.ts
+++ b/editors/code/src/ctx.ts
@@ -187,6 +187,11 @@ export class Ctx {
this.setServerStatus(params)
)
);
+ this.pushClientCleanup(
+ this._client.onNotification(ra.openServerLogs, () => {
+ this.outputChannel!.show();
+ })
+ );
}
return this._client;
}
diff --git a/editors/code/src/lsp_ext.ts b/editors/code/src/lsp_ext.ts
index 29349cc20f..6ddf83799c 100644
--- a/editors/code/src/lsp_ext.ts
+++ b/editors/code/src/lsp_ext.ts
@@ -21,6 +21,7 @@ export interface ServerStatusParams {
export const serverStatus = new lc.NotificationType<ServerStatusParams>(
"experimental/serverStatus"
);
+export const openServerLogs = new lc.NotificationType0("rust-analyzer/openServerLogs");
export const reloadWorkspace = new lc.RequestType0<null, void>("rust-analyzer/reloadWorkspace");