diff options
author | Brooks J Rady <b.j.rady@gmail.com> | 2021-06-01 18:05:32 +0100 |
---|---|---|
committer | Brooks J Rady <b.j.rady@gmail.com> | 2021-06-01 18:05:32 +0100 |
commit | 98c29832e17683875d5c40c65c5df184972554da (patch) | |
tree | 3d8b8b45d5ee9eec5b5b2423a7d93f041f763b98 | |
parent | f2c5ee44f7f2c61f50b043bd8e55f915a3667fce (diff) | |
parent | d7f12ea58c3e936ecf26d74a639da4e92d346a9b (diff) |
Merge branch 'main' into resize-overhaul
-rw-r--r-- | CHANGELOG.md | 4 | ||||
-rw-r--r-- | assets/layouts/disable-status-bar.yaml | 8 | ||||
-rw-r--r-- | default-plugins/tab-bar/src/tab.rs | 6 | ||||
-rw-r--r-- | docs/MANPAGE.md | 62 | ||||
-rw-r--r-- | src/install.rs | 1 | ||||
-rw-r--r-- | zellij-client/src/lib.rs | 11 | ||||
-rw-r--r-- | zellij-server/src/lib.rs | 4 | ||||
-rw-r--r-- | zellij-server/src/route.rs | 4 | ||||
-rw-r--r-- | zellij-server/src/tab.rs | 7 | ||||
-rw-r--r-- | zellij-tile/src/data.rs | 11 | ||||
-rw-r--r-- | zellij-utils/src/input/config.rs | 19 | ||||
-rw-r--r-- | zellij-utils/src/input/mod.rs | 1 | ||||
-rw-r--r-- | zellij-utils/src/input/options.rs | 12 | ||||
-rw-r--r-- | zellij-utils/src/input/theme.rs | 94 | ||||
-rw-r--r-- | zellij-utils/src/shared.rs | 12 |
15 files changed, 226 insertions, 30 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index ae5491b68..719b09d0f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) * Fix(ui): session mode should be disabled in locked mode (https://github.com/zellij-org/zellij/pull/548) * Add option to start in arbitrary modes (https://github.com/zellij-org/zellij/pull/513) * Attaching to a session respects the `default_mode` setting of the client (https://github.com/zellij-org/zellij/pull/549) +* Add option to specify a color theme in the config (https://github.com/zellij-org/zellij/pull/550) +* Fix config options to not depend on `simplified_ui` (https://github.com/zellij-org/zellij/pull/556) +* Don't rename `unnamed` tabs upon deletion of other tabs (https://github.com/zellij-org/zellij/pull/554) +* Add layout to disable the status bar (https://github.com/zellij-org/zellij/pull/555) ## [0.12.1] - 2021-05-28 * HOTFIX: fix Zellij not responding to input on certain terminals (https://github.com/zellij-org/zellij/issues/538) diff --git a/assets/layouts/disable-status-bar.yaml b/assets/layouts/disable-status-bar.yaml new file mode 100644 index 000000000..fd9c97da6 --- /dev/null +++ b/assets/layouts/disable-status-bar.yaml @@ -0,0 +1,8 @@ +--- +direction: Horizontal +parts: + - direction: Vertical + split_size: + Fixed: 1 + plugin: tab-bar + - direction: Vertical diff --git a/default-plugins/tab-bar/src/tab.rs b/default-plugins/tab-bar/src/tab.rs index fb8e377d1..7e83e85bb 100644 --- a/default-plugins/tab-bar/src/tab.rs +++ b/default-plugins/tab-bar/src/tab.rs @@ -46,11 +46,7 @@ pub fn tab_style( capabilities: PluginCapabilities, ) -> LinePart { let separator = tab_separator(capabilities); - let mut tab_text = if text.is_empty() { - format!("Tab #{}", position + 1) - } else { - text - }; + let mut tab_text = text; if is_sync_panes_active { tab_text.push_str(" (Sync)"); } diff --git a/docs/MANPAGE.md b/docs/MANPAGE.md index 8f9f45b5c..2f78b8312 100644 --- a/docs/MANPAGE.md +++ b/docs/MANPAGE.md @@ -13,6 +13,9 @@ and screen), but this is merely its infrastructure layer. Zellij includes a layout system, and a plugin system allowing one to create plugins in any language that compiles to WebAssembly. +To list currently running sessions run: `zellij list-sessions` +To attach to a currently running session run: `zellij attach [session-name]` + OPTIONS ======= @@ -24,9 +27,12 @@ CONFIGURATION Zellij looks for configuration file in the following order: 1. the file provided with _--config_ -2. under the path provided in *ZELLIJ_CONFIG* environment variable +2. under the path provided in *ZELLIJ_CONFIG_FILE* environment variable 3. the default location (see FILES section) +4. the system location +Run `zellij setup --check` in order to see possible issues with the +configuration. LAYOUTS ======= @@ -85,7 +91,7 @@ KEYBINDINGS =========== Zellij comes with a default set of keybindings which aims to fit as many users -as possible but that behaviour can be overidden or modified in user +as possible but that behaviour can be overridden or modified in user configuration files. The information about bindings is available in the _keybinds_ section of configuration. For example, to introduce a keybinding that will create a new tab and go to tab 1 after pressing 'c' one can write: @@ -147,6 +153,8 @@ ACTIONS Right, Up, Down). * __ScrollUp__ - scrolls up 1 line in the focused pane. * __ScrollDown__ - scrolls down 1 line in the focused pane. +* __PageScrollUp__ - scrolls up 1 page in the focused pane. +* __PageScrollDown__ - scrolls down 1 page in the focused pane. * __ToggleFocusFullscreen__ - toggles between fullscreen focus pane and normal layout. * __NewPane: <Direction\>__ - opens a new pane in the specified direction (Left, @@ -157,6 +165,10 @@ ACTIONS * __GoToPreviousTab__ - goes to previous tab. * __CloseTab__ - closes current tab. * __GoToTab: <Index\>__ - goes to the tab with the specified index number. +* __Detach__ - detach session and exit. +* __ToggleActiveSyncTab__ - toggle between sending text commands to all panes + on the current tab and normal mode. + KEYS ---- @@ -190,8 +202,45 @@ MODES moving, closing). * __resize__ - allows resizing of the focused pane. * __scroll__ - allows scrolling within the focused pane. -* __RenameTab__ - is a "hidden" mode that can be passed to _SwitchToMode_ +* __renametab__ - is a "hidden" mode that can be passed to _SwitchToMode_ action. It will trigger renaming of a tab. +* __session__ - allows detaching from a session. + + +Theme +===== +A color theme can be defined either in truecolor, or 256 format. +Truecolor: +``` +fg: [0, 0, 0] +``` +256: +``` +fg: 0 +``` +The color theme can be specified in the following way: +``` +themes: + default: + fg: [0,0,0] + bg: [0,0,0] + black: [0,0,0] + red: [0,0,0] + green: [0,0,0] + yellow: [0,0,0] + blue: [0,0,0] + magenta: [0,0,0] + cyan: [0,0,0] + white: [0,0,0] + orange: [0,0,0] +``` + +If the theme is called `default`, then zellij will pick it on startup. +To specify a different theme, run zellij with: +``` +zellij options --theme [NAME] +``` +or put the name in the configuration file with `theme: [NAME]`. PLUGINS ======= @@ -210,8 +259,11 @@ Default user configuration file location: ENVIRONMENT =========== -ZELLIJ_CONFIG - Path of Zellij config to load. +ZELLIJ_CONFIG_FILE + Path of Zellij config to load. +ZELLIJ_CONFIG_DIR + Path of the Zellij config directory. + NOTES diff --git a/src/install.rs b/src/install.rs index e9f58a8b9..4fb693763 100644 --- a/src/install.rs +++ b/src/install.rs @@ -19,6 +19,7 @@ pub(crate) fn populate_data_dir(data_dir: &Path) { let mut assets = asset_map! { "assets/layouts/default.yaml" => "layouts/default.yaml", "assets/layouts/strider.yaml" => "layouts/strider.yaml", + "assets/layouts/disable-status-bar.yaml" => "layouts/disable-status-bar.yaml", }; assets.extend(asset_map! { "assets/plugins/status-bar.wasm" => "plugins/status-bar.wasm", diff --git a/zellij-client/src/lib.rs b/zellij-client/src/lib.rs index bd46c90b7..ece154ea7 100644 --- a/zellij-client/src/lib.rs +++ b/zellij-client/src/lib.rs @@ -91,7 +91,14 @@ pub fn start_client( let take_snapshot = "\u{1b}[?1049h"; let bracketed_paste = "\u{1b}[?2004h"; os_input.unset_raw_mode(0); - let palette = os_input.load_palette(); + let config_options = Options::from_cli(&config.options, opts.command.clone()); + let palette = config.themes.clone().map_or_else( + || os_input.load_palette(), + |t| { + t.theme_config(&config_options) + .unwrap_or_else(|| os_input.load_palette()) + }, + ); let _ = os_input .get_stdout_writer() .write(take_snapshot.as_bytes()) @@ -102,8 +109,6 @@ pub fn start_client( .unwrap(); std::env::set_var(&"ZELLIJ", "0"); - let config_options = Options::from_cli(&config.options, opts.command.clone()); - let full_screen_ws = os_input.get_terminal_size_using_fd(0); let client_attributes = ClientAttributes { position_and_size: full_screen_ws, diff --git a/zellij-server/src/lib.rs b/zellij-server/src/lib.rs index 6e6392c2e..4dff7838c 100644 --- a/zellij-server/src/lib.rs +++ b/zellij-server/src/lib.rs @@ -15,7 +15,7 @@ use std::path::PathBuf; use std::sync::{Arc, Mutex, RwLock}; use std::thread; use wasmer::Store; -use zellij_tile::data::{Event, PluginCapabilities}; +use zellij_tile::data::{Event, Palette, PluginCapabilities}; use crate::{ os_input_output::ServerOsApi, @@ -84,6 +84,7 @@ impl ErrorInstruction for ServerInstruction { pub(crate) struct SessionMetaData { pub senders: ThreadSenders, pub capabilities: PluginCapabilities, + pub palette: Palette, screen_thread: Option<thread::JoinHandle<()>>, pty_thread: Option<thread::JoinHandle<()>>, wasm_thread: Option<thread::JoinHandle<()>>, @@ -403,6 +404,7 @@ fn init_session( to_server: None, }, capabilities, + palette: client_attributes.palette, screen_thread: Some(screen_thread), pty_thread: Some(pty_thread), wasm_thread: Some(wasm_thread), diff --git a/zellij-server/src/route.rs b/zellij-server/src/route.rs index 673f563a5..285f333cb 100644 --- a/zellij-server/src/route.rs +++ b/zellij-server/src/route.rs @@ -18,7 +18,7 @@ use zellij_utils::{ fn route_action( action: Action, session: &SessionMetaData, - os_input: &dyn ServerOsApi, + _os_input: &dyn ServerOsApi, to_server: &SenderWithContext<ServerInstruction>, ) -> bool { let mut should_break = false; @@ -34,7 +34,7 @@ fn route_action( .unwrap(); } Action::SwitchToMode(mode) => { - let palette = os_input.load_palette(); + let palette = session.palette; // TODO: use the palette from the client and remove it from the server os api // this is left here as a stop gap measure until we shift some code around // to allow for this diff --git a/zellij-server/src/tab.rs b/zellij-server/src/tab.rs index 45f386c72..0ef616b4d 100644 --- a/zellij-server/src/tab.rs +++ b/zellij-server/src/tab.rs @@ -246,6 +246,13 @@ impl Tab { } else { BTreeMap::new() }; + + let name = if name.is_empty() { + format!("Tab #{}", position + 1) + } else { + name + }; + Tab { index, position, diff --git a/zellij-tile/src/data.rs b/zellij-tile/src/data.rs index 3bd926ca6..4e4b68236 100644 --- a/zellij-tile/src/data.rs +++ b/zellij-tile/src/data.rs @@ -72,13 +72,13 @@ impl Default for InputMode { } #[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq, Hash)] -pub enum Theme { +pub enum ThemeHue { Light, Dark, } -impl Default for Theme { - fn default() -> Theme { - Theme::Dark +impl Default for ThemeHue { + fn default() -> ThemeHue { + ThemeHue::Dark } } @@ -105,6 +105,7 @@ impl FromStr for InputMode { "tab" => Ok(InputMode::Tab), "scroll" => Ok(InputMode::Scroll), "renametab" => Ok(InputMode::RenameTab), + "session" => Ok(InputMode::Session), e => Err(e.to_string().into()), } } @@ -123,7 +124,7 @@ impl Default for PaletteSource { #[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq, Hash, Default)] pub struct Palette { pub source: PaletteSource, - pub theme: Theme, + pub theme_hue: ThemeHue, pub fg: PaletteColor, pub bg: PaletteColor, pub black: PaletteColor, diff --git a/zellij-utils/src/input/config.rs b/zellij-utils/src/input/config.rs index c4cf0cd72..56e333f46 100644 --- a/zellij-utils/src/input/config.rs +++ b/zellij-utils/src/input/config.rs @@ -7,6 +7,7 @@ use std::path::{Path, PathBuf}; use super::keybinds::{Keybinds, KeybindsFromYaml}; use super::options::Options; +use super::theme::ThemesFromYaml; use crate::cli::{CliArgs, Command}; use crate::setup; @@ -23,6 +24,7 @@ pub struct ConfigFromYaml { #[serde(flatten)] pub options: Option<Options>, pub keybinds: Option<KeybindsFromYaml>, + pub themes: Option<ThemesFromYaml>, } /// Main configuration. @@ -30,6 +32,7 @@ pub struct ConfigFromYaml { pub struct Config { pub keybinds: Keybinds, pub options: Options, + pub themes: Option<ThemesFromYaml>, } #[derive(Debug)] @@ -48,7 +51,13 @@ impl Default for Config { fn default() -> Self { let keybinds = Keybinds::default(); let options = Options::default(); - Config { keybinds, options } + let themes = None; + + Config { + keybinds, + options, + themes, + } } } @@ -90,7 +99,13 @@ impl Config { let config_from_yaml: ConfigFromYaml = serde_yaml::from_str(&yaml_config)?; let keybinds = Keybinds::get_default_keybinds_with_config(config_from_yaml.keybinds); let options = Options::from_yaml(config_from_yaml.options); - Ok(Config { keybinds, options }) + let themes = config_from_yaml.themes; + + Ok(Config { + keybinds, + options, + themes, + }) } /// Deserializes from given path. diff --git a/zellij-utils/src/input/mod.rs b/zellij-utils/src/input/mod.rs index 068e22bc4..93a1d2255 100644 --- a/zellij-utils/src/input/mod.rs +++ b/zellij-utils/src/input/mod.rs @@ -4,6 +4,7 @@ pub mod actions; pub mod config; pub mod keybinds; pub mod options; +pub mod theme; use termion::input::TermRead; use zellij_tile::data::{InputMode, Key, ModeInfo, Palette, PluginCapabilities}; diff --git a/zellij-utils/src/input/options.rs b/zellij-utils/src/input/options.rs index 3476c2fb9..04bca6127 100644 --- a/zellij-utils/src/input/options.rs +++ b/zellij-utils/src/input/options.rs @@ -11,8 +11,12 @@ pub struct Options { /// Allow plugins to use a more simplified layout /// that is compatible with more fonts #[structopt(long)] + #[serde(default)] pub simplified_ui: bool, - /// Allows to specify the default mode + /// Set the default theme + #[structopt(long)] + pub theme: Option<String>, + /// Set the default mode #[structopt(long)] pub default_mode: Option<InputMode>, } @@ -41,8 +45,14 @@ impl Options { other => other, }; + let theme = match other.theme { + None => self.theme.clone(), + other => other, + }; + Options { simplified_ui, + theme, default_mode, } } diff --git a/zellij-utils/src/input/theme.rs b/zellij-utils/src/input/theme.rs new file mode 100644 index 000000000..35bd3d87b --- /dev/null +++ b/zellij-utils/src/input/theme.rs @@ -0,0 +1,94 @@ +use serde::{Deserialize, Serialize}; +use std::collections::HashMap; + +use super::options::Options; +use zellij_tile::data::{Palette, PaletteColor}; + +/// Intermediate deserialization of themes +#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)] +pub struct ThemesFromYaml(HashMap<String, Theme>); + +#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)] +struct Theme { + #[serde(flatten)] + palette: PaletteFromYaml, +} + +/// Intermediate deserialization struct +#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq, Hash, Default)] +pub struct PaletteFromYaml { + pub fg: PaletteColorFromYaml, + pub bg: PaletteColorFromYaml, + pub black: PaletteColorFromYaml, + pub red: PaletteColorFromYaml, + pub green: PaletteColorFromYaml, + pub yellow: PaletteColorFromYaml, + pub blue: PaletteColorFromYaml, + pub magenta: PaletteColorFromYaml, + pub cyan: PaletteColorFromYaml, + pub white: PaletteColorFromYaml, + pub orange: PaletteColorFromYaml, +} + +/// Intermediate deserialization enum +// This is here in order to make the untagged enum work +#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq, Hash)] +#[serde(untagged)] +pub enum PaletteColorFromYaml { + Rgb((u8, u8, u8)), + EightBit(u8), +} + +impl Default for PaletteColorFromYaml { + fn default() -> Self { + PaletteColorFromYaml::EightBit(0) + } +} + +impl ThemesFromYaml { + pub fn theme_config(self, opts: &Options) -> Option<Palette> { + let mut from_yaml = self; + match &opts.theme { + Some(theme) => from_yaml.from_default_theme(theme.to_owned()), + None => from_yaml.from_default_theme("default".into()), + } + } + + fn get_theme(&mut self, theme: String) -> Option<Theme> { + self.0.remove(&theme) + } + + fn from_default_theme(&mut self, theme: String) -> Option<Palette> { + self.clone() + .get_theme(theme) + .map(|t| Palette::from(t.palette)) + } +} + +impl From<PaletteFromYaml> for Palette { + fn from(yaml: PaletteFromYaml) -> Self { + Palette { + fg: yaml.fg.into(), + bg: yaml.fg.into(), + black: yaml.black.into(), + red: yaml.red.into(), + green: yaml.green.into(), + yellow: yaml.yellow.into(), + blue: yaml.blue.into(), + magenta: yaml.magenta.into(), + cyan: yaml.cyan.into(), + white: yaml.white.into(), + orange: yaml.orange.into(), + ..Palette::default() + } + } +} + +impl From<PaletteColorFromYaml> for PaletteColor { + fn from(yaml: PaletteColorFromYaml) -> Self { + match yaml { + PaletteColorFromYaml::Rgb(color) => PaletteColor::Rgb(color), + PaletteColorFromYaml::EightBit(color) => PaletteColor::EightBit(color), + } + } +} diff --git a/zellij-utils/src/shared.rs b/zellij-utils/src/shared.rs index bc8b67711..a741cc10b 100644 --- a/zellij-utils/src/shared.rs +++ b/zellij-utils/src/shared.rs @@ -8,7 +8,7 @@ use colors_transform::{Color, Rgb}; use std::os::unix::fs::PermissionsExt; use std::path::Path; use std::{fs, io}; -use zellij_tile::data::{Palette, PaletteColor, PaletteSource, Theme}; +use zellij_tile::data::{Palette, PaletteColor, PaletteSource, ThemeHue}; const UNIX_PERMISSIONS: u32 = 0o700; @@ -64,7 +64,7 @@ pub fn _hex_to_rgb(hex: &str) -> (u8, u8, u8) { pub fn default_palette() -> Palette { Palette { source: PaletteSource::Default, - theme: Theme::Dark, + theme_hue: ThemeHue::Dark, fg: PaletteColor::EightBit(colors::BRIGHT_GRAY), bg: PaletteColor::EightBit(colors::GRAY), black: PaletteColor::EightBit(colors::BLACK), @@ -80,7 +80,7 @@ pub fn default_palette() -> Palette { } // Dark magic -pub fn _detect_theme(bg: PaletteColor) -> Theme { +pub fn _detect_theme_hue(bg: PaletteColor) -> ThemeHue { match bg { PaletteColor::Rgb((r, g, b)) => { // HSP, P stands for perceived brightness @@ -89,11 +89,11 @@ pub fn _detect_theme(bg: PaletteColor) -> Theme { + 0.114 * (b as f64 * b as f64)) .sqrt(); match hsp > 127.5 { - true => Theme::Light, - false => Theme::Dark, + true => ThemeHue::Light, + false => ThemeHue::Dark, } } - _ => Theme::Dark, + _ => ThemeHue::Dark, } } |