Extract a LanguageServerStatus
struct
This commit is contained in:
parent
45fb470f4d
commit
5157b42896
2 changed files with 106 additions and 50 deletions
|
@ -51,8 +51,7 @@ pub struct Project {
|
|||
languages: Arc<LanguageRegistry>,
|
||||
language_servers: HashMap<(WorktreeId, Arc<str>), Arc<LanguageServer>>,
|
||||
started_language_servers: HashMap<(WorktreeId, Arc<str>), Task<Option<Arc<LanguageServer>>>>,
|
||||
pending_language_server_work: BTreeMap<(usize, String), LanguageServerProgress>,
|
||||
language_server_names: HashMap<usize, String>,
|
||||
language_server_statuses: BTreeMap<usize, LanguageServerStatus>,
|
||||
next_language_server_id: usize,
|
||||
client: Arc<client::Client>,
|
||||
user_store: ModelHandle<UserStore>,
|
||||
|
@ -131,6 +130,12 @@ enum LanguageServerEvent {
|
|||
DiagnosticsUpdate(lsp::PublishDiagnosticsParams),
|
||||
}
|
||||
|
||||
pub struct LanguageServerStatus {
|
||||
pub name: String,
|
||||
pub pending_work: BTreeMap<String, LanguageServerProgress>,
|
||||
pending_diagnostic_updates: isize,
|
||||
}
|
||||
|
||||
#[derive(Clone, Default)]
|
||||
pub struct LanguageServerProgress {
|
||||
pub message: Option<String>,
|
||||
|
@ -326,8 +331,7 @@ impl Project {
|
|||
language_servers_with_diagnostics_running: 0,
|
||||
language_servers: Default::default(),
|
||||
started_language_servers: Default::default(),
|
||||
pending_language_server_work: Default::default(),
|
||||
language_server_names: Default::default(),
|
||||
language_server_statuses: Default::default(),
|
||||
next_language_server_id: 0,
|
||||
nonce: StdRng::from_entropy().gen(),
|
||||
}
|
||||
|
@ -398,11 +402,19 @@ impl Project {
|
|||
language_servers_with_diagnostics_running: 0,
|
||||
language_servers: Default::default(),
|
||||
started_language_servers: Default::default(),
|
||||
pending_language_server_work: Default::default(),
|
||||
language_server_names: response
|
||||
language_server_statuses: response
|
||||
.language_servers
|
||||
.into_iter()
|
||||
.map(|s| (s.id as usize, s.name))
|
||||
.map(|server| {
|
||||
(
|
||||
server.id as usize,
|
||||
LanguageServerStatus {
|
||||
name: server.name,
|
||||
pending_work: Default::default(),
|
||||
pending_diagnostic_updates: 0,
|
||||
},
|
||||
)
|
||||
})
|
||||
.collect(),
|
||||
next_language_server_id: 0,
|
||||
opened_buffers: Default::default(),
|
||||
|
@ -1274,8 +1286,14 @@ impl Project {
|
|||
this.update(&mut cx, |this, cx| {
|
||||
this.language_servers
|
||||
.insert(key.clone(), language_server.clone());
|
||||
this.language_server_names
|
||||
.insert(server_id, language_server.name().to_string());
|
||||
this.language_server_statuses.insert(
|
||||
server_id,
|
||||
LanguageServerStatus {
|
||||
name: language_server.name().to_string(),
|
||||
pending_work: Default::default(),
|
||||
pending_diagnostic_updates: 0,
|
||||
},
|
||||
);
|
||||
|
||||
if let Some(project_id) = this.remote_id() {
|
||||
this.client
|
||||
|
@ -1359,16 +1377,26 @@ impl Project {
|
|||
cx: &mut ModelContext<Self>,
|
||||
) {
|
||||
let disk_diagnostics_token = language.disk_based_diagnostics_progress_token();
|
||||
let language_server_status =
|
||||
if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
|
||||
status
|
||||
} else {
|
||||
return;
|
||||
};
|
||||
|
||||
match event {
|
||||
LanguageServerEvent::WorkStart { token } => {
|
||||
if Some(&token) == disk_diagnostics_token {
|
||||
self.disk_based_diagnostics_started(cx);
|
||||
self.broadcast_language_server_update(
|
||||
language_server_id,
|
||||
proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(
|
||||
proto::LspDiskBasedDiagnosticsUpdating {},
|
||||
),
|
||||
);
|
||||
language_server_status.pending_diagnostic_updates += 1;
|
||||
if language_server_status.pending_diagnostic_updates == 1 {
|
||||
self.disk_based_diagnostics_started(cx);
|
||||
self.broadcast_language_server_update(
|
||||
language_server_id,
|
||||
proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(
|
||||
proto::LspDiskBasedDiagnosticsUpdating {},
|
||||
),
|
||||
);
|
||||
}
|
||||
} else {
|
||||
self.on_lsp_work_start(language_server_id, token.clone(), cx);
|
||||
self.broadcast_language_server_update(
|
||||
|
@ -1401,13 +1429,16 @@ impl Project {
|
|||
}
|
||||
LanguageServerEvent::WorkEnd { token } => {
|
||||
if Some(&token) == disk_diagnostics_token {
|
||||
self.disk_based_diagnostics_finished(cx);
|
||||
self.broadcast_language_server_update(
|
||||
language_server_id,
|
||||
proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(
|
||||
proto::LspDiskBasedDiagnosticsUpdated {},
|
||||
),
|
||||
);
|
||||
language_server_status.pending_diagnostic_updates -= 1;
|
||||
if language_server_status.pending_diagnostic_updates == 0 {
|
||||
self.disk_based_diagnostics_finished(cx);
|
||||
self.broadcast_language_server_update(
|
||||
language_server_id,
|
||||
proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(
|
||||
proto::LspDiskBasedDiagnosticsUpdated {},
|
||||
),
|
||||
);
|
||||
}
|
||||
} else {
|
||||
self.on_lsp_work_end(language_server_id, token.clone(), cx);
|
||||
self.broadcast_language_server_update(
|
||||
|
@ -1457,14 +1488,16 @@ impl Project {
|
|||
token: String,
|
||||
cx: &mut ModelContext<Self>,
|
||||
) {
|
||||
self.pending_language_server_work.insert(
|
||||
(language_server_id, token),
|
||||
LanguageServerProgress {
|
||||
message: None,
|
||||
percentage: None,
|
||||
},
|
||||
);
|
||||
cx.notify();
|
||||
if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
|
||||
status.pending_work.insert(
|
||||
token,
|
||||
LanguageServerProgress {
|
||||
message: None,
|
||||
percentage: None,
|
||||
},
|
||||
);
|
||||
cx.notify();
|
||||
}
|
||||
}
|
||||
|
||||
fn on_lsp_work_progress(
|
||||
|
@ -1474,9 +1507,10 @@ impl Project {
|
|||
progress: LanguageServerProgress,
|
||||
cx: &mut ModelContext<Self>,
|
||||
) {
|
||||
self.pending_language_server_work
|
||||
.insert((language_server_id, token), progress);
|
||||
cx.notify();
|
||||
if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
|
||||
status.pending_work.insert(token, progress);
|
||||
cx.notify();
|
||||
}
|
||||
}
|
||||
|
||||
fn on_lsp_work_end(
|
||||
|
@ -1485,9 +1519,10 @@ impl Project {
|
|||
token: String,
|
||||
cx: &mut ModelContext<Self>,
|
||||
) {
|
||||
self.pending_language_server_work
|
||||
.remove(&(language_server_id, token));
|
||||
cx.notify();
|
||||
if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
|
||||
status.pending_work.remove(&token);
|
||||
cx.notify();
|
||||
}
|
||||
}
|
||||
|
||||
fn broadcast_language_server_update(
|
||||
|
@ -1506,15 +1541,8 @@ impl Project {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn pending_language_server_work(
|
||||
&self,
|
||||
) -> impl Iterator<Item = (&str, &str, &LanguageServerProgress)> {
|
||||
self.pending_language_server_work.iter().filter_map(
|
||||
|((language_server_id, token), progress)| {
|
||||
let name = self.language_server_names.get(language_server_id)?;
|
||||
Some((name.as_str(), token.as_str(), progress))
|
||||
},
|
||||
)
|
||||
pub fn language_server_statuses(&self) -> impl Iterator<Item = &LanguageServerStatus> {
|
||||
self.language_server_statuses.values()
|
||||
}
|
||||
|
||||
pub fn update_diagnostics(
|
||||
|
@ -3266,8 +3294,14 @@ impl Project {
|
|||
.server
|
||||
.ok_or_else(|| anyhow!("invalid server"))?;
|
||||
this.update(&mut cx, |this, cx| {
|
||||
this.language_server_names
|
||||
.insert(server.id as usize, server.name);
|
||||
this.language_server_statuses.insert(
|
||||
server.id as usize,
|
||||
LanguageServerStatus {
|
||||
name: server.name,
|
||||
pending_work: Default::default(),
|
||||
pending_diagnostic_updates: 0,
|
||||
},
|
||||
);
|
||||
cx.notify();
|
||||
});
|
||||
Ok(())
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
use crate::{ItemViewHandle, Settings, StatusItemView};
|
||||
use futures::StreamExt;
|
||||
use gpui::AppContext;
|
||||
use gpui::{
|
||||
action, elements::*, platform::CursorStyle, Entity, ModelHandle, MutableAppContext,
|
||||
RenderContext, View, ViewContext,
|
||||
};
|
||||
use language::{LanguageRegistry, LanguageServerBinaryStatus};
|
||||
use postage::watch;
|
||||
use project::Project;
|
||||
use project::{LanguageServerProgress, Project};
|
||||
use std::fmt::Write;
|
||||
use std::sync::Arc;
|
||||
|
||||
|
@ -81,6 +82,27 @@ impl LspStatus {
|
|||
self.failed.clear();
|
||||
cx.notify();
|
||||
}
|
||||
|
||||
fn pending_language_server_work<'a>(
|
||||
&self,
|
||||
cx: &'a AppContext,
|
||||
) -> impl Iterator<Item = (&'a str, &'a str, &'a LanguageServerProgress)> {
|
||||
self.project
|
||||
.read(cx)
|
||||
.language_server_statuses()
|
||||
.filter_map(|status| {
|
||||
if status.pending_work.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(
|
||||
status.pending_work.iter().map(|(token, progress)| {
|
||||
(status.name.as_str(), token.as_str(), progress)
|
||||
}),
|
||||
)
|
||||
}
|
||||
})
|
||||
.flatten()
|
||||
}
|
||||
}
|
||||
|
||||
impl Entity for LspStatus {
|
||||
|
@ -95,7 +117,7 @@ impl View for LspStatus {
|
|||
fn render(&mut self, cx: &mut RenderContext<Self>) -> ElementBox {
|
||||
let theme = &self.settings_rx.borrow().theme;
|
||||
|
||||
let mut pending_work = self.project.read(cx).pending_language_server_work();
|
||||
let mut pending_work = self.pending_language_server_work(cx);
|
||||
if let Some((lang_server_name, progress_token, progress)) = pending_work.next() {
|
||||
let mut message = lang_server_name.to_string();
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue