Show more information in lsp status bar item
* Distinguish between checking for updates and downloading * Show dismissable error message when downloading failed and there is no cached server. Co-Authored-By: Nathan Sobo <nathan@zed.dev>
This commit is contained in:
parent
ededfff3a8
commit
79910ba931
6 changed files with 263 additions and 90 deletions
|
@ -1,13 +1,24 @@
|
|||
use crate::{ItemViewHandle, Settings, StatusItemView};
|
||||
use futures::StreamExt;
|
||||
use gpui::{elements::*, Entity, RenderContext, View, ViewContext};
|
||||
use language::LanguageRegistry;
|
||||
use gpui::{
|
||||
action, elements::*, platform::CursorStyle, Entity, MutableAppContext, RenderContext, View,
|
||||
ViewContext,
|
||||
};
|
||||
use language::{LanguageRegistry, LanguageServerBinaryStatus};
|
||||
use postage::watch;
|
||||
use std::sync::Arc;
|
||||
|
||||
action!(DismissErrorMessage);
|
||||
|
||||
pub struct LspStatus {
|
||||
pending_lsp_binaries: usize,
|
||||
settings_rx: watch::Receiver<Settings>,
|
||||
checking_for_update: Vec<String>,
|
||||
downloading: Vec<String>,
|
||||
failed: Vec<String>,
|
||||
}
|
||||
|
||||
pub fn init(cx: &mut MutableAppContext) {
|
||||
cx.add_action(LspStatus::dismiss_error_message);
|
||||
}
|
||||
|
||||
impl LspStatus {
|
||||
|
@ -16,12 +27,33 @@ impl LspStatus {
|
|||
settings_rx: watch::Receiver<Settings>,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) -> Self {
|
||||
let mut pending_lsp_binaries = languages.pending_lsp_binaries();
|
||||
let mut status_events = languages.language_server_binary_statuses();
|
||||
cx.spawn_weak(|this, mut cx| async move {
|
||||
while let Some(pending_lsp_binaries) = pending_lsp_binaries.next().await {
|
||||
while let Some((language, event)) = status_events.next().await {
|
||||
if let Some(this) = this.upgrade(&cx) {
|
||||
this.update(&mut cx, |this, cx| {
|
||||
this.pending_lsp_binaries = pending_lsp_binaries;
|
||||
for vector in [
|
||||
&mut this.checking_for_update,
|
||||
&mut this.downloading,
|
||||
&mut this.failed,
|
||||
] {
|
||||
vector.retain(|name| name != language.name());
|
||||
}
|
||||
|
||||
match event {
|
||||
LanguageServerBinaryStatus::CheckingForUpdate => {
|
||||
this.checking_for_update.push(language.name().to_string());
|
||||
}
|
||||
LanguageServerBinaryStatus::Downloading => {
|
||||
this.downloading.push(language.name().to_string());
|
||||
}
|
||||
LanguageServerBinaryStatus::Failed => {
|
||||
this.failed.push(language.name().to_string());
|
||||
}
|
||||
LanguageServerBinaryStatus::Downloaded
|
||||
| LanguageServerBinaryStatus::Cached => {}
|
||||
}
|
||||
|
||||
cx.notify();
|
||||
});
|
||||
} else {
|
||||
|
@ -31,10 +63,17 @@ impl LspStatus {
|
|||
})
|
||||
.detach();
|
||||
Self {
|
||||
pending_lsp_binaries: 0,
|
||||
settings_rx,
|
||||
checking_for_update: Default::default(),
|
||||
downloading: Default::default(),
|
||||
failed: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
fn dismiss_error_message(&mut self, _: &DismissErrorMessage, cx: &mut ViewContext<Self>) {
|
||||
self.failed.clear();
|
||||
cx.notify();
|
||||
}
|
||||
}
|
||||
|
||||
impl Entity for LspStatus {
|
||||
|
@ -46,16 +85,49 @@ impl View for LspStatus {
|
|||
"LspStatus"
|
||||
}
|
||||
|
||||
fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
|
||||
if self.pending_lsp_binaries == 0 {
|
||||
Empty::new().boxed()
|
||||
} else {
|
||||
let theme = &self.settings_rx.borrow().theme;
|
||||
fn render(&mut self, cx: &mut RenderContext<Self>) -> ElementBox {
|
||||
let theme = &self.settings_rx.borrow().theme;
|
||||
if !self.downloading.is_empty() {
|
||||
Label::new(
|
||||
"Downloading language servers...".to_string(),
|
||||
format!(
|
||||
"Downloading {} language server{}...",
|
||||
self.downloading.join(", "),
|
||||
if self.downloading.len() > 1 { "s" } else { "" }
|
||||
),
|
||||
theme.workspace.status_bar.lsp_message.clone(),
|
||||
)
|
||||
.boxed()
|
||||
} else if !self.checking_for_update.is_empty() {
|
||||
Label::new(
|
||||
format!(
|
||||
"Checking for updates to {} language server{}...",
|
||||
self.checking_for_update.join(", "),
|
||||
if self.checking_for_update.len() > 1 {
|
||||
"s"
|
||||
} else {
|
||||
""
|
||||
}
|
||||
),
|
||||
theme.workspace.status_bar.lsp_message.clone(),
|
||||
)
|
||||
.boxed()
|
||||
} else if !self.failed.is_empty() {
|
||||
MouseEventHandler::new::<Self, _, _>(0, cx, |_, _| {
|
||||
Label::new(
|
||||
format!(
|
||||
"Failed to download {} language server{}. Click to dismiss.",
|
||||
self.failed.join(", "),
|
||||
if self.failed.len() > 1 { "s" } else { "" }
|
||||
),
|
||||
theme.workspace.status_bar.lsp_message.clone(),
|
||||
)
|
||||
.boxed()
|
||||
})
|
||||
.with_cursor_style(CursorStyle::PointingHand)
|
||||
.on_click(|cx| cx.dispatch_action(DismissErrorMessage))
|
||||
.boxed()
|
||||
} else {
|
||||
Empty::new().boxed()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue