Merge branch 'main' into settings-file

This commit is contained in:
Max Brunsfeld 2022-03-11 10:04:17 -08:00
commit 6091caee8e
25 changed files with 858 additions and 227 deletions

View file

@ -1,11 +1,16 @@
use crate::{ItemViewHandle, Settings, StatusItemView};
use futures::StreamExt;
use gpui::AppContext;
use gpui::{
action, elements::*, platform::CursorStyle, Entity, MutableAppContext, RenderContext, View,
ViewContext,
action, elements::*, platform::CursorStyle, Entity, ModelHandle, MutableAppContext,
RenderContext, View, ViewContext,
};
use language::{LanguageRegistry, LanguageServerBinaryStatus};
use postage::watch;
use project::{LanguageServerProgress, Project};
use smallvec::SmallVec;
use std::cmp::Reverse;
use std::fmt::Write;
use std::sync::Arc;
action!(DismissErrorMessage);
@ -15,6 +20,7 @@ pub struct LspStatus {
checking_for_update: Vec<String>,
downloading: Vec<String>,
failed: Vec<String>,
project: ModelHandle<Project>,
}
pub fn init(cx: &mut MutableAppContext) {
@ -23,6 +29,7 @@ pub fn init(cx: &mut MutableAppContext) {
impl LspStatus {
pub fn new(
project: &ModelHandle<Project>,
languages: Arc<LanguageRegistry>,
settings_rx: watch::Receiver<Settings>,
cx: &mut ViewContext<Self>,
@ -62,11 +69,14 @@ impl LspStatus {
}
})
.detach();
cx.observe(project, |_, _, cx| cx.notify()).detach();
Self {
settings_rx,
checking_for_update: Default::default(),
downloading: Default::default(),
failed: Default::default(),
project: project.clone(),
}
}
@ -74,6 +84,30 @@ 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()
.rev()
.filter_map(|status| {
if status.pending_work.is_empty() {
None
} else {
let mut pending_work = status
.pending_work
.iter()
.map(|(token, progress)| (status.name.as_str(), token.as_str(), progress))
.collect::<SmallVec<[_; 4]>>();
pending_work.sort_by_key(|(_, _, progress)| Reverse(progress.last_update_at));
Some(pending_work)
}
})
.flatten()
}
}
impl Entity for LspStatus {
@ -87,7 +121,29 @@ impl View for LspStatus {
fn render(&mut self, cx: &mut RenderContext<Self>) -> ElementBox {
let theme = &self.settings_rx.borrow().theme;
if !self.downloading.is_empty() {
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();
message.push_str(": ");
if let Some(progress_message) = progress.message.as_ref() {
message.push_str(progress_message);
} else {
message.push_str(progress_token);
}
if let Some(percentage) = progress.percentage {
write!(&mut message, " ({}%)", percentage).unwrap();
}
let additional_work_count = pending_work.count();
if additional_work_count > 0 {
write!(&mut message, " + {} more", additional_work_count).unwrap();
}
Label::new(message, theme.workspace.status_bar.lsp_message.clone()).boxed()
} else if !self.downloading.is_empty() {
Label::new(
format!(
"Downloading {} language server{}...",
@ -112,6 +168,7 @@ impl View for LspStatus {
)
.boxed()
} else if !self.failed.is_empty() {
drop(pending_work);
MouseEventHandler::new::<Self, _, _>(0, cx, |_, _| {
Label::new(
format!(

View file

@ -6,9 +6,9 @@ use gpui::{
elements::*,
geometry::{rect::RectF, vector::vec2f},
keymap::Binding,
platform::CursorStyle,
platform::{CursorStyle, NavigationDirection},
AnyViewHandle, Entity, MutableAppContext, Quad, RenderContext, Task, View, ViewContext,
ViewHandle,
ViewHandle, WeakViewHandle,
};
use postage::watch;
use project::ProjectPath;
@ -27,8 +27,8 @@ action!(ActivateNextItem);
action!(CloseActiveItem);
action!(CloseInactiveItems);
action!(CloseItem, usize);
action!(GoBack);
action!(GoForward);
action!(GoBack, Option<WeakViewHandle<Pane>>);
action!(GoForward, Option<WeakViewHandle<Pane>>);
const MAX_NAVIGATION_HISTORY_LEN: usize = 1024;
@ -54,11 +54,27 @@ pub fn init(cx: &mut MutableAppContext) {
cx.add_action(|pane: &mut Pane, action: &Split, cx| {
pane.split(action.0, cx);
});
cx.add_action(|workspace: &mut Workspace, _: &GoBack, cx| {
Pane::go_back(workspace, cx).detach();
cx.add_action(|workspace: &mut Workspace, action: &GoBack, cx| {
Pane::go_back(
workspace,
action
.0
.as_ref()
.and_then(|weak_handle| weak_handle.upgrade(cx)),
cx,
)
.detach();
});
cx.add_action(|workspace: &mut Workspace, _: &GoForward, cx| {
Pane::go_forward(workspace, cx).detach();
cx.add_action(|workspace: &mut Workspace, action: &GoForward, cx| {
Pane::go_forward(
workspace,
action
.0
.as_ref()
.and_then(|weak_handle| weak_handle.upgrade(cx)),
cx,
)
.detach();
});
cx.add_bindings(vec![
@ -70,8 +86,8 @@ pub fn init(cx: &mut MutableAppContext) {
Binding::new("cmd-k down", Split(SplitDirection::Down), Some("Pane")),
Binding::new("cmd-k left", Split(SplitDirection::Left), Some("Pane")),
Binding::new("cmd-k right", Split(SplitDirection::Right), Some("Pane")),
Binding::new("ctrl--", GoBack, Some("Pane")),
Binding::new("shift-ctrl-_", GoForward, Some("Pane")),
Binding::new("ctrl--", GoBack(None), Some("Pane")),
Binding::new("shift-ctrl-_", GoForward(None), Some("Pane")),
]);
}
@ -163,19 +179,27 @@ impl Pane {
cx.emit(Event::Activate);
}
pub fn go_back(workspace: &mut Workspace, cx: &mut ViewContext<Workspace>) -> Task<()> {
pub fn go_back(
workspace: &mut Workspace,
pane: Option<ViewHandle<Pane>>,
cx: &mut ViewContext<Workspace>,
) -> Task<()> {
Self::navigate_history(
workspace,
workspace.active_pane().clone(),
pane.unwrap_or_else(|| workspace.active_pane().clone()),
NavigationMode::GoingBack,
cx,
)
}
pub fn go_forward(workspace: &mut Workspace, cx: &mut ViewContext<Workspace>) -> Task<()> {
pub fn go_forward(
workspace: &mut Workspace,
pane: Option<ViewHandle<Pane>>,
cx: &mut ViewContext<Workspace>,
) -> Task<()> {
Self::navigate_history(
workspace,
workspace.active_pane().clone(),
pane.unwrap_or_else(|| workspace.active_pane().clone()),
NavigationMode::GoingForward,
cx,
)
@ -187,6 +211,8 @@ impl Pane {
mode: NavigationMode,
cx: &mut ViewContext<Workspace>,
) -> Task<()> {
workspace.activate_pane(pane.clone(), cx);
let to_load = pane.update(cx, |pane, cx| {
// Retrieve the weak item handle from the history.
let entry = pane.nav_history.borrow_mut().pop(mode)?;
@ -634,7 +660,9 @@ impl View for Pane {
}
fn render(&mut self, cx: &mut RenderContext<Self>) -> ElementBox {
if let Some(active_item) = self.active_item() {
let this = cx.handle();
EventHandler::new(if let Some(active_item) = self.active_item() {
Flex::column()
.with_child(self.render_tabs(cx))
.with_children(
@ -643,10 +671,20 @@ impl View for Pane {
.map(|view| ChildView::new(view).boxed()),
)
.with_child(ChildView::new(active_item).flexible(1., true).boxed())
.named("pane")
.boxed()
} else {
Empty::new().named("pane")
}
Empty::new().boxed()
})
.on_navigate_mouse_down(move |direction, cx| {
let this = this.clone();
match direction {
NavigationDirection::Back => cx.dispatch_action(GoBack(Some(this))),
NavigationDirection::Forward => cx.dispatch_action(GoForward(Some(this))),
}
true
})
.named("pane")
}
fn on_focus(&mut self, cx: &mut ViewContext<Self>) {