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