Fix cleanup of LSP request status messages (#10336)

This fixes a bug in https://github.com/zed-industries/zed/pull/9818,
where the status was not removed if the request failed. It also adds
replication of these new status messages to guests when collaborating.

Release Notes:

- Fixed an issue where the status of failed LSP actions was left in the
status bar

---------

Co-authored-by: Marshall <marshall@zed.dev>
Co-authored-by: Marshall Bowers <elliott.codes@gmail.com>
This commit is contained in:
Max Brunsfeld 2024-04-09 14:34:51 -07:00 committed by GitHub
parent a0ee29a806
commit 6b320b9efe
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 150 additions and 68 deletions

View file

@ -347,7 +347,7 @@ pub enum LanguageServerState {
},
}
#[derive(Serialize)]
#[derive(Clone, Debug, Serialize)]
pub struct LanguageServerStatus {
pub name: String,
pub pending_work: BTreeMap<String, LanguageServerProgress>,
@ -3924,19 +3924,6 @@ impl Project {
},
cx,
);
self.enqueue_buffer_ordered_message(
BufferOrderedMessage::LanguageServerUpdate {
language_server_id,
message: proto::update_language_server::Variant::WorkStart(
proto::LspWorkStart {
token,
message: report.message,
percentage: report.percentage,
},
),
},
)
.ok();
}
}
lsp::WorkDoneProgress::Report(report) => {
@ -3984,15 +3971,6 @@ impl Project {
.ok();
} else {
self.on_lsp_work_end(language_server_id, token.clone(), cx);
self.enqueue_buffer_ordered_message(
BufferOrderedMessage::LanguageServerUpdate {
language_server_id,
message: proto::update_language_server::Variant::WorkEnd(
proto::LspWorkEnd { token },
),
},
)
.ok();
}
}
}
@ -4006,9 +3984,21 @@ impl Project {
cx: &mut ModelContext<Self>,
) {
if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
status.pending_work.insert(token, progress);
status.pending_work.insert(token.clone(), progress.clone());
cx.notify();
}
if self.is_local() {
self.enqueue_buffer_ordered_message(BufferOrderedMessage::LanguageServerUpdate {
language_server_id,
message: proto::update_language_server::Variant::WorkStart(proto::LspWorkStart {
token,
message: progress.message,
percentage: progress.percentage.map(|p| p as u32),
}),
})
.ok();
}
}
fn on_lsp_work_progress(
@ -4049,6 +4039,16 @@ impl Project {
status.pending_work.remove(&token);
cx.notify();
}
if self.is_local() {
self.enqueue_buffer_ordered_message(BufferOrderedMessage::LanguageServerUpdate {
language_server_id,
message: proto::update_language_server::Variant::WorkEnd(proto::LspWorkEnd {
token,
}),
})
.ok();
}
}
fn on_lsp_did_change_watched_files(
@ -6721,7 +6721,7 @@ impl Project {
let lsp_request = language_server.request::<R::LspRequest>(lsp_params);
let id = lsp_request.id();
if status.is_some() {
let _cleanup = if status.is_some() {
cx.update(|cx| {
this.update(cx, |this, cx| {
this.on_lsp_work_start(
@ -6737,22 +6737,35 @@ impl Project {
})
})
.log_err();
}
Some(defer(|| {
cx.update(|cx| {
this.update(cx, |this, cx| {
this.on_lsp_work_end(
language_server.server_id(),
id.to_string(),
cx,
);
})
})
.log_err();
}))
} else {
None
};
let result = lsp_request.await;
let response = match result {
Ok(response) => response,
Err(err) => {
log::warn!(
"Generic lsp request to {} failed: {}",
language_server.name(),
err
);
return Err(err);
}
};
let result = request
let response = result.map_err(|err| {
log::warn!(
"Generic lsp request to {} failed: {}",
language_server.name(),
err
);
err
})?;
request
.response_from_lsp(
response,
this.upgrade().ok_or_else(|| anyhow!("no app context"))?,
@ -6760,22 +6773,7 @@ impl Project {
language_server.server_id(),
cx.clone(),
)
.await;
if status.is_some() {
cx.update(|cx| {
this.update(cx, |this, cx| {
this.on_lsp_work_end(
language_server.server_id(),
id.to_string(),
cx,
);
})
})
.log_err();
}
result
.await
});
}
} else if let Some(project_id) = self.remote_id() {