Merge branch 'main' into resize-overhaul

This commit is contained in:
Brooks J Rady 2021-06-01 18:05:32 +01:00
commit 98c29832e1
15 changed files with 226 additions and 30 deletions

View File

@ -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)

View File

@ -0,0 +1,8 @@
---
direction: Horizontal
parts:
- direction: Vertical
split_size:
Fixed: 1
plugin: tab-bar
- direction: Vertical

View File

@ -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)");
}

View File

@ -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

View File

@ -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",

View File

@ -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,

View File

@ -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),

View File

@ -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

View File

@ -246,6 +246,13 @@ impl Tab {
} else {
BTreeMap::new()
};
let name = if name.is_empty() {
format!("Tab #{}", position + 1)
} else {
name
};
Tab {
index,
position,

View File

@ -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,

View File

@ -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.

View File

@ -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};

View File

@ -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,
}
}

View File

@ -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),
}
}
}

View File

@ -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,
}
}