diff options
| author | denis <denismaximov98@gmail.com> | 2021-04-22 11:45:29 +0300 |
|---|---|---|
| committer | denis <denismaximov98@gmail.com> | 2021-04-22 11:45:29 +0300 |
| commit | 8d98ca7da0bc278a832e4e7de23ff63a84deb529 (patch) | |
| tree | e7fdfaa6c1ae25e7737dbb36bd1dbcb94d62ab47 /src/common | |
| parent | wip: fixing the first arrow (diff) | |
| parent | fix(cargo): reduce crate size by 4.8MB using `cargo diet`, to 77kB (diff) | |
| download | sl0ppij-8d98ca7da0bc278a832e4e7de23ff63a84deb529.tar.gz sl0ppij-8d98ca7da0bc278a832e4e7de23ff63a84deb529.tar.xz sl0ppij-8d98ca7da0bc278a832e4e7de23ff63a84deb529.zip | |
wip: merge main in
Diffstat (limited to 'src/common')
| -rw-r--r-- | src/common/errors.rs | 16 | ||||
| -rw-r--r-- | src/common/input/actions.rs | 4 | ||||
| -rw-r--r-- | src/common/input/config.rs | 26 | ||||
| -rw-r--r-- | src/common/input/handler.rs | 14 | ||||
| -rw-r--r-- | src/common/input/keybinds.rs | 69 | ||||
| -rw-r--r-- | src/common/input/unit/keybinds_test.rs | 31 | ||||
| -rw-r--r-- | src/common/install.rs | 31 | ||||
| -rw-r--r-- | src/common/mod.rs | 103 | ||||
| -rw-r--r-- | src/common/os_input_output.rs | 13 | ||||
| -rw-r--r-- | src/common/pty_bus.rs | 11 | ||||
| -rw-r--r-- | src/common/screen.rs | 4 | ||||
| -rw-r--r-- | src/common/utils/logging.rs | 6 | ||||
| -rw-r--r-- | src/common/utils/shared.rs | 4 |
13 files changed, 234 insertions, 98 deletions
diff --git a/src/common/errors.rs b/src/common/errors.rs index 9801428c..dd675738 100644 --- a/src/common/errors.rs +++ b/src/common/errors.rs @@ -1,7 +1,7 @@ //! Error context system based on a thread-local representation of the call stack, itself based on //! the instructions that are sent between threads. -use super::{AppInstruction, OPENCALLS}; +use super::{AppInstruction, ASYNCOPENCALLS, OPENCALLS}; use crate::pty_bus::PtyInstruction; use crate::screen::ScreenInstruction; @@ -72,6 +72,12 @@ pub fn handle_panic( } } +pub fn get_current_ctx() -> ErrorContext { + ASYNCOPENCALLS + .try_with(|ctx| *ctx.borrow()) + .unwrap_or_else(|_| OPENCALLS.with(|ctx| *ctx.borrow())) +} + /// A representation of the call stack. #[derive(Clone, Copy)] pub struct ErrorContext { @@ -95,7 +101,9 @@ impl ErrorContext { break; } } - OPENCALLS.with(|ctx| *ctx.borrow_mut() = *self); + ASYNCOPENCALLS + .try_with(|ctx| *ctx.borrow_mut() = *self) + .unwrap_or_else(|_| OPENCALLS.with(|ctx| *ctx.borrow_mut() = *self)); } } @@ -188,6 +196,8 @@ pub enum ScreenContext { Quit, ScrollUp, ScrollDown, + PageScrollUp, + PageScrollDown, ClearScroll, CloseFocusedPane, ToggleActiveTerminalFullscreen, @@ -230,6 +240,8 @@ impl From<&ScreenInstruction> for ScreenContext { ScreenInstruction::Quit => ScreenContext::Quit, ScreenInstruction::ScrollUp => ScreenContext::ScrollUp, ScreenInstruction::ScrollDown => ScreenContext::ScrollDown, + ScreenInstruction::PageScrollUp => ScreenContext::PageScrollUp, + ScreenInstruction::PageScrollDown => ScreenContext::PageScrollDown, ScreenInstruction::ClearScroll => ScreenContext::ClearScroll, ScreenInstruction::CloseFocusedPane => ScreenContext::CloseFocusedPane, ScreenInstruction::ToggleActiveTerminalFullscreen => { diff --git a/src/common/input/actions.rs b/src/common/input/actions.rs index 47a5f763..3bcadf15 100644 --- a/src/common/input/actions.rs +++ b/src/common/input/actions.rs @@ -33,6 +33,10 @@ pub enum Action { ScrollUp, /// Scroll down in focus pane. ScrollDown, + /// Scroll up one page in focus pane. + PageScrollUp, + /// Scroll down one page in focus pane. + PageScrollDown, /// Toggle between fullscreen focus pane and normal layout. ToggleFocusFullscreen, /// Open a new pane in the specified direction (relative to focus). diff --git a/src/common/input/config.rs b/src/common/input/config.rs index 4bb9e10f..542116d9 100644 --- a/src/common/input/config.rs +++ b/src/common/input/config.rs @@ -51,7 +51,6 @@ impl Config { } /// Deserializes from given path. - #[allow(unused_must_use)] pub fn new(path: &Path) -> ConfigResult { match File::open(path) { Ok(mut file) => { @@ -80,20 +79,23 @@ impl Config { /// Entry point of the configuration #[cfg(not(test))] - pub fn from_cli_config(cli_config: Option<ConfigCli>) -> ConfigResult { + pub fn from_cli_config( + location: Option<PathBuf>, + cli_config: Option<ConfigCli>, + ) -> ConfigResult { + if let Some(path) = location { + return Config::new(&path); + } + match cli_config { Some(ConfigCli::Config { clean, .. }) if clean => Ok(Config::default()), - Some(ConfigCli::Config { path, .. }) if path.is_some() => { - Ok(Config::new(&path.unwrap())?) - } Some(_) | None => Ok(Config::from_default_path()?), } } - //#[allow(unused_must_use)] /// In order not to mess up tests from changing configurations #[cfg(test)] - pub fn from_cli_config(_: Option<ConfigCli>) -> ConfigResult { + pub fn from_cli_config(_: Option<PathBuf>, _: Option<ConfigCli>) -> ConfigResult { Ok(Config::default()) } } @@ -139,19 +141,15 @@ mod config_test { #[test] fn clean_option_equals_default_config() { - let no_file = PathBuf::from(r"../fixtures/config/config.yamlll"); - let cli_config = ConfigCli::Config { - path: Some(no_file), - clean: true, - }; - let config = Config::from_cli_config(Some(cli_config)).unwrap(); + let cli_config = ConfigCli::Config { clean: true }; + let config = Config::from_cli_config(None, Some(cli_config)).unwrap(); let default = Config::default(); assert_eq!(config, default); } #[test] fn no_config_option_file_equals_default_config() { - let config = Config::from_cli_config(None).unwrap(); + let config = Config::from_cli_config(None, None).unwrap(); let default = Config::default(); assert_eq!(config, default); } diff --git a/src/common/input/handler.rs b/src/common/input/handler.rs index 2484f08c..bbb594a3 100644 --- a/src/common/input/handler.rs +++ b/src/common/input/handler.rs @@ -59,9 +59,6 @@ impl InputHandler { fn handle_input(&mut self) { let mut err_ctx = OPENCALLS.with(|ctx| *ctx.borrow()); err_ctx.add_call(ContextType::StdinHandler); - self.send_pty_instructions.update(err_ctx); - self.send_app_instructions.update(err_ctx); - self.send_screen_instructions.update(err_ctx); let keybinds = self.config.keybinds.clone(); let alt_left_bracket = vec![27, 91]; loop { @@ -188,6 +185,16 @@ impl InputHandler { .send(ScreenInstruction::ScrollDown) .unwrap(); } + Action::PageScrollUp => { + self.send_screen_instructions + .send(ScreenInstruction::PageScrollUp) + .unwrap(); + } + Action::PageScrollDown => { + self.send_screen_instructions + .send(ScreenInstruction::PageScrollDown) + .unwrap(); + } Action::ToggleFocusFullscreen => { self.send_screen_instructions .send(ScreenInstruction::ToggleActiveTerminalFullscreen) @@ -298,6 +305,7 @@ pub fn get_mode_info(mode: InputMode) -> ModeInfo { } InputMode::Scroll => { keybinds.push(("↓↑".to_string(), "Scroll".to_string())); + keybinds.push(("PgUp/PgDn".to_string(), "Scroll Page".to_string())); } InputMode::RenameTab => { keybinds.push(("Enter".to_string(), "when done".to_string())); diff --git a/src/common/input/keybinds.rs b/src/common/input/keybinds.rs index 8a064970..8e04c44a 100644 --- a/src/common/input/keybinds.rs +++ b/src/common/input/keybinds.rs @@ -7,14 +7,30 @@ use serde::Deserialize; use strum::IntoEnumIterator; use zellij_tile::data::*; +/// Used in the config struct #[derive(Clone, Debug, PartialEq)] pub struct Keybinds(HashMap<InputMode, ModeKeybinds>); #[derive(Clone, Debug, Default, PartialEq)] pub struct ModeKeybinds(HashMap<Key, Vec<Action>>); /// Intermediate struct used for deserialisation +/// Used in the config file. #[derive(Clone, Debug, PartialEq, Deserialize)] -pub struct KeybindsFromYaml(HashMap<InputMode, Vec<KeyActionFromYaml>>); +pub struct KeybindsFromYaml { + #[serde(flatten)] + keybinds: HashMap<InputMode, Vec<KeyActionUnbind>>, + #[serde(default)] + unbind: Unbind, +} + +/// Intermediate enum used for deserialisation +#[derive(Clone, Debug, PartialEq, Deserialize)] +#[serde(untagged)] +enum KeyActionUnbind { + KeyAction(KeyActionFromYaml), + // TODO: use the enum + //Unbind(UnbindFromYaml), +} /// Intermediate struct used for deserialisation #[derive(Clone, Debug, PartialEq, Deserialize)] @@ -23,6 +39,22 @@ pub struct KeyActionFromYaml { key: Vec<Key>, } +/// Intermediate struct used for deserialisation +#[derive(Clone, Debug, PartialEq, Eq, Hash, Deserialize)] +struct UnbindFromYaml { + unbind: Unbind, +} + +/// List of keys, for which to disable their respective default actions +/// `All` is a catch all, and will disable the default actions for all keys. +#[derive(Clone, Debug, PartialEq, Eq, Hash, Deserialize)] +#[serde(untagged)] +enum Unbind { + All(bool), + // TODO@a-kenji: use the enum + //Keys(Vec<Key>), +} + impl Default for Keybinds { fn default() -> Keybinds { let mut defaults = Keybinds::new(); @@ -41,9 +73,16 @@ impl Keybinds { Keybinds(HashMap::<InputMode, ModeKeybinds>::new()) } - pub fn get_default_keybinds_with_config(keybinds: Option<KeybindsFromYaml>) -> Keybinds { - let default_keybinds = Keybinds::default(); - if let Some(keybinds) = keybinds { + pub fn get_default_keybinds_with_config(from_yaml: Option<KeybindsFromYaml>) -> Keybinds { + let default_keybinds = match from_yaml.clone() { + Some(keybinds) => match keybinds.unbind { + Unbind::All(true) => Keybinds::new(), + Unbind::All(false) => Keybinds::default(), + }, + None => Keybinds::default(), + }; + + if let Some(keybinds) = from_yaml { default_keybinds.merge_keybinds(Keybinds::from(keybinds)) } else { default_keybinds @@ -301,6 +340,11 @@ impl Keybinds { defaults.insert(Key::Char('j'), vec![Action::ScrollDown]); defaults.insert(Key::Char('k'), vec![Action::ScrollUp]); + defaults.insert(Key::Ctrl('f'), vec![Action::PageScrollDown]); + defaults.insert(Key::Ctrl('b'), vec![Action::PageScrollUp]); + defaults.insert(Key::PageDown, vec![Action::PageScrollDown]); + defaults.insert(Key::PageUp, vec![Action::PageScrollUp]); + defaults.insert(Key::Down, vec![Action::ScrollDown]); defaults.insert(Key::Up, vec![Action::ScrollUp]); @@ -383,7 +427,7 @@ impl From<KeybindsFromYaml> for Keybinds { for mode in InputMode::iter() { let mut mode_keybinds = ModeKeybinds::new(); - for key_action in keybinds_from_yaml.0.get(&mode).iter() { + for key_action in keybinds_from_yaml.keybinds.get(&mode).iter() { for keybind in key_action.iter() { mode_keybinds = mode_keybinds.merge(ModeKeybinds::from(keybind.clone())); } @@ -409,6 +453,21 @@ impl From<KeyActionFromYaml> for ModeKeybinds { } } +// Currently an enum for future use +impl From<KeyActionUnbind> for ModeKeybinds { + fn from(key_action_unbind: KeyActionUnbind) -> ModeKeybinds { + match key_action_unbind { + KeyActionUnbind::KeyAction(key_action) => ModeKeybinds::from(key_action), + } + } +} + +impl Default for Unbind { + fn default() -> Unbind { + Unbind::All(false) + } +} + // The unit test location. #[cfg(test)] #[path = "./unit/keybinds_test.rs"] diff --git a/src/common/input/unit/keybinds_test.rs b/src/common/input/unit/keybinds_test.rs index 6411d017..e0d78b62 100644 --- a/src/common/input/unit/keybinds_test.rs +++ b/src/common/input/unit/keybinds_test.rs @@ -124,12 +124,25 @@ fn from_keyaction_from_yaml_to_mode_keybindings() { assert_eq!(expected, ModeKeybinds::from(keyaction)); } -//#[test] -//fn from_keybinds_from_yaml_to_keybinds(){ -//let mut keybinds_from_yaml = KeybindsFromYaml(HashMap<InputMode, Vec<KeyActionFromYaml>>); -//let actions = vec![Action::NoOp, Action::GoToTab(1), ]; -//let keyaction = KeyActionFromYaml { -//action : actions.clone(), -//key : vec![ Key::F(1), Key::Backspace , Key::Char('t'), ], -//}; -//} +#[test] +fn toplevel_unbind_unbinds_all() { + let from_yaml = KeybindsFromYaml { + unbind: Unbind::All(true), + keybinds: HashMap::new(), + }; + + let keybinds_from_yaml = Keybinds::get_default_keybinds_with_config(Some(from_yaml)); + + assert_eq!(keybinds_from_yaml, Keybinds::new()); +} + +fn no_unbind_unbinds_none() { + let from_yaml = KeybindsFromYaml { + unbind: Unbind::All(false), + keybinds: HashMap::new(), + }; + + let keybinds_from_yaml = Keybinds::get_default_keybinds_with_config(Some(from_yaml)); + + assert_eq!(keybinds_from_yaml, Keybinds::new()); +} diff --git a/src/common/install.rs b/src/common/install.rs index 8b070848..86fdd269 100644 --- a/src/common/install.rs +++ b/src/common/install.rs @@ -1,12 +1,41 @@ +use std::{fs, path::Path}; + +const VERSION: &str = env!("CARGO_PKG_VERSION"); + #[macro_export] macro_rules! asset_map { ($($src:literal => $dst:literal),+ $(,)?) => { { let mut assets = std::collections::HashMap::new(); $( - assets.insert($dst, include_bytes!(concat!("../", $src)).to_vec()); + assets.insert($dst, include_bytes!(concat!(env!("CARGO_MANIFEST_DIR"), "/", $src)).to_vec()); )+ assets } } } + +pub fn populate_data_dir(data_dir: &Path) { + // First run installation of default plugins & layouts + let mut assets = asset_map! { + "assets/layouts/default.yaml" => "layouts/default.yaml", + "assets/layouts/strider.yaml" => "layouts/strider.yaml", + }; + assets.extend(asset_map! { + "assets/plugins/status-bar.wasm" => "plugins/status-bar.wasm", + "assets/plugins/tab-bar.wasm" => "plugins/tab-bar.wasm", + "assets/plugins/strider.wasm" => "plugins/strider.wasm", + }); + assets.insert("VERSION", VERSION.as_bytes().to_vec()); + + let last_version = fs::read_to_string(data_dir.join("VERSION")).unwrap_or_default(); + let out_of_date = VERSION != last_version; + + for (path, bytes) in assets { + let path = data_dir.join(path); + fs::create_dir_all(path.parent().unwrap()).unwrap(); + if out_of_date || !path.exists() { + fs::write(path, bytes).expect("Failed to install default assets!"); + } + } +} diff --git a/src/common/mod.rs b/src/common/mod.rs index b3bcec9b..3bb5ca88 100644 --- a/src/common/mod.rs +++ b/src/common/mod.rs @@ -16,6 +16,7 @@ use std::thread; use std::{collections::HashMap, fs}; use std::{ collections::HashSet, + env, io::Write, str::FromStr, sync::{Arc, Mutex}, @@ -26,10 +27,15 @@ use crate::common::input::config::Config; use crate::layout::Layout; use crate::panes::PaneId; use colors_transform::{Color, Rgb}; +use async_std::task_local; use command_is_executing::CommandIsExecuting; use directories_next::ProjectDirs; -use errors::{AppContext, ContextType, ErrorContext, PluginContext, PtyContext, ScreenContext}; +use errors::{ + get_current_ctx, AppContext, ContextType, ErrorContext, PluginContext, PtyContext, + ScreenContext, +}; use input::handler::input_loop; +use install::populate_data_dir; use os_input_output::OsApi; use pty_bus::{PtyBus, PtyInstruction}; use screen::{Screen, ScreenInstruction}; @@ -76,32 +82,23 @@ enum SenderType<T: Clone> { /// synchronously or asynchronously depending on the underlying [`SenderType`]. #[derive(Clone)] pub struct SenderWithContext<T: Clone> { - err_ctx: ErrorContext, sender: SenderType<T>, } impl<T: Clone> SenderWithContext<T> { - fn new(err_ctx: ErrorContext, sender: SenderType<T>) -> Self { - Self { err_ctx, sender } + fn new(sender: SenderType<T>) -> Self { + Self { sender } } /// Sends an event, along with the current [`ErrorContext`], on this /// [`SenderWithContext`]'s channel. pub fn send(&self, event: T) -> Result<(), mpsc::SendError<(T, ErrorContext)>> { + let err_ctx = get_current_ctx(); match self.sender { - SenderType::Sender(ref s) => s.send((event, self.err_ctx)), - SenderType::SyncSender(ref s) => s.send((event, self.err_ctx)), + SenderType::Sender(ref s) => s.send((event, err_ctx)), + SenderType::SyncSender(ref s) => s.send((event, err_ctx)), } } - - /// Updates this [`SenderWithContext`]'s [`ErrorContext`]. This is the way one adds - /// a call to the error context. - /// - /// Updating [`ErrorContext`]s works in this way so that these contexts are only ever - /// allocated on the stack (which is thread-specific), and not on the heap. - pub fn update(&mut self, new_ctx: ErrorContext) { - self.err_ctx = new_ctx; - } } unsafe impl<T: Clone> Send for SenderWithContext<T> {} @@ -113,6 +110,12 @@ thread_local!( static OPENCALLS: RefCell<ErrorContext> = RefCell::default() ); +task_local! { + /// A key to some task local storage that holds a representation of the task's call + /// stack in the form of an [`ErrorContext`]. + static ASYNCOPENCALLS: RefCell<ErrorContext> = RefCell::default() +} + /// Instructions related to the entire application. #[derive(Clone)] pub enum AppInstruction { @@ -130,7 +133,9 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: CliArgs) { .write(take_snapshot.as_bytes()) .unwrap(); - let config = Config::from_cli_config(opts.config) + env::set_var(&"ZELLIJ", "0"); + + let config = Config::from_cli_config(opts.config, opts.option) .map_err(|e| { eprintln!("There was an error in the config file:\n{}", e); std::process::exit(1); @@ -144,25 +149,23 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: CliArgs) { let (send_screen_instructions, receive_screen_instructions): ChannelWithContext< ScreenInstruction, > = mpsc::channel(); - let err_ctx = OPENCALLS.with(|ctx| *ctx.borrow()); - let mut send_screen_instructions = - SenderWithContext::new(err_ctx, SenderType::Sender(send_screen_instructions)); + let send_screen_instructions = + SenderWithContext::new(SenderType::Sender(send_screen_instructions)); let (send_pty_instructions, receive_pty_instructions): ChannelWithContext<PtyInstruction> = mpsc::channel(); - let mut send_pty_instructions = - SenderWithContext::new(err_ctx, SenderType::Sender(send_pty_instructions)); + let send_pty_instructions = SenderWithContext::new(SenderType::Sender(send_pty_instructions)); let (send_plugin_instructions, receive_plugin_instructions): ChannelWithContext< PluginInstruction, > = mpsc::channel(); let send_plugin_instructions = - SenderWithContext::new(err_ctx, SenderType::Sender(send_plugin_instructions)); + SenderWithContext::new(SenderType::Sender(send_plugin_instructions)); let (send_app_instructions, receive_app_instructions): SyncChannelWithContext<AppInstruction> = mpsc::sync_channel(0); let send_app_instructions = - SenderWithContext::new(err_ctx, SenderType::SyncSender(send_app_instructions)); + SenderWithContext::new(SenderType::SyncSender(send_app_instructions)); let mut pty_bus = PtyBus::new( receive_pty_instructions, @@ -172,12 +175,22 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: CliArgs) { opts.debug, ); + // Determine and initialize the data directory + let project_dirs = ProjectDirs::from("org", "Zellij Contributors", "Zellij").unwrap(); + let data_dir = opts + .data_dir + .unwrap_or_else(|| project_dirs.data_dir().to_path_buf()); + populate_data_dir(&data_dir); + // Don't use default layouts in tests, but do everywhere else #[cfg(not(test))] let default_layout = Some(PathBuf::from("default")); #[cfg(test)] let default_layout = None; - let maybe_layout = opts.layout.or(default_layout).map(Layout::new); + let maybe_layout = opts + .layout + .or(default_layout) + .map(|p| Layout::new(&p, &data_dir)); #[cfg(not(test))] std::panic::set_hook({ @@ -199,7 +212,6 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: CliArgs) { .recv() .expect("failed to receive event on channel"); err_ctx.add_call(ContextType::Pty(PtyContext::from(&event))); - pty_bus.send_screen_instructions.update(err_ctx); match event { PtyInstruction::SpawnTerminal(file_to_open) => { let pid = pty_bus.spawn_terminal(file_to_open); @@ -282,8 +294,6 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: CliArgs) { .recv() .expect("failed to receive event on channel"); err_ctx.add_call(ContextType::Screen(ScreenContext::from(&event))); - screen.send_app_instructions.update(err_ctx); - screen.send_pty_instructions.update(err_ctx); match event { ScreenInstruction::PtyBytes(pid, vte_bytes) => { let active_tab = screen.get_active_tab_mut().unwrap(); @@ -369,6 +379,18 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: CliArgs) { .unwrap() .scroll_active_terminal_down(); } + ScreenInstruction::PageScrollUp => { + screen + .get_active_tab_mut() + .unwrap() + .scroll_active_terminal_up_page(); + } + ScreenInstruction::PageScrollDown => { + screen + .get_active_tab_mut() + .unwrap() + .scroll_active_terminal_down_page(); + } ScreenInstruction::ClearScroll => { screen .get_active_tab_mut() @@ -443,9 +465,9 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: CliArgs) { let wasm_thread = thread::Builder::new() .name("wasm".to_string()) .spawn({ - let mut send_pty_instructions = send_pty_instructions.clone(); - let mut send_screen_instructions = send_screen_instructions.clone(); - let mut send_app_instructions = send_app_instructions.clone(); + 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 store = Store::default(); let mut plugin_id = 0; @@ -455,14 +477,9 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: CliArgs) { .recv() .expect("failed to receive event on channel"); err_ctx.add_call(ContextType::Plugin(PluginContext::from(&event))); - send_screen_instructions.update(err_ctx); - send_pty_instructions.update(err_ctx); - send_app_instructions.update(err_ctx); match event { PluginInstruction::Load(pid_tx, path) => { - let project_dirs = - ProjectDirs::from("org", "Zellij Contributors", "Zellij").unwrap(); - let plugin_dir = project_dirs.data_dir().join("plugins/"); + let plugin_dir = data_dir.join("plugins/"); let wasm_bytes = fs::read(&path) .or_else(|_| fs::read(&path.with_extension("wasm"))) .or_else(|_| fs::read(&plugin_dir.join(&path).with_extension("wasm"))) @@ -566,16 +583,14 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: CliArgs) { .name("ipc_server".to_string()) .spawn({ use std::io::Read; - let mut send_pty_instructions = send_pty_instructions.clone(); - let mut send_screen_instructions = send_screen_instructions.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) .expect("could not listen on ipc socket"); let mut err_ctx = OPENCALLS.with(|ctx| *ctx.borrow()); err_ctx.add_call(ContextType::IpcServer); - send_pty_instructions.update(err_ctx); - send_screen_instructions.update(err_ctx); for stream in listener.incoming() { match stream { @@ -647,8 +662,6 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: CliArgs) { .expect("failed to receive app instruction on channel"); err_ctx.add_call(ContextType::App(AppContext::from(&app_instruction))); - send_screen_instructions.update(err_ctx); - send_pty_instructions.update(err_ctx); match app_instruction { AppInstruction::Exit => { break; @@ -662,7 +675,11 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: CliArgs) { 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); - let error = format!("{}\n{}", goto_start_of_last_line, backtrace); + let restore_snapshot = "\u{1b}[?1049l"; + let error = format!( + "{}\n{}{}", + goto_start_of_last_line, restore_snapshot, backtrace + ); let _ = os_input .get_stdout_writer() .write(error.as_bytes()) diff --git a/src/common/os_input_output.rs b/src/common/os_input_output.rs index 013b9f12..35d77fdd 100644 --- a/src/common/os_input_output.rs +++ b/src/common/os_input_output.rs @@ -84,15 +84,10 @@ fn handle_command_exit(mut child: Child) { } for signal in signals.pending() { - // FIXME: We need to handle more signals here! - #[allow(clippy::single_match)] - match signal { - SIGINT => { - child.kill().unwrap(); - child.wait().unwrap(); - break 'handle_exit; - } - _ => {} + if let SIGINT = signal { + child.kill().unwrap(); + child.wait().unwrap(); + break 'handle_exit; } } } diff --git a/src/common/pty_bus.rs b/src/common/pty_bus.rs index 2cab8ae8..2c132228 100644 --- a/src/common/pty_bus.rs +++ b/src/common/pty_bus.rs @@ -8,11 +8,11 @@ use ::std::sync::mpsc::Receiver; use ::std::time::{Duration, Instant}; use std::path::PathBuf; -use super::{ScreenInstruction, SenderWithContext, OPENCALLS}; +use super::{ScreenInstruction, SenderWithContext}; use crate::os_input_output::OsApi; use crate::utils::logging::debug_to_file; use crate::{ - errors::{ContextType, ErrorContext}, + errors::{get_current_ctx, ContextType, ErrorContext}, panes::PaneId, }; use crate::{layout::Layout, wasm_vm::PluginInstruction}; @@ -43,7 +43,7 @@ impl Stream for ReadFromPid { // indicates end of file Poll::Ready(None) } else { - let res = Some(read_buffer[..=*res].to_vec()); + let res = Some(read_buffer[..*res].to_vec()); Poll::Ready(res) } } @@ -89,15 +89,14 @@ pub struct PtyBus { fn stream_terminal_bytes( pid: RawFd, - mut send_screen_instructions: SenderWithContext<ScreenInstruction>, + send_screen_instructions: SenderWithContext<ScreenInstruction>, os_input: Box<dyn OsApi>, debug: bool, ) -> JoinHandle<()> { - let mut err_ctx = OPENCALLS.with(|ctx| *ctx.borrow()); + let mut err_ctx = get_current_ctx(); task::spawn({ async move { err_ctx.add_call(ContextType::AsyncTask); - send_screen_instructions.update(err_ctx); let mut terminal_bytes = ReadFromPid::new(&pid, os_input); let mut last_byte_receive_time: Option<Instant> = None; diff --git a/src/common/screen.rs b/src/common/screen.rs index 563221e9..03cfa0bf 100644 --- a/src/common/screen.rs +++ b/src/common/screen.rs @@ -38,6 +38,8 @@ pub enum ScreenInstruction { Quit, ScrollUp, ScrollDown, + PageScrollUp, + PageScrollDown, ClearScroll, CloseFocusedPane, ToggleActiveTerminalFullscreen, @@ -83,7 +85,9 @@ pub struct Screen { } 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<PtyInstruction>, diff --git a/src/common/utils/logging.rs b/src/common/utils/logging.rs index d08639aa..06827bfc 100644 --- a/src/common/utils/logging.rs +++ b/src/common/utils/logging.rs @@ -47,8 +47,7 @@ pub fn _debug_log_to_file_pid_3(message: String, pid: RawFd) -> io::Result<()> { } } -#[allow(dead_code)] -pub fn delete_log_file() -> io::Result<()> { +pub fn _delete_log_file() -> io::Result<()> { if fs::metadata(ZELLIJ_TMP_LOG_FILE).is_ok() { fs::remove_file(ZELLIJ_TMP_LOG_FILE) } else { @@ -56,8 +55,7 @@ pub fn delete_log_file() -> io::Result<()> { } } -#[allow(dead_code)] -pub fn delete_log_dir() -> io::Result<()> { +pub fn _delete_log_dir() -> io::Result<()> { if fs::metadata(ZELLIJ_TMP_LOG_DIR).is_ok() { fs::remove_dir_all(ZELLIJ_TMP_LOG_DIR) } else { diff --git a/src/common/utils/shared.rs b/src/common/utils/shared.rs index 5d01e78e..de15d784 100644 --- a/src/common/utils/shared.rs +++ b/src/common/utils/shared.rs @@ -22,9 +22,9 @@ pub fn adjust_to_size(s: &str, rows: usize, columns: usize) -> String { if actual_len > columns { let mut line = String::from(l); line.truncate(columns); - return line; + line } else { - return [l, &str::repeat(" ", columns - ansi_len(l))].concat(); + [l, &str::repeat(" ", columns - ansi_len(l))].concat() } }) .chain(iter::repeat(str::repeat(" ", columns))) |
