aboutsummaryrefslogtreecommitdiffstats
path: root/src/common
diff options
context:
space:
mode:
authordenis <denismaximov98@gmail.com>2021-04-22 11:45:29 +0300
committerdenis <denismaximov98@gmail.com>2021-04-22 11:45:29 +0300
commit8d98ca7da0bc278a832e4e7de23ff63a84deb529 (patch)
treee7fdfaa6c1ae25e7737dbb36bd1dbcb94d62ab47 /src/common
parentwip: fixing the first arrow (diff)
parentfix(cargo): reduce crate size by 4.8MB using `cargo diet`, to 77kB (diff)
downloadsl0ppij-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.rs16
-rw-r--r--src/common/input/actions.rs4
-rw-r--r--src/common/input/config.rs26
-rw-r--r--src/common/input/handler.rs14
-rw-r--r--src/common/input/keybinds.rs69
-rw-r--r--src/common/input/unit/keybinds_test.rs31
-rw-r--r--src/common/install.rs31
-rw-r--r--src/common/mod.rs103
-rw-r--r--src/common/os_input_output.rs13
-rw-r--r--src/common/pty_bus.rs11
-rw-r--r--src/common/screen.rs4
-rw-r--r--src/common/utils/logging.rs6
-rw-r--r--src/common/utils/shared.rs4
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)))