Send an actual ShowMessage instead of InternalFeedback in feedback()

This now allows us to send a notification that can be shown in the UI when the
workspace has been loaded.

Additionally this removes the need for internal_mode flag.
This commit is contained in:
Ville Penttinen 2019-03-05 21:59:01 +02:00
parent ab288a32f9
commit 9063dabcca
3 changed files with 27 additions and 20 deletions

View file

@ -43,7 +43,7 @@ fn main_inner() -> Result<()> {
.and_then(|v| InitializationOptions::deserialize(v).ok()) .and_then(|v| InitializationOptions::deserialize(v).ok())
.and_then(|it| it.publish_decorations) .and_then(|it| it.publish_decorations)
== Some(true); == Some(true);
ra_lsp_server::main_loop(false, root, supports_decorations, r, s) ra_lsp_server::main_loop(root, supports_decorations, r, s)
})?; })?;
log::info!("shutting down IO..."); log::info!("shutting down IO...");
threads.join()?; threads.join()?;

View file

@ -46,7 +46,6 @@ enum Task {
const THREADPOOL_SIZE: usize = 8; const THREADPOOL_SIZE: usize = 8;
pub fn main_loop( pub fn main_loop(
internal_mode: bool,
ws_root: PathBuf, ws_root: PathBuf,
supports_decorations: bool, supports_decorations: bool,
msg_receiver: &Receiver<RawMessage>, msg_receiver: &Receiver<RawMessage>,
@ -63,11 +62,12 @@ pub fn main_loop(
Ok(ws) => vec![ws], Ok(ws) => vec![ws],
Err(e) => { Err(e) => {
log::error!("loading workspace failed: {}", e); log::error!("loading workspace failed: {}", e);
let msg = RawNotification::new::<req::ShowMessage>(&req::ShowMessageParams {
typ: req::MessageType::Error, feedback(
message: format!("rust-analyzer failed to load workspace: {}", e), req::MessageType::Error,
}); format!("rust-analyzer failed to load workspace: {}", e),
msg_sender.send(msg.into()).unwrap(); msg_sender,
);
Vec::new() Vec::new()
} }
} }
@ -80,7 +80,6 @@ pub fn main_loop(
let mut pending_requests = FxHashSet::default(); let mut pending_requests = FxHashSet::default();
let mut subs = Subscriptions::new(); let mut subs = Subscriptions::new();
let main_res = main_loop_inner( let main_res = main_loop_inner(
internal_mode,
supports_decorations, supports_decorations,
&pool, &pool,
msg_sender, msg_sender,
@ -148,7 +147,6 @@ impl fmt::Debug for Event {
} }
fn main_loop_inner( fn main_loop_inner(
internal_mode: bool,
supports_decorations: bool, supports_decorations: bool,
pool: &ThreadPool, pool: &ThreadPool,
msg_sender: &Sender<RawMessage>, msg_sender: &Sender<RawMessage>,
@ -163,6 +161,7 @@ fn main_loop_inner(
// time to always have a thread ready to react to input. // time to always have a thread ready to react to input.
let mut in_flight_libraries = 0; let mut in_flight_libraries = 0;
let mut pending_libraries = Vec::new(); let mut pending_libraries = Vec::new();
let mut send_workspace_notification = true;
let (libdata_sender, libdata_receiver) = unbounded(); let (libdata_sender, libdata_receiver) = unbounded();
loop { loop {
@ -190,7 +189,6 @@ fn main_loop_inner(
state_changed = true; state_changed = true;
} }
Event::Lib(lib) => { Event::Lib(lib) => {
feedback(internal_mode, "library loaded", msg_sender);
state.add_lib(lib); state.add_lib(lib);
in_flight_libraries -= 1; in_flight_libraries -= 1;
} }
@ -244,8 +242,14 @@ fn main_loop_inner(
}); });
} }
if state.roots_to_scan == 0 && pending_libraries.is_empty() && in_flight_libraries == 0 { if send_workspace_notification
feedback(internal_mode, "workspace loaded", msg_sender); && state.roots_to_scan == 0
&& pending_libraries.is_empty()
&& in_flight_libraries == 0
{
feedback(req::MessageType::Info, "workspace loaded", msg_sender);
// Only send the notification first time
send_workspace_notification = false;
} }
if state_changed { if state_changed {
@ -501,11 +505,12 @@ fn update_file_notifications_on_threadpool(
}); });
} }
fn feedback(intrnal_mode: bool, msg: &str, sender: &Sender<RawMessage>) { fn feedback<M: Into<String>>(typ: req::MessageType, msg: M, sender: &Sender<RawMessage>) {
if !intrnal_mode { let not = RawNotification::new::<req::ShowMessage>(&req::ShowMessageParams {
return; typ,
} message: msg.into(),
let not = RawNotification::new::<req::InternalFeedback>(&msg.to_string()); });
sender.send(not.into()).unwrap(); sender.send(not.into()).unwrap();
} }

View file

@ -13,6 +13,7 @@ use lsp_types::{
notification::DidOpenTextDocument, notification::DidOpenTextDocument,
request::{Request, Shutdown}, request::{Request, Shutdown},
DidOpenTextDocumentParams, TextDocumentIdentifier, TextDocumentItem, Url, DidOpenTextDocumentParams, TextDocumentIdentifier, TextDocumentItem, Url,
notification::{Notification, ShowMessage},
}; };
use serde::Serialize; use serde::Serialize;
use serde_json::{to_string_pretty, Value}; use serde_json::{to_string_pretty, Value};
@ -56,7 +57,7 @@ impl Server {
"test server", "test server",
128, 128,
move |mut msg_receiver, mut msg_sender| { move |mut msg_receiver, mut msg_sender| {
main_loop(true, path, true, &mut msg_receiver, &mut msg_sender).unwrap() main_loop(path, true, &mut msg_receiver, &mut msg_sender).unwrap()
}, },
); );
let res = Server { let res = Server {
@ -138,8 +139,9 @@ impl Server {
} }
pub fn wait_for_feedback_n(&self, feedback: &str, n: usize) { pub fn wait_for_feedback_n(&self, feedback: &str, n: usize) {
let f = |msg: &RawMessage| match msg { let f = |msg: &RawMessage| match msg {
RawMessage::Notification(n) if n.method == "internalFeedback" => { RawMessage::Notification(n) if n.method == ShowMessage::METHOD => {
return n.clone().cast::<req::InternalFeedback>().unwrap() == feedback; let message = n.clone().cast::<req::ShowMessage>().unwrap();
message.message == feedback
} }
_ => false, _ => false,
}; };