on master help sign in
lsp: Display LSP progress messages (#216)
098806cWojciech Kępka
helix-lsp/src/client.rs+4
@@ -228,6 +228,10 @@ impl Client {
228 }),
228 }),
229 ..Default::default()
229 ..Default::default()
230 }),
230 }),
231+ window: Some(lsp::WindowClientCapabilities {
232+ work_done_progress: Some(true),
233+ ..Default::default()
234+ }),
231 ..Default::default()
235 ..Default::default()
232 },
236 },
233 trace: None,
237 trace: None,
helix-lsp/src/lib.rs+8−4
@@ -134,6 +134,7 @@ pub enum Notification {
134 PublishDiagnostics(lsp::PublishDiagnosticsParams),
134 PublishDiagnostics(lsp::PublishDiagnosticsParams),
135 ShowMessage(lsp::ShowMessageParams),
135 ShowMessage(lsp::ShowMessageParams),
136 LogMessage(lsp::LogMessageParams),
136 LogMessage(lsp::LogMessageParams),
137+ ProgressMessage(lsp::ProgressParams),
137}
138}
138
139
139impl Notification {
140impl Notification {
@@ -151,17 +152,20 @@ impl Notification {
151 }
152 }
152
153
153 lsp::notification::ShowMessage::METHOD => {
154 lsp::notification::ShowMessage::METHOD => {
154− let params: lsp::ShowMessageParams =
155+ let params: lsp::ShowMessageParams = params.parse().ok()?;
155− params.parse().expect("Failed to parse ShowMessage params");
156
156
157 Self::ShowMessage(params)
157 Self::ShowMessage(params)
158 }
158 }
159 lsp::notification::LogMessage::METHOD => {
159 lsp::notification::LogMessage::METHOD => {
160− let params: lsp::LogMessageParams =
160+ let params: lsp::LogMessageParams = params.parse().ok()?;
161− params.parse().expect("Failed to parse ShowMessage params");
162
161
163 Self::LogMessage(params)
162 Self::LogMessage(params)
164 }
163 }
164+ lsp::notification::Progress::METHOD => {
165+ let params: lsp::ProgressParams = params.parse().ok()?;
166+
167+ Self::ProgressMessage(params)
168+ }
165 _ => {
169 _ => {
166 log::error!("unhandled LSP notification: {}", method);
170 log::error!("unhandled LSP notification: {}", method);
167 return None;
171 return None;
helix-term/src/application.rs+54
@@ -1,3 +1,4 @@
1+use helix_lsp::lsp;
1use helix_view::{document::Mode, Document, Editor, Theme, View};
2use helix_view::{document::Mode, Document, Editor, Theme, View};
2
3
3use crate::{args::Args, compositor::Compositor, ui};
4use crate::{args::Args, compositor::Compositor, ui};
@@ -228,6 +229,59 @@ impl Application {
228 Notification::LogMessage(params) => {
229 Notification::LogMessage(params) => {
229 log::warn!("unhandled window/logMessage: {:?}", params);
230 log::warn!("unhandled window/logMessage: {:?}", params);
230 }
231 }
232+ Notification::ProgressMessage(params) => {
233+ let token = match params.token {
234+ lsp::NumberOrString::Number(n) => n.to_string(),
235+ lsp::NumberOrString::String(s) => s,
236+ };
237+ let msg = {
238+ let lsp::ProgressParamsValue::WorkDone(work) = params.value;
239+ let parts = match work {
240+ lsp::WorkDoneProgress::Begin(lsp::WorkDoneProgressBegin {
241+ title,
242+ message,
243+ percentage,
244+ ..
245+ }) => (Some(title), message, percentage.map(|n| n.to_string())),
246+ lsp::WorkDoneProgress::Report(lsp::WorkDoneProgressReport {
247+ message,
248+ percentage,
249+ ..
250+ }) => (None, message, percentage.map(|n| n.to_string())),
251+ lsp::WorkDoneProgress::End(lsp::WorkDoneProgressEnd {
252+ message,
253+ }) => {
254+ if let Some(message) = message {
255+ (None, Some(message), None)
256+ } else {
257+ self.editor.clear_status();
258+ return;
259+ }
260+ }
261+ };
262+ match parts {
263+ (Some(title), Some(message), Some(percentage)) => {
264+ format!("{}% {} - {}", percentage, title, message)
265+ }
266+ (Some(title), None, Some(percentage)) => {
267+ format!("{}% {}", percentage, title)
268+ }
269+ (Some(title), Some(message), None) => {
270+ format!("{} - {}", title, message)
271+ }
272+ (None, Some(message), Some(percentage)) => {
273+ format!("{}% {}", percentage, message)
274+ }
275+ (Some(title), None, None) => title,
276+ (None, Some(message), None) => message,
277+ (None, None, Some(percentage)) => format!("{}%", percentage),
278+ (None, None, None) => "".into(),
279+ }
280+ };
281+ let status = format!("[{}] {}", token, msg);
282+ self.editor.set_status(status);
283+ self.render();
284+ }
231 _ => unreachable!(),
285 _ => unreachable!(),
232 }
286 }
233 }
287 }
helix-view/src/editor.rs+4
@@ -66,6 +66,10 @@ impl Editor {
66 }
66 }
67 }
67 }
68
68
69+ pub fn clear_status(&mut self) {
70+ self.status_msg = None;
71+ }
72+
69 pub fn set_status(&mut self, status: String) {
73 pub fn set_status(&mut self, status: String) {
70 self.status_msg = Some((status, Severity::Info));
74 self.status_msg = Some((status, Severity::Info));
71 }
75 }