Update LspLog view to use new gpui APIs

This commit is contained in:
Max Brunsfeld 2023-04-21 14:45:16 -07:00
parent a280a93cd8
commit 6ef6f03322

View file

@ -7,16 +7,15 @@ use gpui::{
AnchorCorner, ChildView, Empty, Flex, Label, MouseEventHandler, Overlay, OverlayFitMode, AnchorCorner, ChildView, Empty, Flex, Label, MouseEventHandler, Overlay, OverlayFitMode,
ParentElement, Stack, ParentElement, Stack,
}, },
impl_internal_actions,
platform::MouseButton, platform::MouseButton,
AppContext, Element, ElementBox, Entity, ModelHandle, RenderContext, View, ViewContext, AnyElement, AppContext, Element, Entity, ModelHandle, View, ViewContext, ViewHandle,
ViewHandle,
}; };
use language::{Buffer, LanguageServerId, LanguageServerName}; use language::{Buffer, LanguageServerId, LanguageServerName};
use project::{Project, WorktreeId}; use project::{Project, WorktreeId};
use settings::Settings; use settings::Settings;
use std::{borrow::Cow, sync::Arc}; use std::{borrow::Cow, sync::Arc};
use theme::Theme; use theme::Theme;
use util::ResultExt;
use workspace::{ use workspace::{
item::{Item, ItemHandle}, item::{Item, ItemHandle},
ToolbarItemLocation, ToolbarItemView, Workspace, ToolbarItemLocation, ToolbarItemView, Workspace,
@ -51,21 +50,10 @@ enum MessageKind {
Receive, Receive,
} }
#[derive(Clone, Copy, PartialEq, Eq)]
struct ActivateLog {
server_id: LanguageServerId,
}
#[derive(Clone, Copy, PartialEq, Eq)]
struct ToggleMenu;
impl_internal_actions!(log, [ActivateLog, ToggleMenu]);
actions!(log, [OpenLanguageServerLogs]); actions!(log, [OpenLanguageServerLogs]);
pub fn init(cx: &mut AppContext) { pub fn init(cx: &mut AppContext) {
cx.add_action(LspLogView::deploy); cx.add_action(LspLogView::open);
cx.add_action(LspLogToolbarItemView::toggle_menu);
cx.add_action(LspLogToolbarItemView::activate_log_for_server);
} }
impl LspLogView { impl LspLogView {
@ -84,14 +72,16 @@ impl LspLogView {
message.push('\n'); message.push('\n');
this.on_io(language_server_id, is_output, &message, cx); this.on_io(language_server_id, is_output, &message, cx);
}) })
.log_err();
} }
} }
anyhow::Ok(())
}) })
.detach(); .detach();
this this
} }
fn deploy( fn open(
workspace: &mut Workspace, workspace: &mut Workspace,
_: &OpenLanguageServerLogs, _: &OpenLanguageServerLogs,
cx: &mut ViewContext<Workspace>, cx: &mut ViewContext<Workspace>,
@ -105,9 +95,9 @@ impl LspLogView {
workspace.add_item(Box::new(log_view), cx); workspace.add_item(Box::new(log_view), cx);
} }
fn activate_log(&mut self, action: &ActivateLog, cx: &mut ViewContext<Self>) { fn activate_log(&mut self, server_id: LanguageServerId, cx: &mut ViewContext<Self>) {
self.enable_logs_for_language_server(action.server_id, cx); self.enable_logs_for_language_server(server_id, cx);
self.current_server_id = Some(action.server_id); self.current_server_id = Some(server_id);
cx.notify(); cx.notify();
} }
@ -188,19 +178,24 @@ impl View for LspLogView {
"LspLogView" "LspLogView"
} }
fn render(&mut self, cx: &mut gpui::RenderContext<'_, Self>) -> gpui::ElementBox { fn render(&mut self, cx: &mut ViewContext<Self>) -> AnyElement<Self> {
if let Some(id) = self.current_server_id { if let Some(id) = self.current_server_id {
if let Some(log) = self.enabled_logs.get_mut(&id) { if let Some(log) = self.enabled_logs.get_mut(&id) {
return ChildView::new(&log.editor, cx).boxed(); return ChildView::new(&log.editor, cx).into_any();
} }
} }
Empty::new().boxed() Empty::new().into_any()
} }
} }
impl Item for LspLogView { impl Item for LspLogView {
fn tab_content(&self, _: Option<usize>, style: &theme::Tab, _: &AppContext) -> ElementBox { fn tab_content<V: View>(
Label::new("Logs", style.label.clone()).boxed() &self,
_: Option<usize>,
style: &theme::Tab,
_: &AppContext,
) -> AnyElement<V> {
Label::new("Logs", style.label.clone()).into_any()
} }
} }
@ -208,7 +203,7 @@ impl ToolbarItemView for LspLogToolbarItemView {
fn set_active_pane_item( fn set_active_pane_item(
&mut self, &mut self,
active_pane_item: Option<&dyn ItemHandle>, active_pane_item: Option<&dyn ItemHandle>,
cx: &mut ViewContext<Self>, _: &mut ViewContext<Self>,
) -> workspace::ToolbarItemLocation { ) -> workspace::ToolbarItemLocation {
self.menu_open = false; self.menu_open = false;
if let Some(item) = active_pane_item { if let Some(item) = active_pane_item {
@ -229,9 +224,9 @@ impl View for LspLogToolbarItemView {
"LspLogView" "LspLogView"
} }
fn render(&mut self, cx: &mut RenderContext<'_, Self>) -> ElementBox { fn render(&mut self, cx: &mut ViewContext<Self>) -> AnyElement<Self> {
let theme = cx.global::<Settings>().theme.clone(); let theme = cx.global::<Settings>().theme.clone();
let Some(log_view) = self.log_view.as_ref() else { return Empty::new().boxed() }; let Some(log_view) = self.log_view.as_ref() else { return Empty::new().into_any() };
let project = self.project.read(cx); let project = self.project.read(cx);
let mut language_servers = project.language_servers().collect::<Vec<_>>(); let mut language_servers = project.language_servers().collect::<Vec<_>>();
language_servers.sort_by_key(|a| a.0); language_servers.sort_by_key(|a| a.0);
@ -272,21 +267,19 @@ impl View for LspLogToolbarItemView {
.with_style(theme.contacts_popover.container) .with_style(theme.contacts_popover.container)
.constrained() .constrained()
.with_width(200.) .with_width(200.)
.with_height(400.) .with_height(400.),
.boxed(),
) )
.with_fit_mode(OverlayFitMode::SwitchAnchor) .with_fit_mode(OverlayFitMode::SwitchAnchor)
.with_anchor_corner(AnchorCorner::TopRight) .with_anchor_corner(AnchorCorner::TopRight)
.with_z_index(999) .with_z_index(999)
.aligned() .aligned()
.bottom() .bottom()
.right() .right(),
.boxed(),
) )
} else { } else {
None None
}) })
.boxed() .into_any()
} }
} }
@ -299,15 +292,15 @@ impl LspLogToolbarItemView {
} }
} }
fn toggle_menu(&mut self, _: &ToggleMenu, cx: &mut ViewContext<Self>) { fn toggle_menu(&mut self, cx: &mut ViewContext<Self>) {
self.menu_open = !self.menu_open; self.menu_open = !self.menu_open;
cx.notify(); cx.notify();
} }
fn activate_log_for_server(&mut self, action: &ActivateLog, cx: &mut ViewContext<Self>) { fn activate_log_for_server(&mut self, id: LanguageServerId, cx: &mut ViewContext<Self>) {
if let Some(log_view) = &self.log_view { if let Some(log_view) = &self.log_view {
log_view.update(cx, |log_view, cx| { log_view.update(cx, |log_view, cx| {
log_view.activate_log(action, cx); log_view.activate_log(id, cx);
}); });
self.menu_open = false; self.menu_open = false;
} }
@ -318,9 +311,10 @@ impl LspLogToolbarItemView {
current_server: Option<(LanguageServerId, LanguageServerName, WorktreeId)>, current_server: Option<(LanguageServerId, LanguageServerName, WorktreeId)>,
project: &ModelHandle<Project>, project: &ModelHandle<Project>,
theme: &Arc<Theme>, theme: &Arc<Theme>,
cx: &mut RenderContext<Self>, cx: &mut ViewContext<Self>,
) -> ElementBox { ) -> impl Element<Self> {
MouseEventHandler::<ToggleMenu>::new(0, cx, move |state, cx| { enum ToggleMenu {}
MouseEventHandler::<ToggleMenu, Self>::new(0, cx, move |state, cx| {
let project = project.read(cx); let project = project.read(cx);
let label: Cow<str> = current_server let label: Cow<str> = current_server
.and_then(|(_, server_name, worktree_id)| { .and_then(|(_, server_name, worktree_id)| {
@ -329,12 +323,11 @@ impl LspLogToolbarItemView {
Some(format!("{} - ({})", server_name.0, worktree.root_name()).into()) Some(format!("{} - ({})", server_name.0, worktree.root_name()).into())
}) })
.unwrap_or_else(|| "No server selected".into()); .unwrap_or_else(|| "No server selected".into());
Label::new(label, theme.context_menu.item.default.label.clone()).boxed() Label::new(label, theme.context_menu.item.default.label.clone())
}) })
.on_click(MouseButton::Left, move |_, cx| { .on_click(MouseButton::Left, move |_, view, cx| {
cx.dispatch_action(ToggleMenu); view.toggle_menu(cx);
}) })
.boxed()
} }
fn render_language_server_menu_item( fn render_language_server_menu_item(
@ -343,8 +336,9 @@ impl LspLogToolbarItemView {
worktree_id: WorktreeId, worktree_id: WorktreeId,
project: &ModelHandle<Project>, project: &ModelHandle<Project>,
theme: &Arc<Theme>, theme: &Arc<Theme>,
cx: &mut RenderContext<Self>, cx: &mut ViewContext<Self>,
) -> Option<ElementBox> { ) -> Option<impl Element<Self>> {
enum ActivateLog {}
let project = project.read(cx); let project = project.read(cx);
let worktree = project.worktree_for_id(worktree_id, cx)?; let worktree = project.worktree_for_id(worktree_id, cx)?;
let worktree = &worktree.read(cx); let worktree = &worktree.read(cx);
@ -354,13 +348,12 @@ impl LspLogToolbarItemView {
let label = format!("{} - ({})", name.0, worktree.root_name()); let label = format!("{} - ({})", name.0, worktree.root_name());
Some( Some(
MouseEventHandler::<ActivateLog>::new(id.0, cx, move |state, cx| { MouseEventHandler::<ActivateLog, _>::new(id.0, cx, move |state, cx| {
Label::new(label, theme.context_menu.item.default.label.clone()).boxed() Label::new(label, theme.context_menu.item.default.label.clone())
}) })
.on_click(MouseButton::Left, move |_, cx| { .on_click(MouseButton::Left, move |_, view, cx| {
cx.dispatch_action(ActivateLog { server_id: id }) view.activate_log_for_server(id, cx);
}) }),
.boxed(),
) )
} }
} }