Skip to content

Commit 382f533

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

File tree

6 files changed

+57
-11
lines changed

6 files changed

+57
-11
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

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)