diff options
author | a-kenji <aks.kenji@protonmail.com> | 2021-07-22 16:12:35 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-07-22 16:12:35 +0200 |
commit | c9ccfb2919172af58938f9334109c5bdea811713 (patch) | |
tree | 4020b4360cb13c6479362c4f1acc368ae0f24f0d /zellij-utils | |
parent | c5a25f267fdc42ff66a5de6f75720150985b0dce (diff) | |
parent | 2bb3c08ae2b0026ee1109857b62db995b0a4474f (diff) |
Merge branch 'main' into display-session-name
Diffstat (limited to 'zellij-utils')
-rw-r--r-- | zellij-utils/Cargo.toml | 6 | ||||
-rw-r--r-- | zellij-utils/assets/config/default.yaml | 7 | ||||
-rw-r--r-- | zellij-utils/assets/layouts/default.yaml | 6 | ||||
-rw-r--r-- | zellij-utils/assets/layouts/disable-status-bar.yaml | 3 | ||||
-rw-r--r-- | zellij-utils/assets/layouts/strider.yaml | 9 | ||||
-rw-r--r-- | zellij-utils/src/input/actions.rs | 10 | ||||
-rw-r--r-- | zellij-utils/src/input/command.rs | 1 | ||||
-rw-r--r-- | zellij-utils/src/input/layout.rs | 36 | ||||
-rw-r--r-- | zellij-utils/src/input/options.rs | 71 | ||||
-rw-r--r-- | zellij-utils/src/logging.rs | 51 |
10 files changed, 158 insertions, 42 deletions
diff --git a/zellij-utils/Cargo.toml b/zellij-utils/Cargo.toml index 6b530ee96..5761f4140 100644 --- a/zellij-utils/Cargo.toml +++ b/zellij-utils/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "zellij-utils" -version = "0.15.0" +version = "0.16.0" authors = ["Kunal Mohan <kunalmohan99@gmail.com>"] edition = "2018" description = "A utility library for Zellij client and server" @@ -27,7 +27,9 @@ structopt = "0.3" strum = "0.20.0" termion = "1.5.0" vte = "0.10.1" -zellij-tile = { path = "../zellij-tile/", version = "0.15.0" } +zellij-tile = { path = "../zellij-tile/", version = "0.16.0" } +log = "0.4.14" +log4rs = "1.0.0" [dependencies.async-std] version = "1.3.0" diff --git a/zellij-utils/assets/config/default.yaml b/zellij-utils/assets/config/default.yaml index 42bc16886..d9090a8dc 100644 --- a/zellij-utils/assets/config/default.yaml +++ b/zellij-utils/assets/config/default.yaml @@ -240,3 +240,10 @@ keybinds: key: [Ctrl: 'q',] - action: [Detach,] key: [Char: 'd',] + +# Choose what to do when zellij receives SIGTERM, SIGINT, SIGQUIT or SIGHUP +# eg. when terminal window with an active zellij session is closed +# Options: +# - detach (Default) +# - quit +#on_force_close: quit diff --git a/zellij-utils/assets/layouts/default.yaml b/zellij-utils/assets/layouts/default.yaml index 9be7af2a7..96bf1809c 100644 --- a/zellij-utils/assets/layouts/default.yaml +++ b/zellij-utils/assets/layouts/default.yaml @@ -4,9 +4,11 @@ parts: - direction: Vertical split_size: Fixed: 1 - plugin: tab-bar + run: + plugin: tab-bar - direction: Vertical - direction: Vertical split_size: Fixed: 2 - plugin: status-bar + run: + plugin: status-bar diff --git a/zellij-utils/assets/layouts/disable-status-bar.yaml b/zellij-utils/assets/layouts/disable-status-bar.yaml index fd9c97da6..b990ba500 100644 --- a/zellij-utils/assets/layouts/disable-status-bar.yaml +++ b/zellij-utils/assets/layouts/disable-status-bar.yaml @@ -4,5 +4,6 @@ parts: - direction: Vertical split_size: Fixed: 1 - plugin: tab-bar + run: + plugin: tab-bar - direction: Vertical diff --git a/zellij-utils/assets/layouts/strider.yaml b/zellij-utils/assets/layouts/strider.yaml index 5dc9b08f9..9bbe5772f 100644 --- a/zellij-utils/assets/layouts/strider.yaml +++ b/zellij-utils/assets/layouts/strider.yaml @@ -4,15 +4,18 @@ parts: - direction: Vertical split_size: Fixed: 1 - plugin: tab-bar + run: + plugin: tab-bar - direction: Vertical parts: - direction: Horizontal split_size: Percent: 20 - plugin: strider + run: + plugin: strider - direction: Horizontal - direction: Vertical split_size: Fixed: 2 - plugin: status-bar + run: + plugin: status-bar diff --git a/zellij-utils/src/input/actions.rs b/zellij-utils/src/input/actions.rs index ecd515a4a..bfd7d2559 100644 --- a/zellij-utils/src/input/actions.rs +++ b/zellij-utils/src/input/actions.rs @@ -1,6 +1,7 @@ //! Definition of the actions that can be bound to keys. use super::command::RunCommandAction; +use crate::input::options::OnForceClose; use serde::{Deserialize, Serialize}; use zellij_tile::data::InputMode; @@ -81,3 +82,12 @@ pub enum Action { MouseHold(Position), Copy, } + +impl From<OnForceClose> for Action { + fn from(ofc: OnForceClose) -> Action { + match ofc { + OnForceClose::Quit => Action::Quit, + OnForceClose::Detach => Action::Detach, + } + } +} diff --git a/zellij-utils/src/input/command.rs b/zellij-utils/src/input/command.rs index b66c7500e..2054f208d 100644 --- a/zellij-utils/src/input/command.rs +++ b/zellij-utils/src/input/command.rs @@ -11,6 +11,7 @@ pub enum TerminalAction { #[derive(Clone, Debug, Deserialize, Default, Serialize, PartialEq, Eq)] pub struct RunCommand { + #[serde(alias = "cmd")] pub command: PathBuf, #[serde(default)] pub args: Vec<String>, diff --git a/zellij-utils/src/input/layout.rs b/zellij-utils/src/input/layout.rs index 16309db1d..a48c35219 100644 --- a/zellij-utils/src/input/layout.rs +++ b/zellij-utils/src/input/layout.rs @@ -8,7 +8,11 @@ // place. // If plugins should be able to depend on the layout system // then [`zellij-utils`] could be a proper place. -use crate::{input::config::ConfigError, pane_size::PositionAndSize, setup}; +use crate::{ + input::{command::RunCommand, config::ConfigError}, + pane_size::PositionAndSize, + setup, +}; use crate::{serde, serde_yaml}; use serde::{Deserialize, Serialize}; @@ -31,12 +35,21 @@ pub enum SplitSize { #[derive(Debug, Serialize, Deserialize, Clone)] #[serde(crate = "self::serde")] +pub enum Run { + #[serde(rename = "plugin")] + Plugin(Option<PathBuf>), + #[serde(rename = "command")] + Command(RunCommand), +} + +#[derive(Debug, Serialize, Deserialize, Clone)] +#[serde(crate = "self::serde")] pub struct Layout { pub direction: Direction, #[serde(default)] pub parts: Vec<Layout>, pub split_size: Option<SplitSize>, - pub plugin: Option<PathBuf>, + pub run: Option<Run>, } type LayoutResult = Result<Layout, ConfigError>; @@ -127,13 +140,28 @@ impl Layout { let mut total_panes = 0; total_panes += self.parts.len(); for part in self.parts.iter() { - if part.plugin.is_none() { - total_panes += part.total_terminal_panes(); + match part.run { + Some(Run::Command(_)) | None => { + total_panes += part.total_terminal_panes(); + } + Some(Run::Plugin(_)) => {} } } total_panes } + pub fn extract_run_instructions(&self) -> Vec<Option<Run>> { + let mut run_instructions = vec![]; + if self.parts.is_empty() { + run_instructions.push(self.run.clone()); + } + for part in self.parts.iter() { + let mut current_runnables = part.extract_run_instructions(); + run_instructions.append(&mut current_runnables); + } + run_instructions + } + pub fn position_panes_in_space( &self, space: &PositionAndSize, diff --git a/zellij-utils/src/input/options.rs b/zellij-utils/src/input/options.rs index 2ba2be86e..a2f9231cd 100644 --- a/zellij-utils/src/input/options.rs +++ b/zellij-utils/src/input/options.rs @@ -2,12 +2,39 @@ use crate::cli::Command; use serde::{Deserialize, Serialize}; use std::path::PathBuf; +use std::str::FromStr; use structopt::StructOpt; use zellij_tile::data::InputMode; +#[derive(Copy, Clone, Debug, PartialEq, Deserialize, Serialize)] +pub enum OnForceClose { + #[serde(alias = "quit")] + Quit, + #[serde(alias = "detach")] + Detach, +} + +impl Default for OnForceClose { + fn default() -> Self { + Self::Detach + } +} + +impl FromStr for OnForceClose { + type Err = Box<dyn std::error::Error>; + + fn from_str(s: &str) -> Result<Self, Self::Err> { + match s { + "quit" => Ok(Self::Quit), + "detach" => Ok(Self::Detach), + e => Err(e.to_string().into()), + } + } +} + #[derive(Clone, Default, Debug, PartialEq, Deserialize, Serialize, StructOpt)] /// Options that can be set either through the config file, -/// or cli flags +/// or cli flags - cli flags should take precedence over the config file pub struct Options { /// Allow plugins to use a more simplified layout /// that is compatible with more fonts @@ -29,7 +56,11 @@ pub struct Options { pub layout_dir: Option<PathBuf>, #[structopt(long)] #[serde(default)] + /// Disable handling of mouse events pub disable_mouse_mode: bool, + /// Set behaviour on force close (quit or detach) + #[structopt(long)] + pub on_force_close: Option<OnForceClose>, } impl Options { @@ -45,37 +76,16 @@ impl Options { /// will supercede a `Some` in `self` // TODO: Maybe a good candidate for a macro? pub fn merge(&self, other: Options) -> Options { - let simplified_ui = if other.simplified_ui { - true - } else { - self.simplified_ui - }; + let merge_bool = |opt_other, opt_self| if opt_other { true } else { opt_self }; - let default_mode = match other.default_mode { - None => self.default_mode, - other => other, - }; + let simplified_ui = merge_bool(other.simplified_ui, self.simplified_ui); + let disable_mouse_mode = merge_bool(other.disable_mouse_mode, self.disable_mouse_mode); - let default_shell = match other.default_shell { - None => self.default_shell.clone(), - other => other, - }; - - let layout_dir = match other.layout_dir { - None => self.layout_dir.clone(), - other => other, - }; - - let theme = match other.theme { - None => self.theme.clone(), - other => other, - }; - - let disable_mouse_mode = if other.disable_mouse_mode { - true - } else { - self.disable_mouse_mode - }; + let default_mode = other.default_mode.or(self.default_mode); + let default_shell = other.default_shell.or_else(|| self.default_shell.clone()); + let layout_dir = other.layout_dir.or_else(|| self.layout_dir.clone()); + let theme = other.theme.or_else(|| self.theme.clone()); + let on_force_close = other.on_force_close.or(self.on_force_close); Options { simplified_ui, @@ -84,6 +94,7 @@ impl Options { default_shell, layout_dir, disable_mouse_mode, + on_force_close, } } diff --git a/zellij-utils/src/logging.rs b/zellij-utils/src/logging.rs index 6d415e38f..7e57eebda 100644 --- a/zellij-utils/src/logging.rs +++ b/zellij-utils/src/logging.rs @@ -7,9 +7,60 @@ use std::{ path::{Path, PathBuf}, }; +use log::LevelFilter; + +use log4rs::append::file::FileAppender; +use log4rs::config::{Appender, Config, Logger, Root}; +use log4rs::encode::pattern::PatternEncoder; + use crate::consts::{ZELLIJ_TMP_LOG_DIR, ZELLIJ_TMP_LOG_FILE}; use crate::shared::set_permissions; +pub fn configure_logger() { + // {n} means platform dependent newline + // module is padded to exactly 25 bytes and thread is padded to be between 10 and 15 bytes. + let file_pattern = "{highlight({level:<6})} |{module:<25.25}| {date(%Y-%m-%d %H:%M:%S.%3f)} [{thread:<10.15}] [{file}:{line}]: {message} {n}"; + + // default zellij appender, should be used across most of the codebase. + let log_file = FileAppender::builder() + .encoder(Box::new(PatternEncoder::new(file_pattern))) + .append(true) + .build(ZELLIJ_TMP_LOG_DIR.join("zellij.log")) + .unwrap(); + + // plugin appender. To be used in loggin_pipe to forward stderr output from plugins. We do some formatting + // in logging_pipe to print plugin name as 'module' and plugin_id instead of thread. + let log_plugin = FileAppender::builder() + .encoder(Box::new(PatternEncoder::new( + "{highlight({level:<6})} {message} {n}", + ))) + .append(true) + .build(ZELLIJ_TMP_LOG_DIR.join("zellij.log")) + .unwrap(); + + // Set the default logging level to "info" and log it to zellij.log file + // Decrease verbosity for `wasmer_compiler_cranelift` module because it has a lot of useless info logs + // For `zellij_server::logging_pipe`, we use custom format as we use logging macros to forward stderr output from plugins + let config = Config::builder() + .appender(Appender::builder().build("logFile", Box::new(log_file))) + .appender(Appender::builder().build("logPlugin", Box::new(log_plugin))) + .logger( + Logger::builder() + .appender("logFile") + .build("wasmer_compiler_cranelift", LevelFilter::Warn), + ) + .logger( + Logger::builder() + .appender("logPlugin") + .additive(false) + .build("zellij_server::logging_pipe", LevelFilter::Trace), + ) + .build(Root::builder().appender("logFile").build(LevelFilter::Info)) + .unwrap(); + + let _ = log4rs::init_config(config).unwrap(); +} + pub fn atomic_create_file(file_name: &Path) -> io::Result<()> { let _ = fs::OpenOptions::new() .append(true) |