Skip to content

Commit ed88fd4

Browse files
committed
Auto merge of #14007 - Veykril:open-server-logs, r=Veykril
Add a 'open server logs' button to the error notification Closes #13995 (comment) ![Code_pUQurJ9BRn](https://user-images.githubusercontent.com/3757771/214038673-658f3b43-5310-47b0-99da-d3222d173b0c.gif)
2 parents e1d7a71 + b9fe5af commit ed88fd4

File tree

7 files changed

+58
-12
lines changed

7 files changed

+58
-12
lines changed

crates/rust-analyzer/src/config.rs

+4
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

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

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

+1-1
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

+1
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

+5
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

+1
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)