* Initial mouse support * enable mouse support (termion MouseTerminal) * handle scroll up and down events * Allow enabling/disabling of mouse reporting Store the mouse terminal on OsInputOutput * WIP: switch pane focus with mouse * testing to get mouse character selection * wip mouse selection * wip: mouse selection - initial handling of mouse events for text selection within a pane - wide characters currently problematic - selection is not highlighted * highlight currently selected text * improve get currently selected text from TerminalPane * copy selection to clipboard (wayland only for now) * Add missing set_should_render on selection update * Improve text selection - Strip whitespace from end of lines - Insert newlines when selection spans multiple lines * Simplify selection logic - Remove Range struct - Selection is not an Option anymore, it's empty when start == end * copy selection to clipboard with OSC-52 sequence * Improve text selection with multiple panes - Constrain mouse hold and release events to currently active pane - Fix calculation of columns with side by side panes * fix for PositionAndSize changes * Fix mouse selection with full screen pane. - Transform mouse event positions to relative when passing to pane. * Move selection to grid, rework highlighting. - Mark selected lines for update in grid output buffer, for now in the simplest way possible, but can be made more efficient by calculating changed lines only. - Clear selection on pane resize. - Re-add logic to forward mouse hold and release events only to currently active pane. * Tidy up selection - add method to get selection line range - add method to sort the current selection * Grid: move current selection up/down when scrolling - Make the selection work with lines in lines_above and lines_below - Todo: update selection end when scrolling with mouse button being held - Todo: figure out how to move selection when new characters are added. * Grid: move selection when new lines are added * Keep track of selection being active - Handle the selection growing/shrinking when scrolling with mouse button held down but not yet released. * Improve selection end with multiple panes * Tidying up - remove logging statements, unused code * Add some unit tests for selection, move position to zellij-utils * Change Position::new to take i32 for line * Grid: add unit tests for copy from selection * add basic integration test for mouse pane focus * Add basic integration test for mouse scroll * Use color from palette for selection rendering * Improve performance of selection render - Try to minimize lines to update on selection start/update/end * fixes for updated start method * fix lines not in viewport being marked for rendering - the previous optimization to grid selection rendering was always adding the lines at the extremes of previous selection, causing problems when scrolling up or down - make sure to only add lines in viewport * Disable mouse mode on exit * use saturating_sub for usize subtractions * copy selection to clipboard on mouse release * disable mouse on exit after error * remove left-over comments * remove copy keybinding * add default impl for selection methods in Pane - remove the useless methods from Impl Pane in PluginPane * move line diff between selections to selection * add option to disable mouse mode * Allow scrolling with mouse while selecting. * move action repeater to os_input_output, change timeout to 10ms - change repeater to take an action instead of a position with hardcoded action * replace mouse mode integration tests with e2e tests * cleanup * cleanup * check if mouse mode is disabled from merged options * fix missing changes in tests, cleanup
94 lines
3.5 KiB
Rust
94 lines
3.5 KiB
Rust
//! The way terminal input is handled.
|
|
|
|
pub mod actions;
|
|
pub mod command;
|
|
pub mod config;
|
|
pub mod keybinds;
|
|
pub mod layout;
|
|
pub mod mouse;
|
|
pub mod options;
|
|
pub mod theme;
|
|
|
|
use termion::input::TermRead;
|
|
use zellij_tile::data::{InputMode, Key, ModeInfo, Palette, PluginCapabilities};
|
|
|
|
/// Creates a [`Help`] struct indicating the current [`InputMode`] and its keybinds
|
|
/// (as pairs of [`String`]s).
|
|
// TODO this should probably be automatically generated in some way
|
|
pub fn get_mode_info(
|
|
mode: InputMode,
|
|
palette: Palette,
|
|
capabilities: PluginCapabilities,
|
|
) -> ModeInfo {
|
|
let mut keybinds: Vec<(String, String)> = vec![];
|
|
match mode {
|
|
InputMode::Normal | InputMode::Locked => {}
|
|
InputMode::Resize => {
|
|
keybinds.push(("←↓↑→".to_string(), "Resize".to_string()));
|
|
}
|
|
InputMode::Pane => {
|
|
keybinds.push(("←↓↑→".to_string(), "Move focus".to_string()));
|
|
keybinds.push(("p".to_string(), "Next".to_string()));
|
|
keybinds.push(("n".to_string(), "New".to_string()));
|
|
keybinds.push(("d".to_string(), "Down split".to_string()));
|
|
keybinds.push(("r".to_string(), "Right split".to_string()));
|
|
keybinds.push(("x".to_string(), "Close".to_string()));
|
|
keybinds.push(("f".to_string(), "Fullscreen".to_string()));
|
|
}
|
|
InputMode::Tab => {
|
|
keybinds.push(("←↓↑→".to_string(), "Move focus".to_string()));
|
|
keybinds.push(("n".to_string(), "New".to_string()));
|
|
keybinds.push(("x".to_string(), "Close".to_string()));
|
|
keybinds.push(("r".to_string(), "Rename".to_string()));
|
|
keybinds.push(("s".to_string(), "Sync".to_string()));
|
|
}
|
|
InputMode::Scroll => {
|
|
keybinds.push(("↓↑".to_string(), "Scroll".to_string()));
|
|
keybinds.push(("PgUp/PgDn".to_string(), "Scroll Page".to_string()));
|
|
}
|
|
InputMode::RenameTab => {
|
|
keybinds.push(("Enter".to_string(), "when done".to_string()));
|
|
}
|
|
InputMode::Session => {
|
|
keybinds.push(("d".to_string(), "Detach".to_string()));
|
|
}
|
|
}
|
|
ModeInfo {
|
|
mode,
|
|
keybinds,
|
|
palette,
|
|
capabilities,
|
|
}
|
|
}
|
|
|
|
pub fn parse_keys(input_bytes: &[u8]) -> Vec<Key> {
|
|
input_bytes.keys().flatten().map(cast_termion_key).collect()
|
|
}
|
|
|
|
// FIXME: This is an absolutely cursed function that should be destroyed as soon
|
|
// as an alternative that doesn't touch zellij-tile can be developed...
|
|
pub fn cast_termion_key(event: termion::event::Key) -> Key {
|
|
match event {
|
|
termion::event::Key::Backspace => Key::Backspace,
|
|
termion::event::Key::Left => Key::Left,
|
|
termion::event::Key::Right => Key::Right,
|
|
termion::event::Key::Up => Key::Up,
|
|
termion::event::Key::Down => Key::Down,
|
|
termion::event::Key::Home => Key::Home,
|
|
termion::event::Key::End => Key::End,
|
|
termion::event::Key::PageUp => Key::PageUp,
|
|
termion::event::Key::PageDown => Key::PageDown,
|
|
termion::event::Key::BackTab => Key::BackTab,
|
|
termion::event::Key::Delete => Key::Delete,
|
|
termion::event::Key::Insert => Key::Insert,
|
|
termion::event::Key::F(n) => Key::F(n),
|
|
termion::event::Key::Char(c) => Key::Char(c),
|
|
termion::event::Key::Alt(c) => Key::Alt(c),
|
|
termion::event::Key::Ctrl(c) => Key::Ctrl(c),
|
|
termion::event::Key::Null => Key::Null,
|
|
termion::event::Key::Esc => Key::Esc,
|
|
_ => {
|
|
unimplemented!("Encountered an unknown key!")
|
|
}
|
|
}
|
|
}
|