Skip to content

Commit b9fe5af

Browse files
committed
Add a 'open server logs' button to the error notification
1 parent 84239a1 commit b9fe5af

File tree

7 files changed

+58
-12
lines changed

7 files changed

+58
-12
lines changed

crates/rust-analyzer/src/config.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -989,6 +989,10 @@ impl Config {
989989
self.experimental("codeActionGroup")
990990
}
991991

992+
pub fn open_server_logs(&self) -> bool {
993+
self.experimental("openServerLogs")
994+
}
995+
992996
pub fn server_status_notification(&self) -> bool {
993997
self.experimental("serverStatusNotification")
994998
}

crates/rust-analyzer/src/lsp_ext.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,13 @@ impl Notification for ClearFlycheck {
151151
const METHOD: &'static str = "rust-analyzer/clearFlycheck";
152152
}
153153

154+
pub enum OpenServerLogs {}
155+
156+
impl Notification for OpenServerLogs {
157+
type Params = ();
158+
const METHOD: &'static str = "rust-analyzer/openServerLogs";
159+
}
160+
154161
#[derive(Deserialize, Serialize, Debug)]
155162
#[serde(rename_all = "camelCase")]
156163
pub struct RunFlycheckParams {

crates/rust-analyzer/src/lsp_utils.rs

Lines changed: 39 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,13 @@
22
use std::{mem, ops::Range, sync::Arc};
33

44
use lsp_server::Notification;
5+
use lsp_types::request::Request;
56

67
use crate::{
78
from_proto,
89
global_state::GlobalState,
910
line_index::{LineEndings, LineIndex, PositionEncoding},
10-
LspError,
11+
lsp_ext, LspError,
1112
};
1213

1314
pub(crate) fn invalid_params_error(message: String) -> LspError {
@@ -46,20 +47,47 @@ impl GlobalState {
4647
/// If `additional_info` is [`Some`], appends a note to the notification telling to check the logs.
4748
/// This will always log `message` + `additional_info` to the server's error log.
4849
pub(crate) fn show_and_log_error(&mut self, message: String, additional_info: Option<String>) {
49-
let mut message = message;
5050
match additional_info {
5151
Some(additional_info) => {
52-
tracing::error!("{}\n\n{}", &message, &additional_info);
53-
if tracing::enabled!(tracing::Level::ERROR) {
54-
message.push_str("\n\nCheck the server logs for additional info.");
52+
tracing::error!("{}:\n{}", &message, &additional_info);
53+
match self.config.open_server_logs() && tracing::enabled!(tracing::Level::ERROR) {
54+
true => self.send_request::<lsp_types::request::ShowMessageRequest>(
55+
lsp_types::ShowMessageRequestParams {
56+
typ: lsp_types::MessageType::ERROR,
57+
message,
58+
actions: Some(vec![lsp_types::MessageActionItem {
59+
title: "Open server logs".to_owned(),
60+
properties: Default::default(),
61+
}]),
62+
},
63+
|this, resp| {
64+
let lsp_server::Response { error: None, result: Some(result), .. } = resp
65+
else { return };
66+
if let Ok(Some(_item)) = crate::from_json::<
67+
<lsp_types::request::ShowMessageRequest as lsp_types::request::Request>::Result,
68+
>(
69+
lsp_types::request::ShowMessageRequest::METHOD, &result
70+
) {
71+
this.send_notification::<lsp_ext::OpenServerLogs>(());
72+
}
73+
},
74+
),
75+
false => self.send_notification::<lsp_types::notification::ShowMessage>(
76+
lsp_types::ShowMessageParams {
77+
typ: lsp_types::MessageType::ERROR,
78+
message,
79+
},
80+
),
5581
}
5682
}
57-
None => tracing::error!("{}", &message),
58-
}
83+
None => {
84+
tracing::error!("{}", &message);
5985

60-
self.send_notification::<lsp_types::notification::ShowMessage>(
61-
lsp_types::ShowMessageParams { typ: lsp_types::MessageType::ERROR, message },
62-
)
86+
self.send_notification::<lsp_types::notification::ShowMessage>(
87+
lsp_types::ShowMessageParams { typ: lsp_types::MessageType::ERROR, message },
88+
);
89+
}
90+
}
6391
}
6492

6593
/// rust-analyzer is resilient -- if it fails, this doesn't usually affect
@@ -77,7 +105,7 @@ impl GlobalState {
77105
let from_source_build = option_env!("POKE_RA_DEVS").is_some();
78106
let profiling_enabled = std::env::var("RA_PROFILE").is_ok();
79107
if from_source_build || profiling_enabled {
80-
self.show_message(lsp_types::MessageType::ERROR, message)
108+
self.show_and_log_error(message, None);
81109
}
82110
}
83111

docs/dev/lsp-extensions.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<!---
2-
lsp_ext.rs hash: d296ce1226e3568d
2+
lsp_ext.rs hash: ec29403e67dfd15b
33
44
If you need to change the above hash to make the test pass, please check if you
55
need to adjust this doc as well and ping this issue:

editors/code/src/client.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,7 @@ class ExperimentalFeatures implements lc.StaticFeature {
316316
caps.hoverActions = true;
317317
caps.serverStatusNotification = true;
318318
caps.colorDiagnosticOutput = true;
319+
caps.openServerLogs = true;
319320
caps.commands = {
320321
commands: [
321322
"rust-analyzer.runSingle",

editors/code/src/ctx.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,11 @@ export class Ctx {
187187
this.setServerStatus(params)
188188
)
189189
);
190+
this.pushClientCleanup(
191+
this._client.onNotification(ra.openServerLogs, () => {
192+
this.outputChannel!.show();
193+
})
194+
);
190195
}
191196
return this._client;
192197
}

editors/code/src/lsp_ext.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ export interface ServerStatusParams {
2121
export const serverStatus = new lc.NotificationType<ServerStatusParams>(
2222
"experimental/serverStatus"
2323
);
24+
export const openServerLogs = new lc.NotificationType0("rust-analyzer/openServerLogs");
2425

2526
export const reloadWorkspace = new lc.RequestType0<null, void>("rust-analyzer/reloadWorkspace");
2627

0 commit comments

Comments
 (0)