From 551af2f47bc22b01a08cd71ada5aeef69f568ed4 Mon Sep 17 00:00:00 2001 From: Wez Furlong Date: Wed, 4 May 2022 22:49:58 -0700 Subject: [PATCH] define copy_mode key table and use it in copy mode Moves the key handling in the copy overlay to be driven entirely by configurable key assignments. Note: copy mode wants you to use the `Copy` assignment to actually do the copy, but this implementation hides the normal key assignments by activating the copy mode key table. This will be addressed in the following commit. refs: https://github.com/wez/wezterm/issues/993 --- wezterm-gui/src/inputmap.rs | 4 + wezterm-gui/src/overlay/copy.rs | 300 ++++++++++++++++++++++-------- wezterm-gui/src/overlay/mod.rs | 12 +- wezterm-gui/src/termwindow/mod.rs | 2 + 4 files changed, 236 insertions(+), 82 deletions(-) diff --git a/wezterm-gui/src/inputmap.rs b/wezterm-gui/src/inputmap.rs index 41d53bc97..a08c1aed6 100644 --- a/wezterm-gui/src/inputmap.rs +++ b/wezterm-gui/src/inputmap.rs @@ -174,6 +174,10 @@ impl InputMap { .retain(|_, v| v.action != KeyAssignment::DisableDefaultAssignment); mouse.retain(|_, v| *v != KeyAssignment::DisableDefaultAssignment); + keys.by_name + .entry("copy_mode".to_string()) + .or_insert_with(crate::overlay::copy::key_table); + Self { keys, leader, diff --git a/wezterm-gui/src/overlay/copy.rs b/wezterm-gui/src/overlay/copy.rs index b72e48431..00def3050 100644 --- a/wezterm-gui/src/overlay/copy.rs +++ b/wezterm-gui/src/overlay/copy.rs @@ -1,6 +1,8 @@ use crate::selection::{SelectionCoordinate, SelectionRange}; use crate::termwindow::{TermWindow, TermWindowNotif}; -use config::keyassignment::{CopyModeAssignment, KeyAssignment, ScrollbackEraseMode}; +use config::keyassignment::{ + CopyModeAssignment, KeyAssignment, KeyTable, KeyTableEntry, ScrollbackEraseMode, +}; use mux::domain::DomainId; use mux::pane::{Pane, PaneId}; use mux::renderable::*; @@ -17,7 +19,7 @@ use wezterm_term::color::ColorPalette; use wezterm_term::{ unicode_column_width, Clipboard, KeyCode, KeyModifiers, Line, MouseEvent, StableRowIndex, }; -use window::WindowOps; +use window::{KeyCode as WKeyCode, Modifiers, WindowOps}; pub struct CopyOverlay { delegate: Rc, @@ -436,80 +438,7 @@ impl Pane for CopyOverlay { } } - fn key_down(&self, key: KeyCode, mods: KeyModifiers) -> anyhow::Result<()> { - match (key, mods) { - (KeyCode::Char('c'), KeyModifiers::CTRL) - | (KeyCode::Char('g'), KeyModifiers::CTRL) - | (KeyCode::Char('q'), KeyModifiers::NONE) - | (KeyCode::Escape, KeyModifiers::NONE) => self.render.borrow().close(), - (KeyCode::Char('h'), KeyModifiers::NONE) | (KeyCode::LeftArrow, KeyModifiers::NONE) => { - self.render.borrow_mut().move_left_single_cell(); - } - (KeyCode::Char('j'), KeyModifiers::NONE) | (KeyCode::DownArrow, KeyModifiers::NONE) => { - self.render.borrow_mut().move_down_single_row(); - } - (KeyCode::Char('k'), KeyModifiers::NONE) | (KeyCode::UpArrow, KeyModifiers::NONE) => { - self.render.borrow_mut().move_up_single_row(); - } - (KeyCode::Char('l'), KeyModifiers::NONE) - | (KeyCode::RightArrow, KeyModifiers::NONE) => { - self.render.borrow_mut().move_right_single_cell(); - } - - (KeyCode::RightArrow, KeyModifiers::ALT) | - (KeyCode::Char('f'), KeyModifiers::ALT)| - (KeyCode::Tab, KeyModifiers::NONE) | - (KeyCode::Char('w'), KeyModifiers::NONE) => { - self.render.borrow_mut().move_forward_one_word(); - } - - (KeyCode::LeftArrow, KeyModifiers::ALT) | - (KeyCode::Char('b'), KeyModifiers::ALT) | - (KeyCode::Tab, KeyModifiers::SHIFT) | - (KeyCode::Char('b'), KeyModifiers::NONE) => { - self.render.borrow_mut().move_backward_one_word(); - } - (KeyCode::Char('0'), KeyModifiers::NONE) => { - self.render.borrow_mut().move_to_start_of_line(); - } - (KeyCode::Enter, KeyModifiers::NONE) => { - self.render.borrow_mut().move_to_start_of_next_line(); - } - (KeyCode::Char('$'), KeyModifiers::SHIFT) | // FIXME: normalize the shift away! - (KeyCode::Char('$'), KeyModifiers::NONE) => { - self.render.borrow_mut().move_to_end_of_line_content(); - } - (KeyCode::Char('m'), KeyModifiers::ALT) | - (KeyCode::Char('^'), KeyModifiers::SHIFT) | // FIXME: normalize the shift away! - (KeyCode::Char('^'), KeyModifiers::NONE) => { - self.render.borrow_mut().move_to_start_of_line_content(); - } - (KeyCode::Char(' '), KeyModifiers::NONE) | (KeyCode::Char('v'), KeyModifiers::NONE) => { - self.render.borrow_mut().toggle_selection_by_cell(); - } - (KeyCode::Char('G'), KeyModifiers::SHIFT) | // FIXME: normalize the shift away! - (KeyCode::Char('G'), KeyModifiers::NONE) => { - self.render.borrow_mut().move_to_bottom(); - } - (KeyCode::Char('g'), KeyModifiers::NONE) => { - self.render.borrow_mut().move_to_top(); - } - (KeyCode::Char('H'), KeyModifiers::SHIFT) | // FIXME: normalize the shift away! - (KeyCode::Char('H'), KeyModifiers::NONE) => { - self.render.borrow_mut().move_to_viewport_top(); - } - (KeyCode::Char('M'), KeyModifiers::SHIFT) | // FIXME: normalize the shift away! - (KeyCode::Char('M'), KeyModifiers::NONE) => { - self.render.borrow_mut().move_to_viewport_middle(); - } - (KeyCode::Char('L'), KeyModifiers::SHIFT) | // FIXME: normalize the shift away! - (KeyCode::Char('L'), KeyModifiers::NONE) => { - self.render.borrow_mut().move_to_viewport_bottom(); - } - (KeyCode::PageUp, KeyModifiers::NONE) | (KeyCode::Char('b'), KeyModifiers::CTRL) => self.render.borrow_mut().page_up(), - (KeyCode::PageDown, KeyModifiers::NONE) | (KeyCode::Char('f'), KeyModifiers::CTRL) => self.render.borrow_mut().page_down(), - _ => {} - } + fn key_down(&self, _key: KeyCode, _mods: KeyModifiers) -> anyhow::Result<()> { Ok(()) } @@ -586,3 +515,222 @@ fn is_whitespace_word(word: &str) -> bool { false } } + +pub fn key_table() -> KeyTable { + let mut table = KeyTable::default(); + for (key, mods, action) in [ + ( + WKeyCode::Char('c'), + Modifiers::CTRL, + KeyAssignment::CopyMode(CopyModeAssignment::Close), + ), + ( + WKeyCode::Char('g'), + Modifiers::CTRL, + KeyAssignment::CopyMode(CopyModeAssignment::Close), + ), + ( + WKeyCode::Char('q'), + Modifiers::NONE, + KeyAssignment::CopyMode(CopyModeAssignment::Close), + ), + ( + WKeyCode::Char('\x1b'), + Modifiers::NONE, + KeyAssignment::CopyMode(CopyModeAssignment::Close), + ), + ( + WKeyCode::Char('h'), + Modifiers::NONE, + KeyAssignment::CopyMode(CopyModeAssignment::MoveLeft), + ), + ( + WKeyCode::LeftArrow, + Modifiers::NONE, + KeyAssignment::CopyMode(CopyModeAssignment::MoveLeft), + ), + ( + WKeyCode::Char('j'), + Modifiers::NONE, + KeyAssignment::CopyMode(CopyModeAssignment::MoveDown), + ), + ( + WKeyCode::DownArrow, + Modifiers::NONE, + KeyAssignment::CopyMode(CopyModeAssignment::MoveDown), + ), + ( + WKeyCode::Char('k'), + Modifiers::NONE, + KeyAssignment::CopyMode(CopyModeAssignment::MoveUp), + ), + ( + WKeyCode::UpArrow, + Modifiers::NONE, + KeyAssignment::CopyMode(CopyModeAssignment::MoveUp), + ), + ( + WKeyCode::Char('l'), + Modifiers::NONE, + KeyAssignment::CopyMode(CopyModeAssignment::MoveRight), + ), + ( + WKeyCode::RightArrow, + Modifiers::NONE, + KeyAssignment::CopyMode(CopyModeAssignment::MoveRight), + ), + ( + WKeyCode::RightArrow, + Modifiers::ALT, + KeyAssignment::CopyMode(CopyModeAssignment::MoveForwardWord), + ), + ( + WKeyCode::Char('f'), + Modifiers::ALT, + KeyAssignment::CopyMode(CopyModeAssignment::MoveForwardWord), + ), + ( + WKeyCode::Char('\t'), + Modifiers::NONE, + KeyAssignment::CopyMode(CopyModeAssignment::MoveForwardWord), + ), + ( + WKeyCode::Char('w'), + Modifiers::NONE, + KeyAssignment::CopyMode(CopyModeAssignment::MoveForwardWord), + ), + ( + WKeyCode::LeftArrow, + Modifiers::ALT, + KeyAssignment::CopyMode(CopyModeAssignment::MoveBackwardWord), + ), + ( + WKeyCode::Char('b'), + Modifiers::ALT, + KeyAssignment::CopyMode(CopyModeAssignment::MoveBackwardWord), + ), + ( + WKeyCode::Char('\t'), + Modifiers::SHIFT, + KeyAssignment::CopyMode(CopyModeAssignment::MoveBackwardWord), + ), + ( + WKeyCode::Char('b'), + Modifiers::NONE, + KeyAssignment::CopyMode(CopyModeAssignment::MoveBackwardWord), + ), + ( + WKeyCode::Char('0'), + Modifiers::NONE, + KeyAssignment::CopyMode(CopyModeAssignment::MoveToStartOfLine), + ), + ( + WKeyCode::Char('\n'), + Modifiers::NONE, + KeyAssignment::CopyMode(CopyModeAssignment::MoveToStartOfNextLine), + ), + ( + WKeyCode::Char('$'), + Modifiers::SHIFT, + KeyAssignment::CopyMode(CopyModeAssignment::MoveToEndOfLineContent), + ), + ( + WKeyCode::Char('$'), + Modifiers::NONE, + KeyAssignment::CopyMode(CopyModeAssignment::MoveToEndOfLineContent), + ), + ( + WKeyCode::Char('m'), + Modifiers::ALT, + KeyAssignment::CopyMode(CopyModeAssignment::MoveToStartOfLineContent), + ), + ( + WKeyCode::Char('^'), + Modifiers::SHIFT, + KeyAssignment::CopyMode(CopyModeAssignment::MoveToStartOfLineContent), + ), + ( + WKeyCode::Char('^'), + Modifiers::NONE, + KeyAssignment::CopyMode(CopyModeAssignment::MoveToStartOfLineContent), + ), + ( + WKeyCode::Char(' '), + Modifiers::NONE, + KeyAssignment::CopyMode(CopyModeAssignment::ToggleSelectionByCell), + ), + ( + WKeyCode::Char('v'), + Modifiers::NONE, + KeyAssignment::CopyMode(CopyModeAssignment::ToggleSelectionByCell), + ), + ( + WKeyCode::Char('G'), + Modifiers::SHIFT, + KeyAssignment::CopyMode(CopyModeAssignment::MoveToScrollbackBottom), + ), + ( + WKeyCode::Char('G'), + Modifiers::NONE, + KeyAssignment::CopyMode(CopyModeAssignment::MoveToScrollbackBottom), + ), + ( + WKeyCode::Char('g'), + Modifiers::NONE, + KeyAssignment::CopyMode(CopyModeAssignment::MoveToScrollbackTop), + ), + ( + WKeyCode::Char('H'), + Modifiers::NONE, + KeyAssignment::CopyMode(CopyModeAssignment::MoveToViewportTop), + ), + ( + WKeyCode::Char('H'), + Modifiers::SHIFT, + KeyAssignment::CopyMode(CopyModeAssignment::MoveToViewportTop), + ), + ( + WKeyCode::Char('M'), + Modifiers::NONE, + KeyAssignment::CopyMode(CopyModeAssignment::MoveToViewportMiddle), + ), + ( + WKeyCode::Char('M'), + Modifiers::SHIFT, + KeyAssignment::CopyMode(CopyModeAssignment::MoveToViewportMiddle), + ), + ( + WKeyCode::Char('L'), + Modifiers::NONE, + KeyAssignment::CopyMode(CopyModeAssignment::MoveToViewportBottom), + ), + ( + WKeyCode::Char('L'), + Modifiers::SHIFT, + KeyAssignment::CopyMode(CopyModeAssignment::MoveToViewportBottom), + ), + ( + WKeyCode::PageUp, + Modifiers::NONE, + KeyAssignment::CopyMode(CopyModeAssignment::PageUp), + ), + ( + WKeyCode::PageDown, + Modifiers::NONE, + KeyAssignment::CopyMode(CopyModeAssignment::PageDown), + ), + ( + WKeyCode::Char('b'), + Modifiers::CTRL, + KeyAssignment::CopyMode(CopyModeAssignment::PageUp), + ), + ( + WKeyCode::Char('f'), + Modifiers::CTRL, + KeyAssignment::CopyMode(CopyModeAssignment::PageDown), + ), + ] { + table.insert((key, mods), KeyTableEntry { action }); + } + table +} diff --git a/wezterm-gui/src/overlay/mod.rs b/wezterm-gui/src/overlay/mod.rs index d3a50be0b..d022f5388 100644 --- a/wezterm-gui/src/overlay/mod.rs +++ b/wezterm-gui/src/overlay/mod.rs @@ -6,12 +6,12 @@ use portable_pty::PtySize; use std::pin::Pin; use std::rc::Rc; -mod confirm_close_pane; -mod copy; -mod debug; -mod launcher; -mod quickselect; -mod search; +pub mod confirm_close_pane; +pub mod copy; +pub mod debug; +pub mod launcher; +pub mod quickselect; +pub mod search; pub use confirm_close_pane::{ confirm_close_pane, confirm_close_tab, confirm_close_window, confirm_quit_program, diff --git a/wezterm-gui/src/termwindow/mod.rs b/wezterm-gui/src/termwindow/mod.rs index 0bb3b3833..af3faaaf9 100644 --- a/wezterm-gui/src/termwindow/mod.rs +++ b/wezterm-gui/src/termwindow/mod.rs @@ -2277,6 +2277,8 @@ impl TermWindow { if let Some(pane) = self.get_active_pane_no_overlay() { let copy = CopyOverlay::with_pane(self, &pane); self.assign_overlay_for_pane(pane.pane_id(), copy); + self.key_table_state + .activate("copy_mode", None, false, false); } } AdjustPaneSize(direction, amount) => {