diff --git a/app/src/tab.rs b/app/src/tab.rs index b2bc28b2..b7e74fbb 100644 --- a/app/src/tab.rs +++ b/app/src/tab.rs @@ -23,6 +23,7 @@ use crate::ui_components::icons::{Icon, ICON_DIMENSIONS}; use crate::util::color::{coloru_with_opacity, Opacity}; use crate::util::truncation::truncate_from_end; +use crate::undo_close::UndoCloseStack; use crate::window_settings::WindowSettings; use crate::workspace::sync_inputs::SyncedInputState; use crate::workspace::tab_settings::{TabCloseButtonPosition, TabSettings}; @@ -408,6 +409,15 @@ impl TabData { .into_item(), ); } + + let is_empty = UndoCloseStack::as_ref(ctx).is_empty(); + menu_items.push( + MenuItemFields::new("Reopen closed session") + .with_on_select_action(WorkspaceAction::ReopenClosedSession) + .with_disabled(is_empty) + .into_item(), + ); + menu_items } diff --git a/crates/integration/src/test.rs b/crates/integration/src/test.rs index 024d8f74..2a7aea89 100644 --- a/crates/integration/src/test.rs +++ b/crates/integration/src/test.rs @@ -2018,6 +2018,37 @@ pub fn test_removing_tabs_out_of_order() -> Builder { ) } +pub fn test_reopen_closed_session_from_tab_context_menu() -> Builder { + new_builder() + .with_step(wait_until_bootstrapped_single_pane_for_tab(0)) + .with_step( + new_step_with_default_assertions("Open a second tab") + .with_keystrokes(&[cmd_or_ctrl_shift("t")]) + .set_timeout(Duration::from_secs(10)) + .add_assertion(|app, window_id| { + assert_single_terminal_in_tab_bootstrapped(app, window_id, 1) + }) + .add_assertion(assert_tab_count(2)), + ) + .with_step( + new_step_with_default_assertions("Close the second tab") + .with_keystrokes(&[cmd_or_ctrl_shift("w")]) + .add_assertion(assert_tab_count(1)), + ) + .with_step( + new_step_with_default_assertions("Right-click first tab to open context menu") + .with_right_click_on_saved_position("tab_position_0"), + ) + .with_step( + new_step_with_default_assertions( + "Click 'Reopen closed session' and verify tab is restored", + ) + .with_click_on_saved_position("Reopen closed session") + .set_timeout(Duration::from_secs(10)) + .add_assertion(assert_tab_count(2)), + ) +} + pub fn test_add_and_close_session() -> Builder { let pid = Rc::new(std::cell::RefCell::new(0_u32)); let pid_clone = pid.clone(); diff --git a/crates/integration/tests/integration/ui_tests.rs b/crates/integration/tests/integration/ui_tests.rs index c9d74feb..b7098ea5 100644 --- a/crates/integration/tests/integration/ui_tests.rs +++ b/crates/integration/tests/integration/ui_tests.rs @@ -20,6 +20,7 @@ integration_tests! { test_unescaped_prompt_bootstraps, test_unnecessary_resizes, test_removing_tabs_out_of_order, + test_reopen_closed_session_from_tab_context_menu, #[ignore = "Affected by agent_view feature flag UI changes"] test_suggestions_menu_positioning, test_open_and_close_theme_creator_modal,