mirror of
https://github.com/wez/wezterm.git
synced 2024-11-23 23:21:08 +03:00
wezterm: add confirm parameter to CloseCurrentTab
When confirmation is enabled, a really basic overlay is rendered over the top of the tab to request confirmation. The default key assignment for CloseCurrentTab now has confirmation enabled. ```lua action=wezterm.action{CloseCurrentTab={confirm=true}} action=wezterm.action{CloseCurrentTab={confirm=false}} ``` refs: https://github.com/wez/wezterm/issues/157 refs: https://github.com/wez/wezterm/issues/280
This commit is contained in:
parent
1b9d561e56
commit
b2911ccc41
@ -1,4 +1,4 @@
|
||||
use crate::mux::tab::PaneId;
|
||||
use crate::mux::tab::{PaneId, TabId};
|
||||
use crate::mux::window::WindowId;
|
||||
use crate::mux::Mux;
|
||||
use crate::termwiztermtab::TermWizTerminal;
|
||||
@ -58,3 +58,51 @@ pub fn confirm_close_pane(
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn confirm_close_tab(
|
||||
tab_id: TabId,
|
||||
mut term: TermWizTerminal,
|
||||
_mux_window_id: WindowId,
|
||||
) -> anyhow::Result<()> {
|
||||
term.set_raw_mode()?;
|
||||
|
||||
let changes = vec![
|
||||
Change::ClearScreen(ColorAttribute::Default),
|
||||
Change::CursorPosition {
|
||||
x: Position::Absolute(0),
|
||||
y: Position::Absolute(0),
|
||||
},
|
||||
Change::Text("Really kill this tab and all contained panes? [y/n]\r\n".to_string()),
|
||||
];
|
||||
|
||||
term.render(&changes)?;
|
||||
term.flush()?;
|
||||
|
||||
while let Ok(Some(event)) = term.poll_input(None) {
|
||||
match event {
|
||||
InputEvent::Key(KeyEvent {
|
||||
key: KeyCode::Char('y'),
|
||||
..
|
||||
}) => {
|
||||
promise::spawn::spawn_into_main_thread(async move {
|
||||
let mux = Mux::get().unwrap();
|
||||
mux.remove_tab(tab_id);
|
||||
});
|
||||
break;
|
||||
}
|
||||
InputEvent::Key(KeyEvent {
|
||||
key: KeyCode::Char('n'),
|
||||
..
|
||||
})
|
||||
| InputEvent::Key(KeyEvent {
|
||||
key: KeyCode::Escape,
|
||||
..
|
||||
}) => {
|
||||
break;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ mod search;
|
||||
mod tabnavigator;
|
||||
|
||||
pub use confirm_close_pane::confirm_close_pane;
|
||||
pub use confirm_close_pane::confirm_close_tab;
|
||||
pub use copy::CopyOverlay;
|
||||
pub use launcher::launcher;
|
||||
pub use search::SearchOverlay;
|
||||
|
@ -9,8 +9,8 @@ use crate::font::FontConfiguration;
|
||||
use crate::frontend::activity::Activity;
|
||||
use crate::frontend::front_end;
|
||||
use crate::frontend::gui::overlay::{
|
||||
confirm_close_pane, launcher, start_overlay, start_overlay_pane, tab_navigator, CopyOverlay,
|
||||
SearchOverlay,
|
||||
confirm_close_pane, confirm_close_tab, launcher, start_overlay, start_overlay_pane,
|
||||
tab_navigator, CopyOverlay, SearchOverlay,
|
||||
};
|
||||
use crate::frontend::gui::scrollbar::*;
|
||||
use crate::frontend::gui::selection::*;
|
||||
@ -1855,7 +1855,7 @@ impl TermWindow {
|
||||
w.show();
|
||||
}
|
||||
}
|
||||
CloseCurrentTab => self.close_current_tab(),
|
||||
CloseCurrentTab { confirm } => self.close_current_tab(*confirm),
|
||||
CloseCurrentPane { confirm } => self.close_current_pane(*confirm),
|
||||
Nop | DisableDefaultAssignment => {}
|
||||
ReloadConfiguration => crate::config::reload(),
|
||||
@ -2153,17 +2153,23 @@ impl TermWindow {
|
||||
}
|
||||
}
|
||||
|
||||
fn close_current_tab(&mut self) {
|
||||
fn close_current_tab(&mut self, confirm: bool) {
|
||||
let mux = Mux::get().unwrap();
|
||||
let tab = match mux.get_active_tab_for_window(self.mux_window_id) {
|
||||
Some(tab) => tab,
|
||||
None => return,
|
||||
};
|
||||
mux.remove_tab(tab.tab_id());
|
||||
if let Some(mut win) = mux.get_window_mut(self.mux_window_id) {
|
||||
win.remove_by_id(tab.tab_id());
|
||||
let tab_id = tab.tab_id();
|
||||
let mux_window_id = self.mux_window_id;
|
||||
if confirm {
|
||||
let (overlay, future) = start_overlay(self, &tab, move |tab_id, term| {
|
||||
confirm_close_tab(tab_id, term, mux_window_id)
|
||||
});
|
||||
self.assign_overlay(tab_id, overlay);
|
||||
promise::spawn::spawn(future);
|
||||
} else {
|
||||
mux.remove_tab(tab_id);
|
||||
}
|
||||
self.activate_tab_relative(0).ok();
|
||||
}
|
||||
|
||||
fn close_tab_idx(&mut self, idx: usize) -> anyhow::Result<()> {
|
||||
|
@ -97,7 +97,7 @@ pub enum KeyAssignment {
|
||||
DisableDefaultAssignment,
|
||||
Hide,
|
||||
Show,
|
||||
CloseCurrentTab,
|
||||
CloseCurrentTab { confirm: bool },
|
||||
ReloadConfiguration,
|
||||
MoveTabRelative(isize),
|
||||
MoveTab(usize),
|
||||
@ -227,7 +227,11 @@ impl InputMap {
|
||||
[KeyModifiers::SUPER, KeyCode::Char('7'), ActivateTab(6)],
|
||||
[KeyModifiers::SUPER, KeyCode::Char('8'), ActivateTab(7)],
|
||||
[KeyModifiers::SUPER, KeyCode::Char('9'), ActivateTab(-1)],
|
||||
[KeyModifiers::SUPER, KeyCode::Char('w'), CloseCurrentTab],
|
||||
[
|
||||
KeyModifiers::SUPER,
|
||||
KeyCode::Char('w'),
|
||||
CloseCurrentTab { confirm: true }
|
||||
],
|
||||
[ctrl_shift, KeyCode::Char('1'), ActivateTab(0)],
|
||||
[ctrl_shift, KeyCode::Char('2'), ActivateTab(1)],
|
||||
[ctrl_shift, KeyCode::Char('3'), ActivateTab(2)],
|
||||
@ -237,7 +241,11 @@ impl InputMap {
|
||||
[ctrl_shift, KeyCode::Char('7'), ActivateTab(6)],
|
||||
[ctrl_shift, KeyCode::Char('8'), ActivateTab(7)],
|
||||
[ctrl_shift, KeyCode::Char('9'), ActivateTab(-1)],
|
||||
[KeyModifiers::CTRL, KeyCode::Char('W'), CloseCurrentTab],
|
||||
[
|
||||
KeyModifiers::CTRL,
|
||||
KeyCode::Char('W'),
|
||||
CloseCurrentTab { confirm: true }
|
||||
],
|
||||
[
|
||||
KeyModifiers::SUPER | KeyModifiers::SHIFT,
|
||||
KeyCode::Char('['),
|
||||
|
@ -231,17 +231,20 @@ impl Mux {
|
||||
}
|
||||
}
|
||||
|
||||
fn remove_tab_internal(&self, tab_id: TabId) {
|
||||
fn remove_tab_internal(&self, tab_id: TabId) -> Option<Rc<Tab>> {
|
||||
log::debug!("remove_tab_internal tab {}", tab_id);
|
||||
|
||||
let tab = self.tabs.borrow_mut().remove(&tab_id)?;
|
||||
|
||||
let mut pane_ids = vec![];
|
||||
if let Some(tab) = self.tabs.borrow_mut().remove(&tab_id) {
|
||||
for pos in tab.iter_panes() {
|
||||
pane_ids.push(pos.pane.pane_id());
|
||||
}
|
||||
for pos in tab.iter_panes() {
|
||||
pane_ids.push(pos.pane.pane_id());
|
||||
}
|
||||
for pane_id in pane_ids {
|
||||
self.remove_pane_internal(pane_id);
|
||||
}
|
||||
|
||||
Some(tab)
|
||||
}
|
||||
|
||||
fn remove_window_internal(&self, window_id: WindowId) {
|
||||
@ -259,9 +262,10 @@ impl Mux {
|
||||
self.prune_dead_windows();
|
||||
}
|
||||
|
||||
pub fn remove_tab(&self, tab_id: TabId) {
|
||||
self.remove_tab_internal(tab_id);
|
||||
pub fn remove_tab(&self, tab_id: TabId) -> Option<Rc<Tab>> {
|
||||
let tab = self.remove_tab_internal(tab_id);
|
||||
self.prune_dead_windows();
|
||||
tab
|
||||
}
|
||||
|
||||
pub fn prune_dead_windows(&self) {
|
||||
|
Loading…
Reference in New Issue
Block a user