diff --git a/Cargo.lock b/Cargo.lock index 2e7997458e..693d276669 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8299,6 +8299,7 @@ dependencies = [ "serde_json", "settings", "smallvec", + "terminal", "theme", "util", "uuid 1.2.2", diff --git a/crates/workspace/src/terminal_button.rs b/crates/terminal_view/src/terminal_button.rs similarity index 78% rename from crates/workspace/src/terminal_button.rs rename to crates/terminal_view/src/terminal_button.rs index 64bf1fa0eb..c63712d524 100644 --- a/crates/workspace/src/terminal_button.rs +++ b/crates/terminal_view/src/terminal_button.rs @@ -1,21 +1,26 @@ use context_menu::{ContextMenu, ContextMenuItem}; use gpui::{ - actions, elements::*, geometry::vector::vec2f, CursorStyle, Element, ElementBox, Entity, - MouseButton, MutableAppContext, RenderContext, View, ViewContext, ViewHandle, WeakViewHandle, + actions, elements::*, geometry::vector::vec2f, impl_internal_actions, CursorStyle, Element, + ElementBox, Entity, MouseButton, MutableAppContext, RenderContext, View, ViewContext, + ViewHandle, WeakModelHandle, WeakViewHandle, }; use settings::Settings; +use terminal::Terminal; +use workspace::{dock::FocusDock, item::ItemHandle, NewTerminal, StatusItemView, Workspace}; -use crate::{dock::FocusDock, item::ItemHandle, NewTerminal, StatusItemView, Workspace}; +use crate::TerminalView; -// #[derive(Clone, PartialEq)] -// pub struct DeployTerminalMenu { -// position: Vector2F, -// } +#[derive(Clone, PartialEq)] +pub struct FocusTerminal { + terminal_handle: WeakModelHandle, +} actions!(terminal, [DeployTerminalMenu]); +impl_internal_actions!(terminal, [FocusTerminal]); pub fn init(cx: &mut MutableAppContext) { cx.add_action(TerminalButton::deploy_terminal_menu); + cx.add_action(TerminalButton::focus_terminal); } pub struct TerminalButton { @@ -125,10 +130,11 @@ impl TerminalButton { for local_terminal_handle in local_terminal_handles { if let Some(terminal) = local_terminal_handle.upgrade(cx) { - // TODO: Replace the `NewTerminal` action with an action that instead focuses the selected terminal menu_options.push(ContextMenuItem::item( terminal.read(cx).title(), - NewTerminal, + FocusTerminal { + terminal_handle: local_terminal_handle.clone(), + }, )) } } @@ -138,6 +144,21 @@ impl TerminalButton { menu.show(vec2f(0., 0.), AnchorCorner::TopRight, menu_options, cx); }); } + + pub fn focus_terminal(&mut self, action: &FocusTerminal, cx: &mut ViewContext) { + if let Some(workspace) = self.workspace.upgrade(cx) { + workspace.update(cx, |workspace, cx| { + let terminal = workspace + .items_of_type::(cx) + .find(|terminal| { + terminal.read(cx).model().downgrade() == action.terminal_handle + }); + if let Some(terminal) = terminal { + workspace.activate_item(&terminal, cx); + } + }); + } + } } impl StatusItemView for TerminalButton { diff --git a/crates/terminal_view/src/terminal_view.rs b/crates/terminal_view/src/terminal_view.rs index 302186d8c7..634fab938d 100644 --- a/crates/terminal_view/src/terminal_view.rs +++ b/crates/terminal_view/src/terminal_view.rs @@ -1,4 +1,5 @@ mod persistence; +pub mod terminal_button; pub mod terminal_element; use std::{ @@ -177,8 +178,8 @@ impl TerminalView { } } - pub fn handle(&self) -> ModelHandle { - self.terminal.clone() + pub fn model(&self) -> &ModelHandle { + &self.terminal } pub fn has_new_content(&self) -> bool { diff --git a/crates/workspace/Cargo.toml b/crates/workspace/Cargo.toml index fc069fe6c8..cdc1a799da 100644 --- a/crates/workspace/Cargo.toml +++ b/crates/workspace/Cargo.toml @@ -31,6 +31,7 @@ language = { path = "../language" } menu = { path = "../menu" } project = { path = "../project" } settings = { path = "../settings" } +terminal = { path = "../terminal" } theme = { path = "../theme" } util = { path = "../util" } async-recursion = "1.0.0" diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index db15839ad0..c134c7f68c 100644 --- a/crates/workspace/src/workspace.rs +++ b/crates/workspace/src/workspace.rs @@ -12,7 +12,6 @@ pub mod searchable; pub mod shared_screen; pub mod sidebar; mod status_bar; -pub mod terminal_button; mod toolbar; pub use smallvec; @@ -57,7 +56,6 @@ use std::{ sync::Arc, time::Duration, }; -use terminal_button::TerminalButton; use crate::{ notifications::simple_message_notification::{MessageNotification, OsOpen}, @@ -83,7 +81,7 @@ use status_bar::StatusBar; pub use status_bar::StatusItemView; use theme::{Theme, ThemeRegistry}; pub use toolbar::{ToolbarItemLocation, ToolbarItemView}; -use util::{ResultExt, StaffMode}; +use util::ResultExt; lazy_static! { static ref ZED_WINDOW_SIZE: Option = env::var("ZED_WINDOW_SIZE") @@ -185,7 +183,6 @@ impl_actions!(workspace, [ActivatePane]); pub fn init(app_state: Arc, cx: &mut MutableAppContext) { pane::init(cx); dock::init(cx); - terminal_button::init(cx); notifications::init(cx); cx.add_global_action(open); @@ -587,7 +584,6 @@ impl Workspace { let left_sidebar = cx.add_view(|_| Sidebar::new(SidebarSide::Left)); let right_sidebar = cx.add_view(|_| Sidebar::new(SidebarSide::Right)); let left_sidebar_buttons = cx.add_view(|cx| SidebarButtons::new(left_sidebar.clone(), cx)); - let toggle_terminal = cx.add_view(|cx| TerminalButton::new(handle.clone(), cx)); let toggle_dock = cx.add_view(|cx| ToggleDockButton::new(handle, cx)); let right_sidebar_buttons = cx.add_view(|cx| SidebarButtons::new(right_sidebar.clone(), cx)); @@ -596,10 +592,6 @@ impl Workspace { status_bar.add_left_item(left_sidebar_buttons, cx); status_bar.add_right_item(right_sidebar_buttons, cx); status_bar.add_right_item(toggle_dock, cx); - // TOOD: Remove this when things are done - if **cx.default_global::() { - status_bar.add_right_item(toggle_terminal, cx); - } status_bar }); diff --git a/crates/zed/src/zed.rs b/crates/zed/src/zed.rs index 2fbac3613e..0d9d094f87 100644 --- a/crates/zed/src/zed.rs +++ b/crates/zed/src/zed.rs @@ -31,6 +31,7 @@ use serde::Deserialize; use serde_json::to_string_pretty; use settings::{keymap_file_json_schema, settings_file_json_schema, Settings}; use std::{borrow::Cow, env, path::Path, str, sync::Arc}; +use terminal_view::terminal_button::{self, TerminalButton}; use util::{channel::ReleaseChannel, paths, ResultExt, StaffMode}; use uuid::Uuid; pub use workspace; @@ -73,6 +74,7 @@ actions!( const MIN_FONT_SIZE: f32 = 6.0; pub fn init(app_state: &Arc, cx: &mut gpui::MutableAppContext) { + terminal_button::init(cx); cx.add_action(about); cx.add_global_action(|_: &Hide, cx: &mut gpui::MutableAppContext| { cx.platform().hide(); @@ -330,6 +332,7 @@ pub fn initialize_workspace( ) }); + let toggle_terminal = cx.add_view(|cx| TerminalButton::new(workspace_handle.clone(), cx)); let diagnostic_summary = cx.add_view(|cx| diagnostics::items::DiagnosticIndicator::new(workspace.project(), cx)); let activity_indicator = @@ -340,6 +343,10 @@ pub fn initialize_workspace( workspace.status_bar().update(cx, |status_bar, cx| { status_bar.add_left_item(diagnostic_summary, cx); status_bar.add_left_item(activity_indicator, cx); + // TODO: Remove this when things are done + if **cx.default_global::() { + status_bar.add_right_item(toggle_terminal, cx); + } status_bar.add_right_item(cursor_position, cx); status_bar.add_right_item(feedback_button, cx); });