From f01887463f0231a1ff4519aa9c1461d07b1f407b Mon Sep 17 00:00:00 2001 From: Kyle Sutherland-Cash Date: Sat, 1 May 2021 08:26:31 -0700 Subject: [PATCH 1/8] Define shared bus type --- src/common/mod.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/common/mod.rs b/src/common/mod.rs index ef518053..ba506e8b 100644 --- a/src/common/mod.rs +++ b/src/common/mod.rs @@ -118,6 +118,7 @@ pub enum AppInstruction { Error(String), } +pub struct Bus { /// Start Zellij with the specified [`OsApi`] and command-line arguments. // FIXME this should definitely be modularized and split into different functions. pub fn start(mut os_input: Box, opts: CliArgs) { From ae6192d698fb4ddbd8514eb4fff26543034d13de Mon Sep 17 00:00:00 2001 From: Kyle Sutherland-Cash Date: Sat, 1 May 2021 08:26:57 -0700 Subject: [PATCH 2/8] Use Bus type for screen thread --- src/common/mod.rs | 47 ++++++++++++++++++++++++++++++-------- src/common/screen.rs | 54 ++++++++++++++++---------------------------- 2 files changed, 58 insertions(+), 43 deletions(-) diff --git a/src/common/mod.rs b/src/common/mod.rs index ba506e8b..2b8adf4e 100644 --- a/src/common/mod.rs +++ b/src/common/mod.rs @@ -119,6 +119,34 @@ pub enum AppInstruction { } pub struct Bus { + receiver: mpsc::Receiver<(T, ErrorContext)>, + to_screen: Option>, + to_pty: Option>, + to_plugin: Option>, + to_app: Option>, + os_input: Option>, +} + +impl Bus { + fn new( + receiver: mpsc::Receiver<(T, ErrorContext)>, + to_screen: Option<&SenderWithContext>, + to_pty: Option<&SenderWithContext>, + to_plugin: Option<&SenderWithContext>, + to_app: Option<&SenderWithContext>, + os_input: Option<&Box>, + ) -> Self { + Bus { + receiver, + to_screen: to_screen.cloned(), + to_pty: to_pty.cloned(), + to_plugin: to_plugin.cloned(), + to_app: to_app.cloned(), + os_input: os_input.cloned(), + } + } +} + /// Start Zellij with the specified [`OsApi`] and command-line arguments. // FIXME this should definitely be modularized and split into different functions. pub fn start(mut os_input: Box, opts: CliArgs) { @@ -263,25 +291,26 @@ pub fn start(mut os_input: Box, opts: CliArgs) { .name("screen".to_string()) .spawn({ let mut command_is_executing = command_is_executing.clone(); - let os_input = os_input.clone(); - let send_pty_instructions = send_pty_instructions.clone(); - let send_plugin_instructions = send_plugin_instructions.clone(); - let send_app_instructions = send_app_instructions.clone(); + let screen_bus = Bus::new( + receive_screen_instructions, + None, + Some(&send_pty_instructions), + Some(&send_plugin_instructions), + Some(&send_app_instructions), + Some(&os_input), + ); let max_panes = opts.max_panes; move || { let mut screen = Screen::new( - receive_screen_instructions, - send_pty_instructions, - send_plugin_instructions, - send_app_instructions, + screen_bus, &full_screen_ws, - os_input, max_panes, ModeInfo::default(), ); loop { let (event, mut err_ctx) = screen + .bus .receiver .recv() .expect("failed to receive event on channel"); diff --git a/src/common/screen.rs b/src/common/screen.rs index eee1166f..513368c7 100644 --- a/src/common/screen.rs +++ b/src/common/screen.rs @@ -6,6 +6,7 @@ use std::str; use std::sync::mpsc::Receiver; use super::{AppInstruction, SenderWithContext}; +use crate::common::Bus; use crate::os_input_output::OsApi; use crate::panes::PositionAndSize; use crate::pty_bus::{PtyInstruction, VteBytes}; @@ -62,51 +63,33 @@ pub enum ScreenInstruction { /// A [`Screen`] holds multiple [`Tab`]s, each one holding multiple [`panes`](crate::client::panes). /// It only directly controls which tab is active, delegating the rest to the individual `Tab`. pub struct Screen { - /// A [`ScreenInstruction`] and [`ErrorContext`] receiver. - pub receiver: Receiver<(ScreenInstruction, ErrorContext)>, + /// A Bus for sending and receiving messages with the other threads. + pub bus: Bus, /// An optional maximal amount of panes allowed per [`Tab`] in this [`Screen`] instance. max_panes: Option, /// A map between this [`Screen`]'s tabs and their ID/key. tabs: BTreeMap, - /// A [`PtyInstruction`] and [`ErrorContext`] sender. - pub send_pty_instructions: SenderWithContext, - /// A [`PluginInstruction`] and [`ErrorContext`] sender. - pub send_plugin_instructions: SenderWithContext, - /// An [`AppInstruction`] and [`ErrorContext`] sender. - pub send_app_instructions: SenderWithContext, /// The full size of this [`Screen`]. full_screen_ws: PositionAndSize, /// The index of this [`Screen`]'s active [`Tab`]. active_tab_index: Option, - /// The [`OsApi`] this [`Screen`] uses. - os_api: Box, mode_info: ModeInfo, } impl Screen { - // FIXME: This lint needs actual fixing! Maybe by bundling the Senders /// Creates and returns a new [`Screen`]. - #[allow(clippy::too_many_arguments)] pub fn new( - receive_screen_instructions: Receiver<(ScreenInstruction, ErrorContext)>, - send_pty_instructions: SenderWithContext, - send_plugin_instructions: SenderWithContext, - send_app_instructions: SenderWithContext, + bus: Bus, full_screen_ws: &PositionAndSize, - os_api: Box, max_panes: Option, mode_info: ModeInfo, ) -> Self { Screen { - receiver: receive_screen_instructions, + bus, max_panes, - send_pty_instructions, - send_plugin_instructions, - send_app_instructions, full_screen_ws: *full_screen_ws, active_tab_index: None, tabs: BTreeMap::new(), - os_api, mode_info, } } @@ -121,10 +104,10 @@ impl Screen { position, String::new(), &self.full_screen_ws, - self.os_api.clone(), - self.send_pty_instructions.clone(), - self.send_plugin_instructions.clone(), - self.send_app_instructions.clone(), + self.bus.os_input.as_ref().unwrap().clone(), + self.bus.to_pty.as_ref().unwrap().clone(), + self.bus.to_plugin.as_ref().unwrap().clone(), + self.bus.to_app.as_ref().unwrap().clone(), self.max_panes, Some(PaneId::Terminal(pane_id)), self.mode_info.clone(), @@ -207,11 +190,14 @@ impl Screen { // because this might be happening when the app is closing, at which point the pty thread // has already closed and this would result in an error let _ = self - .send_pty_instructions + .bus + .to_pty + .as_ref() + .unwrap() .send(PtyInstruction::CloseTab(pane_ids)); if self.tabs.is_empty() { self.active_tab_index = None; - self.send_app_instructions + self.bus.to_app.as_ref().unwrap() .send(AppInstruction::Exit) .unwrap(); } else { @@ -225,7 +211,7 @@ impl Screen { } pub fn resize_to_screen(&mut self) { - let new_screen_size = self.os_api.get_terminal_size_using_fd(0); + let new_screen_size = self.bus.os_input.as_ref().unwrap().get_terminal_size_using_fd(0); self.full_screen_ws = new_screen_size; for (_, tab) in self.tabs.iter_mut() { tab.resize_whole_tab(new_screen_size); @@ -276,10 +262,10 @@ impl Screen { position, String::new(), &self.full_screen_ws, - self.os_api.clone(), - self.send_pty_instructions.clone(), - self.send_plugin_instructions.clone(), - self.send_app_instructions.clone(), + self.bus.os_input.as_ref().unwrap().clone(), + self.bus.to_pty.as_ref().unwrap().clone(), + self.bus.to_plugin.as_ref().unwrap().clone(), + self.bus.to_app.as_ref().unwrap().clone(), self.max_panes, None, self.mode_info.clone(), @@ -301,7 +287,7 @@ impl Screen { is_sync_panes_active: tab.is_sync_panes_active(), }); } - self.send_plugin_instructions + self.bus.to_plugin.as_ref().unwrap() .send(PluginInstruction::Update(None, Event::TabUpdate(tab_data))) .unwrap(); } From bb2369dcb84fe8d66e40d7cc670bafea3173bca1 Mon Sep 17 00:00:00 2001 From: Kyle Sutherland-Cash Date: Sat, 1 May 2021 08:48:58 -0700 Subject: [PATCH 3/8] Use Bus type for PTY thread (incomplete) --- src/client/panes/plugin_pane.rs | 2 +- src/client/panes/terminal_pane.rs | 2 +- src/client/tab.rs | 2 +- src/common/errors.rs | 2 +- src/common/input/handler.rs | 2 +- src/common/mod.rs | 68 ++++++++++++++++++------------- src/common/{pty_bus.rs => pty.rs} | 58 +++++++++++++------------- src/common/screen.rs | 8 ++-- src/common/utils/bus.rs | 0 src/common/wasm_vm.rs | 2 +- src/main.rs | 2 +- 11 files changed, 79 insertions(+), 69 deletions(-) rename src/common/{pty_bus.rs => pty.rs} (84%) create mode 100644 src/common/utils/bus.rs diff --git a/src/client/panes/plugin_pane.rs b/src/client/panes/plugin_pane.rs index c3b633ec..05871275 100644 --- a/src/client/panes/plugin_pane.rs +++ b/src/client/panes/plugin_pane.rs @@ -1,4 +1,4 @@ -use crate::{common::SenderWithContext, pty_bus::VteBytes, tab::Pane, wasm_vm::PluginInstruction}; +use crate::{common::SenderWithContext, common::pty::VteBytes, tab::Pane, wasm_vm::PluginInstruction}; use crate::panes::{PaneId, PositionAndSize}; diff --git a/src/client/panes/terminal_pane.rs b/src/client/panes/terminal_pane.rs index a5a957e6..6d03c910 100644 --- a/src/client/panes/terminal_pane.rs +++ b/src/client/panes/terminal_pane.rs @@ -8,7 +8,7 @@ use crate::panes::grid::Grid; use crate::panes::terminal_character::{ CharacterStyles, TerminalCharacter, EMPTY_TERMINAL_CHARACTER, }; -use crate::pty_bus::VteBytes; +use crate::common::pty::VteBytes; #[derive(PartialEq, Eq, Ord, PartialOrd, Hash, Clone, Copy, Debug)] pub enum PaneId { diff --git a/src/client/tab.rs b/src/client/tab.rs index f9bf7b57..50921991 100644 --- a/src/client/tab.rs +++ b/src/client/tab.rs @@ -7,7 +7,7 @@ use crate::common::{input::handler::parse_keys, AppInstruction, SenderWithContex use crate::layout::Layout; use crate::os_input_output::OsApi; use crate::panes::{PaneId, PositionAndSize, TerminalPane}; -use crate::pty_bus::{PtyInstruction, VteBytes}; +use crate::common::pty::{PtyInstruction, VteBytes}; use crate::utils::shared::adjust_to_size; use crate::wasm_vm::PluginInstruction; use crate::{boundaries::Boundaries, panes::PluginPane}; diff --git a/src/common/errors.rs b/src/common/errors.rs index c1c6753f..ab7c57ae 100644 --- a/src/common/errors.rs +++ b/src/common/errors.rs @@ -2,7 +2,7 @@ //! the instructions that are sent between threads. use super::{AppInstruction, ASYNCOPENCALLS, OPENCALLS}; -use crate::pty_bus::PtyInstruction; +use crate::common::pty::PtyInstruction; use crate::screen::ScreenInstruction; use std::fmt::{Display, Error, Formatter}; diff --git a/src/common/input/handler.rs b/src/common/input/handler.rs index 62118722..472a0520 100644 --- a/src/common/input/handler.rs +++ b/src/common/input/handler.rs @@ -6,7 +6,7 @@ use crate::common::input::config::Config; use crate::common::{AppInstruction, SenderWithContext, OPENCALLS}; use crate::errors::ContextType; use crate::os_input_output::OsApi; -use crate::pty_bus::PtyInstruction; +use crate::common::pty::PtyInstruction; use crate::screen::ScreenInstruction; use crate::wasm_vm::PluginInstruction; use crate::CommandIsExecuting; diff --git a/src/common/mod.rs b/src/common/mod.rs index 2b8adf4e..3ae1f570 100644 --- a/src/common/mod.rs +++ b/src/common/mod.rs @@ -4,7 +4,7 @@ pub mod input; pub mod install; pub mod ipc; pub mod os_input_output; -pub mod pty_bus; +pub mod pty; pub mod screen; pub mod utils; pub mod wasm_vm; @@ -36,7 +36,7 @@ use errors::{ use input::handler::input_loop; use install::populate_data_dir; use os_input_output::OsApi; -use pty_bus::{PtyBus, PtyInstruction}; +use pty::{Pty, PtyInstruction}; use screen::{Screen, ScreenInstruction}; use serde::{Deserialize, Serialize}; use utils::consts::ZELLIJ_IPC_PIPE; @@ -193,11 +193,16 @@ pub fn start(mut os_input: Box, opts: CliArgs) { let send_app_instructions = SenderWithContext::new(SenderType::SyncSender(send_app_instructions)); - let mut pty_bus = PtyBus::new( + let pty_bus = Bus::new( receive_pty_instructions, - send_screen_instructions.clone(), - send_plugin_instructions.clone(), - os_input.clone(), + Some(&send_screen_instructions), + None, + Some(&send_plugin_instructions), + None, + Some(&os_input), + ); + let mut pty = Pty::new( + pty_bus, opts.debug, ); @@ -233,50 +238,59 @@ pub fn start(mut os_input: Box, opts: CliArgs) { let mut command_is_executing = command_is_executing.clone(); send_pty_instructions.send(PtyInstruction::NewTab).unwrap(); move || loop { - let (event, mut err_ctx) = pty_bus - .receive_pty_instructions + let (event, mut err_ctx) = pty + .bus + .receiver .recv() .expect("failed to receive event on channel"); err_ctx.add_call(ContextType::Pty(PtyContext::from(&event))); match event { PtyInstruction::SpawnTerminal(file_to_open) => { - let pid = pty_bus.spawn_terminal(file_to_open); - pty_bus - .send_screen_instructions + let pid = pty.spawn_terminal(file_to_open); + pty.bus + .to_screen + .as_ref() + .unwrap() .send(ScreenInstruction::NewPane(PaneId::Terminal(pid))) .unwrap(); } PtyInstruction::SpawnTerminalVertically(file_to_open) => { - let pid = pty_bus.spawn_terminal(file_to_open); - pty_bus - .send_screen_instructions + let pid = pty.spawn_terminal(file_to_open); + pty.bus + .to_screen + .as_ref() + .unwrap() .send(ScreenInstruction::VerticalSplit(PaneId::Terminal(pid))) .unwrap(); } PtyInstruction::SpawnTerminalHorizontally(file_to_open) => { - let pid = pty_bus.spawn_terminal(file_to_open); - pty_bus - .send_screen_instructions + let pid = pty.spawn_terminal(file_to_open); + pty.bus + .to_screen + .as_ref() + .unwrap() .send(ScreenInstruction::HorizontalSplit(PaneId::Terminal(pid))) .unwrap(); } PtyInstruction::NewTab => { if let Some(layout) = maybe_layout.clone() { - pty_bus.spawn_terminals_for_layout(layout); + pty.spawn_terminals_for_layout(layout); } else { - let pid = pty_bus.spawn_terminal(None); - pty_bus - .send_screen_instructions + let pid = pty.spawn_terminal(None); + pty.bus + .to_screen + .as_ref() + .unwrap() .send(ScreenInstruction::NewTab(pid)) .unwrap(); } } PtyInstruction::ClosePane(id) => { - pty_bus.close_pane(id); + pty.close_pane(id); command_is_executing.done_closing_pane(); } PtyInstruction::CloseTab(ids) => { - pty_bus.close_tab(ids); + pty.close_tab(ids); command_is_executing.done_closing_pane(); } PtyInstruction::Quit => { @@ -302,12 +316,8 @@ pub fn start(mut os_input: Box, opts: CliArgs) { let max_panes = opts.max_panes; move || { - let mut screen = Screen::new( - screen_bus, - &full_screen_ws, - max_panes, - ModeInfo::default(), - ); + let mut screen = + Screen::new(screen_bus, &full_screen_ws, max_panes, ModeInfo::default()); loop { let (event, mut err_ctx) = screen .bus diff --git a/src/common/pty_bus.rs b/src/common/pty.rs similarity index 84% rename from src/common/pty_bus.rs rename to src/common/pty.rs index 2c132228..3a6798f1 100644 --- a/src/common/pty_bus.rs +++ b/src/common/pty.rs @@ -4,7 +4,6 @@ use ::async_std::task::*; use ::std::collections::HashMap; use ::std::os::unix::io::RawFd; use ::std::pin::*; -use ::std::sync::mpsc::Receiver; use ::std::time::{Duration, Instant}; use std::path::PathBuf; @@ -12,7 +11,8 @@ use super::{ScreenInstruction, SenderWithContext}; use crate::os_input_output::OsApi; use crate::utils::logging::debug_to_file; use crate::{ - errors::{get_current_ctx, ContextType, ErrorContext}, + common::Bus, + errors::{get_current_ctx, ContextType}, panes::PaneId, }; use crate::{layout::Layout, wasm_vm::PluginInstruction}; @@ -77,12 +77,9 @@ pub enum PtyInstruction { Quit, } -pub struct PtyBus { - pub send_screen_instructions: SenderWithContext, - pub send_plugin_instructions: SenderWithContext, - pub receive_pty_instructions: Receiver<(PtyInstruction, ErrorContext)>, +pub struct Pty { + pub bus: Bus, pub id_to_child_pid: HashMap, - os_input: Box, debug_to_file: bool, task_handles: HashMap>, } @@ -156,31 +153,29 @@ fn stream_terminal_bytes( }) } -impl PtyBus { +impl Pty { pub fn new( - receive_pty_instructions: Receiver<(PtyInstruction, ErrorContext)>, - send_screen_instructions: SenderWithContext, - send_plugin_instructions: SenderWithContext, - os_input: Box, + bus: Bus, debug_to_file: bool, ) -> Self { - PtyBus { - send_screen_instructions, - send_plugin_instructions, - receive_pty_instructions, - os_input, + Pty { + bus, id_to_child_pid: HashMap::new(), debug_to_file, task_handles: HashMap::new(), } } pub fn spawn_terminal(&mut self, file_to_open: Option) -> RawFd { - let (pid_primary, pid_secondary): (RawFd, RawFd) = - self.os_input.spawn_terminal(file_to_open); + let (pid_primary, pid_secondary): (RawFd, RawFd) = self + .bus + .os_input + .as_mut() + .unwrap() + .spawn_terminal(file_to_open); let task_handle = stream_terminal_bytes( pid_primary, - self.send_screen_instructions.clone(), - self.os_input.clone(), + self.bus.to_screen.as_ref().unwrap().clone(), + self.bus.os_input.as_ref().unwrap().clone(), self.debug_to_file, ); self.task_handles.insert(pid_primary, task_handle); @@ -191,11 +186,15 @@ impl PtyBus { let total_panes = layout.total_terminal_panes(); let mut new_pane_pids = vec![]; for _ in 0..total_panes { - let (pid_primary, pid_secondary): (RawFd, RawFd) = self.os_input.spawn_terminal(None); + let (pid_primary, pid_secondary): (RawFd, RawFd) = + self.bus.os_input.as_mut().unwrap().spawn_terminal(None); self.id_to_child_pid.insert(pid_primary, pid_secondary); new_pane_pids.push(pid_primary); } - self.send_screen_instructions + self.bus + .to_screen + .as_ref() + .unwrap() .send(ScreenInstruction::ApplyLayout(( layout, new_pane_pids.clone(), @@ -204,8 +203,8 @@ impl PtyBus { for id in new_pane_pids { let task_handle = stream_terminal_bytes( id, - self.send_screen_instructions.clone(), - self.os_input.clone(), + self.bus.to_screen.as_ref().unwrap().clone(), + self.bus.os_input.as_ref().unwrap().clone(), self.debug_to_file, ); self.task_handles.insert(id, task_handle); @@ -216,13 +215,16 @@ impl PtyBus { PaneId::Terminal(id) => { let child_pid = self.id_to_child_pid.remove(&id).unwrap(); let handle = self.task_handles.remove(&id).unwrap(); - self.os_input.kill(child_pid).unwrap(); + self.bus.os_input.as_mut().unwrap().kill(child_pid).unwrap(); task::block_on(async { handle.cancel().await; }); } PaneId::Plugin(pid) => drop( - self.send_plugin_instructions + self.bus + .to_plugin + .as_ref() + .unwrap() .send(PluginInstruction::Unload(pid)), ), } @@ -234,7 +236,7 @@ impl PtyBus { } } -impl Drop for PtyBus { +impl Drop for Pty { fn drop(&mut self) { let child_ids: Vec = self.id_to_child_pid.keys().copied().collect(); for id in child_ids { diff --git a/src/common/screen.rs b/src/common/screen.rs index 513368c7..d5df24b0 100644 --- a/src/common/screen.rs +++ b/src/common/screen.rs @@ -3,15 +3,13 @@ use std::collections::BTreeMap; use std::os::unix::io::RawFd; use std::str; -use std::sync::mpsc::Receiver; -use super::{AppInstruction, SenderWithContext}; +use super::AppInstruction; use crate::common::Bus; -use crate::os_input_output::OsApi; use crate::panes::PositionAndSize; -use crate::pty_bus::{PtyInstruction, VteBytes}; +use crate::common::pty::{PtyInstruction, VteBytes}; use crate::tab::Tab; -use crate::{errors::ErrorContext, wasm_vm::PluginInstruction}; +use crate::wasm_vm::PluginInstruction; use crate::{layout::Layout, panes::PaneId}; use zellij_tile::data::{Event, ModeInfo, TabInfo}; diff --git a/src/common/utils/bus.rs b/src/common/utils/bus.rs new file mode 100644 index 00000000..e69de29b diff --git a/src/common/wasm_vm.rs b/src/common/wasm_vm.rs index bd98a85b..f04d4d5f 100644 --- a/src/common/wasm_vm.rs +++ b/src/common/wasm_vm.rs @@ -12,7 +12,7 @@ use wasmer_wasi::WasiEnv; use zellij_tile::data::{Event, EventType, PluginIds}; use super::{ - pty_bus::PtyInstruction, screen::ScreenInstruction, AppInstruction, PaneId, SenderWithContext, + pty::PtyInstruction, screen::ScreenInstruction, AppInstruction, PaneId, SenderWithContext, }; #[derive(Clone, Debug)] diff --git a/src/main.rs b/src/main.rs index 12269ae9..fbe76a84 100644 --- a/src/main.rs +++ b/src/main.rs @@ -14,7 +14,7 @@ use crate::utils::{ }; use client::{boundaries, layout, panes, tab}; use common::{ - command_is_executing, errors, install, os_input_output, pty_bus, screen, start, utils, wasm_vm, + command_is_executing, errors, install, os_input_output, screen, start, utils, wasm_vm, ApiCommand, }; use std::io::Write; From e7d8aefa795c63ccec847518fb0f2963683e28d5 Mon Sep 17 00:00:00 2001 From: Kyle Sutherland-Cash Date: Sat, 1 May 2021 09:11:22 -0700 Subject: [PATCH 4/8] Simplify some names and start using Bus in the plugin thread --- src/common/mod.rs | 159 +++++++++++++++++++++++++--------------------- 1 file changed, 86 insertions(+), 73 deletions(-) diff --git a/src/common/mod.rs b/src/common/mod.rs index 3ae1f570..a05b1280 100644 --- a/src/common/mod.rs +++ b/src/common/mod.rs @@ -119,7 +119,7 @@ pub enum AppInstruction { } pub struct Bus { - receiver: mpsc::Receiver<(T, ErrorContext)>, + receiver: Option>, to_screen: Option>, to_pty: Option>, to_plugin: Option>, @@ -129,7 +129,7 @@ pub struct Bus { impl Bus { fn new( - receiver: mpsc::Receiver<(T, ErrorContext)>, + receiver: Option>, to_screen: Option<&SenderWithContext>, to_pty: Option<&SenderWithContext>, to_plugin: Option<&SenderWithContext>, @@ -172,39 +172,17 @@ pub fn start(mut os_input: Box, opts: CliArgs) { let full_screen_ws = os_input.get_terminal_size_using_fd(0); os_input.set_raw_mode(0); - let (send_screen_instructions, receive_screen_instructions): ChannelWithContext< - ScreenInstruction, - > = mpsc::channel(); - let send_screen_instructions = - SenderWithContext::new(SenderType::Sender(send_screen_instructions)); + let (to_screen, from_screen): ChannelWithContext = mpsc::channel(); + let to_screen = SenderWithContext::new(SenderType::Sender(to_screen)); - let (send_pty_instructions, receive_pty_instructions): ChannelWithContext = - mpsc::channel(); - let send_pty_instructions = SenderWithContext::new(SenderType::Sender(send_pty_instructions)); + let (to_pty, from_pty): ChannelWithContext = mpsc::channel(); + let to_pty = SenderWithContext::new(SenderType::Sender(to_pty)); - let (send_plugin_instructions, receive_plugin_instructions): ChannelWithContext< - PluginInstruction, - > = mpsc::channel(); - let send_plugin_instructions = - SenderWithContext::new(SenderType::Sender(send_plugin_instructions)); + let (to_plugin, from_plugin): ChannelWithContext = mpsc::channel(); + let to_plugin = SenderWithContext::new(SenderType::Sender(to_plugin)); - let (send_app_instructions, receive_app_instructions): SyncChannelWithContext = - mpsc::sync_channel(0); - let send_app_instructions = - SenderWithContext::new(SenderType::SyncSender(send_app_instructions)); - - let pty_bus = Bus::new( - receive_pty_instructions, - Some(&send_screen_instructions), - None, - Some(&send_plugin_instructions), - None, - Some(&os_input), - ); - let mut pty = Pty::new( - pty_bus, - opts.debug, - ); + let (to_app, from_app): SyncChannelWithContext = mpsc::sync_channel(0); + let to_app = SenderWithContext::new(SenderType::SyncSender(to_app)); // Determine and initialize the data directory let project_dirs = ProjectDirs::from("org", "Zellij Contributors", "Zellij").unwrap(); @@ -226,21 +204,35 @@ pub fn start(mut os_input: Box, opts: CliArgs) { #[cfg(not(test))] std::panic::set_hook({ use crate::errors::handle_panic; - let send_app_instructions = send_app_instructions.clone(); + let to_app = to_app.clone(); Box::new(move |info| { - handle_panic(info, &send_app_instructions); + handle_panic(info, &to_app); }) }); let pty_thread = thread::Builder::new() .name("pty".to_string()) .spawn({ + let mut pty = Pty::new( + Bus::new( + Some(from_pty), + Some(&to_screen), + None, + Some(&to_plugin), + None, + Some(&os_input), + ), + opts.debug, + ); + let mut command_is_executing = command_is_executing.clone(); - send_pty_instructions.send(PtyInstruction::NewTab).unwrap(); + to_pty.send(PtyInstruction::NewTab).unwrap(); move || loop { let (event, mut err_ctx) = pty .bus .receiver + .as_ref() + .unwrap() .recv() .expect("failed to receive event on channel"); err_ctx.add_call(ContextType::Pty(PtyContext::from(&event))); @@ -306,11 +298,11 @@ pub fn start(mut os_input: Box, opts: CliArgs) { .spawn({ let mut command_is_executing = command_is_executing.clone(); let screen_bus = Bus::new( - receive_screen_instructions, + Some(from_screen), None, - Some(&send_pty_instructions), - Some(&send_plugin_instructions), - Some(&send_app_instructions), + Some(&to_pty), + Some(&to_plugin), + Some(&to_app), Some(&os_input), ); let max_panes = opts.max_panes; @@ -322,6 +314,8 @@ pub fn start(mut os_input: Box, opts: CliArgs) { let (event, mut err_ctx) = screen .bus .receiver + .as_ref() + .unwrap() .recv() .expect("failed to receive event on channel"); err_ctx.add_call(ContextType::Screen(ScreenContext::from(&event))); @@ -504,16 +498,23 @@ pub fn start(mut os_input: Box, opts: CliArgs) { let wasm_thread = thread::Builder::new() .name("wasm".to_string()) .spawn({ - let send_pty_instructions = send_pty_instructions.clone(); - let send_screen_instructions = send_screen_instructions.clone(); - let send_app_instructions = send_app_instructions.clone(); - let send_plugin_instructions = send_plugin_instructions.clone(); + let plugin_bus = Bus::new( + Some(from_plugin), + Some(&to_screen), + Some(&to_pty), + Some(&to_plugin), + Some(&to_app), + None, + ); let store = Store::default(); let mut plugin_id = 0; let mut plugin_map = HashMap::new(); move || loop { - let (event, mut err_ctx) = receive_plugin_instructions + let (event, mut err_ctx) = plugin_bus + .receiver + .as_ref() + .unwrap() .recv() .expect("failed to receive event on channel"); err_ctx.add_call(ContextType::Plugin(PluginContext::from(&event))); @@ -549,10 +550,18 @@ pub fn start(mut os_input: Box, opts: CliArgs) { let plugin_env = PluginEnv { plugin_id, - send_pty_instructions: send_pty_instructions.clone(), - send_screen_instructions: send_screen_instructions.clone(), - send_app_instructions: send_app_instructions.clone(), - send_plugin_instructions: send_plugin_instructions.clone(), + send_pty_instructions: plugin_bus.to_pty.as_ref().unwrap().clone(), + send_screen_instructions: plugin_bus + .to_screen + .as_ref() + .unwrap() + .clone(), + send_app_instructions: plugin_bus.to_app.as_ref().unwrap().clone(), + send_plugin_instructions: plugin_bus + .to_plugin + .as_ref() + .unwrap() + .clone(), wasi_env, subscriptions: Arc::new(Mutex::new(HashSet::new())), }; @@ -580,7 +589,13 @@ pub fn start(mut os_input: Box, opts: CliArgs) { update.call(&[]).unwrap(); } } - drop(send_screen_instructions.send(ScreenInstruction::Render)); + drop( + plugin_bus + .to_screen + .as_ref() + .unwrap() + .send(ScreenInstruction::Render), + ); } PluginInstruction::Render(buf_tx, pid, rows, cols) => { let (instance, plugin_env) = plugin_map.get(&pid).unwrap(); @@ -604,10 +619,10 @@ pub fn start(mut os_input: Box, opts: CliArgs) { .name("signal_listener".to_string()) .spawn({ let os_input = os_input.clone(); - let send_screen_instructions = send_screen_instructions.clone(); + let to_screen = to_screen.clone(); move || { os_input.receive_sigwinch(Box::new(move || { - let _ = send_screen_instructions.send(ScreenInstruction::TerminalResize); + let _ = to_screen.send(ScreenInstruction::TerminalResize); })); } }) @@ -621,8 +636,8 @@ pub fn start(mut os_input: Box, opts: CliArgs) { .name("ipc_server".to_string()) .spawn({ use std::io::Read; - let send_pty_instructions = send_pty_instructions.clone(); - let send_screen_instructions = send_screen_instructions.clone(); + let to_pty = to_pty.clone(); + let to_screen = to_screen.clone(); move || { std::fs::remove_file(ZELLIJ_IPC_PIPE).ok(); let listener = std::os::unix::net::UnixListener::bind(ZELLIJ_IPC_PIPE) @@ -642,24 +657,22 @@ pub fn start(mut os_input: Box, opts: CliArgs) { match &decoded { ApiCommand::OpenFile(file_name) => { let path = PathBuf::from(file_name); - send_pty_instructions + to_pty .send(PtyInstruction::SpawnTerminal(Some(path))) .unwrap(); } ApiCommand::SplitHorizontally => { - send_pty_instructions + to_pty .send(PtyInstruction::SpawnTerminalHorizontally(None)) .unwrap(); } ApiCommand::SplitVertically => { - send_pty_instructions + to_pty .send(PtyInstruction::SpawnTerminalVertically(None)) .unwrap(); } ApiCommand::MoveFocus => { - send_screen_instructions - .send(ScreenInstruction::FocusNextPane) - .unwrap(); + to_screen.send(ScreenInstruction::FocusNextPane).unwrap(); } } } @@ -675,9 +688,9 @@ pub fn start(mut os_input: Box, opts: CliArgs) { 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_plugin_instructions = send_plugin_instructions.clone(); + let to_screen = to_screen.clone(); + let to_pty = to_pty.clone(); + let to_plugin = to_plugin.clone(); let os_input = os_input.clone(); let config = config; move || { @@ -685,17 +698,17 @@ pub fn start(mut os_input: Box, opts: CliArgs) { os_input, config, command_is_executing, - send_screen_instructions, - send_pty_instructions, - send_plugin_instructions, - send_app_instructions, + to_screen, + to_pty, + to_plugin, + to_app, ) } }); #[warn(clippy::never_loop)] loop { - let (app_instruction, mut err_ctx) = receive_app_instructions + let (app_instruction, mut err_ctx) = from_app .recv() .expect("failed to receive app instruction on channel"); @@ -705,11 +718,11 @@ pub fn start(mut os_input: Box, opts: CliArgs) { break; } AppInstruction::Error(backtrace) => { - let _ = send_screen_instructions.send(ScreenInstruction::Quit); + let _ = to_screen.send(ScreenInstruction::Quit); let _ = screen_thread.join(); - let _ = send_pty_instructions.send(PtyInstruction::Quit); + let _ = to_pty.send(PtyInstruction::Quit); let _ = pty_thread.join(); - let _ = send_plugin_instructions.send(PluginInstruction::Quit); + let _ = to_plugin.send(PluginInstruction::Quit); let _ = wasm_thread.join(); os_input.unset_raw_mode(0); let goto_start_of_last_line = format!("\u{1b}[{};{}H", full_screen_ws.rows, 1); @@ -727,11 +740,11 @@ pub fn start(mut os_input: Box, opts: CliArgs) { } } - let _ = send_pty_instructions.send(PtyInstruction::Quit); + let _ = to_pty.send(PtyInstruction::Quit); pty_thread.join().unwrap(); - let _ = send_screen_instructions.send(ScreenInstruction::Quit); + let _ = to_screen.send(ScreenInstruction::Quit); screen_thread.join().unwrap(); - let _ = send_plugin_instructions.send(PluginInstruction::Quit); + let _ = to_plugin.send(PluginInstruction::Quit); wasm_thread.join().unwrap(); // cleanup(); From 2eadcb86a5377381c41e7fa52395a1dbd75f5a84 Mon Sep 17 00:00:00 2001 From: Kyle Sutherland-Cash Date: Sat, 1 May 2021 09:22:21 -0700 Subject: [PATCH 5/8] Bit of renaming --- src/common/mod.rs | 16 ++++------------ src/common/wasm_vm.rs | 18 +++++++++--------- 2 files changed, 13 insertions(+), 21 deletions(-) diff --git a/src/common/mod.rs b/src/common/mod.rs index a05b1280..0990172d 100644 --- a/src/common/mod.rs +++ b/src/common/mod.rs @@ -550,18 +550,10 @@ pub fn start(mut os_input: Box, opts: CliArgs) { let plugin_env = PluginEnv { plugin_id, - send_pty_instructions: plugin_bus.to_pty.as_ref().unwrap().clone(), - send_screen_instructions: plugin_bus - .to_screen - .as_ref() - .unwrap() - .clone(), - send_app_instructions: plugin_bus.to_app.as_ref().unwrap().clone(), - send_plugin_instructions: plugin_bus - .to_plugin - .as_ref() - .unwrap() - .clone(), + to_pty: plugin_bus.to_pty.as_ref().unwrap().clone(), + to_screen: plugin_bus.to_screen.as_ref().unwrap().clone(), + to_app: plugin_bus.to_app.as_ref().unwrap().clone(), + to_plugin: plugin_bus.to_plugin.as_ref().unwrap().clone(), wasi_env, subscriptions: Arc::new(Mutex::new(HashSet::new())), }; diff --git a/src/common/wasm_vm.rs b/src/common/wasm_vm.rs index f04d4d5f..253f52f7 100644 --- a/src/common/wasm_vm.rs +++ b/src/common/wasm_vm.rs @@ -28,10 +28,10 @@ pub enum PluginInstruction { pub struct PluginEnv { pub plugin_id: u32, // FIXME: This should be a big bundle of all of the channels - pub send_screen_instructions: SenderWithContext, - pub send_app_instructions: SenderWithContext, - pub send_pty_instructions: SenderWithContext, - pub send_plugin_instructions: SenderWithContext, + pub to_screen: SenderWithContext, + pub to_app: SenderWithContext, + pub to_pty: SenderWithContext, + pub to_plugin: SenderWithContext, pub wasi_env: WasiEnv, pub subscriptions: Arc>>, } @@ -77,7 +77,7 @@ fn host_unsubscribe(plugin_env: &PluginEnv) { fn host_set_selectable(plugin_env: &PluginEnv, selectable: i32) { let selectable = selectable != 0; plugin_env - .send_screen_instructions + .to_screen .send(ScreenInstruction::SetSelectable( PaneId::Plugin(plugin_env.plugin_id), selectable, @@ -88,7 +88,7 @@ fn host_set_selectable(plugin_env: &PluginEnv, selectable: i32) { fn host_set_max_height(plugin_env: &PluginEnv, max_height: i32) { let max_height = max_height as usize; plugin_env - .send_screen_instructions + .to_screen .send(ScreenInstruction::SetMaxHeight( PaneId::Plugin(plugin_env.plugin_id), max_height, @@ -99,7 +99,7 @@ fn host_set_max_height(plugin_env: &PluginEnv, max_height: i32) { fn host_set_invisible_borders(plugin_env: &PluginEnv, invisible_borders: i32) { let invisible_borders = invisible_borders != 0; plugin_env - .send_screen_instructions + .to_screen .send(ScreenInstruction::SetInvisibleBorders( PaneId::Plugin(plugin_env.plugin_id), invisible_borders, @@ -118,7 +118,7 @@ fn host_get_plugin_ids(plugin_env: &PluginEnv) { fn host_open_file(plugin_env: &PluginEnv) { let path: PathBuf = wasi_read_object(&plugin_env.wasi_env); plugin_env - .send_pty_instructions + .to_pty .send(PtyInstruction::SpawnTerminal(Some(path))) .unwrap(); } @@ -133,7 +133,7 @@ fn host_set_timeout(plugin_env: &PluginEnv, secs: f64) { // timers as we'd like. // // But that's a lot of code, and this is a few lines: - let send_plugin_instructions = plugin_env.send_plugin_instructions.clone(); + let send_plugin_instructions = plugin_env.to_plugin.clone(); let update_target = Some(plugin_env.plugin_id); thread::spawn(move || { let start_time = Instant::now(); From 69d34c3e093f30df38f3eea30877e0292f3bd785 Mon Sep 17 00:00:00 2001 From: Kyle Sutherland-Cash Date: Sat, 1 May 2021 09:32:30 -0700 Subject: [PATCH 6/8] Don't commit to master like an idiot... :( --- src/client/panes/plugin_pane.rs | 2 +- src/client/panes/terminal_pane.rs | 2 +- src/client/tab.rs | 2 +- src/common/errors.rs | 2 +- src/common/input/handler.rs | 2 +- src/common/mod.rs | 235 ++++++++++++------------------ src/common/{pty.rs => pty_bus.rs} | 58 ++++---- src/common/screen.rs | 62 +++++--- src/common/utils/bus.rs | 0 src/common/wasm_vm.rs | 20 +-- src/main.rs | 2 +- 11 files changed, 178 insertions(+), 209 deletions(-) rename src/common/{pty.rs => pty_bus.rs} (84%) delete mode 100644 src/common/utils/bus.rs diff --git a/src/client/panes/plugin_pane.rs b/src/client/panes/plugin_pane.rs index 05871275..c3b633ec 100644 --- a/src/client/panes/plugin_pane.rs +++ b/src/client/panes/plugin_pane.rs @@ -1,4 +1,4 @@ -use crate::{common::SenderWithContext, common::pty::VteBytes, tab::Pane, wasm_vm::PluginInstruction}; +use crate::{common::SenderWithContext, pty_bus::VteBytes, tab::Pane, wasm_vm::PluginInstruction}; use crate::panes::{PaneId, PositionAndSize}; diff --git a/src/client/panes/terminal_pane.rs b/src/client/panes/terminal_pane.rs index 6d03c910..a5a957e6 100644 --- a/src/client/panes/terminal_pane.rs +++ b/src/client/panes/terminal_pane.rs @@ -8,7 +8,7 @@ use crate::panes::grid::Grid; use crate::panes::terminal_character::{ CharacterStyles, TerminalCharacter, EMPTY_TERMINAL_CHARACTER, }; -use crate::common::pty::VteBytes; +use crate::pty_bus::VteBytes; #[derive(PartialEq, Eq, Ord, PartialOrd, Hash, Clone, Copy, Debug)] pub enum PaneId { diff --git a/src/client/tab.rs b/src/client/tab.rs index 50921991..f9bf7b57 100644 --- a/src/client/tab.rs +++ b/src/client/tab.rs @@ -7,7 +7,7 @@ use crate::common::{input::handler::parse_keys, AppInstruction, SenderWithContex use crate::layout::Layout; use crate::os_input_output::OsApi; use crate::panes::{PaneId, PositionAndSize, TerminalPane}; -use crate::common::pty::{PtyInstruction, VteBytes}; +use crate::pty_bus::{PtyInstruction, VteBytes}; use crate::utils::shared::adjust_to_size; use crate::wasm_vm::PluginInstruction; use crate::{boundaries::Boundaries, panes::PluginPane}; diff --git a/src/common/errors.rs b/src/common/errors.rs index ab7c57ae..c1c6753f 100644 --- a/src/common/errors.rs +++ b/src/common/errors.rs @@ -2,7 +2,7 @@ //! the instructions that are sent between threads. use super::{AppInstruction, ASYNCOPENCALLS, OPENCALLS}; -use crate::common::pty::PtyInstruction; +use crate::pty_bus::PtyInstruction; use crate::screen::ScreenInstruction; use std::fmt::{Display, Error, Formatter}; diff --git a/src/common/input/handler.rs b/src/common/input/handler.rs index 472a0520..62118722 100644 --- a/src/common/input/handler.rs +++ b/src/common/input/handler.rs @@ -6,7 +6,7 @@ use crate::common::input::config::Config; use crate::common::{AppInstruction, SenderWithContext, OPENCALLS}; use crate::errors::ContextType; use crate::os_input_output::OsApi; -use crate::common::pty::PtyInstruction; +use crate::pty_bus::PtyInstruction; use crate::screen::ScreenInstruction; use crate::wasm_vm::PluginInstruction; use crate::CommandIsExecuting; diff --git a/src/common/mod.rs b/src/common/mod.rs index 0990172d..ef518053 100644 --- a/src/common/mod.rs +++ b/src/common/mod.rs @@ -4,7 +4,7 @@ pub mod input; pub mod install; pub mod ipc; pub mod os_input_output; -pub mod pty; +pub mod pty_bus; pub mod screen; pub mod utils; pub mod wasm_vm; @@ -36,7 +36,7 @@ use errors::{ use input::handler::input_loop; use install::populate_data_dir; use os_input_output::OsApi; -use pty::{Pty, PtyInstruction}; +use pty_bus::{PtyBus, PtyInstruction}; use screen::{Screen, ScreenInstruction}; use serde::{Deserialize, Serialize}; use utils::consts::ZELLIJ_IPC_PIPE; @@ -118,35 +118,6 @@ pub enum AppInstruction { Error(String), } -pub struct Bus { - receiver: Option>, - to_screen: Option>, - to_pty: Option>, - to_plugin: Option>, - to_app: Option>, - os_input: Option>, -} - -impl Bus { - fn new( - receiver: Option>, - to_screen: Option<&SenderWithContext>, - to_pty: Option<&SenderWithContext>, - to_plugin: Option<&SenderWithContext>, - to_app: Option<&SenderWithContext>, - os_input: Option<&Box>, - ) -> Self { - Bus { - receiver, - to_screen: to_screen.cloned(), - to_pty: to_pty.cloned(), - to_plugin: to_plugin.cloned(), - to_app: to_app.cloned(), - os_input: os_input.cloned(), - } - } -} - /// Start Zellij with the specified [`OsApi`] and command-line arguments. // FIXME this should definitely be modularized and split into different functions. pub fn start(mut os_input: Box, opts: CliArgs) { @@ -172,17 +143,34 @@ pub fn start(mut os_input: Box, opts: CliArgs) { let full_screen_ws = os_input.get_terminal_size_using_fd(0); os_input.set_raw_mode(0); - let (to_screen, from_screen): ChannelWithContext = mpsc::channel(); - let to_screen = SenderWithContext::new(SenderType::Sender(to_screen)); + let (send_screen_instructions, receive_screen_instructions): ChannelWithContext< + ScreenInstruction, + > = mpsc::channel(); + let send_screen_instructions = + SenderWithContext::new(SenderType::Sender(send_screen_instructions)); - let (to_pty, from_pty): ChannelWithContext = mpsc::channel(); - let to_pty = SenderWithContext::new(SenderType::Sender(to_pty)); + let (send_pty_instructions, receive_pty_instructions): ChannelWithContext = + mpsc::channel(); + let send_pty_instructions = SenderWithContext::new(SenderType::Sender(send_pty_instructions)); - let (to_plugin, from_plugin): ChannelWithContext = mpsc::channel(); - let to_plugin = SenderWithContext::new(SenderType::Sender(to_plugin)); + let (send_plugin_instructions, receive_plugin_instructions): ChannelWithContext< + PluginInstruction, + > = mpsc::channel(); + let send_plugin_instructions = + SenderWithContext::new(SenderType::Sender(send_plugin_instructions)); - let (to_app, from_app): SyncChannelWithContext = mpsc::sync_channel(0); - let to_app = SenderWithContext::new(SenderType::SyncSender(to_app)); + let (send_app_instructions, receive_app_instructions): SyncChannelWithContext = + mpsc::sync_channel(0); + let send_app_instructions = + SenderWithContext::new(SenderType::SyncSender(send_app_instructions)); + + let mut pty_bus = PtyBus::new( + receive_pty_instructions, + send_screen_instructions.clone(), + send_plugin_instructions.clone(), + os_input.clone(), + opts.debug, + ); // Determine and initialize the data directory let project_dirs = ProjectDirs::from("org", "Zellij Contributors", "Zellij").unwrap(); @@ -204,85 +192,62 @@ pub fn start(mut os_input: Box, opts: CliArgs) { #[cfg(not(test))] std::panic::set_hook({ use crate::errors::handle_panic; - let to_app = to_app.clone(); + let send_app_instructions = send_app_instructions.clone(); Box::new(move |info| { - handle_panic(info, &to_app); + handle_panic(info, &send_app_instructions); }) }); let pty_thread = thread::Builder::new() .name("pty".to_string()) .spawn({ - let mut pty = Pty::new( - Bus::new( - Some(from_pty), - Some(&to_screen), - None, - Some(&to_plugin), - None, - Some(&os_input), - ), - opts.debug, - ); - let mut command_is_executing = command_is_executing.clone(); - to_pty.send(PtyInstruction::NewTab).unwrap(); + send_pty_instructions.send(PtyInstruction::NewTab).unwrap(); move || loop { - let (event, mut err_ctx) = pty - .bus - .receiver - .as_ref() - .unwrap() + let (event, mut err_ctx) = pty_bus + .receive_pty_instructions .recv() .expect("failed to receive event on channel"); err_ctx.add_call(ContextType::Pty(PtyContext::from(&event))); match event { PtyInstruction::SpawnTerminal(file_to_open) => { - let pid = pty.spawn_terminal(file_to_open); - pty.bus - .to_screen - .as_ref() - .unwrap() + let pid = pty_bus.spawn_terminal(file_to_open); + pty_bus + .send_screen_instructions .send(ScreenInstruction::NewPane(PaneId::Terminal(pid))) .unwrap(); } PtyInstruction::SpawnTerminalVertically(file_to_open) => { - let pid = pty.spawn_terminal(file_to_open); - pty.bus - .to_screen - .as_ref() - .unwrap() + let pid = pty_bus.spawn_terminal(file_to_open); + pty_bus + .send_screen_instructions .send(ScreenInstruction::VerticalSplit(PaneId::Terminal(pid))) .unwrap(); } PtyInstruction::SpawnTerminalHorizontally(file_to_open) => { - let pid = pty.spawn_terminal(file_to_open); - pty.bus - .to_screen - .as_ref() - .unwrap() + let pid = pty_bus.spawn_terminal(file_to_open); + pty_bus + .send_screen_instructions .send(ScreenInstruction::HorizontalSplit(PaneId::Terminal(pid))) .unwrap(); } PtyInstruction::NewTab => { if let Some(layout) = maybe_layout.clone() { - pty.spawn_terminals_for_layout(layout); + pty_bus.spawn_terminals_for_layout(layout); } else { - let pid = pty.spawn_terminal(None); - pty.bus - .to_screen - .as_ref() - .unwrap() + let pid = pty_bus.spawn_terminal(None); + pty_bus + .send_screen_instructions .send(ScreenInstruction::NewTab(pid)) .unwrap(); } } PtyInstruction::ClosePane(id) => { - pty.close_pane(id); + pty_bus.close_pane(id); command_is_executing.done_closing_pane(); } PtyInstruction::CloseTab(ids) => { - pty.close_tab(ids); + pty_bus.close_tab(ids); command_is_executing.done_closing_pane(); } PtyInstruction::Quit => { @@ -297,25 +262,26 @@ pub fn start(mut os_input: Box, opts: CliArgs) { .name("screen".to_string()) .spawn({ let mut command_is_executing = command_is_executing.clone(); - let screen_bus = Bus::new( - Some(from_screen), - None, - Some(&to_pty), - Some(&to_plugin), - Some(&to_app), - Some(&os_input), - ); + let os_input = os_input.clone(); + let send_pty_instructions = send_pty_instructions.clone(); + let send_plugin_instructions = send_plugin_instructions.clone(); + let send_app_instructions = send_app_instructions.clone(); let max_panes = opts.max_panes; move || { - let mut screen = - Screen::new(screen_bus, &full_screen_ws, max_panes, ModeInfo::default()); + let mut screen = Screen::new( + receive_screen_instructions, + send_pty_instructions, + send_plugin_instructions, + send_app_instructions, + &full_screen_ws, + os_input, + max_panes, + ModeInfo::default(), + ); loop { let (event, mut err_ctx) = screen - .bus .receiver - .as_ref() - .unwrap() .recv() .expect("failed to receive event on channel"); err_ctx.add_call(ContextType::Screen(ScreenContext::from(&event))); @@ -498,23 +464,16 @@ pub fn start(mut os_input: Box, opts: CliArgs) { let wasm_thread = thread::Builder::new() .name("wasm".to_string()) .spawn({ - let plugin_bus = Bus::new( - Some(from_plugin), - Some(&to_screen), - Some(&to_pty), - Some(&to_plugin), - Some(&to_app), - None, - ); + let send_pty_instructions = send_pty_instructions.clone(); + let send_screen_instructions = send_screen_instructions.clone(); + let send_app_instructions = send_app_instructions.clone(); + let send_plugin_instructions = send_plugin_instructions.clone(); let store = Store::default(); let mut plugin_id = 0; let mut plugin_map = HashMap::new(); move || loop { - let (event, mut err_ctx) = plugin_bus - .receiver - .as_ref() - .unwrap() + let (event, mut err_ctx) = receive_plugin_instructions .recv() .expect("failed to receive event on channel"); err_ctx.add_call(ContextType::Plugin(PluginContext::from(&event))); @@ -550,10 +509,10 @@ pub fn start(mut os_input: Box, opts: CliArgs) { let plugin_env = PluginEnv { plugin_id, - to_pty: plugin_bus.to_pty.as_ref().unwrap().clone(), - to_screen: plugin_bus.to_screen.as_ref().unwrap().clone(), - to_app: plugin_bus.to_app.as_ref().unwrap().clone(), - to_plugin: plugin_bus.to_plugin.as_ref().unwrap().clone(), + send_pty_instructions: send_pty_instructions.clone(), + send_screen_instructions: send_screen_instructions.clone(), + send_app_instructions: send_app_instructions.clone(), + send_plugin_instructions: send_plugin_instructions.clone(), wasi_env, subscriptions: Arc::new(Mutex::new(HashSet::new())), }; @@ -581,13 +540,7 @@ pub fn start(mut os_input: Box, opts: CliArgs) { update.call(&[]).unwrap(); } } - drop( - plugin_bus - .to_screen - .as_ref() - .unwrap() - .send(ScreenInstruction::Render), - ); + drop(send_screen_instructions.send(ScreenInstruction::Render)); } PluginInstruction::Render(buf_tx, pid, rows, cols) => { let (instance, plugin_env) = plugin_map.get(&pid).unwrap(); @@ -611,10 +564,10 @@ pub fn start(mut os_input: Box, opts: CliArgs) { .name("signal_listener".to_string()) .spawn({ let os_input = os_input.clone(); - let to_screen = to_screen.clone(); + let send_screen_instructions = send_screen_instructions.clone(); move || { os_input.receive_sigwinch(Box::new(move || { - let _ = to_screen.send(ScreenInstruction::TerminalResize); + let _ = send_screen_instructions.send(ScreenInstruction::TerminalResize); })); } }) @@ -628,8 +581,8 @@ pub fn start(mut os_input: Box, opts: CliArgs) { .name("ipc_server".to_string()) .spawn({ use std::io::Read; - let to_pty = to_pty.clone(); - let to_screen = to_screen.clone(); + let send_pty_instructions = send_pty_instructions.clone(); + let send_screen_instructions = send_screen_instructions.clone(); move || { std::fs::remove_file(ZELLIJ_IPC_PIPE).ok(); let listener = std::os::unix::net::UnixListener::bind(ZELLIJ_IPC_PIPE) @@ -649,22 +602,24 @@ pub fn start(mut os_input: Box, opts: CliArgs) { match &decoded { ApiCommand::OpenFile(file_name) => { let path = PathBuf::from(file_name); - to_pty + send_pty_instructions .send(PtyInstruction::SpawnTerminal(Some(path))) .unwrap(); } ApiCommand::SplitHorizontally => { - to_pty + send_pty_instructions .send(PtyInstruction::SpawnTerminalHorizontally(None)) .unwrap(); } ApiCommand::SplitVertically => { - to_pty + send_pty_instructions .send(PtyInstruction::SpawnTerminalVertically(None)) .unwrap(); } ApiCommand::MoveFocus => { - to_screen.send(ScreenInstruction::FocusNextPane).unwrap(); + send_screen_instructions + .send(ScreenInstruction::FocusNextPane) + .unwrap(); } } } @@ -680,9 +635,9 @@ pub fn start(mut os_input: Box, opts: CliArgs) { let _stdin_thread = thread::Builder::new() .name("stdin_handler".to_string()) .spawn({ - let to_screen = to_screen.clone(); - let to_pty = to_pty.clone(); - let to_plugin = to_plugin.clone(); + let send_screen_instructions = send_screen_instructions.clone(); + let send_pty_instructions = send_pty_instructions.clone(); + let send_plugin_instructions = send_plugin_instructions.clone(); let os_input = os_input.clone(); let config = config; move || { @@ -690,17 +645,17 @@ pub fn start(mut os_input: Box, opts: CliArgs) { os_input, config, command_is_executing, - to_screen, - to_pty, - to_plugin, - to_app, + send_screen_instructions, + send_pty_instructions, + send_plugin_instructions, + send_app_instructions, ) } }); #[warn(clippy::never_loop)] loop { - let (app_instruction, mut err_ctx) = from_app + let (app_instruction, mut err_ctx) = receive_app_instructions .recv() .expect("failed to receive app instruction on channel"); @@ -710,11 +665,11 @@ pub fn start(mut os_input: Box, opts: CliArgs) { break; } AppInstruction::Error(backtrace) => { - let _ = to_screen.send(ScreenInstruction::Quit); + let _ = send_screen_instructions.send(ScreenInstruction::Quit); let _ = screen_thread.join(); - let _ = to_pty.send(PtyInstruction::Quit); + let _ = send_pty_instructions.send(PtyInstruction::Quit); let _ = pty_thread.join(); - let _ = to_plugin.send(PluginInstruction::Quit); + let _ = send_plugin_instructions.send(PluginInstruction::Quit); let _ = wasm_thread.join(); os_input.unset_raw_mode(0); let goto_start_of_last_line = format!("\u{1b}[{};{}H", full_screen_ws.rows, 1); @@ -732,11 +687,11 @@ pub fn start(mut os_input: Box, opts: CliArgs) { } } - let _ = to_pty.send(PtyInstruction::Quit); + let _ = send_pty_instructions.send(PtyInstruction::Quit); pty_thread.join().unwrap(); - let _ = to_screen.send(ScreenInstruction::Quit); + let _ = send_screen_instructions.send(ScreenInstruction::Quit); screen_thread.join().unwrap(); - let _ = to_plugin.send(PluginInstruction::Quit); + let _ = send_plugin_instructions.send(PluginInstruction::Quit); wasm_thread.join().unwrap(); // cleanup(); diff --git a/src/common/pty.rs b/src/common/pty_bus.rs similarity index 84% rename from src/common/pty.rs rename to src/common/pty_bus.rs index 3a6798f1..2c132228 100644 --- a/src/common/pty.rs +++ b/src/common/pty_bus.rs @@ -4,6 +4,7 @@ use ::async_std::task::*; use ::std::collections::HashMap; use ::std::os::unix::io::RawFd; use ::std::pin::*; +use ::std::sync::mpsc::Receiver; use ::std::time::{Duration, Instant}; use std::path::PathBuf; @@ -11,8 +12,7 @@ use super::{ScreenInstruction, SenderWithContext}; use crate::os_input_output::OsApi; use crate::utils::logging::debug_to_file; use crate::{ - common::Bus, - errors::{get_current_ctx, ContextType}, + errors::{get_current_ctx, ContextType, ErrorContext}, panes::PaneId, }; use crate::{layout::Layout, wasm_vm::PluginInstruction}; @@ -77,9 +77,12 @@ pub enum PtyInstruction { Quit, } -pub struct Pty { - pub bus: Bus, +pub struct PtyBus { + pub send_screen_instructions: SenderWithContext, + pub send_plugin_instructions: SenderWithContext, + pub receive_pty_instructions: Receiver<(PtyInstruction, ErrorContext)>, pub id_to_child_pid: HashMap, + os_input: Box, debug_to_file: bool, task_handles: HashMap>, } @@ -153,29 +156,31 @@ fn stream_terminal_bytes( }) } -impl Pty { +impl PtyBus { pub fn new( - bus: Bus, + receive_pty_instructions: Receiver<(PtyInstruction, ErrorContext)>, + send_screen_instructions: SenderWithContext, + send_plugin_instructions: SenderWithContext, + os_input: Box, debug_to_file: bool, ) -> Self { - Pty { - bus, + PtyBus { + send_screen_instructions, + send_plugin_instructions, + receive_pty_instructions, + os_input, id_to_child_pid: HashMap::new(), debug_to_file, task_handles: HashMap::new(), } } pub fn spawn_terminal(&mut self, file_to_open: Option) -> RawFd { - let (pid_primary, pid_secondary): (RawFd, RawFd) = self - .bus - .os_input - .as_mut() - .unwrap() - .spawn_terminal(file_to_open); + let (pid_primary, pid_secondary): (RawFd, RawFd) = + self.os_input.spawn_terminal(file_to_open); let task_handle = stream_terminal_bytes( pid_primary, - self.bus.to_screen.as_ref().unwrap().clone(), - self.bus.os_input.as_ref().unwrap().clone(), + self.send_screen_instructions.clone(), + self.os_input.clone(), self.debug_to_file, ); self.task_handles.insert(pid_primary, task_handle); @@ -186,15 +191,11 @@ impl Pty { let total_panes = layout.total_terminal_panes(); let mut new_pane_pids = vec![]; for _ in 0..total_panes { - let (pid_primary, pid_secondary): (RawFd, RawFd) = - self.bus.os_input.as_mut().unwrap().spawn_terminal(None); + let (pid_primary, pid_secondary): (RawFd, RawFd) = self.os_input.spawn_terminal(None); self.id_to_child_pid.insert(pid_primary, pid_secondary); new_pane_pids.push(pid_primary); } - self.bus - .to_screen - .as_ref() - .unwrap() + self.send_screen_instructions .send(ScreenInstruction::ApplyLayout(( layout, new_pane_pids.clone(), @@ -203,8 +204,8 @@ impl Pty { for id in new_pane_pids { let task_handle = stream_terminal_bytes( id, - self.bus.to_screen.as_ref().unwrap().clone(), - self.bus.os_input.as_ref().unwrap().clone(), + self.send_screen_instructions.clone(), + self.os_input.clone(), self.debug_to_file, ); self.task_handles.insert(id, task_handle); @@ -215,16 +216,13 @@ impl Pty { PaneId::Terminal(id) => { let child_pid = self.id_to_child_pid.remove(&id).unwrap(); let handle = self.task_handles.remove(&id).unwrap(); - self.bus.os_input.as_mut().unwrap().kill(child_pid).unwrap(); + self.os_input.kill(child_pid).unwrap(); task::block_on(async { handle.cancel().await; }); } PaneId::Plugin(pid) => drop( - self.bus - .to_plugin - .as_ref() - .unwrap() + self.send_plugin_instructions .send(PluginInstruction::Unload(pid)), ), } @@ -236,7 +234,7 @@ impl Pty { } } -impl Drop for Pty { +impl Drop for PtyBus { fn drop(&mut self) { let child_ids: Vec = self.id_to_child_pid.keys().copied().collect(); for id in child_ids { diff --git a/src/common/screen.rs b/src/common/screen.rs index d5df24b0..eee1166f 100644 --- a/src/common/screen.rs +++ b/src/common/screen.rs @@ -3,13 +3,14 @@ use std::collections::BTreeMap; use std::os::unix::io::RawFd; use std::str; +use std::sync::mpsc::Receiver; -use super::AppInstruction; -use crate::common::Bus; +use super::{AppInstruction, SenderWithContext}; +use crate::os_input_output::OsApi; use crate::panes::PositionAndSize; -use crate::common::pty::{PtyInstruction, VteBytes}; +use crate::pty_bus::{PtyInstruction, VteBytes}; use crate::tab::Tab; -use crate::wasm_vm::PluginInstruction; +use crate::{errors::ErrorContext, wasm_vm::PluginInstruction}; use crate::{layout::Layout, panes::PaneId}; use zellij_tile::data::{Event, ModeInfo, TabInfo}; @@ -61,33 +62,51 @@ pub enum ScreenInstruction { /// A [`Screen`] holds multiple [`Tab`]s, each one holding multiple [`panes`](crate::client::panes). /// It only directly controls which tab is active, delegating the rest to the individual `Tab`. pub struct Screen { - /// A Bus for sending and receiving messages with the other threads. - pub bus: Bus, + /// A [`ScreenInstruction`] and [`ErrorContext`] receiver. + pub receiver: Receiver<(ScreenInstruction, ErrorContext)>, /// An optional maximal amount of panes allowed per [`Tab`] in this [`Screen`] instance. max_panes: Option, /// A map between this [`Screen`]'s tabs and their ID/key. tabs: BTreeMap, + /// A [`PtyInstruction`] and [`ErrorContext`] sender. + pub send_pty_instructions: SenderWithContext, + /// A [`PluginInstruction`] and [`ErrorContext`] sender. + pub send_plugin_instructions: SenderWithContext, + /// An [`AppInstruction`] and [`ErrorContext`] sender. + pub send_app_instructions: SenderWithContext, /// The full size of this [`Screen`]. full_screen_ws: PositionAndSize, /// The index of this [`Screen`]'s active [`Tab`]. active_tab_index: Option, + /// The [`OsApi`] this [`Screen`] uses. + os_api: Box, mode_info: ModeInfo, } impl Screen { + // FIXME: This lint needs actual fixing! Maybe by bundling the Senders /// Creates and returns a new [`Screen`]. + #[allow(clippy::too_many_arguments)] pub fn new( - bus: Bus, + receive_screen_instructions: Receiver<(ScreenInstruction, ErrorContext)>, + send_pty_instructions: SenderWithContext, + send_plugin_instructions: SenderWithContext, + send_app_instructions: SenderWithContext, full_screen_ws: &PositionAndSize, + os_api: Box, max_panes: Option, mode_info: ModeInfo, ) -> Self { Screen { - bus, + receiver: receive_screen_instructions, max_panes, + send_pty_instructions, + send_plugin_instructions, + send_app_instructions, full_screen_ws: *full_screen_ws, active_tab_index: None, tabs: BTreeMap::new(), + os_api, mode_info, } } @@ -102,10 +121,10 @@ impl Screen { position, String::new(), &self.full_screen_ws, - self.bus.os_input.as_ref().unwrap().clone(), - self.bus.to_pty.as_ref().unwrap().clone(), - self.bus.to_plugin.as_ref().unwrap().clone(), - self.bus.to_app.as_ref().unwrap().clone(), + self.os_api.clone(), + self.send_pty_instructions.clone(), + self.send_plugin_instructions.clone(), + self.send_app_instructions.clone(), self.max_panes, Some(PaneId::Terminal(pane_id)), self.mode_info.clone(), @@ -188,14 +207,11 @@ impl Screen { // because this might be happening when the app is closing, at which point the pty thread // has already closed and this would result in an error let _ = self - .bus - .to_pty - .as_ref() - .unwrap() + .send_pty_instructions .send(PtyInstruction::CloseTab(pane_ids)); if self.tabs.is_empty() { self.active_tab_index = None; - self.bus.to_app.as_ref().unwrap() + self.send_app_instructions .send(AppInstruction::Exit) .unwrap(); } else { @@ -209,7 +225,7 @@ impl Screen { } pub fn resize_to_screen(&mut self) { - let new_screen_size = self.bus.os_input.as_ref().unwrap().get_terminal_size_using_fd(0); + let new_screen_size = self.os_api.get_terminal_size_using_fd(0); self.full_screen_ws = new_screen_size; for (_, tab) in self.tabs.iter_mut() { tab.resize_whole_tab(new_screen_size); @@ -260,10 +276,10 @@ impl Screen { position, String::new(), &self.full_screen_ws, - self.bus.os_input.as_ref().unwrap().clone(), - self.bus.to_pty.as_ref().unwrap().clone(), - self.bus.to_plugin.as_ref().unwrap().clone(), - self.bus.to_app.as_ref().unwrap().clone(), + self.os_api.clone(), + self.send_pty_instructions.clone(), + self.send_plugin_instructions.clone(), + self.send_app_instructions.clone(), self.max_panes, None, self.mode_info.clone(), @@ -285,7 +301,7 @@ impl Screen { is_sync_panes_active: tab.is_sync_panes_active(), }); } - self.bus.to_plugin.as_ref().unwrap() + self.send_plugin_instructions .send(PluginInstruction::Update(None, Event::TabUpdate(tab_data))) .unwrap(); } diff --git a/src/common/utils/bus.rs b/src/common/utils/bus.rs deleted file mode 100644 index e69de29b..00000000 diff --git a/src/common/wasm_vm.rs b/src/common/wasm_vm.rs index 253f52f7..bd98a85b 100644 --- a/src/common/wasm_vm.rs +++ b/src/common/wasm_vm.rs @@ -12,7 +12,7 @@ use wasmer_wasi::WasiEnv; use zellij_tile::data::{Event, EventType, PluginIds}; use super::{ - pty::PtyInstruction, screen::ScreenInstruction, AppInstruction, PaneId, SenderWithContext, + pty_bus::PtyInstruction, screen::ScreenInstruction, AppInstruction, PaneId, SenderWithContext, }; #[derive(Clone, Debug)] @@ -28,10 +28,10 @@ pub enum PluginInstruction { pub struct PluginEnv { pub plugin_id: u32, // FIXME: This should be a big bundle of all of the channels - pub to_screen: SenderWithContext, - pub to_app: SenderWithContext, - pub to_pty: SenderWithContext, - pub to_plugin: SenderWithContext, + pub send_screen_instructions: SenderWithContext, + pub send_app_instructions: SenderWithContext, + pub send_pty_instructions: SenderWithContext, + pub send_plugin_instructions: SenderWithContext, pub wasi_env: WasiEnv, pub subscriptions: Arc>>, } @@ -77,7 +77,7 @@ fn host_unsubscribe(plugin_env: &PluginEnv) { fn host_set_selectable(plugin_env: &PluginEnv, selectable: i32) { let selectable = selectable != 0; plugin_env - .to_screen + .send_screen_instructions .send(ScreenInstruction::SetSelectable( PaneId::Plugin(plugin_env.plugin_id), selectable, @@ -88,7 +88,7 @@ fn host_set_selectable(plugin_env: &PluginEnv, selectable: i32) { fn host_set_max_height(plugin_env: &PluginEnv, max_height: i32) { let max_height = max_height as usize; plugin_env - .to_screen + .send_screen_instructions .send(ScreenInstruction::SetMaxHeight( PaneId::Plugin(plugin_env.plugin_id), max_height, @@ -99,7 +99,7 @@ fn host_set_max_height(plugin_env: &PluginEnv, max_height: i32) { fn host_set_invisible_borders(plugin_env: &PluginEnv, invisible_borders: i32) { let invisible_borders = invisible_borders != 0; plugin_env - .to_screen + .send_screen_instructions .send(ScreenInstruction::SetInvisibleBorders( PaneId::Plugin(plugin_env.plugin_id), invisible_borders, @@ -118,7 +118,7 @@ fn host_get_plugin_ids(plugin_env: &PluginEnv) { fn host_open_file(plugin_env: &PluginEnv) { let path: PathBuf = wasi_read_object(&plugin_env.wasi_env); plugin_env - .to_pty + .send_pty_instructions .send(PtyInstruction::SpawnTerminal(Some(path))) .unwrap(); } @@ -133,7 +133,7 @@ fn host_set_timeout(plugin_env: &PluginEnv, secs: f64) { // timers as we'd like. // // But that's a lot of code, and this is a few lines: - let send_plugin_instructions = plugin_env.to_plugin.clone(); + let send_plugin_instructions = plugin_env.send_plugin_instructions.clone(); let update_target = Some(plugin_env.plugin_id); thread::spawn(move || { let start_time = Instant::now(); diff --git a/src/main.rs b/src/main.rs index fbe76a84..12269ae9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -14,7 +14,7 @@ use crate::utils::{ }; use client::{boundaries, layout, panes, tab}; use common::{ - command_is_executing, errors, install, os_input_output, screen, start, utils, wasm_vm, + command_is_executing, errors, install, os_input_output, pty_bus, screen, start, utils, wasm_vm, ApiCommand, }; use std::io::Write; From 168deabea7825f1b2bf81ec79de9f4bfaab8413e Mon Sep 17 00:00:00 2001 From: Yutaka Kamei Date: Fri, 30 Apr 2021 23:35:12 +0900 Subject: [PATCH 7/8] Load config before start() Previously, a config file was loaded within `start()`, and if the config file is invalid, Zellij was supposed to show a user what's wrong with it. However, since `start()` starts setting up its terminal with an alternative screen buffer, neither standard output nor standard error could display such an error. This change intends to address this issue by making Zellij load a config file before `start()`. In addition, the patch also includes some refactorings: * Redefine `from_cli_config` with `TryFrom`, which was introduced in Rust 1.34 * Remove conditional declaration `cfg(not(test))` because `start()` now receive a `Config` as the third argument * Introduce [`tempfile`](https://crates.io/crates/tempfile) in order to run tests with actual files * Typo?: "Deserialisation" -> "Deserialization" --- Cargo.lock | 1 + Cargo.toml | 1 + src/common/input/config.rs | 135 +++++++++++------- src/common/mod.rs | 11 +- src/main.rs | 11 +- src/tests/integration/basic.rs | 71 +++++++-- src/tests/integration/close_pane.rs | 79 ++++++++-- src/tests/integration/compatibility.rs | 121 +++++++++++++--- src/tests/integration/layouts.rs | 3 +- src/tests/integration/move_focus_down.rs | 13 +- src/tests/integration/move_focus_left.rs | 13 +- src/tests/integration/move_focus_right.rs | 13 +- src/tests/integration/move_focus_up.rs | 13 +- src/tests/integration/resize_down.rs | 79 ++++++++-- src/tests/integration/resize_left.rs | 79 ++++++++-- src/tests/integration/resize_right.rs | 79 ++++++++-- src/tests/integration/resize_up.rs | 79 ++++++++-- src/tests/integration/tabs.rs | 49 +++++-- .../integration/terminal_window_resize.rs | 9 +- src/tests/integration/toggle_fullscreen.rs | 13 +- 20 files changed, 687 insertions(+), 185 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c94f39ae..55cfcf01 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2205,6 +2205,7 @@ dependencies = [ "strip-ansi-escapes", "structopt", "strum", + "tempfile", "termion", "termios", "unicode-truncate", diff --git a/Cargo.toml b/Cargo.toml index d712b372..743379b2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -44,6 +44,7 @@ features = ["unstable"] [dev-dependencies] insta = "1.6.0" +tempfile = "3.2.0" [build-dependencies] structopt = "0.3" diff --git a/src/common/input/config.rs b/src/common/input/config.rs index 62ec3dfe..daa52b03 100644 --- a/src/common/input/config.rs +++ b/src/common/input/config.rs @@ -6,14 +6,17 @@ use std::io::{self, Read}; use std::path::{Path, PathBuf}; use super::keybinds::{Keybinds, KeybindsFromYaml}; -use crate::cli::ConfigCli; +use crate::cli::{CliArgs, ConfigCli}; use crate::common::install; use serde::Deserialize; +use std::convert::TryFrom; + +const DEFAULT_CONFIG_FILE_NAME: &str = "config.yaml"; type ConfigResult = Result; -/// Intermediate deserialisation config struct +/// Intermediate deserialization config struct #[derive(Debug, Deserialize)] pub struct ConfigFromYaml { pub keybinds: Option, @@ -27,13 +30,13 @@ pub struct Config { #[derive(Debug)] pub enum ConfigError { - // Deserialisation error + // Deserialization error Serde(serde_yaml::Error), // Io error Io(io::Error), // Io error with path context IoPath(io::Error, PathBuf), - // Internal Deserialisation Error + // Internal Deserialization Error FromUtf8(std::string::FromUtf8Error), } @@ -44,6 +47,35 @@ impl Default for Config { } } +impl TryFrom<&CliArgs> for Config { + type Error = ConfigError; + + fn try_from(opts: &CliArgs) -> ConfigResult { + if let Some(ref path) = opts.config { + return Config::new(&path); + } + + if let Some(ConfigCli::Config { clean, .. }) = opts.option { + if clean { + return Config::from_default_assets(); + } + } + + let config_dir = opts.config_dir.clone().or_else(install::default_config_dir); + + if let Some(ref config) = config_dir { + let path = config.join(DEFAULT_CONFIG_FILE_NAME); + if path.exists() { + Config::new(&path) + } else { + Config::from_default_assets() + } + } else { + Config::from_default_assets() + } + } +} + impl Config { /// Uses defaults, but lets config override them. pub fn from_yaml(yaml_config: &str) -> ConfigResult { @@ -71,45 +103,6 @@ impl Config { pub fn from_default_assets() -> ConfigResult { Self::from_yaml(String::from_utf8(install::DEFAULT_CONFIG.to_vec())?.as_str()) } - - /// Entry point of the configuration - #[cfg(not(test))] - pub fn from_cli_config( - location: Option, - cli_config: Option, - config_dir: Option, - ) -> ConfigResult { - if let Some(path) = location { - return Config::new(&path); - } - - if let Some(ConfigCli::Config { clean, .. }) = cli_config { - if clean { - return Config::from_default_assets(); - } - } - - if let Some(config) = config_dir { - let path = config.join("config.yaml"); - if path.exists() { - Config::new(&path) - } else { - Config::from_default_assets() - } - } else { - Config::from_default_assets() - } - } - - /// In order not to mess up tests from changing configurations - #[cfg(test)] - pub fn from_cli_config( - _: Option, - _: Option, - _: Option, - ) -> ConfigResult { - Ok(Config::default()) - } } impl Display for ConfigError { @@ -119,7 +112,7 @@ impl Display for ConfigError { ConfigError::IoPath(ref err, ref path) => { write!(formatter, "IoError: {}, File: {}", err, path.display(),) } - ConfigError::Serde(ref err) => write!(formatter, "Deserialisation error: {}", err), + ConfigError::Serde(ref err) => write!(formatter, "Deserialization error: {}", err), ConfigError::FromUtf8(ref err) => write!(formatter, "FromUtf8Error: {}", err), } } @@ -157,20 +150,56 @@ impl From for ConfigError { // The unit test location. #[cfg(test)] mod config_test { + use std::io::Write; + + use tempfile::tempdir; + use super::*; #[test] - fn clean_option_equals_default_config() { - let cli_config = ConfigCli::Config { clean: true }; - let config = Config::from_cli_config(None, Some(cli_config), None).unwrap(); - let default = Config::default(); - assert_eq!(config, default); + fn try_from_cli_args_with_config() { + let arbitrary_config = PathBuf::from("nonexistent.yaml"); + let mut opts = CliArgs::default(); + opts.config = Some(arbitrary_config); + println!("OPTS= {:?}", opts); + let result = Config::try_from(&opts); + assert!(result.is_err()); } #[test] - fn no_config_option_file_equals_default_config() { - let config = Config::from_cli_config(None, None, None).unwrap(); - let default = Config::default(); - assert_eq!(config, default); + fn try_from_cli_args_with_option_clean() { + let mut opts = CliArgs::default(); + opts.option = Some(ConfigCli::Config { clean: true }); + let result = Config::try_from(&opts); + assert!(result.is_ok()); + } + + #[test] + fn try_from_cli_args_with_config_dir() { + let mut opts = CliArgs::default(); + let tmp = tempdir().unwrap(); + File::create(tmp.path().join(DEFAULT_CONFIG_FILE_NAME)) + .unwrap() + .write_all(b"keybinds: invalid\n") + .unwrap(); + opts.config_dir = Some(tmp.path().to_path_buf()); + let result = Config::try_from(&opts); + assert!(result.is_err()); + } + + #[test] + fn try_from_cli_args_with_config_dir_without_config() { + let mut opts = CliArgs::default(); + let tmp = tempdir().unwrap(); + opts.config_dir = Some(tmp.path().to_path_buf()); + let result = Config::try_from(&opts); + assert_eq!(result.unwrap(), Config::default()); + } + + #[test] + fn try_from_cli_args_default() { + let opts = CliArgs::default(); + let result = Config::try_from(&opts); + assert_eq!(result.unwrap(), Config::default()); } } diff --git a/src/common/mod.rs b/src/common/mod.rs index ef518053..0afc6ef2 100644 --- a/src/common/mod.rs +++ b/src/common/mod.rs @@ -120,7 +120,7 @@ pub enum AppInstruction { /// Start Zellij with the specified [`OsApi`] and command-line arguments. // FIXME this should definitely be modularized and split into different functions. -pub fn start(mut os_input: Box, opts: CliArgs) { +pub fn start(mut os_input: Box, opts: CliArgs, config: Config) { let take_snapshot = "\u{1b}[?1049h"; os_input.unset_raw_mode(0); let _ = os_input @@ -130,15 +130,6 @@ pub fn start(mut os_input: Box, opts: CliArgs) { env::set_var(&"ZELLIJ", "0"); - let config_dir = opts.config_dir.or_else(install::default_config_dir); - - let config = Config::from_cli_config(opts.config, opts.option, config_dir) - .map_err(|e| { - eprintln!("There was an error in the config file:\n{}", e); - std::process::exit(1); - }) - .unwrap(); - let command_is_executing = CommandIsExecuting::new(); let full_screen_ws = os_input.get_terminal_size_using_fd(0); diff --git a/src/main.rs b/src/main.rs index 12269ae9..e95471fb 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,6 +7,7 @@ mod client; use crate::cli::CliArgs; use crate::command_is_executing::CommandIsExecuting; +use crate::common::input::config::Config; use crate::os_input_output::get_os_input; use crate::utils::{ consts::{ZELLIJ_IPC_PIPE, ZELLIJ_TMP_DIR, ZELLIJ_TMP_LOG_DIR}, @@ -17,12 +18,20 @@ use common::{ command_is_executing, errors, install, os_input_output, pty_bus, screen, start, utils, wasm_vm, ApiCommand, }; +use std::convert::TryFrom; use std::io::Write; use std::os::unix::net::UnixStream; use structopt::StructOpt; pub fn main() { let opts = CliArgs::from_args(); + let config = match Config::try_from(&opts) { + Ok(config) => config, + Err(e) => { + eprintln!("There was an error in the config file:\n{}", e); + std::process::exit(1); + } + }; if let Some(split_dir) = opts.split { match split_dir { 'h' => { @@ -66,6 +75,6 @@ pub fn main() { let os_input = get_os_input(); atomic_create_dir(ZELLIJ_TMP_DIR).unwrap(); atomic_create_dir(ZELLIJ_TMP_LOG_DIR).unwrap(); - start(Box::new(os_input), opts); + start(Box::new(os_input), opts, config); } } diff --git a/src/tests/integration/basic.rs b/src/tests/integration/basic.rs index 9b1b2bdd..f785666a 100644 --- a/src/tests/integration/basic.rs +++ b/src/tests/integration/basic.rs @@ -1,6 +1,7 @@ use crate::panes::PositionAndSize; use ::insta::assert_snapshot; +use crate::common::input::config::Config; use crate::tests::fakes::FakeInputOutput; use crate::tests::utils::commands::{ PANE_MODE, QUIT, SCROLL_DOWN_IN_SCROLL_MODE, SCROLL_MODE, SCROLL_PAGE_DOWN_IN_SCROLL_MODE, @@ -26,7 +27,11 @@ pub fn starts_with_one_terminal() { }; let mut fake_input_output = get_fake_os_input(&fake_win_size); fake_input_output.add_terminal_input(&[&QUIT]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer .output_frames @@ -49,7 +54,11 @@ pub fn split_terminals_vertically() { }; let mut fake_input_output = get_fake_os_input(&fake_win_size); fake_input_output.add_terminal_input(&[&PANE_MODE, &SPLIT_RIGHT_IN_PANE_MODE, &QUIT]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer .output_frames @@ -72,7 +81,11 @@ pub fn split_terminals_horizontally() { }; let mut fake_input_output = get_fake_os_input(&fake_win_size); fake_input_output.add_terminal_input(&[&PANE_MODE, &SPLIT_DOWN_IN_PANE_MODE, &QUIT]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer .output_frames @@ -102,7 +115,11 @@ pub fn split_largest_terminal() { &SPAWN_TERMINAL_IN_PANE_MODE, &QUIT, ]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer .output_frames @@ -125,7 +142,11 @@ pub fn cannot_split_terminals_vertically_when_active_terminal_is_too_small() { }; let mut fake_input_output = get_fake_os_input(&fake_win_size); fake_input_output.add_terminal_input(&[&PANE_MODE, &SPLIT_RIGHT_IN_PANE_MODE, &QUIT]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer .output_frames @@ -148,7 +169,11 @@ pub fn cannot_split_terminals_horizontally_when_active_terminal_is_too_small() { }; let mut fake_input_output = get_fake_os_input(&fake_win_size); fake_input_output.add_terminal_input(&[&PANE_MODE, &SPLIT_DOWN_IN_PANE_MODE, &QUIT]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer .output_frames @@ -171,7 +196,11 @@ pub fn cannot_split_largest_terminal_when_there_is_no_room() { }; let mut fake_input_output = get_fake_os_input(&fake_win_size); fake_input_output.add_terminal_input(&[&PANE_MODE, &SPAWN_TERMINAL_IN_PANE_MODE, &QUIT]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer .output_frames @@ -202,7 +231,11 @@ pub fn scrolling_up_inside_a_pane() { &SCROLL_UP_IN_SCROLL_MODE, &QUIT, ]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer .output_frames @@ -235,7 +268,11 @@ pub fn scrolling_down_inside_a_pane() { &SCROLL_DOWN_IN_SCROLL_MODE, &QUIT, ]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer .output_frames @@ -265,7 +302,11 @@ pub fn scrolling_page_up_inside_a_pane() { &SCROLL_PAGE_UP_IN_SCROLL_MODE, &QUIT, ]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer .output_frames @@ -298,7 +339,11 @@ pub fn scrolling_page_down_inside_a_pane() { &SCROLL_PAGE_DOWN_IN_SCROLL_MODE, &QUIT, ]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer .output_frames @@ -332,7 +377,7 @@ pub fn max_panes() { ]); let mut opts = CliArgs::default(); opts.max_panes = Some(4); - start(Box::new(fake_input_output.clone()), opts); + start(Box::new(fake_input_output.clone()), opts, Config::default()); let output_frames = fake_input_output .stdout_writer .output_frames @@ -364,7 +409,7 @@ pub fn toggle_focused_pane_fullscreen() { ]); let mut opts = CliArgs::default(); opts.max_panes = Some(4); - start(Box::new(fake_input_output.clone()), opts); + start(Box::new(fake_input_output.clone()), opts, Config::default()); let output_frames = fake_input_output .stdout_writer .output_frames diff --git a/src/tests/integration/close_pane.rs b/src/tests/integration/close_pane.rs index c7ce2038..f73f4027 100644 --- a/src/tests/integration/close_pane.rs +++ b/src/tests/integration/close_pane.rs @@ -5,6 +5,7 @@ use crate::tests::fakes::FakeInputOutput; use crate::tests::utils::{get_next_to_last_snapshot, get_output_frame_snapshots}; use crate::{start, CliArgs}; +use crate::common::input::config::Config; use crate::tests::utils::commands::{ CLOSE_PANE_IN_PANE_MODE, ESC, MOVE_FOCUS_IN_PANE_MODE, PANE_MODE, QUIT, RESIZE_DOWN_IN_RESIZE_MODE, RESIZE_LEFT_IN_RESIZE_MODE, RESIZE_MODE, RESIZE_UP_IN_RESIZE_MODE, @@ -39,7 +40,11 @@ pub fn close_pane_with_another_pane_above_it() { &CLOSE_PANE_IN_PANE_MODE, &QUIT, ]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer @@ -77,7 +82,11 @@ pub fn close_pane_with_another_pane_below_it() { &CLOSE_PANE_IN_PANE_MODE, &QUIT, ]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer @@ -112,7 +121,11 @@ pub fn close_pane_with_another_pane_to_the_left() { &CLOSE_PANE_IN_PANE_MODE, &QUIT, ]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer @@ -148,7 +161,11 @@ pub fn close_pane_with_another_pane_to_the_right() { &CLOSE_PANE_IN_PANE_MODE, &QUIT, ]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer @@ -189,7 +206,11 @@ pub fn close_pane_with_multiple_panes_above_it() { &CLOSE_PANE_IN_PANE_MODE, &QUIT, ]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer @@ -228,7 +249,11 @@ pub fn close_pane_with_multiple_panes_below_it() { &CLOSE_PANE_IN_PANE_MODE, &QUIT, ]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer @@ -269,7 +294,11 @@ pub fn close_pane_with_multiple_panes_to_the_left() { &CLOSE_PANE_IN_PANE_MODE, &QUIT, ]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer @@ -308,7 +337,11 @@ pub fn close_pane_with_multiple_panes_to_the_right() { &CLOSE_PANE_IN_PANE_MODE, &QUIT, ]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer @@ -369,7 +402,11 @@ pub fn close_pane_with_multiple_panes_above_it_away_from_screen_edges() { &CLOSE_PANE_IN_PANE_MODE, &QUIT, ]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer @@ -426,7 +463,11 @@ pub fn close_pane_with_multiple_panes_below_it_away_from_screen_edges() { &CLOSE_PANE_IN_PANE_MODE, &QUIT, ]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer @@ -485,7 +526,11 @@ pub fn close_pane_with_multiple_panes_to_the_left_away_from_screen_edges() { &CLOSE_PANE_IN_PANE_MODE, &QUIT, ]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer @@ -544,7 +589,11 @@ pub fn close_pane_with_multiple_panes_to_the_right_away_from_screen_edges() { &CLOSE_PANE_IN_PANE_MODE, &QUIT, ]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer @@ -576,7 +625,11 @@ pub fn closing_last_pane_exits_app() { &CLOSE_PANE_IN_PANE_MODE, &CLOSE_PANE_IN_PANE_MODE, ]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer diff --git a/src/tests/integration/compatibility.rs b/src/tests/integration/compatibility.rs index 59c5c54d..ef93135e 100644 --- a/src/tests/integration/compatibility.rs +++ b/src/tests/integration/compatibility.rs @@ -7,6 +7,7 @@ use crate::tests::possible_tty_inputs::Bytes; use crate::tests::utils::{get_next_to_last_snapshot, get_output_frame_snapshots}; use crate::{start, CliArgs}; +use crate::common::input::config::Config; use crate::tests::utils::commands::QUIT; /* @@ -41,7 +42,11 @@ 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]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer .output_frames @@ -65,7 +70,11 @@ 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]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer .output_frames @@ -94,7 +103,11 @@ 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]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer .output_frames @@ -127,7 +140,11 @@ 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(&[&QUIT]); // quit (ctrl-q) - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer .output_frames @@ -157,7 +174,11 @@ 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]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer .output_frames @@ -186,7 +207,11 @@ 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]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer .output_frames @@ -210,7 +235,11 @@ pub fn htop() { let fixture_name = "htop"; let mut fake_input_output = get_fake_os_input(&fake_win_size, fixture_name); fake_input_output.add_terminal_input(&[&QUIT]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer .output_frames @@ -234,7 +263,11 @@ pub fn htop_scrolling() { let fixture_name = "htop_scrolling"; let mut fake_input_output = get_fake_os_input(&fake_win_size, fixture_name); fake_input_output.add_terminal_input(&[&QUIT]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer .output_frames @@ -258,7 +291,11 @@ pub fn htop_right_scrolling() { let fixture_name = "htop_right_scrolling"; let mut fake_input_output = get_fake_os_input(&fake_win_size, fixture_name); fake_input_output.add_terminal_input(&[&QUIT]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer .output_frames @@ -290,7 +327,11 @@ pub fn vim_overwrite() { let fixture_name = "vim_overwrite"; let mut fake_input_output = get_fake_os_input(&fake_win_size, fixture_name); fake_input_output.add_terminal_input(&[&QUIT]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer .output_frames @@ -317,7 +358,11 @@ pub fn clear_scroll_region() { let fixture_name = "clear_scroll_region"; let mut fake_input_output = get_fake_os_input(&fake_win_size, fixture_name); fake_input_output.add_terminal_input(&[&QUIT]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer .output_frames @@ -341,7 +386,11 @@ pub fn display_tab_characters_properly() { let fixture_name = "tab_characters"; let mut fake_input_output = get_fake_os_input(&fake_win_size, fixture_name); fake_input_output.add_terminal_input(&[&QUIT]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer .output_frames @@ -365,7 +414,11 @@ pub fn neovim_insert_mode() { let fixture_name = "nvim_insert"; let mut fake_input_output = get_fake_os_input(&fake_win_size, fixture_name); fake_input_output.add_terminal_input(&[&QUIT]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer .output_frames @@ -391,7 +444,11 @@ pub fn bash_cursor_linewrap() { let fixture_name = "bash_cursor_linewrap"; let mut fake_input_output = get_fake_os_input(&fake_win_size, fixture_name); fake_input_output.add_terminal_input(&[&QUIT]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer .output_frames @@ -417,7 +474,11 @@ pub fn fish_paste_multiline() { let fixture_name = "fish_paste_multiline"; let mut fake_input_output = get_fake_os_input(&fake_win_size, fixture_name); fake_input_output.add_terminal_input(&[&QUIT]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer .output_frames @@ -441,7 +502,11 @@ pub fn git_log() { let fixture_name = "git_log"; let mut fake_input_output = get_fake_os_input(&fake_win_size, fixture_name); fake_input_output.add_terminal_input(&[&QUIT]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer .output_frames @@ -467,7 +532,11 @@ pub fn git_diff_scrollup() { let fixture_name = "git_diff_scrollup"; let mut fake_input_output = get_fake_os_input(&fake_win_size, fixture_name); fake_input_output.add_terminal_input(&[&QUIT]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer .output_frames @@ -491,7 +560,11 @@ pub fn emacs_longbuf() { let fixture_name = "emacs_longbuf_tutorial"; let mut fake_input_output = get_fake_os_input(&fake_win_size, fixture_name); fake_input_output.add_terminal_input(&[&QUIT]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer .output_frames @@ -515,7 +588,11 @@ pub fn top_and_quit() { let fixture_name = "top_and_quit"; let mut fake_input_output = get_fake_os_input(&fake_win_size, fixture_name); fake_input_output.add_terminal_input(&[&QUIT]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer .output_frames @@ -545,7 +622,11 @@ pub fn exa_plus_omf_theme() { let fixture_name = "exa_plus_omf_theme"; let mut fake_input_output = get_fake_os_input(&fake_win_size, fixture_name); fake_input_output.add_terminal_input(&[&QUIT]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer .output_frames diff --git a/src/tests/integration/layouts.rs b/src/tests/integration/layouts.rs index 78956f1f..a2ac4702 100644 --- a/src/tests/integration/layouts.rs +++ b/src/tests/integration/layouts.rs @@ -1,6 +1,7 @@ use insta::assert_snapshot; use std::path::PathBuf; +use crate::common::input::config::Config; use crate::panes::PositionAndSize; use crate::tests::fakes::FakeInputOutput; use crate::tests::utils::commands::QUIT; @@ -27,7 +28,7 @@ pub fn accepts_basic_layout() { "src/tests/fixtures/layouts/three-panes-with-nesting.yaml", )); - start(Box::new(fake_input_output.clone()), opts); + start(Box::new(fake_input_output.clone()), opts, Config::default()); let output_frames = fake_input_output .stdout_writer .output_frames diff --git a/src/tests/integration/move_focus_down.rs b/src/tests/integration/move_focus_down.rs index 273696ae..21fa7925 100644 --- a/src/tests/integration/move_focus_down.rs +++ b/src/tests/integration/move_focus_down.rs @@ -5,6 +5,7 @@ use crate::tests::fakes::FakeInputOutput; use crate::tests::utils::{get_next_to_last_snapshot, get_output_frame_snapshots}; use crate::{start, CliArgs}; +use crate::common::input::config::Config; use crate::tests::utils::commands::{ MOVE_FOCUS_DOWN_IN_PANE_MODE, MOVE_FOCUS_UP_IN_PANE_MODE, PANE_MODE, QUIT, SPLIT_DOWN_IN_PANE_MODE, SPLIT_RIGHT_IN_PANE_MODE, @@ -31,7 +32,11 @@ pub fn move_focus_down() { &MOVE_FOCUS_DOWN_IN_PANE_MODE, &QUIT, ]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer @@ -63,7 +68,11 @@ pub fn move_focus_down_to_the_most_recently_used_pane() { &MOVE_FOCUS_DOWN_IN_PANE_MODE, &QUIT, ]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer diff --git a/src/tests/integration/move_focus_left.rs b/src/tests/integration/move_focus_left.rs index e36b8fcf..6441357d 100644 --- a/src/tests/integration/move_focus_left.rs +++ b/src/tests/integration/move_focus_left.rs @@ -5,6 +5,7 @@ use crate::tests::fakes::FakeInputOutput; use crate::tests::utils::{get_next_to_last_snapshot, get_output_frame_snapshots}; use crate::{start, CliArgs}; +use crate::common::input::config::Config; use crate::tests::utils::commands::{ MOVE_FOCUS_LEFT_IN_PANE_MODE, MOVE_FOCUS_RIGHT_IN_PANE_MODE, PANE_MODE, QUIT, SPLIT_DOWN_IN_PANE_MODE, SPLIT_RIGHT_IN_PANE_MODE, @@ -30,7 +31,11 @@ pub fn move_focus_left() { &MOVE_FOCUS_LEFT_IN_PANE_MODE, &QUIT, ]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer @@ -63,7 +68,11 @@ pub fn move_focus_left_to_the_most_recently_used_pane() { &MOVE_FOCUS_LEFT_IN_PANE_MODE, &QUIT, ]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer diff --git a/src/tests/integration/move_focus_right.rs b/src/tests/integration/move_focus_right.rs index 88d86a26..bc4f551c 100644 --- a/src/tests/integration/move_focus_right.rs +++ b/src/tests/integration/move_focus_right.rs @@ -5,6 +5,7 @@ use crate::tests::fakes::FakeInputOutput; use crate::tests::utils::{get_next_to_last_snapshot, get_output_frame_snapshots}; use crate::{start, CliArgs}; +use crate::common::input::config::Config; use crate::tests::utils::commands::{ MOVE_FOCUS_LEFT_IN_PANE_MODE, MOVE_FOCUS_RIGHT_IN_PANE_MODE, PANE_MODE, QUIT, SPLIT_DOWN_IN_PANE_MODE, SPLIT_RIGHT_IN_PANE_MODE, @@ -31,7 +32,11 @@ pub fn move_focus_right() { &MOVE_FOCUS_RIGHT_IN_PANE_MODE, &QUIT, ]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer @@ -63,7 +68,11 @@ pub fn move_focus_right_to_the_most_recently_used_pane() { &MOVE_FOCUS_RIGHT_IN_PANE_MODE, &QUIT, ]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer diff --git a/src/tests/integration/move_focus_up.rs b/src/tests/integration/move_focus_up.rs index d4ef6c8f..77f06703 100644 --- a/src/tests/integration/move_focus_up.rs +++ b/src/tests/integration/move_focus_up.rs @@ -5,6 +5,7 @@ use crate::tests::fakes::FakeInputOutput; use crate::tests::utils::{get_next_to_last_snapshot, get_output_frame_snapshots}; use crate::{start, CliArgs}; +use crate::common::input::config::Config; use crate::tests::utils::commands::{ MOVE_FOCUS_DOWN_IN_PANE_MODE, MOVE_FOCUS_UP_IN_PANE_MODE, PANE_MODE, QUIT, SPLIT_DOWN_IN_PANE_MODE, SPLIT_RIGHT_IN_PANE_MODE, @@ -30,7 +31,11 @@ pub fn move_focus_up() { &MOVE_FOCUS_UP_IN_PANE_MODE, &QUIT, ]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer @@ -63,7 +68,11 @@ pub fn move_focus_up_to_the_most_recently_used_pane() { &MOVE_FOCUS_UP_IN_PANE_MODE, &QUIT, ]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer diff --git a/src/tests/integration/resize_down.rs b/src/tests/integration/resize_down.rs index 68f8bb41..d5ad4ef8 100644 --- a/src/tests/integration/resize_down.rs +++ b/src/tests/integration/resize_down.rs @@ -5,6 +5,7 @@ use crate::tests::fakes::FakeInputOutput; use crate::tests::utils::{get_next_to_last_snapshot, get_output_frame_snapshots}; use crate::{start, CliArgs}; +use crate::common::input::config::Config; use crate::tests::utils::commands::{ MOVE_FOCUS_IN_PANE_MODE, PANE_MODE, QUIT, RESIZE_DOWN_IN_RESIZE_MODE, RESIZE_LEFT_IN_RESIZE_MODE, RESIZE_MODE, SLEEP, SPLIT_DOWN_IN_PANE_MODE, @@ -42,7 +43,11 @@ pub fn resize_down_with_pane_above() { &SLEEP, &QUIT, ]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer @@ -82,7 +87,11 @@ pub fn resize_down_with_pane_below() { &SLEEP, &QUIT, ]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer @@ -128,7 +137,11 @@ pub fn resize_down_with_panes_above_and_below() { &SLEEP, &QUIT, ]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer @@ -173,7 +186,11 @@ pub fn resize_down_with_multiple_panes_above() { &QUIT, ]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer @@ -220,7 +237,11 @@ pub fn resize_down_with_panes_above_aligned_left_with_current_pane() { &QUIT, ]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer @@ -266,7 +287,11 @@ pub fn resize_down_with_panes_below_aligned_left_with_current_pane() { &QUIT, ]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer @@ -310,7 +335,11 @@ pub fn resize_down_with_panes_above_aligned_right_with_current_pane() { &QUIT, ]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer @@ -355,7 +384,11 @@ pub fn resize_down_with_panes_below_aligned_right_with_current_pane() { &QUIT, ]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer @@ -403,7 +436,11 @@ pub fn resize_down_with_panes_above_aligned_left_and_right_with_current_pane() { &QUIT, ]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer @@ -453,7 +490,11 @@ pub fn resize_down_with_panes_below_aligned_left_and_right_with_current_pane() { &QUIT, ]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer @@ -520,7 +561,11 @@ pub fn resize_down_with_panes_above_aligned_left_and_right_with_panes_to_the_lef &QUIT, ]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer @@ -589,7 +634,11 @@ pub fn resize_down_with_panes_below_aligned_left_and_right_with_to_the_left_and_ &QUIT, ]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer @@ -626,7 +675,11 @@ pub fn cannot_resize_down_when_pane_below_is_at_minimum_height() { &SLEEP, &QUIT, ]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer diff --git a/src/tests/integration/resize_left.rs b/src/tests/integration/resize_left.rs index 2229e236..2444f3a1 100644 --- a/src/tests/integration/resize_left.rs +++ b/src/tests/integration/resize_left.rs @@ -5,6 +5,7 @@ use crate::tests::fakes::FakeInputOutput; use crate::tests::utils::{get_next_to_last_snapshot, get_output_frame_snapshots}; use crate::{start, CliArgs}; +use crate::common::input::config::Config; use crate::tests::utils::commands::{ MOVE_FOCUS_IN_PANE_MODE, PANE_MODE, QUIT, RESIZE_LEFT_IN_RESIZE_MODE, RESIZE_MODE, RESIZE_UP_IN_RESIZE_MODE, SLEEP, SPLIT_DOWN_IN_PANE_MODE, SPLIT_RIGHT_IN_PANE_MODE, @@ -38,7 +39,11 @@ pub fn resize_left_with_pane_to_the_left() { &SLEEP, &QUIT, ]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer @@ -76,7 +81,11 @@ pub fn resize_left_with_pane_to_the_right() { &SLEEP, &QUIT, ]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer @@ -116,7 +125,11 @@ pub fn resize_left_with_panes_to_the_left_and_right() { &SLEEP, &QUIT, ]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer @@ -159,7 +172,11 @@ pub fn resize_left_with_multiple_panes_to_the_left() { &QUIT, ]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer @@ -204,7 +221,11 @@ pub fn resize_left_with_panes_to_the_left_aligned_top_with_current_pane() { &QUIT, ]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer @@ -246,7 +267,11 @@ pub fn resize_left_with_panes_to_the_right_aligned_top_with_current_pane() { &QUIT, ]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer @@ -290,7 +315,11 @@ pub fn resize_left_with_panes_to_the_left_aligned_bottom_with_current_pane() { &QUIT, ]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer @@ -333,7 +362,11 @@ pub fn resize_left_with_panes_to_the_right_aligned_bottom_with_current_pane() { &QUIT, ]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer @@ -381,7 +414,11 @@ pub fn resize_left_with_panes_to_the_left_aligned_top_and_bottom_with_current_pa &QUIT, ]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer @@ -431,7 +468,11 @@ pub fn resize_left_with_panes_to_the_right_aligned_top_and_bottom_with_current_p &QUIT, ]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer @@ -498,7 +539,11 @@ pub fn resize_left_with_panes_to_the_left_aligned_top_and_bottom_with_panes_abov &QUIT, ]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer @@ -568,7 +613,11 @@ pub fn resize_left_with_panes_to_the_right_aligned_top_and_bottom_with_panes_abo &QUIT, ]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer @@ -605,7 +654,11 @@ pub fn cannot_resize_left_when_pane_to_the_left_is_at_minimum_width() { &SLEEP, &QUIT, ]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer diff --git a/src/tests/integration/resize_right.rs b/src/tests/integration/resize_right.rs index 9545cac9..3f242f5a 100644 --- a/src/tests/integration/resize_right.rs +++ b/src/tests/integration/resize_right.rs @@ -5,6 +5,7 @@ use crate::tests::fakes::FakeInputOutput; use crate::tests::utils::{get_next_to_last_snapshot, get_output_frame_snapshots}; use crate::{start, CliArgs}; +use crate::common::input::config::Config; use crate::tests::utils::commands::{ MOVE_FOCUS_IN_PANE_MODE, PANE_MODE, QUIT, RESIZE_MODE, RESIZE_RIGHT_IN_RESIZE_MODE, RESIZE_UP_IN_RESIZE_MODE, SLEEP, SPLIT_DOWN_IN_PANE_MODE, SPLIT_RIGHT_IN_PANE_MODE, @@ -38,7 +39,11 @@ pub fn resize_right_with_pane_to_the_left() { &SLEEP, &QUIT, ]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer @@ -76,7 +81,11 @@ pub fn resize_right_with_pane_to_the_right() { &SLEEP, &QUIT, ]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer @@ -116,7 +125,11 @@ pub fn resize_right_with_panes_to_the_left_and_right() { &SLEEP, &QUIT, ]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer @@ -159,7 +172,11 @@ pub fn resize_right_with_multiple_panes_to_the_left() { &QUIT, ]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer @@ -204,7 +221,11 @@ pub fn resize_right_with_panes_to_the_left_aligned_top_with_current_pane() { &QUIT, ]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer @@ -246,7 +267,11 @@ pub fn resize_right_with_panes_to_the_right_aligned_top_with_current_pane() { &QUIT, ]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer @@ -290,7 +315,11 @@ pub fn resize_right_with_panes_to_the_left_aligned_bottom_with_current_pane() { &QUIT, ]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer @@ -333,7 +362,11 @@ pub fn resize_right_with_panes_to_the_right_aligned_bottom_with_current_pane() { &QUIT, ]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer @@ -381,7 +414,11 @@ pub fn resize_right_with_panes_to_the_left_aligned_top_and_bottom_with_current_p &QUIT, ]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer @@ -431,7 +468,11 @@ pub fn resize_right_with_panes_to_the_right_aligned_top_and_bottom_with_current_ &QUIT, ]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer @@ -498,7 +539,11 @@ pub fn resize_right_with_panes_to_the_left_aligned_top_and_bottom_with_panes_abo &QUIT, ]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer @@ -567,7 +612,11 @@ pub fn resize_right_with_panes_to_the_right_aligned_top_and_bottom_with_panes_ab &QUIT, ]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer @@ -604,7 +653,11 @@ pub fn cannot_resize_right_when_pane_to_the_left_is_at_minimum_width() { &SLEEP, &QUIT, ]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer diff --git a/src/tests/integration/resize_up.rs b/src/tests/integration/resize_up.rs index ae39d843..e2d0c4ba 100644 --- a/src/tests/integration/resize_up.rs +++ b/src/tests/integration/resize_up.rs @@ -5,6 +5,7 @@ use crate::tests::fakes::FakeInputOutput; use crate::tests::utils::{get_next_to_last_snapshot, get_output_frame_snapshots}; use crate::{start, CliArgs}; +use crate::common::input::config::Config; use crate::tests::utils::commands::{ MOVE_FOCUS_IN_PANE_MODE, PANE_MODE, QUIT, RESIZE_LEFT_IN_RESIZE_MODE, RESIZE_MODE, RESIZE_UP_IN_RESIZE_MODE, SLEEP, SPLIT_DOWN_IN_PANE_MODE, SPLIT_RIGHT_IN_PANE_MODE, @@ -40,7 +41,11 @@ pub fn resize_up_with_pane_above() { &SLEEP, &QUIT, ]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer @@ -80,7 +85,11 @@ pub fn resize_up_with_pane_below() { &SLEEP, &QUIT, ]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer @@ -125,7 +134,11 @@ pub fn resize_up_with_panes_above_and_below() { &SLEEP, &QUIT, ]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer @@ -169,7 +182,11 @@ pub fn resize_up_with_multiple_panes_above() { &QUIT, ]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer @@ -214,7 +231,11 @@ pub fn resize_up_with_panes_above_aligned_left_with_current_pane() { &QUIT, ]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer @@ -260,7 +281,11 @@ pub fn resize_up_with_panes_below_aligned_left_with_current_pane() { &QUIT, ]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer @@ -304,7 +329,11 @@ pub fn resize_up_with_panes_above_aligned_right_with_current_pane() { &QUIT, ]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer @@ -349,7 +378,11 @@ pub fn resize_up_with_panes_below_aligned_right_with_current_pane() { &QUIT, ]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer @@ -397,7 +430,11 @@ pub fn resize_up_with_panes_above_aligned_left_and_right_with_current_pane() { &QUIT, ]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer @@ -447,7 +484,11 @@ pub fn resize_up_with_panes_below_aligned_left_and_right_with_current_pane() { &QUIT, ]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer @@ -514,7 +555,11 @@ pub fn resize_up_with_panes_above_aligned_left_and_right_with_panes_to_the_left_ &QUIT, ]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer @@ -583,7 +628,11 @@ pub fn resize_up_with_panes_below_aligned_left_and_right_with_to_the_left_and_ri &QUIT, ]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer @@ -620,7 +669,11 @@ pub fn cannot_resize_up_when_pane_above_is_at_minimum_height() { &SLEEP, &QUIT, ]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer diff --git a/src/tests/integration/tabs.rs b/src/tests/integration/tabs.rs index 183b1b2a..f62ad0c4 100644 --- a/src/tests/integration/tabs.rs +++ b/src/tests/integration/tabs.rs @@ -5,6 +5,7 @@ use crate::tests::utils::{get_next_to_last_snapshot, get_output_frame_snapshots} use crate::{panes::PositionAndSize, tests::utils::commands::CLOSE_PANE_IN_PANE_MODE}; use crate::{start, CliArgs}; +use crate::common::input::config::Config; use crate::tests::utils::commands::{ CLOSE_TAB_IN_TAB_MODE, NEW_TAB_IN_TAB_MODE, PANE_MODE, QUIT, SPLIT_DOWN_IN_PANE_MODE, SWITCH_NEXT_TAB_IN_TAB_MODE, SWITCH_PREV_TAB_IN_TAB_MODE, TAB_MODE, @@ -32,7 +33,11 @@ pub fn open_new_tab() { &NEW_TAB_IN_TAB_MODE, &QUIT, ]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer @@ -63,7 +68,11 @@ pub fn switch_to_prev_tab() { &SWITCH_PREV_TAB_IN_TAB_MODE, &QUIT, ]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer @@ -94,7 +103,11 @@ pub fn switch_to_next_tab() { &SWITCH_NEXT_TAB_IN_TAB_MODE, &QUIT, ]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer @@ -125,7 +138,11 @@ pub fn close_tab() { &CLOSE_TAB_IN_TAB_MODE, &QUIT, ]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer @@ -157,7 +174,11 @@ pub fn close_last_pane_in_a_tab() { &CLOSE_PANE_IN_PANE_MODE, &QUIT, ]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer @@ -191,7 +212,11 @@ pub fn close_the_middle_tab() { &CLOSE_TAB_IN_TAB_MODE, &QUIT, ]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer @@ -230,7 +255,11 @@ pub fn close_the_tab_that_has_a_pane_in_fullscreen() { &CLOSE_TAB_IN_TAB_MODE, &QUIT, ]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer @@ -261,7 +290,11 @@ pub fn closing_last_tab_exits_the_app() { &CLOSE_TAB_IN_TAB_MODE, &CLOSE_TAB_IN_TAB_MODE, ]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer diff --git a/src/tests/integration/terminal_window_resize.rs b/src/tests/integration/terminal_window_resize.rs index 1ee5828a..ebea82c0 100644 --- a/src/tests/integration/terminal_window_resize.rs +++ b/src/tests/integration/terminal_window_resize.rs @@ -1,6 +1,7 @@ use crate::panes::PositionAndSize; use ::insta::assert_snapshot; +use crate::common::input::config::Config; use crate::tests::fakes::FakeInputOutput; use crate::tests::utils::commands::QUIT; use crate::tests::utils::{get_next_to_last_snapshot, get_output_frame_snapshots}; @@ -29,7 +30,7 @@ pub fn window_width_decrease_with_one_pane() { ..Default::default() }); let opts = CliArgs::default(); - start(Box::new(fake_input_output.clone()), opts); + start(Box::new(fake_input_output.clone()), opts, Config::default()); let output_frames = fake_input_output .stdout_writer .output_frames @@ -60,7 +61,7 @@ pub fn window_width_increase_with_one_pane() { ..Default::default() }); let opts = CliArgs::default(); - start(Box::new(fake_input_output.clone()), opts); + start(Box::new(fake_input_output.clone()), opts, Config::default()); let output_frames = fake_input_output .stdout_writer .output_frames @@ -91,7 +92,7 @@ pub fn window_height_increase_with_one_pane() { ..Default::default() }); let opts = CliArgs::default(); - start(Box::new(fake_input_output.clone()), opts); + start(Box::new(fake_input_output.clone()), opts, Config::default()); let output_frames = fake_input_output .stdout_writer .output_frames @@ -122,7 +123,7 @@ pub fn window_width_and_height_decrease_with_one_pane() { ..Default::default() }); let opts = CliArgs::default(); - start(Box::new(fake_input_output.clone()), opts); + start(Box::new(fake_input_output.clone()), opts, Config::default()); let output_frames = fake_input_output .stdout_writer .output_frames diff --git a/src/tests/integration/toggle_fullscreen.rs b/src/tests/integration/toggle_fullscreen.rs index c36849f7..9fd22144 100644 --- a/src/tests/integration/toggle_fullscreen.rs +++ b/src/tests/integration/toggle_fullscreen.rs @@ -5,6 +5,7 @@ use crate::tests::fakes::FakeInputOutput; use crate::tests::utils::{get_next_to_last_snapshot, get_output_frame_snapshots}; use crate::{start, CliArgs}; +use crate::common::input::config::Config; use crate::tests::utils::commands::{ MOVE_FOCUS_IN_PANE_MODE, PANE_MODE, QUIT, SPLIT_DOWN_IN_PANE_MODE, SPLIT_RIGHT_IN_PANE_MODE, TOGGLE_ACTIVE_TERMINAL_FULLSCREEN_IN_PANE_MODE, @@ -31,7 +32,11 @@ pub fn adding_new_terminal_in_fullscreen() { &SPLIT_DOWN_IN_PANE_MODE, &QUIT, ]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer @@ -61,7 +66,11 @@ pub fn move_focus_is_disabled_in_fullscreen() { &MOVE_FOCUS_IN_PANE_MODE, &QUIT, ]); - start(Box::new(fake_input_output.clone()), CliArgs::default()); + start( + Box::new(fake_input_output.clone()), + CliArgs::default(), + Config::default(), + ); let output_frames = fake_input_output .stdout_writer From 099861ff5b0f83773ca0af4c70e6e39be3b0336c Mon Sep 17 00:00:00 2001 From: a-kenji Date: Sun, 2 May 2021 00:19:14 +0200 Subject: [PATCH 8/8] docs(changelog): Improved Config Loading #423 --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 76dd7497..20878035 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) ## [Unreleased] * Fix the tab '(Sync)' suffix in named tabs (https://github.com/zellij-org/zellij/pull/410) * Improve performance when multiple panes are open (https://github.com/zellij-org/zellij/pull/318) +* Improve error reporting and tests of configuration (https://github.com/zellij-org/zellij/pull/423) ## [0.6.0] - 2021-04-29 * Doesn't quit anymore on single `q` press while in tab mode (https://github.com/zellij-org/zellij/pull/342)