Track progress title an display in place of internal token (#13180)

Co-authored-by: Michael Davis <mcarsondavis@gmail.com>
This commit is contained in:
Keir Lawson 2025-03-27 17:00:23 +00:00 committed by GitHub
parent 68d7308e25
commit 7929c0719d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 77 additions and 48 deletions

View file

@ -733,14 +733,17 @@ impl Registry {
#[derive(Debug)]
pub enum ProgressStatus {
Created,
Started(lsp::WorkDoneProgress),
Started {
title: String,
progress: lsp::WorkDoneProgress,
},
}
impl ProgressStatus {
pub fn progress(&self) -> Option<&lsp::WorkDoneProgress> {
match &self {
ProgressStatus::Created => None,
ProgressStatus::Started(progress) => Some(progress),
ProgressStatus::Started { title: _, progress } => Some(progress),
}
}
}
@ -777,6 +780,13 @@ impl LspProgressMap {
self.0.get(&id).and_then(|values| values.get(token))
}
pub fn title(&self, id: LanguageServerId, token: &lsp::ProgressToken) -> Option<&String> {
self.progress(id, token).and_then(|p| match p {
ProgressStatus::Created => None,
ProgressStatus::Started { title, .. } => Some(title),
})
}
/// Checks if progress `token` for server with `id` is created.
pub fn is_created(&mut self, id: LanguageServerId, token: &lsp::ProgressToken) -> bool {
self.0
@ -801,17 +811,39 @@ impl LspProgressMap {
self.0.get_mut(&id).and_then(|vals| vals.remove(token))
}
/// Updates the progress of `token` for server with `id` to `status`, returns the value replaced or `None`.
/// Updates the progress of `token` for server with `id` to begin state `status`
pub fn begin(
&mut self,
id: LanguageServerId,
token: lsp::ProgressToken,
status: lsp::WorkDoneProgressBegin,
) {
self.0.entry(id).or_default().insert(
token,
ProgressStatus::Started {
title: status.title.clone(),
progress: lsp::WorkDoneProgress::Begin(status),
},
);
}
/// Updates the progress of `token` for server with `id` to report state `status`.
pub fn update(
&mut self,
id: LanguageServerId,
token: lsp::ProgressToken,
status: lsp::WorkDoneProgress,
) -> Option<ProgressStatus> {
status: lsp::WorkDoneProgressReport,
) {
self.0
.entry(id)
.or_default()
.insert(token, ProgressStatus::Started(status))
.entry(token)
.and_modify(|e| match e {
ProgressStatus::Created => (),
ProgressStatus::Started { progress, .. } => {
*progress = lsp::WorkDoneProgress::Report(status)
}
});
}
}

View file

@ -756,10 +756,11 @@ impl Application {
.compositor
.find::<ui::EditorView>()
.expect("expected at least one EditorView");
let lsp::ProgressParams { token, value } = params;
let lsp::ProgressParamsValue::WorkDone(work) = value;
let parts = match &work {
let lsp::ProgressParams {
token,
value: lsp::ProgressParamsValue::WorkDone(work),
} = params;
let (title, message, percentage) = match &work {
lsp::WorkDoneProgress::Begin(lsp::WorkDoneProgressBegin {
title,
message,
@ -787,47 +788,43 @@ impl Application {
}
};
let token_d: &dyn std::fmt::Display = match &token {
lsp::NumberOrString::Number(n) => n,
lsp::NumberOrString::String(s) => s,
};
let status = match parts {
(Some(title), Some(message), Some(percentage)) => {
format!("[{}] {}% {} - {}", token_d, percentage, title, message)
if self.editor.config().lsp.display_progress_messages {
let title =
title.or_else(|| self.lsp_progress.title(server_id, &token));
if title.is_some() || percentage.is_some() || message.is_some() {
use std::fmt::Write as _;
let mut status = format!("{}: ", language_server!().name());
if let Some(percentage) = percentage {
write!(status, "{percentage:>2}% ").unwrap();
}
if let Some(title) = title {
status.push_str(title);
}
if title.is_some() && message.is_some() {
status.push_str("");
}
if let Some(message) = message {
status.push_str(message);
}
self.editor.set_status(status);
}
(Some(title), None, Some(percentage)) => {
format!("[{}] {}% {}", token_d, percentage, title)
}
(Some(title), Some(message), None) => {
format!("[{}] {} - {}", token_d, title, message)
}
(None, Some(message), Some(percentage)) => {
format!("[{}] {}% {}", token_d, percentage, message)
}
(Some(title), None, None) => {
format!("[{}] {}", token_d, title)
}
(None, Some(message), None) => {
format!("[{}] {}", token_d, message)
}
(None, None, Some(percentage)) => {
format!("[{}] {}%", token_d, percentage)
}
(None, None, None) => format!("[{}]", token_d),
};
if let lsp::WorkDoneProgress::End(_) = work {
self.lsp_progress.end_progress(server_id, &token);
if !self.lsp_progress.is_progressing(server_id) {
editor_view.spinners_mut().get_or_create(server_id).stop();
}
} else {
self.lsp_progress.update(server_id, token, work);
}
if self.config.load().editor.lsp.display_progress_messages {
self.editor.set_status(status);
match work {
lsp::WorkDoneProgress::Begin(begin_status) => {
self.lsp_progress
.begin(server_id, token.clone(), begin_status);
}
lsp::WorkDoneProgress::Report(report_status) => {
self.lsp_progress
.update(server_id, token.clone(), report_status);
}
lsp::WorkDoneProgress::End(_) => {
self.lsp_progress.end_progress(server_id, &token);
if !self.lsp_progress.is_progressing(server_id) {
editor_view.spinners_mut().get_or_create(server_id).stop();
};
}
}
}
Notification::ProgressMessage(_params) => {