From 11e72b3d6b97c117633d73c46cd7c91b549c3e8e Mon Sep 17 00:00:00 2001 From: Kyle Sutherland-Cash Date: Sat, 21 Nov 2020 14:55:49 +0000 Subject: [PATCH] feat(ux): add a command mode (#42) * Move the input loop into a separate module * Proof of concept implementation of command mode * Update readme to reflect command mode * Have Esc exit command mode * Update tests to use command mode and make it transient by default * Some merge fixes * fix(tests): add missing COMMAND_TOGGLE and fix false positive test * style(format): make rustfmt happy * Update readme to describe command mode Co-authored-by: Aram Drevekenin --- .gitignore | 1 + README.md | 36 ++- src/input.rs | 266 +++++++++++++++++++++ src/main.rs | 134 ++--------- src/tests/fakes.rs | 27 ++- src/tests/integration/basic.rs | 32 ++- src/tests/integration/close_pane.rs | 49 +++- src/tests/integration/compatibility.rs | 17 +- src/tests/integration/layouts.rs | 4 +- src/tests/integration/resize_down.rs | 40 +++- src/tests/integration/resize_left.rs | 39 ++- src/tests/integration/resize_right.rs | 39 ++- src/tests/integration/resize_up.rs | 39 ++- src/tests/integration/toggle_fullscreen.rs | 6 +- src/tests/utils.rs | 42 ++-- 15 files changed, 590 insertions(+), 181 deletions(-) create mode 100644 src/input.rs diff --git a/.gitignore b/.gitignore index ea8c4bf7..eabafffe 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ /target +*.new \ No newline at end of file diff --git a/README.md b/README.md index a9ba1b04..4088bfbb 100644 --- a/README.md +++ b/README.md @@ -32,19 +32,29 @@ If you're interested, watch this space or better yet - get involved! (note that right now Mosaic only supports linux and maybe mac) -Some temporary controls (these will be changed to something more convenient when the project matures a little): - * ctrl-n - split focused pane vertically - * ctrl-b - split focused pane horizontally - * ctrl-m - split largest terminal on screen (vertically or horizontally) - * ctrl-j - resize focused pane down - * ctrl-k - resize focused pane up - * ctrl-h - resize focused pane left - * ctrl-l - resize focused pane right - * ctrl-p - move focus to next pane - * ctrl-PgUp - scroll up in focused pane - * ctrl-PgDown - scroll down in focused pane - * ctrl-x - close focused pane - * ctrl-q - quit Mosaic +mosaic has three modes, which are a bit like vim or tmux: + * Normal mode - allows you to enter text, input will be sent through to stdin on the pane you're typing in + * Command mode - input is interpreted as commands to control mosaic. This comes in two variants: + * Temporary - once a single valid command has been parsed, returns to normal mode (e.g. quickly opening a new pane and start typing) + * Permanent - remain in command mode until you issue the exit command mode command + +The keys and behavior will update when the project matures a bit, but for now: + * ctrl-g to cycle between modes (normal mode -> temporary command mode -> permanent command mode -> normal mode) + * Esc - exit command mode (any) and return to normal mode + +In command mode: + * n - split focused pane vertically + * b - split focused pane horizontally + * m - split largest terminal on screen (vertically or horizontally) + * j - resize focused pane down + * k - resize focused pane up + * h - resize focused pane left + * l - resize focused pane right + * p - move focus to next pane + * PgUp - scroll up in focused pane + * PgDown - scroll down in focused pane + * x - close focused pane + * q - quit Mosaic # What is the current status of the project? diff --git a/src/input.rs b/src/input.rs new file mode 100644 index 00000000..976ef71d --- /dev/null +++ b/src/input.rs @@ -0,0 +1,266 @@ +/// Module for handling input +use std::io::Read; +use std::sync::mpsc::Sender; + +use crate::os_input_output::OsApi; +use crate::pty_bus::PtyInstruction; +use crate::screen::ScreenInstruction; +use crate::utils::logging::debug_log_to_file; +use crate::AppInstruction; +use crate::CommandIsExecuting; + +struct InputHandler { + buffer: [u8; 10], // TODO: more accurately + mode: InputMode, + stdin: Box, + command_is_executing: CommandIsExecuting, + send_screen_instructions: Sender, + send_pty_instructions: Sender, + send_app_instructions: Sender, +} + +impl InputHandler { + fn new( + os_input: Box, + command_is_executing: CommandIsExecuting, + send_screen_instructions: Sender, + send_pty_instructions: Sender, + send_app_instructions: Sender, + ) -> Self { + InputHandler { + buffer: [0; 10], // TODO: more accurately + mode: InputMode::Normal, + stdin: os_input.get_stdin_reader(), + command_is_executing, + send_screen_instructions, + send_pty_instructions, + send_app_instructions, + } + } + + /// Main event loop + fn get_input(&mut self) { + loop { + match self.mode { + InputMode::Normal => self.read_normal_mode(), + InputMode::Command => self.read_command_mode(false), + InputMode::CommandPersistent => self.read_command_mode(true), + InputMode::Exiting => { + self.exit(); + break; + } + } + } + } + + /// Read input to the terminal (or switch to command mode) + fn read_normal_mode(&mut self) { + assert_eq!(self.mode, InputMode::Normal); + + loop { + self.stdin + .read(&mut self.buffer) + .expect("failed to read stdin"); + + match self.buffer { + [7, 0, 0, 0, 0, 0, 0, 0, 0, 0] => { + // ctrl-g + // debug_log_to_file(format!("switched to command mode")); + self.mode = InputMode::Command; + return; + } + _ => { + self.send_screen_instructions + .send(ScreenInstruction::ClearScroll) + .unwrap(); + self.send_screen_instructions + .send(ScreenInstruction::WriteCharacter(self.buffer)) + .unwrap(); + } + } + } + } + + /// Read input and parse it as commands for mosaic + fn read_command_mode(&mut self, persistent: bool) { + //@@@khs26 Add a powerbar type thing that we can write output to + if persistent { + assert_eq!(self.mode, InputMode::CommandPersistent); + } else { + assert_eq!(self.mode, InputMode::Command); + } + + loop { + self.buffer = [0; 10]; + self.stdin + .read(&mut self.buffer) + .expect("failed to read stdin"); + // uncomment this to print the entered character to a log file (/tmp/mosaic-log.txt) for debugging + // debug_log_to_file(format!("buffer {:?}", self.buffer)); + match self.buffer { + [7, 0, 0, 0, 0, 0, 0, 0, 0, 0] => { + // Ctrl-g + // If we're in command mode, this will let us switch to persistent command mode, to execute + // multiple commands. If we're already in persistent mode, it'll return us to normal mode. + match self.mode { + InputMode::Command => self.mode = InputMode::CommandPersistent, + InputMode::CommandPersistent => { + self.mode = InputMode::Normal; + // debug_log_to_file(format!("switched to normal mode")); + return; + } + _ => panic!(), + } + } + [27, 0, 0, 0, 0, 0, 0, 0, 0, 0] => { + // Esc + self.mode = InputMode::Normal; + // _debug_log_to_file(format!("switched to normal mode")); + return; + } + [106, 0, 0, 0, 0, 0, 0, 0, 0, 0] => { + // j + self.send_screen_instructions + .send(ScreenInstruction::ResizeDown) + .unwrap(); + } + [107, 0, 0, 0, 0, 0, 0, 0, 0, 0] => { + // k + self.send_screen_instructions + .send(ScreenInstruction::ResizeUp) + .unwrap(); + } + [112, 0, 0, 0, 0, 0, 0, 0, 0, 0] => { + // p + self.send_screen_instructions + .send(ScreenInstruction::MoveFocus) + .unwrap(); + } + [104, 0, 0, 0, 0, 0, 0, 0, 0, 0] => { + // h + self.send_screen_instructions + .send(ScreenInstruction::ResizeLeft) + .unwrap(); + } + [108, 0, 0, 0, 0, 0, 0, 0, 0, 0] => { + // l + self.send_screen_instructions + .send(ScreenInstruction::ResizeRight) + .unwrap(); + } + [122, 0, 0, 0, 0, 0, 0, 0, 0, 0] => { + // z + self.command_is_executing.opening_new_pane(); + self.send_pty_instructions + .send(PtyInstruction::SpawnTerminal(None)) + .unwrap(); + self.command_is_executing.wait_until_new_pane_is_opened(); + } + [110, 0, 0, 0, 0, 0, 0, 0, 0, 0] => { + // n + self.command_is_executing.opening_new_pane(); + self.send_pty_instructions + .send(PtyInstruction::SpawnTerminalVertically(None)) + .unwrap(); + self.command_is_executing.wait_until_new_pane_is_opened(); + } + [98, 0, 0, 0, 0, 0, 0, 0, 0, 0] => { + // b + self.command_is_executing.opening_new_pane(); + self.send_pty_instructions + .send(PtyInstruction::SpawnTerminalHorizontally(None)) + .unwrap(); + self.command_is_executing.wait_until_new_pane_is_opened(); + } + [113, 0, 0, 0, 0, 0, 0, 0, 0, 0] => { + // q + self.mode = InputMode::Exiting; + return; + } + [27, 91, 53, 126, 0, 0, 0, 0, 0, 0] => { + // PgUp + self.send_screen_instructions + .send(ScreenInstruction::ScrollUp) + .unwrap(); + } + [27, 91, 54, 126, 0, 0, 0, 0, 0, 0] => { + // PgDown + self.send_screen_instructions + .send(ScreenInstruction::ScrollDown) + .unwrap(); + } + [120, 0, 0, 0, 0, 0, 0, 0, 0, 0] => { + // x + self.command_is_executing.closing_pane(); + self.send_screen_instructions + .send(ScreenInstruction::CloseFocusedPane) + .unwrap(); + self.command_is_executing.wait_until_pane_is_closed(); + } + [101, 0, 0, 0, 0, 0, 0, 0, 0, 0] => { + // e + self.send_screen_instructions + .send(ScreenInstruction::ToggleActiveTerminalFullscreen) + .unwrap(); + } + //@@@khs26 Write this to the powerbar? + _ => {} + } + + if self.mode == InputMode::Command { + self.mode = InputMode::Normal; + return; + } + } + } + + /// Routine to be called when the input handler exits (at the moment this is the + /// same as quitting mosaic) + fn exit(&mut self) { + self.send_screen_instructions + .send(ScreenInstruction::Quit) + .unwrap(); + self.send_pty_instructions + .send(PtyInstruction::Quit) + .unwrap(); + self.send_app_instructions + .send(AppInstruction::Exit) + .unwrap(); + } +} + +/// Dictates whether we're in command mode, persistent command mode, normal mode or exiting: +/// - Normal mode either writes characters to the terminal, or switches to command mode +/// using a particular key control +/// - Command mode intercepts characters to control mosaic itself, before switching immediately +/// back to normal mode +/// - Persistent command mode is the same as command mode, but doesn't return automatically to +/// normal mode +/// - Exiting means that we should start the shutdown process for mosaic or the given +/// input handler +#[derive(Debug, PartialEq)] +pub enum InputMode { + Normal, + Command, + CommandPersistent, + Exiting, +} + +/// Entry point to the module that instantiates a new InputHandler and calls its +/// reading loop +pub fn input_loop( + os_input: Box, + command_is_executing: CommandIsExecuting, + send_screen_instructions: Sender, + send_pty_instructions: Sender, + send_app_instructions: Sender, +) { + let _handler = InputHandler::new( + os_input, + command_is_executing, + send_screen_instructions, + send_pty_instructions, + send_app_instructions, + ) + .get_input(); +} diff --git a/src/main.rs b/src/main.rs index 0ed65535..10ee87c1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,6 +3,7 @@ mod tests; mod boundaries; mod command_is_executing; +mod input; mod layout; mod os_input_output; mod pty_bus; @@ -21,6 +22,7 @@ use serde_yaml; use structopt::StructOpt; use crate::command_is_executing::CommandIsExecuting; +use crate::input::input_loop; use crate::layout::Layout; use crate::os_input_output::{get_os_input, OsApi}; use crate::pty_bus::{PtyBus, PtyInstruction, VteEvent}; @@ -97,7 +99,7 @@ pub fn start(mut os_input: Box, opts: Opt) { let command_is_executing = CommandIsExecuting::new(); - delete_log_dir().unwrap(); + let _ = delete_log_dir(); delete_log_file().unwrap(); let full_screen_ws = os_input.get_terminal_size_using_fd(0); @@ -317,120 +319,24 @@ pub fn start(mut os_input: Box, opts: Opt) { }) .unwrap(); - let _stdin_thread = thread::Builder::new().name("stdin".to_string()).spawn({ - let send_screen_instructions = send_screen_instructions.clone(); - let send_pty_instructions = send_pty_instructions.clone(); - let send_app_instructions = send_app_instructions.clone(); - let os_input = os_input.clone(); - - let mut command_is_executing = command_is_executing.clone(); - move || { - let mut stdin = os_input.get_stdin_reader(); - loop { - let mut buffer = [0; 10]; // TODO: more accurately - stdin.read(&mut buffer).expect("failed to read stdin"); - // uncomment this to print the entered character to a log file (/tmp/mosaic-log.txt) for debugging - //crate::utils::logging::debug_log_to_file(format!("buffer {:?}", buffer)); - match buffer { - [10, 0, 0, 0, 0, 0, 0, 0, 0, 0] => { - // ctrl-j - send_screen_instructions - .send(ScreenInstruction::ResizeDown) - .unwrap(); - } - [11, 0, 0, 0, 0, 0, 0, 0, 0, 0] => { - // ctrl-k - send_screen_instructions - .send(ScreenInstruction::ResizeUp) - .unwrap(); - } - [16, 0, 0, 0, 0, 0, 0, 0, 0, 0] => { - // ctrl-p - send_screen_instructions - .send(ScreenInstruction::MoveFocus) - .unwrap(); - } - [8, 0, 0, 0, 0, 0, 0, 0, 0, 0] => { - // ctrl-h - send_screen_instructions - .send(ScreenInstruction::ResizeLeft) - .unwrap(); - } - [12, 0, 0, 0, 0, 0, 0, 0, 0, 0] => { - // ctrl-l - send_screen_instructions - .send(ScreenInstruction::ResizeRight) - .unwrap(); - } - [26, 0, 0, 0, 0, 0, 0, 0, 0, 0] => { - // ctrl-z - command_is_executing.opening_new_pane(); - send_pty_instructions - .send(PtyInstruction::SpawnTerminal(None)) - .unwrap(); - command_is_executing.wait_until_new_pane_is_opened(); - } - [14, 0, 0, 0, 0, 0, 0, 0, 0, 0] => { - // ctrl-n - command_is_executing.opening_new_pane(); - send_pty_instructions - .send(PtyInstruction::SpawnTerminalVertically(None)) - .unwrap(); - command_is_executing.wait_until_new_pane_is_opened(); - } - [2, 0, 0, 0, 0, 0, 0, 0, 0, 0] => { - // ctrl-b - command_is_executing.opening_new_pane(); - send_pty_instructions - .send(PtyInstruction::SpawnTerminalHorizontally(None)) - .unwrap(); - command_is_executing.wait_until_new_pane_is_opened(); - } - [17, 0, 0, 0, 0, 0, 0, 0, 0, 0] => { - // ctrl-q - let _ = send_screen_instructions.send(ScreenInstruction::Quit); - let _ = send_pty_instructions.send(PtyInstruction::Quit); - let _ = send_app_instructions.send(AppInstruction::Exit); - break; - } - [27, 91, 53, 94, 0, 0, 0, 0, 0, 0] => { - // ctrl-PgUp - send_screen_instructions - .send(ScreenInstruction::ScrollUp) - .unwrap(); - } - [27, 91, 54, 94, 0, 0, 0, 0, 0, 0] => { - // ctrl-PgDown - send_screen_instructions - .send(ScreenInstruction::ScrollDown) - .unwrap(); - } - [24, 0, 0, 0, 0, 0, 0, 0, 0, 0] => { - // ctrl-x - command_is_executing.closing_pane(); - send_screen_instructions - .send(ScreenInstruction::CloseFocusedPane) - .unwrap(); - command_is_executing.wait_until_pane_is_closed(); - } - [5, 0, 0, 0, 0, 0, 0, 0, 0, 0] => { - // ctrl-e - send_screen_instructions - .send(ScreenInstruction::ToggleActiveTerminalFullscreen) - .unwrap(); - } - _ => { - send_screen_instructions - .send(ScreenInstruction::ClearScroll) - .unwrap(); - send_screen_instructions - .send(ScreenInstruction::WriteCharacter(buffer)) - .unwrap(); - } - } + let _stdin_thread = thread::Builder::new() + .name("stdin_handler".to_string()) + .spawn({ + let send_screen_instructions = send_screen_instructions.clone(); + let send_pty_instructions = send_pty_instructions.clone(); + let send_app_instructions = send_app_instructions.clone(); + let os_input = os_input.clone(); + let command_is_executing = command_is_executing.clone(); + move || { + input_loop( + os_input, + command_is_executing, + send_screen_instructions, + send_pty_instructions, + send_app_instructions, + ) } - } - }); + }); loop { let app_instruction = receive_app_instructions diff --git a/src/tests/fakes.rs b/src/tests/fakes.rs index 778a77ab..22370d98 100644 --- a/src/tests/fakes.rs +++ b/src/tests/fakes.rs @@ -47,12 +47,28 @@ impl Read for FakeStdinReader { } } let read_position = self.read_position; - let bytes_to_read = self.input_chars.get(read_position).unwrap(); - for (i, byte) in bytes_to_read.iter().enumerate() { - buf[i] = *byte; + match self.input_chars.get(read_position) { + Some(bytes_to_read) => { + for (i, byte) in bytes_to_read.iter().enumerate() { + buf[i] = *byte; + } + self.read_position += 1; + Ok(bytes_to_read.len()) + } + None => { + // what is happening here? + // + // Here the stdin loop is requesting more input than we have provided it with in + // the fake input chars. + // Normally this should not happen, because each test quits in the end. + // There is one case (at the time of this writing) in which it does happen, and + // that's when we quit by closing the last pane. In this case the stdin loop might + // get a chance to request more input before the app quits and drops it. In that + // case, we just give it no input and let it keep doing its thing until it dies + // very shortly after. + Ok(0) + } } - self.read_position += 1; - Ok(bytes_to_read.len()) } } @@ -229,7 +245,6 @@ impl OsApi for FakeInputOutput { input_chars.push(*bytes); } } - input_chars.push([17, 0, 0, 0, 0, 0, 0, 0, 0, 0]); // ctrl-q (quit) let reader = FakeStdinReader::new(input_chars, self.last_snapshot_time.clone()); Box::new(reader) } diff --git a/src/tests/integration/basic.rs b/src/tests/integration/basic.rs index b3b8c2e6..54a174cc 100644 --- a/src/tests/integration/basic.rs +++ b/src/tests/integration/basic.rs @@ -3,8 +3,8 @@ use ::insta::assert_snapshot; use crate::tests::fakes::FakeInputOutput; use crate::tests::utils::commands::{ - MOVE_FOCUS, QUIT, RESIZE_LEFT, RESIZE_RIGHT, RESIZE_UP, SCROLL_DOWN, SCROLL_UP, SPAWN_TERMINAL, - SPLIT_HORIZONTALLY, SPLIT_VERTICALLY, TOGGLE_ACTIVE_TERMINAL_FULLSCREEN, + COMMAND_TOGGLE, MOVE_FOCUS, QUIT, RESIZE_LEFT, RESIZE_RIGHT, RESIZE_UP, SCROLL_DOWN, SCROLL_UP, + SPAWN_TERMINAL, SPLIT_HORIZONTALLY, SPLIT_VERTICALLY, TOGGLE_ACTIVE_TERMINAL_FULLSCREEN, }; use crate::tests::utils::get_output_frame_snapshots; use crate::{start, Opt}; @@ -22,7 +22,7 @@ pub fn starts_with_one_terminal() { y: 0, }; let mut fake_input_output = get_fake_os_input(&fake_win_size); - fake_input_output.add_terminal_input(&[QUIT]); + fake_input_output.add_terminal_input(&[COMMAND_TOGGLE, COMMAND_TOGGLE, QUIT]); start(Box::new(fake_input_output.clone()), Opt::default()); let output_frames = fake_input_output .stdout_writer @@ -44,7 +44,7 @@ pub fn split_terminals_vertically() { y: 0, }; let mut fake_input_output = get_fake_os_input(&fake_win_size); - fake_input_output.add_terminal_input(&[SPLIT_VERTICALLY, QUIT]); + fake_input_output.add_terminal_input(&[COMMAND_TOGGLE, COMMAND_TOGGLE, SPLIT_VERTICALLY, QUIT]); start(Box::new(fake_input_output.clone()), Opt::default()); let output_frames = fake_input_output .stdout_writer @@ -66,7 +66,12 @@ pub fn split_terminals_horizontally() { y: 0, }; let mut fake_input_output = get_fake_os_input(&fake_win_size); - fake_input_output.add_terminal_input(&[SPLIT_HORIZONTALLY, QUIT]); + fake_input_output.add_terminal_input(&[ + COMMAND_TOGGLE, + COMMAND_TOGGLE, + SPLIT_HORIZONTALLY, + QUIT, + ]); start(Box::new(fake_input_output.clone()), Opt::default()); let output_frames = fake_input_output .stdout_writer @@ -89,7 +94,14 @@ pub fn split_largest_terminal() { y: 0, }; let mut fake_input_output = get_fake_os_input(&fake_win_size); - fake_input_output.add_terminal_input(&[SPAWN_TERMINAL, SPAWN_TERMINAL, SPAWN_TERMINAL, QUIT]); + fake_input_output.add_terminal_input(&[ + COMMAND_TOGGLE, + COMMAND_TOGGLE, + SPAWN_TERMINAL, + SPAWN_TERMINAL, + SPAWN_TERMINAL, + QUIT, + ]); start(Box::new(fake_input_output.clone()), Opt::default()); let output_frames = fake_input_output .stdout_writer @@ -128,6 +140,8 @@ pub fn resize_right_and_up_on_the_same_axis() { let mut fake_input_output = get_fake_os_input(&fake_win_size); fake_input_output.add_terminal_input(&[ + COMMAND_TOGGLE, + COMMAND_TOGGLE, SPLIT_HORIZONTALLY, SPLIT_VERTICALLY, MOVE_FOCUS, @@ -161,6 +175,8 @@ pub fn scrolling_inside_a_pane() { }; let mut fake_input_output = get_fake_os_input(&fake_win_size); fake_input_output.add_terminal_input(&[ + COMMAND_TOGGLE, + COMMAND_TOGGLE, SPLIT_HORIZONTALLY, SPLIT_VERTICALLY, SCROLL_UP, @@ -193,6 +209,8 @@ pub fn max_panes() { }; let mut fake_input_output = get_fake_os_input(&fake_win_size); fake_input_output.add_terminal_input(&[ + COMMAND_TOGGLE, + COMMAND_TOGGLE, SPAWN_TERMINAL, SPAWN_TERMINAL, SPAWN_TERMINAL, @@ -223,6 +241,8 @@ pub fn toggle_focused_pane_fullscreen() { }; let mut fake_input_output = get_fake_os_input(&fake_win_size); fake_input_output.add_terminal_input(&[ + COMMAND_TOGGLE, + COMMAND_TOGGLE, SPAWN_TERMINAL, SPAWN_TERMINAL, SPAWN_TERMINAL, diff --git a/src/tests/integration/close_pane.rs b/src/tests/integration/close_pane.rs index 3c2fec2f..6658242f 100644 --- a/src/tests/integration/close_pane.rs +++ b/src/tests/integration/close_pane.rs @@ -6,8 +6,8 @@ use crate::tests::utils::get_output_frame_snapshots; use crate::{start, Opt}; use crate::tests::utils::commands::{ - CLOSE_FOCUSED_PANE, MOVE_FOCUS, QUIT, RESIZE_DOWN, RESIZE_LEFT, RESIZE_UP, SPLIT_HORIZONTALLY, - SPLIT_VERTICALLY, + CLOSE_FOCUSED_PANE, COMMAND_TOGGLE, MOVE_FOCUS, QUIT, RESIZE_DOWN, RESIZE_LEFT, RESIZE_UP, + SPLIT_HORIZONTALLY, SPLIT_VERTICALLY, }; fn get_fake_os_input(fake_win_size: &PositionAndSize) -> FakeInputOutput { @@ -31,7 +31,13 @@ pub fn close_pane_with_another_pane_above_it() { y: 0, }; let mut fake_input_output = get_fake_os_input(&fake_win_size); - fake_input_output.add_terminal_input(&[SPLIT_HORIZONTALLY, CLOSE_FOCUSED_PANE, QUIT]); + fake_input_output.add_terminal_input(&[ + COMMAND_TOGGLE, + COMMAND_TOGGLE, + SPLIT_HORIZONTALLY, + CLOSE_FOCUSED_PANE, + QUIT, + ]); start(Box::new(fake_input_output.clone()), Opt::default()); let output_frames = fake_input_output @@ -63,6 +69,8 @@ pub fn close_pane_with_another_pane_below_it() { }; let mut fake_input_output = get_fake_os_input(&fake_win_size); fake_input_output.add_terminal_input(&[ + COMMAND_TOGGLE, + COMMAND_TOGGLE, SPLIT_HORIZONTALLY, MOVE_FOCUS, CLOSE_FOCUSED_PANE, @@ -96,7 +104,13 @@ pub fn close_pane_with_another_pane_to_the_left() { y: 0, }; let mut fake_input_output = get_fake_os_input(&fake_win_size); - fake_input_output.add_terminal_input(&[SPLIT_VERTICALLY, CLOSE_FOCUSED_PANE, QUIT]); + fake_input_output.add_terminal_input(&[ + COMMAND_TOGGLE, + COMMAND_TOGGLE, + SPLIT_VERTICALLY, + CLOSE_FOCUSED_PANE, + QUIT, + ]); start(Box::new(fake_input_output.clone()), Opt::default()); let output_frames = fake_input_output @@ -125,7 +139,14 @@ pub fn close_pane_with_another_pane_to_the_right() { y: 0, }; let mut fake_input_output = get_fake_os_input(&fake_win_size); - fake_input_output.add_terminal_input(&[SPLIT_VERTICALLY, MOVE_FOCUS, CLOSE_FOCUSED_PANE, QUIT]); + fake_input_output.add_terminal_input(&[ + COMMAND_TOGGLE, + COMMAND_TOGGLE, + SPLIT_VERTICALLY, + MOVE_FOCUS, + CLOSE_FOCUSED_PANE, + QUIT, + ]); start(Box::new(fake_input_output.clone()), Opt::default()); let output_frames = fake_input_output @@ -157,6 +178,8 @@ pub fn close_pane_with_multiple_panes_above_it() { }; let mut fake_input_output = get_fake_os_input(&fake_win_size); fake_input_output.add_terminal_input(&[ + COMMAND_TOGGLE, + COMMAND_TOGGLE, SPLIT_HORIZONTALLY, MOVE_FOCUS, SPLIT_VERTICALLY, @@ -196,6 +219,8 @@ pub fn close_pane_with_multiple_panes_below_it() { }; let mut fake_input_output = get_fake_os_input(&fake_win_size); fake_input_output.add_terminal_input(&[ + COMMAND_TOGGLE, + COMMAND_TOGGLE, SPLIT_HORIZONTALLY, SPLIT_VERTICALLY, MOVE_FOCUS, @@ -233,6 +258,8 @@ pub fn close_pane_with_multiple_panes_to_the_left() { }; let mut fake_input_output = get_fake_os_input(&fake_win_size); fake_input_output.add_terminal_input(&[ + COMMAND_TOGGLE, + COMMAND_TOGGLE, SPLIT_VERTICALLY, MOVE_FOCUS, SPLIT_HORIZONTALLY, @@ -272,6 +299,8 @@ pub fn close_pane_with_multiple_panes_to_the_right() { }; let mut fake_input_output = get_fake_os_input(&fake_win_size); fake_input_output.add_terminal_input(&[ + COMMAND_TOGGLE, + COMMAND_TOGGLE, SPLIT_VERTICALLY, SPLIT_HORIZONTALLY, MOVE_FOCUS, @@ -309,6 +338,8 @@ pub fn close_pane_with_multiple_panes_above_it_away_from_screen_edges() { }; let mut fake_input_output = get_fake_os_input(&fake_win_size); fake_input_output.add_terminal_input(&[ + COMMAND_TOGGLE, + COMMAND_TOGGLE, SPLIT_HORIZONTALLY, SPLIT_VERTICALLY, SPLIT_VERTICALLY, @@ -360,6 +391,8 @@ pub fn close_pane_with_multiple_panes_below_it_away_from_screen_edges() { }; let mut fake_input_output = get_fake_os_input(&fake_win_size); fake_input_output.add_terminal_input(&[ + COMMAND_TOGGLE, + COMMAND_TOGGLE, SPLIT_HORIZONTALLY, SPLIT_VERTICALLY, SPLIT_VERTICALLY, @@ -413,6 +446,8 @@ pub fn close_pane_with_multiple_panes_to_the_left_away_from_screen_edges() { }; let mut fake_input_output = get_fake_os_input(&fake_win_size); fake_input_output.add_terminal_input(&[ + COMMAND_TOGGLE, + COMMAND_TOGGLE, SPLIT_VERTICALLY, SPLIT_HORIZONTALLY, SPLIT_HORIZONTALLY, @@ -466,6 +501,8 @@ pub fn close_pane_with_multiple_panes_to_the_right_away_from_screen_edges() { }; let mut fake_input_output = get_fake_os_input(&fake_win_size); fake_input_output.add_terminal_input(&[ + COMMAND_TOGGLE, + COMMAND_TOGGLE, SPLIT_VERTICALLY, SPLIT_HORIZONTALLY, SPLIT_HORIZONTALLY, @@ -509,6 +546,8 @@ pub fn closing_last_pane_exits_app() { }; let mut fake_input_output = get_fake_os_input(&fake_win_size); fake_input_output.add_terminal_input(&[ + COMMAND_TOGGLE, + COMMAND_TOGGLE, SPLIT_VERTICALLY, SPLIT_HORIZONTALLY, MOVE_FOCUS, diff --git a/src/tests/integration/compatibility.rs b/src/tests/integration/compatibility.rs index 60f45844..a763d594 100644 --- a/src/tests/integration/compatibility.rs +++ b/src/tests/integration/compatibility.rs @@ -4,10 +4,11 @@ use ::std::collections::HashMap; use crate::terminal_pane::PositionAndSize; use crate::tests::fakes::FakeInputOutput; use crate::tests::possible_tty_inputs::Bytes; -use crate::tests::utils::commands::QUIT; use crate::tests::utils::get_output_frame_snapshots; use crate::{start, Opt}; +use crate::tests::utils::commands::{COMMAND_TOGGLE, QUIT}; + /* * These tests are general compatibility tests for non-trivial scenarios running in the terminal. * They use fake TTY input replicated from these scenarios (and so don't actually interact with the @@ -38,7 +39,7 @@ pub fn run_bandwhich_from_fish_shell() { }; let fixture_name = "fish_and_bandwhich"; let mut fake_input_output = get_fake_os_input(&fake_win_size, fixture_name); - fake_input_output.add_terminal_input(&[QUIT]); + fake_input_output.add_terminal_input(&[COMMAND_TOGGLE, COMMAND_TOGGLE, QUIT]); start(Box::new(fake_input_output.clone()), Opt::default()); let output_frames = fake_input_output .stdout_writer @@ -61,7 +62,7 @@ pub fn fish_tab_completion_options() { }; let fixture_name = "fish_tab_completion_options"; let mut fake_input_output = get_fake_os_input(&fake_win_size, fixture_name); - fake_input_output.add_terminal_input(&[QUIT]); + fake_input_output.add_terminal_input(&[COMMAND_TOGGLE, COMMAND_TOGGLE, QUIT]); start(Box::new(fake_input_output.clone()), Opt::default()); let output_frames = fake_input_output .stdout_writer @@ -89,7 +90,7 @@ pub fn fish_select_tab_completion_options() { }; let fixture_name = "fish_select_tab_completion_options"; let mut fake_input_output = get_fake_os_input(&fake_win_size, fixture_name); - fake_input_output.add_terminal_input(&[QUIT]); + fake_input_output.add_terminal_input(&[COMMAND_TOGGLE, COMMAND_TOGGLE, QUIT]); start(Box::new(fake_input_output.clone()), Opt::default()); let output_frames = fake_input_output .stdout_writer @@ -121,8 +122,8 @@ pub fn vim_scroll_region_down() { }; let fixture_name = "vim_scroll_region_down"; let mut fake_input_output = get_fake_os_input(&fake_win_size, fixture_name); - // fake_input_output.add_terminal_input(&[17]); // quit (ctrl-q) - fake_input_output.add_terminal_input(&[QUIT]); // quit (ctrl-q) + // fake_input_output.add_terminal_input(&[COMMAND_TOGGLE, COMMAND_TOGGLE, 17]); // quit (ctrl-q) + fake_input_output.add_terminal_input(&[COMMAND_TOGGLE, COMMAND_TOGGLE, QUIT]); // quit (ctrl-q) start(Box::new(fake_input_output.clone()), Opt::default()); let output_frames = fake_input_output .stdout_writer @@ -151,7 +152,7 @@ pub fn vim_ctrl_d() { }; let fixture_name = "vim_ctrl_d"; let mut fake_input_output = get_fake_os_input(&fake_win_size, fixture_name); - fake_input_output.add_terminal_input(&[QUIT]); + fake_input_output.add_terminal_input(&[COMMAND_TOGGLE, COMMAND_TOGGLE, QUIT]); start(Box::new(fake_input_output.clone()), Opt::default()); let output_frames = fake_input_output .stdout_writer @@ -179,7 +180,7 @@ pub fn vim_ctrl_u() { }; let fixture_name = "vim_ctrl_u"; let mut fake_input_output = get_fake_os_input(&fake_win_size, fixture_name); - fake_input_output.add_terminal_input(&[QUIT]); + fake_input_output.add_terminal_input(&[COMMAND_TOGGLE, COMMAND_TOGGLE, QUIT]); start(Box::new(fake_input_output.clone()), Opt::default()); let output_frames = fake_input_output .stdout_writer diff --git a/src/tests/integration/layouts.rs b/src/tests/integration/layouts.rs index 0212cb06..9781336e 100644 --- a/src/tests/integration/layouts.rs +++ b/src/tests/integration/layouts.rs @@ -2,7 +2,7 @@ use ::insta::assert_snapshot; use crate::terminal_pane::PositionAndSize; use crate::tests::fakes::FakeInputOutput; -use crate::tests::utils::commands::QUIT; +use crate::tests::utils::commands::{COMMAND_TOGGLE, QUIT}; use crate::tests::utils::get_output_frame_snapshots; use crate::{start, Opt}; @@ -19,7 +19,7 @@ pub fn accepts_basic_layout() { y: 0, }; let mut fake_input_output = get_fake_os_input(&fake_win_size); - fake_input_output.add_terminal_input(&[QUIT]); + fake_input_output.add_terminal_input(&[COMMAND_TOGGLE, COMMAND_TOGGLE, QUIT]); use std::path::PathBuf; let mut opts = Opt::default(); opts.layout = Some(PathBuf::from( diff --git a/src/tests/integration/resize_down.rs b/src/tests/integration/resize_down.rs index 24c53340..71559d36 100644 --- a/src/tests/integration/resize_down.rs +++ b/src/tests/integration/resize_down.rs @@ -6,7 +6,8 @@ use crate::tests::utils::get_output_frame_snapshots; use crate::{start, Opt}; use crate::tests::utils::commands::{ - MOVE_FOCUS, QUIT, RESIZE_DOWN, RESIZE_LEFT, SPLIT_HORIZONTALLY, SPLIT_VERTICALLY, + COMMAND_TOGGLE, MOVE_FOCUS, QUIT, RESIZE_DOWN, RESIZE_LEFT, SPLIT_HORIZONTALLY, + SPLIT_VERTICALLY, }; fn get_fake_os_input(fake_win_size: &PositionAndSize) -> FakeInputOutput { @@ -31,7 +32,13 @@ pub fn resize_down_with_pane_above() { y: 0, }; let mut fake_input_output = get_fake_os_input(&fake_win_size); - fake_input_output.add_terminal_input(&[SPLIT_HORIZONTALLY, RESIZE_DOWN, QUIT]); + fake_input_output.add_terminal_input(&[ + COMMAND_TOGGLE, + COMMAND_TOGGLE, + SPLIT_HORIZONTALLY, + RESIZE_DOWN, + QUIT, + ]); start(Box::new(fake_input_output.clone()), Opt::default()); let output_frames = fake_input_output @@ -62,7 +69,14 @@ pub fn resize_down_with_pane_below() { y: 0, }; let mut fake_input_output = get_fake_os_input(&fake_win_size); - fake_input_output.add_terminal_input(&[SPLIT_HORIZONTALLY, MOVE_FOCUS, RESIZE_DOWN, QUIT]); + fake_input_output.add_terminal_input(&[ + COMMAND_TOGGLE, + COMMAND_TOGGLE, + SPLIT_HORIZONTALLY, + MOVE_FOCUS, + RESIZE_DOWN, + QUIT, + ]); start(Box::new(fake_input_output.clone()), Opt::default()); let output_frames = fake_input_output @@ -97,6 +111,8 @@ pub fn resize_down_with_panes_above_and_below() { }; let mut fake_input_output = get_fake_os_input(&fake_win_size); fake_input_output.add_terminal_input(&[ + COMMAND_TOGGLE, + COMMAND_TOGGLE, SPLIT_HORIZONTALLY, SPLIT_HORIZONTALLY, MOVE_FOCUS, @@ -136,6 +152,8 @@ pub fn resize_down_with_multiple_panes_above() { let mut fake_input_output = get_fake_os_input(&fake_win_size); fake_input_output.add_terminal_input(&[ + COMMAND_TOGGLE, + COMMAND_TOGGLE, SPLIT_HORIZONTALLY, MOVE_FOCUS, SPLIT_VERTICALLY, @@ -177,6 +195,8 @@ pub fn resize_down_with_panes_above_aligned_left_with_current_pane() { let mut fake_input_output = get_fake_os_input(&fake_win_size); fake_input_output.add_terminal_input(&[ + COMMAND_TOGGLE, + COMMAND_TOGGLE, SPLIT_VERTICALLY, SPLIT_HORIZONTALLY, MOVE_FOCUS, @@ -220,6 +240,8 @@ pub fn resize_down_with_panes_below_aligned_left_with_current_pane() { let mut fake_input_output = get_fake_os_input(&fake_win_size); fake_input_output.add_terminal_input(&[ + COMMAND_TOGGLE, + COMMAND_TOGGLE, SPLIT_VERTICALLY, SPLIT_HORIZONTALLY, MOVE_FOCUS, @@ -262,6 +284,8 @@ pub fn resize_down_with_panes_above_aligned_right_with_current_pane() { let mut fake_input_output = get_fake_os_input(&fake_win_size); fake_input_output.add_terminal_input(&[ + COMMAND_TOGGLE, + COMMAND_TOGGLE, SPLIT_VERTICALLY, SPLIT_HORIZONTALLY, MOVE_FOCUS, @@ -302,6 +326,8 @@ pub fn resize_down_with_panes_below_aligned_right_with_current_pane() { let mut fake_input_output = get_fake_os_input(&fake_win_size); fake_input_output.add_terminal_input(&[ + COMMAND_TOGGLE, + COMMAND_TOGGLE, SPLIT_VERTICALLY, SPLIT_HORIZONTALLY, MOVE_FOCUS, @@ -343,6 +369,8 @@ pub fn resize_down_with_panes_above_aligned_left_and_right_with_current_pane() { let mut fake_input_output = get_fake_os_input(&fake_win_size); fake_input_output.add_terminal_input(&[ + COMMAND_TOGGLE, + COMMAND_TOGGLE, SPLIT_VERTICALLY, SPLIT_VERTICALLY, SPLIT_HORIZONTALLY, @@ -387,6 +415,8 @@ pub fn resize_down_with_panes_below_aligned_left_and_right_with_current_pane() { let mut fake_input_output = get_fake_os_input(&fake_win_size); fake_input_output.add_terminal_input(&[ + COMMAND_TOGGLE, + COMMAND_TOGGLE, SPLIT_VERTICALLY, SPLIT_VERTICALLY, SPLIT_HORIZONTALLY, @@ -433,6 +463,8 @@ pub fn resize_down_with_panes_above_aligned_left_and_right_with_panes_to_the_lef let mut fake_input_output = get_fake_os_input(&fake_win_size); fake_input_output.add_terminal_input(&[ + COMMAND_TOGGLE, + COMMAND_TOGGLE, SPLIT_VERTICALLY, SPLIT_VERTICALLY, MOVE_FOCUS, @@ -494,6 +526,8 @@ pub fn resize_down_with_panes_below_aligned_left_and_right_with_to_the_left_and_ let mut fake_input_output = get_fake_os_input(&fake_win_size); fake_input_output.add_terminal_input(&[ + COMMAND_TOGGLE, + COMMAND_TOGGLE, SPLIT_VERTICALLY, SPLIT_VERTICALLY, MOVE_FOCUS, diff --git a/src/tests/integration/resize_left.rs b/src/tests/integration/resize_left.rs index 2919d58b..3f78237d 100644 --- a/src/tests/integration/resize_left.rs +++ b/src/tests/integration/resize_left.rs @@ -6,7 +6,7 @@ use crate::tests::utils::get_output_frame_snapshots; use crate::{start, Opt}; use crate::tests::utils::commands::{ - MOVE_FOCUS, QUIT, RESIZE_LEFT, RESIZE_UP, SPLIT_HORIZONTALLY, SPLIT_VERTICALLY, + COMMAND_TOGGLE, MOVE_FOCUS, QUIT, RESIZE_LEFT, RESIZE_UP, SPLIT_HORIZONTALLY, SPLIT_VERTICALLY, }; fn get_fake_os_input(fake_win_size: &PositionAndSize) -> FakeInputOutput { @@ -28,7 +28,13 @@ pub fn resize_left_with_pane_to_the_left() { y: 0, }; let mut fake_input_output = get_fake_os_input(&fake_win_size); - fake_input_output.add_terminal_input(&[SPLIT_VERTICALLY, RESIZE_LEFT, QUIT]); + fake_input_output.add_terminal_input(&[ + COMMAND_TOGGLE, + COMMAND_TOGGLE, + SPLIT_VERTICALLY, + RESIZE_LEFT, + QUIT, + ]); start(Box::new(fake_input_output.clone()), Opt::default()); let output_frames = fake_input_output @@ -57,7 +63,14 @@ pub fn resize_left_with_pane_to_the_right() { y: 0, }; let mut fake_input_output = get_fake_os_input(&fake_win_size); - fake_input_output.add_terminal_input(&[SPLIT_VERTICALLY, MOVE_FOCUS, RESIZE_LEFT, QUIT]); + fake_input_output.add_terminal_input(&[ + COMMAND_TOGGLE, + COMMAND_TOGGLE, + SPLIT_VERTICALLY, + MOVE_FOCUS, + RESIZE_LEFT, + QUIT, + ]); start(Box::new(fake_input_output.clone()), Opt::default()); let output_frames = fake_input_output @@ -87,6 +100,8 @@ pub fn resize_left_with_panes_to_the_left_and_right() { }; let mut fake_input_output = get_fake_os_input(&fake_win_size); fake_input_output.add_terminal_input(&[ + COMMAND_TOGGLE, + COMMAND_TOGGLE, SPLIT_VERTICALLY, SPLIT_VERTICALLY, MOVE_FOCUS, @@ -124,6 +139,8 @@ pub fn resize_left_with_multiple_panes_to_the_left() { let mut fake_input_output = get_fake_os_input(&fake_win_size); fake_input_output.add_terminal_input(&[ + COMMAND_TOGGLE, + COMMAND_TOGGLE, SPLIT_VERTICALLY, MOVE_FOCUS, SPLIT_HORIZONTALLY, @@ -163,6 +180,8 @@ pub fn resize_left_with_panes_to_the_left_aligned_top_with_current_pane() { let mut fake_input_output = get_fake_os_input(&fake_win_size); fake_input_output.add_terminal_input(&[ + COMMAND_TOGGLE, + COMMAND_TOGGLE, SPLIT_VERTICALLY, SPLIT_HORIZONTALLY, MOVE_FOCUS, @@ -204,6 +223,8 @@ pub fn resize_left_with_panes_to_the_right_aligned_top_with_current_pane() { let mut fake_input_output = get_fake_os_input(&fake_win_size); fake_input_output.add_terminal_input(&[ + COMMAND_TOGGLE, + COMMAND_TOGGLE, SPLIT_VERTICALLY, SPLIT_HORIZONTALLY, MOVE_FOCUS, @@ -242,6 +263,8 @@ pub fn resize_left_with_panes_to_the_left_aligned_bottom_with_current_pane() { let mut fake_input_output = get_fake_os_input(&fake_win_size); fake_input_output.add_terminal_input(&[ + COMMAND_TOGGLE, + COMMAND_TOGGLE, SPLIT_VERTICALLY, SPLIT_HORIZONTALLY, MOVE_FOCUS, @@ -282,6 +305,8 @@ pub fn resize_left_with_panes_to_the_right_aligned_bottom_with_current_pane() { let mut fake_input_output = get_fake_os_input(&fake_win_size); fake_input_output.add_terminal_input(&[ + COMMAND_TOGGLE, + COMMAND_TOGGLE, SPLIT_VERTICALLY, SPLIT_HORIZONTALLY, MOVE_FOCUS, @@ -323,6 +348,8 @@ pub fn resize_left_with_panes_to_the_left_aligned_top_and_bottom_with_current_pa let mut fake_input_output = get_fake_os_input(&fake_win_size); fake_input_output.add_terminal_input(&[ + COMMAND_TOGGLE, + COMMAND_TOGGLE, SPLIT_HORIZONTALLY, SPLIT_HORIZONTALLY, SPLIT_VERTICALLY, @@ -367,6 +394,8 @@ pub fn resize_left_with_panes_to_the_right_aligned_top_and_bottom_with_current_p let mut fake_input_output = get_fake_os_input(&fake_win_size); fake_input_output.add_terminal_input(&[ + COMMAND_TOGGLE, + COMMAND_TOGGLE, SPLIT_HORIZONTALLY, SPLIT_HORIZONTALLY, SPLIT_VERTICALLY, @@ -413,6 +442,8 @@ pub fn resize_left_with_panes_to_the_left_aligned_top_and_bottom_with_panes_abov let mut fake_input_output = get_fake_os_input(&fake_win_size); fake_input_output.add_terminal_input(&[ + COMMAND_TOGGLE, + COMMAND_TOGGLE, SPLIT_HORIZONTALLY, SPLIT_HORIZONTALLY, MOVE_FOCUS, @@ -475,6 +506,8 @@ pub fn resize_left_with_panes_to_the_right_aligned_top_and_bottom_with_panes_abo let mut fake_input_output = get_fake_os_input(&fake_win_size); fake_input_output.add_terminal_input(&[ + COMMAND_TOGGLE, + COMMAND_TOGGLE, SPLIT_HORIZONTALLY, SPLIT_HORIZONTALLY, MOVE_FOCUS, diff --git a/src/tests/integration/resize_right.rs b/src/tests/integration/resize_right.rs index 7ea26761..c23e03cf 100644 --- a/src/tests/integration/resize_right.rs +++ b/src/tests/integration/resize_right.rs @@ -6,7 +6,7 @@ use crate::tests::utils::get_output_frame_snapshots; use crate::{start, Opt}; use crate::tests::utils::commands::{ - MOVE_FOCUS, QUIT, RESIZE_RIGHT, RESIZE_UP, SPLIT_HORIZONTALLY, SPLIT_VERTICALLY, + COMMAND_TOGGLE, MOVE_FOCUS, QUIT, RESIZE_RIGHT, RESIZE_UP, SPLIT_HORIZONTALLY, SPLIT_VERTICALLY, }; fn get_fake_os_input(fake_win_size: &PositionAndSize) -> FakeInputOutput { @@ -28,7 +28,13 @@ pub fn resize_right_with_pane_to_the_left() { y: 0, }; let mut fake_input_output = get_fake_os_input(&fake_win_size); - fake_input_output.add_terminal_input(&[SPLIT_VERTICALLY, RESIZE_RIGHT, QUIT]); + fake_input_output.add_terminal_input(&[ + COMMAND_TOGGLE, + COMMAND_TOGGLE, + SPLIT_VERTICALLY, + RESIZE_RIGHT, + QUIT, + ]); start(Box::new(fake_input_output.clone()), Opt::default()); let output_frames = fake_input_output @@ -57,7 +63,14 @@ pub fn resize_right_with_pane_to_the_right() { y: 0, }; let mut fake_input_output = get_fake_os_input(&fake_win_size); - fake_input_output.add_terminal_input(&[SPLIT_VERTICALLY, MOVE_FOCUS, RESIZE_RIGHT, QUIT]); + fake_input_output.add_terminal_input(&[ + COMMAND_TOGGLE, + COMMAND_TOGGLE, + SPLIT_VERTICALLY, + MOVE_FOCUS, + RESIZE_RIGHT, + QUIT, + ]); start(Box::new(fake_input_output.clone()), Opt::default()); let output_frames = fake_input_output @@ -87,6 +100,8 @@ pub fn resize_right_with_panes_to_the_left_and_right() { }; let mut fake_input_output = get_fake_os_input(&fake_win_size); fake_input_output.add_terminal_input(&[ + COMMAND_TOGGLE, + COMMAND_TOGGLE, SPLIT_VERTICALLY, SPLIT_VERTICALLY, MOVE_FOCUS, @@ -124,6 +139,8 @@ pub fn resize_right_with_multiple_panes_to_the_left() { let mut fake_input_output = get_fake_os_input(&fake_win_size); fake_input_output.add_terminal_input(&[ + COMMAND_TOGGLE, + COMMAND_TOGGLE, SPLIT_VERTICALLY, MOVE_FOCUS, SPLIT_HORIZONTALLY, @@ -163,6 +180,8 @@ pub fn resize_right_with_panes_to_the_left_aligned_top_with_current_pane() { let mut fake_input_output = get_fake_os_input(&fake_win_size); fake_input_output.add_terminal_input(&[ + COMMAND_TOGGLE, + COMMAND_TOGGLE, SPLIT_VERTICALLY, SPLIT_HORIZONTALLY, MOVE_FOCUS, @@ -204,6 +223,8 @@ pub fn resize_right_with_panes_to_the_right_aligned_top_with_current_pane() { let mut fake_input_output = get_fake_os_input(&fake_win_size); fake_input_output.add_terminal_input(&[ + COMMAND_TOGGLE, + COMMAND_TOGGLE, SPLIT_VERTICALLY, SPLIT_HORIZONTALLY, MOVE_FOCUS, @@ -242,6 +263,8 @@ pub fn resize_right_with_panes_to_the_left_aligned_bottom_with_current_pane() { let mut fake_input_output = get_fake_os_input(&fake_win_size); fake_input_output.add_terminal_input(&[ + COMMAND_TOGGLE, + COMMAND_TOGGLE, SPLIT_VERTICALLY, SPLIT_HORIZONTALLY, MOVE_FOCUS, @@ -282,6 +305,8 @@ pub fn resize_right_with_panes_to_the_right_aligned_bottom_with_current_pane() { let mut fake_input_output = get_fake_os_input(&fake_win_size); fake_input_output.add_terminal_input(&[ + COMMAND_TOGGLE, + COMMAND_TOGGLE, SPLIT_VERTICALLY, SPLIT_HORIZONTALLY, MOVE_FOCUS, @@ -323,6 +348,8 @@ pub fn resize_right_with_panes_to_the_left_aligned_top_and_bottom_with_current_p let mut fake_input_output = get_fake_os_input(&fake_win_size); fake_input_output.add_terminal_input(&[ + COMMAND_TOGGLE, + COMMAND_TOGGLE, SPLIT_HORIZONTALLY, SPLIT_HORIZONTALLY, SPLIT_VERTICALLY, @@ -367,6 +394,8 @@ pub fn resize_right_with_panes_to_the_right_aligned_top_and_bottom_with_current_ let mut fake_input_output = get_fake_os_input(&fake_win_size); fake_input_output.add_terminal_input(&[ + COMMAND_TOGGLE, + COMMAND_TOGGLE, SPLIT_HORIZONTALLY, SPLIT_HORIZONTALLY, SPLIT_VERTICALLY, @@ -413,6 +442,8 @@ pub fn resize_right_with_panes_to_the_left_aligned_top_and_bottom_with_panes_abo let mut fake_input_output = get_fake_os_input(&fake_win_size); fake_input_output.add_terminal_input(&[ + COMMAND_TOGGLE, + COMMAND_TOGGLE, SPLIT_HORIZONTALLY, SPLIT_HORIZONTALLY, MOVE_FOCUS, @@ -474,6 +505,8 @@ pub fn resize_right_with_panes_to_the_right_aligned_top_and_bottom_with_panes_ab let mut fake_input_output = get_fake_os_input(&fake_win_size); fake_input_output.add_terminal_input(&[ + COMMAND_TOGGLE, + COMMAND_TOGGLE, SPLIT_HORIZONTALLY, SPLIT_HORIZONTALLY, MOVE_FOCUS, diff --git a/src/tests/integration/resize_up.rs b/src/tests/integration/resize_up.rs index 7cf6b481..99121da5 100644 --- a/src/tests/integration/resize_up.rs +++ b/src/tests/integration/resize_up.rs @@ -6,7 +6,7 @@ use crate::tests::utils::get_output_frame_snapshots; use crate::{start, Opt}; use crate::tests::utils::commands::{ - MOVE_FOCUS, QUIT, RESIZE_LEFT, RESIZE_UP, SPLIT_HORIZONTALLY, SPLIT_VERTICALLY, + COMMAND_TOGGLE, MOVE_FOCUS, QUIT, RESIZE_LEFT, RESIZE_UP, SPLIT_HORIZONTALLY, SPLIT_VERTICALLY, }; fn get_fake_os_input(fake_win_size: &PositionAndSize) -> FakeInputOutput { @@ -30,7 +30,13 @@ pub fn resize_up_with_pane_above() { y: 0, }; let mut fake_input_output = get_fake_os_input(&fake_win_size); - fake_input_output.add_terminal_input(&[SPLIT_HORIZONTALLY, RESIZE_UP, QUIT]); + fake_input_output.add_terminal_input(&[ + COMMAND_TOGGLE, + COMMAND_TOGGLE, + SPLIT_HORIZONTALLY, + RESIZE_UP, + QUIT, + ]); start(Box::new(fake_input_output.clone()), Opt::default()); let output_frames = fake_input_output @@ -61,7 +67,14 @@ pub fn resize_up_with_pane_below() { y: 0, }; let mut fake_input_output = get_fake_os_input(&fake_win_size); - fake_input_output.add_terminal_input(&[SPLIT_HORIZONTALLY, MOVE_FOCUS, RESIZE_UP, QUIT]); + fake_input_output.add_terminal_input(&[ + COMMAND_TOGGLE, + COMMAND_TOGGLE, + SPLIT_HORIZONTALLY, + MOVE_FOCUS, + RESIZE_UP, + QUIT, + ]); start(Box::new(fake_input_output.clone()), Opt::default()); let output_frames = fake_input_output @@ -96,6 +109,8 @@ pub fn resize_up_with_panes_above_and_below() { }; let mut fake_input_output = get_fake_os_input(&fake_win_size); fake_input_output.add_terminal_input(&[ + COMMAND_TOGGLE, + COMMAND_TOGGLE, SPLIT_HORIZONTALLY, SPLIT_HORIZONTALLY, MOVE_FOCUS, @@ -134,6 +149,8 @@ pub fn resize_up_with_multiple_panes_above() { let mut fake_input_output = get_fake_os_input(&fake_win_size); fake_input_output.add_terminal_input(&[ + COMMAND_TOGGLE, + COMMAND_TOGGLE, SPLIT_HORIZONTALLY, MOVE_FOCUS, SPLIT_VERTICALLY, @@ -173,6 +190,8 @@ pub fn resize_up_with_panes_above_aligned_left_with_current_pane() { let mut fake_input_output = get_fake_os_input(&fake_win_size); fake_input_output.add_terminal_input(&[ + COMMAND_TOGGLE, + COMMAND_TOGGLE, SPLIT_VERTICALLY, SPLIT_HORIZONTALLY, MOVE_FOCUS, @@ -216,6 +235,8 @@ pub fn resize_up_with_panes_below_aligned_left_with_current_pane() { let mut fake_input_output = get_fake_os_input(&fake_win_size); fake_input_output.add_terminal_input(&[ + COMMAND_TOGGLE, + COMMAND_TOGGLE, SPLIT_VERTICALLY, SPLIT_HORIZONTALLY, MOVE_FOCUS, @@ -258,6 +279,8 @@ pub fn resize_up_with_panes_above_aligned_right_with_current_pane() { let mut fake_input_output = get_fake_os_input(&fake_win_size); fake_input_output.add_terminal_input(&[ + COMMAND_TOGGLE, + COMMAND_TOGGLE, SPLIT_VERTICALLY, SPLIT_HORIZONTALLY, MOVE_FOCUS, @@ -298,6 +321,8 @@ pub fn resize_up_with_panes_below_aligned_right_with_current_pane() { let mut fake_input_output = get_fake_os_input(&fake_win_size); fake_input_output.add_terminal_input(&[ + COMMAND_TOGGLE, + COMMAND_TOGGLE, SPLIT_VERTICALLY, SPLIT_HORIZONTALLY, MOVE_FOCUS, @@ -339,6 +364,8 @@ pub fn resize_up_with_panes_above_aligned_left_and_right_with_current_pane() { let mut fake_input_output = get_fake_os_input(&fake_win_size); fake_input_output.add_terminal_input(&[ + COMMAND_TOGGLE, + COMMAND_TOGGLE, SPLIT_VERTICALLY, SPLIT_VERTICALLY, SPLIT_HORIZONTALLY, @@ -383,6 +410,8 @@ pub fn resize_up_with_panes_below_aligned_left_and_right_with_current_pane() { let mut fake_input_output = get_fake_os_input(&fake_win_size); fake_input_output.add_terminal_input(&[ + COMMAND_TOGGLE, + COMMAND_TOGGLE, SPLIT_VERTICALLY, SPLIT_VERTICALLY, SPLIT_HORIZONTALLY, @@ -429,6 +458,8 @@ pub fn resize_up_with_panes_above_aligned_left_and_right_with_panes_to_the_left_ let mut fake_input_output = get_fake_os_input(&fake_win_size); fake_input_output.add_terminal_input(&[ + COMMAND_TOGGLE, + COMMAND_TOGGLE, SPLIT_VERTICALLY, SPLIT_VERTICALLY, MOVE_FOCUS, @@ -490,6 +521,8 @@ pub fn resize_up_with_panes_below_aligned_left_and_right_with_to_the_left_and_ri let mut fake_input_output = get_fake_os_input(&fake_win_size); fake_input_output.add_terminal_input(&[ + COMMAND_TOGGLE, + COMMAND_TOGGLE, SPLIT_VERTICALLY, SPLIT_VERTICALLY, MOVE_FOCUS, diff --git a/src/tests/integration/toggle_fullscreen.rs b/src/tests/integration/toggle_fullscreen.rs index d7fdc998..9a1261b6 100644 --- a/src/tests/integration/toggle_fullscreen.rs +++ b/src/tests/integration/toggle_fullscreen.rs @@ -6,7 +6,7 @@ use crate::tests::utils::get_output_frame_snapshots; use crate::{start, Opt}; use crate::tests::utils::commands::{ - CLOSE_FOCUSED_PANE, MOVE_FOCUS, QUIT, SPLIT_HORIZONTALLY, SPLIT_VERTICALLY, + CLOSE_FOCUSED_PANE, COMMAND_TOGGLE, MOVE_FOCUS, QUIT, SPLIT_HORIZONTALLY, SPLIT_VERTICALLY, TOGGLE_ACTIVE_TERMINAL_FULLSCREEN, }; @@ -24,6 +24,8 @@ pub fn adding_new_terminal_in_fullscreen() { }; let mut fake_input_output = get_fake_os_input(&fake_win_size); fake_input_output.add_terminal_input(&[ + COMMAND_TOGGLE, + COMMAND_TOGGLE, SPLIT_VERTICALLY, TOGGLE_ACTIVE_TERMINAL_FULLSCREEN, SPLIT_HORIZONTALLY, @@ -53,6 +55,8 @@ pub fn move_focus_is_disabled_in_fullscreen() { }; let mut fake_input_output = get_fake_os_input(&fake_win_size); fake_input_output.add_terminal_input(&[ + COMMAND_TOGGLE, + COMMAND_TOGGLE, SPLIT_VERTICALLY, TOGGLE_ACTIVE_TERMINAL_FULLSCREEN, MOVE_FOCUS, diff --git a/src/tests/utils.rs b/src/tests/utils.rs index 4b399760..25750a90 100644 --- a/src/tests/utils.rs +++ b/src/tests/utils.rs @@ -39,18 +39,32 @@ pub fn get_output_frame_snapshots( } pub mod commands { - pub const SPLIT_HORIZONTALLY: [u8; 10] = [2, 0, 0, 0, 0, 0, 0, 0, 0, 0]; // ctrl-b - pub const SPLIT_VERTICALLY: [u8; 10] = [14, 0, 0, 0, 0, 0, 0, 0, 0, 0]; // ctrl-n - pub const RESIZE_DOWN: [u8; 10] = [10, 0, 0, 0, 0, 0, 0, 0, 0, 0]; // ctrl-j - pub const RESIZE_UP: [u8; 10] = [11, 0, 0, 0, 0, 0, 0, 0, 0, 0]; // ctrl-k - pub const MOVE_FOCUS: [u8; 10] = [16, 0, 0, 0, 0, 0, 0, 0, 0, 0]; // ctrl-p - pub const RESIZE_LEFT: [u8; 10] = [8, 0, 0, 0, 0, 0, 0, 0, 0, 0]; // ctrl-h - pub const RESIZE_RIGHT: [u8; 10] = [12, 0, 0, 0, 0, 0, 0, 0, 0, 0]; // ctrl-l - pub const SPAWN_TERMINAL: [u8; 10] = [26, 0, 0, 0, 0, 0, 0, 0, 0, 0]; // ctrl-z - pub const QUIT: [u8; 10] = [17, 0, 0, 0, 0, 0, 0, 0, 0, 0]; // ctrl-q - pub const SCROLL_UP: [u8; 10] = [27, 91, 53, 94, 0, 0, 0, 0, 0, 0]; // ctrl-PgUp - pub const SCROLL_DOWN: [u8; 10] = [27, 91, 54, 94, 0, 0, 0, 0, 0, 0]; // ctrl-PgDown - pub const CLOSE_FOCUSED_PANE: [u8; 10] = [24, 0, 0, 0, 0, 0, 0, 0, 0, 0]; // ctrl-x - pub const TOGGLE_ACTIVE_TERMINAL_FULLSCREEN: [u8; 10] = [5, 0, 0, 0, 0, 0, 0, 0, 0, 0]; - // ctrl-e + /// ctrl-g + pub const COMMAND_TOGGLE: [u8; 10] = [7, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + /// b + pub const SPLIT_HORIZONTALLY: [u8; 10] = [98, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + /// n + pub const SPLIT_VERTICALLY: [u8; 10] = [110, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + /// j + pub const RESIZE_DOWN: [u8; 10] = [106, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + /// k + pub const RESIZE_UP: [u8; 10] = [107, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + /// p + pub const MOVE_FOCUS: [u8; 10] = [112, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + /// h + pub const RESIZE_LEFT: [u8; 10] = [104, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + /// l + pub const RESIZE_RIGHT: [u8; 10] = [108, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + /// z + pub const SPAWN_TERMINAL: [u8; 10] = [122, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + /// q + pub const QUIT: [u8; 10] = [113, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + /// PgUp + pub const SCROLL_UP: [u8; 10] = [27, 91, 53, 126, 0, 0, 0, 0, 0, 0]; + /// PgDn + pub const SCROLL_DOWN: [u8; 10] = [27, 91, 54, 126, 0, 0, 0, 0, 0, 0]; + /// x + pub const CLOSE_FOCUSED_PANE: [u8; 10] = [120, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + /// e + pub const TOGGLE_ACTIVE_TERMINAL_FULLSCREEN: [u8; 10] = [101, 0, 0, 0, 0, 0, 0, 0, 0, 0]; }