Merge pull request #459 from zed-industries/spurious-macro-errors
Download language servers dynamically on startup
This commit is contained in:
commit
c752383042
23 changed files with 743 additions and 362 deletions
137
crates/workspace/src/lsp_status.rs
Normal file
137
crates/workspace/src/lsp_status.rs
Normal file
|
@ -0,0 +1,137 @@
|
|||
use crate::{ItemViewHandle, Settings, StatusItemView};
|
||||
use futures::StreamExt;
|
||||
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 {
|
||||
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 {
|
||||
pub fn new(
|
||||
languages: Arc<LanguageRegistry>,
|
||||
settings_rx: watch::Receiver<Settings>,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) -> Self {
|
||||
let mut status_events = languages.language_server_binary_statuses();
|
||||
cx.spawn_weak(|this, mut cx| async move {
|
||||
while let Some((language, event)) = status_events.next().await {
|
||||
if let Some(this) = this.upgrade(&cx) {
|
||||
this.update(&mut cx, |this, cx| {
|
||||
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 {
|
||||
break;
|
||||
}
|
||||
}
|
||||
})
|
||||
.detach();
|
||||
Self {
|
||||
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 {
|
||||
type Event = ();
|
||||
}
|
||||
|
||||
impl View for LspStatus {
|
||||
fn ui_name() -> &'static str {
|
||||
"LspStatus"
|
||||
}
|
||||
|
||||
fn render(&mut self, cx: &mut RenderContext<Self>) -> ElementBox {
|
||||
let theme = &self.settings_rx.borrow().theme;
|
||||
if !self.downloading.is_empty() {
|
||||
Label::new(
|
||||
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()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl StatusItemView for LspStatus {
|
||||
fn set_active_pane_item(&mut self, _: Option<&dyn ItemViewHandle>, _: &mut ViewContext<Self>) {}
|
||||
}
|
|
@ -42,17 +42,21 @@ impl View for StatusBar {
|
|||
fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
|
||||
let theme = &self.settings.borrow().theme.workspace.status_bar;
|
||||
Flex::row()
|
||||
.with_children(
|
||||
self.left_items
|
||||
.iter()
|
||||
.map(|i| ChildView::new(i.as_ref()).aligned().boxed()),
|
||||
)
|
||||
.with_children(self.left_items.iter().map(|i| {
|
||||
ChildView::new(i.as_ref())
|
||||
.aligned()
|
||||
.contained()
|
||||
.with_margin_right(theme.item_spacing)
|
||||
.boxed()
|
||||
}))
|
||||
.with_child(Empty::new().flexible(1., true).boxed())
|
||||
.with_children(
|
||||
self.right_items
|
||||
.iter()
|
||||
.map(|i| ChildView::new(i.as_ref()).aligned().boxed()),
|
||||
)
|
||||
.with_children(self.right_items.iter().map(|i| {
|
||||
ChildView::new(i.as_ref())
|
||||
.aligned()
|
||||
.contained()
|
||||
.with_margin_left(theme.item_spacing)
|
||||
.boxed()
|
||||
}))
|
||||
.contained()
|
||||
.with_style(theme.container)
|
||||
.constrained()
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
pub mod lsp_status;
|
||||
pub mod menu;
|
||||
pub mod pane;
|
||||
pub mod pane_group;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue