diff options
Diffstat (limited to 'src/tools/rust-analyzer/crates/rust-analyzer/src/lsp_utils.rs')
-rw-r--r-- | src/tools/rust-analyzer/crates/rust-analyzer/src/lsp_utils.rs | 88 |
1 files changed, 65 insertions, 23 deletions
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp_utils.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp_utils.rs index dcaee9285..30f1c53c1 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp_utils.rs +++ b/src/tools/rust-analyzer/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); } } @@ -133,6 +161,7 @@ impl GlobalState { } pub(crate) fn apply_document_changes( + encoding: PositionEncoding, file_contents: impl FnOnce() -> String, mut content_changes: Vec<lsp_types::TextDocumentContentChangeEvent>, ) -> String { @@ -164,9 +193,9 @@ pub(crate) fn apply_document_changes( let mut line_index = LineIndex { // the index will be overwritten in the bottom loop's first iteration index: Arc::new(ide::LineIndex::new(&text)), - // We don't care about line endings or offset encoding here. + // We don't care about line endings here. endings: LineEndings::Unix, - encoding: PositionEncoding::Utf16, + encoding, }; // The changes we got must be applied sequentially, but can cross lines so we @@ -228,6 +257,7 @@ pub(crate) fn all_edits_are_disjoint( #[cfg(test)] mod tests { + use ide_db::line_index::WideEncoding; use lsp_types::{ CompletionItem, CompletionTextEdit, InsertReplaceEdit, Position, Range, TextDocumentContentChangeEvent, @@ -250,9 +280,11 @@ mod tests { }; } - let text = apply_document_changes(|| String::new(), vec![]); + let encoding = PositionEncoding::Wide(WideEncoding::Utf16); + let text = apply_document_changes(encoding, || String::new(), vec![]); assert_eq!(text, ""); let text = apply_document_changes( + encoding, || text, vec![TextDocumentContentChangeEvent { range: None, @@ -261,39 +293,49 @@ mod tests { }], ); assert_eq!(text, "the"); - let text = apply_document_changes(|| text, c![0, 3; 0, 3 => " quick"]); + let text = apply_document_changes(encoding, || text, c![0, 3; 0, 3 => " quick"]); assert_eq!(text, "the quick"); - let text = apply_document_changes(|| text, c![0, 0; 0, 4 => "", 0, 5; 0, 5 => " foxes"]); + let text = + apply_document_changes(encoding, || text, c![0, 0; 0, 4 => "", 0, 5; 0, 5 => " foxes"]); assert_eq!(text, "quick foxes"); - let text = apply_document_changes(|| text, c![0, 11; 0, 11 => "\ndream"]); + let text = apply_document_changes(encoding, || text, c![0, 11; 0, 11 => "\ndream"]); assert_eq!(text, "quick foxes\ndream"); - let text = apply_document_changes(|| text, c![1, 0; 1, 0 => "have "]); + let text = apply_document_changes(encoding, || text, c![1, 0; 1, 0 => "have "]); assert_eq!(text, "quick foxes\nhave dream"); let text = apply_document_changes( + encoding, || text, c![0, 0; 0, 0 => "the ", 1, 4; 1, 4 => " quiet", 1, 16; 1, 16 => "s\n"], ); assert_eq!(text, "the quick foxes\nhave quiet dreams\n"); - let text = apply_document_changes(|| text, c![0, 15; 0, 15 => "\n", 2, 17; 2, 17 => "\n"]); + let text = apply_document_changes( + encoding, + || text, + c![0, 15; 0, 15 => "\n", 2, 17; 2, 17 => "\n"], + ); assert_eq!(text, "the quick foxes\n\nhave quiet dreams\n\n"); let text = apply_document_changes( + encoding, || text, c![1, 0; 1, 0 => "DREAM", 2, 0; 2, 0 => "they ", 3, 0; 3, 0 => "DON'T THEY?"], ); assert_eq!(text, "the quick foxes\nDREAM\nthey have quiet dreams\nDON'T THEY?\n"); - let text = apply_document_changes(|| text, c![0, 10; 1, 5 => "", 2, 0; 2, 12 => ""]); + let text = + apply_document_changes(encoding, || text, c![0, 10; 1, 5 => "", 2, 0; 2, 12 => ""]); assert_eq!(text, "the quick \nthey have quiet dreams\n"); let text = String::from("❤️"); - let text = apply_document_changes(|| text, c![0, 0; 0, 0 => "a"]); + let text = apply_document_changes(encoding, || text, c![0, 0; 0, 0 => "a"]); assert_eq!(text, "a❤️"); let text = String::from("a\nb"); - let text = apply_document_changes(|| text, c![0, 1; 1, 0 => "\nțc", 0, 1; 1, 1 => "d"]); + let text = + apply_document_changes(encoding, || text, c![0, 1; 1, 0 => "\nțc", 0, 1; 1, 1 => "d"]); assert_eq!(text, "adcb"); let text = String::from("a\nb"); - let text = apply_document_changes(|| text, c![0, 1; 1, 0 => "ț\nc", 0, 2; 0, 2 => "c"]); + let text = + apply_document_changes(encoding, || text, c![0, 1; 1, 0 => "ț\nc", 0, 2; 0, 2 => "c"]); assert_eq!(text, "ațc\ncb"); } |