wip: scary how messy it is, but it's a start

This commit is contained in:
denis 2021-03-26 16:42:38 +02:00
parent a35cade8de
commit 2c402b0b1d
11 changed files with 346 additions and 188 deletions

2
Cargo.lock generated
View File

@ -30,7 +30,6 @@ version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2"
dependencies = [
"serde",
"winapi",
]
@ -2321,7 +2320,6 @@ dependencies = [
name = "zellij-tile"
version = "0.5.0"
dependencies = [
"ansi_term 0.12.1",
"serde",
"serde_json",
]

View File

@ -1,4 +1,4 @@
use ansi_term::{ANSIStrings, Style};
use ansi_term::{ANSIStrings, Color::RGB, Style};
use zellij_tile::*;
use crate::colors::{BLACK, BRIGHT_GRAY, GRAY, GREEN, RED, WHITE};
@ -63,32 +63,38 @@ impl CtrlKeyShortcut {
}
}
fn unselected_mode_shortcut(letter: char, text: &str) -> LinePart {
let prefix_separator = Style::new().fg(GRAY).on(BRIGHT_GRAY).paint(ARROW_SEPARATOR);
fn unselected_mode_shortcut(letter: char, text: &str, palette: Palette) -> LinePart {
let prefix_separator = Style::new()
.fg(RGB(palette.fg.0, palette.fg.1, palette.fg.2))
.on(RGB(palette.bg.0, palette.bg.1, palette.bg.2))
.paint(ARROW_SEPARATOR);
let char_left_separator = Style::new()
.bold()
.fg(BLACK)
.on(BRIGHT_GRAY)
.fg(RGB(palette.fg.0, palette.fg.1, palette.fg.2))
.on(RGB(palette.bg.0, palette.bg.1, palette.bg.2))
.bold()
.paint(format!(" <"));
let char_shortcut = Style::new()
.bold()
.fg(RED)
.on(BRIGHT_GRAY)
.fg(RGB(palette.red.0, palette.red.1, palette.red.2))
.on(RGB(palette.bg.0, palette.bg.1, palette.bg.2))
.bold()
.paint(format!("{}", letter));
let char_right_separator = Style::new()
.bold()
.fg(BLACK)
.on(BRIGHT_GRAY)
.fg(RGB(palette.fg.0, palette.fg.1, palette.fg.2))
.on(RGB(palette.bg.0, palette.bg.1, palette.bg.2))
.bold()
.paint(format!(">"));
let styled_text = Style::new()
.fg(BLACK)
.on(BRIGHT_GRAY)
.fg(RGB(palette.fg.0, palette.fg.1, palette.fg.2))
.on(RGB(palette.bg.0, palette.bg.1, palette.bg.2))
.bold()
.paint(format!("{} ", text));
let suffix_separator = Style::new().fg(BRIGHT_GRAY).on(GRAY).paint(ARROW_SEPARATOR);
let suffix_separator = Style::new()
.fg(RGB(palette.fg.0, palette.fg.1, palette.fg.2))
.on(RGB(palette.bg.0, palette.bg.1, palette.bg.2))
.paint(ARROW_SEPARATOR);
LinePart {
part: format!(
"{}",
@ -105,32 +111,38 @@ fn unselected_mode_shortcut(letter: char, text: &str) -> LinePart {
}
}
fn selected_mode_shortcut(letter: char, text: &str) -> LinePart {
let prefix_separator = Style::new().fg(GRAY).on(GREEN).paint(ARROW_SEPARATOR);
fn selected_mode_shortcut(letter: char, text: &str, palette: Palette) -> LinePart {
let prefix_separator = Style::new()
.fg(RGB(palette.bg.0, palette.bg.1, palette.bg.2))
.on(RGB(palette.green.0, palette.green.1, palette.green.2))
.paint(ARROW_SEPARATOR);
let char_left_separator = Style::new()
.bold()
.fg(BLACK)
.on(GREEN)
.fg(RGB(palette.bg.0, palette.bg.1, palette.bg.2))
.on(RGB(palette.green.0, palette.green.1, palette.green.2))
.bold()
.paint(format!(" <"));
let char_shortcut = Style::new()
.bold()
.fg(RED)
.on(GREEN)
.fg(RGB(palette.red.0, palette.red.1, palette.red.2))
.on(RGB(palette.green.0, palette.green.1, palette.green.2))
.bold()
.paint(format!("{}", letter));
let char_right_separator = Style::new()
.bold()
.fg(BLACK)
.on(GREEN)
.fg(RGB(palette.bg.0, palette.bg.1, palette.bg.2))
.on(RGB(palette.green.0, palette.green.1, palette.green.2))
.bold()
.paint(format!(">"));
let styled_text = Style::new()
.fg(BLACK)
.on(GREEN)
.fg(RGB(palette.bg.0, palette.bg.1, palette.bg.2))
.on(RGB(palette.green.0, palette.green.1, palette.green.2))
.bold()
.paint(format!("{} ", text));
let suffix_separator = Style::new().fg(GREEN).on(GRAY).paint(ARROW_SEPARATOR);
let suffix_separator = Style::new()
.fg(RGB(palette.green.0, palette.green.1, palette.green.2))
.on(RGB(palette.green.0, palette.green.1, palette.green.2))
.paint(ARROW_SEPARATOR);
LinePart {
part: format!(
"{}",
@ -147,31 +159,43 @@ fn selected_mode_shortcut(letter: char, text: &str) -> LinePart {
}
}
fn disabled_mode_shortcut(text: &str) -> LinePart {
let prefix_separator = Style::new().fg(GRAY).on(BRIGHT_GRAY).paint(ARROW_SEPARATOR);
fn disabled_mode_shortcut(text: &str, palette: Palette) -> LinePart {
let prefix_separator = Style::new()
.fg(RGB(palette.fg.0, palette.fg.1, palette.fg.2))
.on(RGB(palette.bg.0, palette.bg.1, palette.bg.2))
.paint(ARROW_SEPARATOR);
let styled_text = Style::new()
.fg(GRAY)
.on(BRIGHT_GRAY)
.fg(RGB(palette.fg.0, palette.fg.1, palette.fg.2))
.on(RGB(palette.bg.0, palette.bg.1, palette.bg.2))
.dimmed()
.paint(format!("{} ", text));
let suffix_separator = Style::new().fg(BRIGHT_GRAY).on(GRAY).paint(ARROW_SEPARATOR);
let suffix_separator = Style::new()
.fg(RGB(palette.fg.0, palette.fg.1, palette.fg.2))
.on(RGB(palette.bg.0, palette.bg.1, palette.bg.2))
.paint(ARROW_SEPARATOR);
LinePart {
part: format!("{}{}{}", prefix_separator, styled_text, suffix_separator),
len: text.chars().count() + 2 + 1, // 2 for the arrows, 1 for the padding in the end
}
}
fn selected_mode_shortcut_single_letter(letter: char) -> LinePart {
fn selected_mode_shortcut_single_letter(letter: char, palette: Palette) -> LinePart {
let char_shortcut_text = format!(" {} ", letter);
let len = char_shortcut_text.chars().count() + 4; // 2 for the arrows, 2 for the padding
let prefix_separator = Style::new().fg(GRAY).on(GREEN).paint(ARROW_SEPARATOR);
let prefix_separator = Style::new()
.fg(RGB(palette.black.0, palette.black.1, palette.black.2))
.on(RGB(palette.green.0, palette.green.1, palette.green.2))
.paint(ARROW_SEPARATOR);
let char_shortcut = Style::new()
.bold()
.fg(RED)
.on(GREEN)
.fg(RGB(palette.red.0, palette.red.1, palette.red.2))
.on(RGB(palette.green.0, palette.green.1, palette.green.2))
.bold()
.paint(char_shortcut_text);
let suffix_separator = Style::new().fg(GREEN).on(GRAY).paint(ARROW_SEPARATOR);
let suffix_separator = Style::new()
.fg(RGB(palette.green.0, palette.green.1, palette.green.2))
.on(RGB(palette.bg.0, palette.bg.1, palette.bg.2))
.paint(ARROW_SEPARATOR);
LinePart {
part: format!(
"{}",
@ -181,17 +205,23 @@ fn selected_mode_shortcut_single_letter(letter: char) -> LinePart {
}
}
fn unselected_mode_shortcut_single_letter(letter: char) -> LinePart {
fn unselected_mode_shortcut_single_letter(letter: char, palette: Palette) -> LinePart {
let char_shortcut_text = format!(" {} ", letter);
let len = char_shortcut_text.chars().count() + 4; // 2 for the arrows, 2 for the padding
let prefix_separator = Style::new().fg(GRAY).on(BRIGHT_GRAY).paint(ARROW_SEPARATOR);
let prefix_separator = Style::new()
.fg(RGB(palette.fg.0, palette.fg.1, palette.fg.2))
.on(RGB(palette.bg.0, palette.bg.1, palette.bg.2))
.paint(ARROW_SEPARATOR);
let char_shortcut = Style::new()
.bold()
.fg(RED)
.on(BRIGHT_GRAY)
.fg(RGB(palette.red.0, palette.red.1, palette.red.2))
.on(RGB(palette.bg.0, palette.bg.1, palette.bg.2))
.bold()
.paint(char_shortcut_text);
let suffix_separator = Style::new().fg(BRIGHT_GRAY).on(GRAY).paint(ARROW_SEPARATOR);
let suffix_separator = Style::new()
.fg(RGB(palette.fg.0, palette.fg.1, palette.fg.2))
.on(RGB(palette.bg.0, palette.bg.1, palette.bg.2))
.paint(ARROW_SEPARATOR);
LinePart {
part: format!(
"{}",
@ -201,23 +231,23 @@ fn unselected_mode_shortcut_single_letter(letter: char) -> LinePart {
}
}
fn full_ctrl_key(key: &CtrlKeyShortcut) -> LinePart {
fn full_ctrl_key(key: &CtrlKeyShortcut, palette: Palette) -> LinePart {
let full_text = key.full_text();
let letter_shortcut = key.letter_shortcut();
match key.mode {
CtrlKeyMode::Unselected => {
unselected_mode_shortcut(letter_shortcut, &format!(" {}", full_text))
unselected_mode_shortcut(letter_shortcut, &format!(" {}", full_text), palette)
}
CtrlKeyMode::Selected => {
selected_mode_shortcut(letter_shortcut, &format!(" {}", full_text))
selected_mode_shortcut(letter_shortcut, &format!(" {}", full_text), palette)
}
CtrlKeyMode::Disabled => {
disabled_mode_shortcut(&format!(" <{}> {}", letter_shortcut, full_text))
disabled_mode_shortcut(&format!(" <{}> {}", letter_shortcut, full_text), palette)
}
}
}
fn shortened_ctrl_key(key: &CtrlKeyShortcut) -> LinePart {
fn shortened_ctrl_key(key: &CtrlKeyShortcut, palette: Palette) -> LinePart {
let shortened_text = key.shortened_text();
let letter_shortcut = key.letter_shortcut();
let shortened_text = match key.action {
@ -226,30 +256,31 @@ fn shortened_ctrl_key(key: &CtrlKeyShortcut) -> LinePart {
};
match key.mode {
CtrlKeyMode::Unselected => {
unselected_mode_shortcut(letter_shortcut, &format!("{}", shortened_text))
unselected_mode_shortcut(letter_shortcut, &format!("{}", shortened_text), palette)
}
CtrlKeyMode::Selected => {
selected_mode_shortcut(letter_shortcut, &format!("{}", shortened_text))
}
CtrlKeyMode::Disabled => {
disabled_mode_shortcut(&format!(" <{}>{}", letter_shortcut, shortened_text))
selected_mode_shortcut(letter_shortcut, &format!("{}", shortened_text), palette)
}
CtrlKeyMode::Disabled => disabled_mode_shortcut(
&format!(" <{}>{}", letter_shortcut, shortened_text),
palette,
),
}
}
fn single_letter_ctrl_key(key: &CtrlKeyShortcut) -> LinePart {
fn single_letter_ctrl_key(key: &CtrlKeyShortcut, palette: Palette) -> LinePart {
let letter_shortcut = key.letter_shortcut();
match key.mode {
CtrlKeyMode::Unselected => unselected_mode_shortcut_single_letter(letter_shortcut),
CtrlKeyMode::Selected => selected_mode_shortcut_single_letter(letter_shortcut),
CtrlKeyMode::Disabled => disabled_mode_shortcut(&format!(" {}", letter_shortcut)),
CtrlKeyMode::Unselected => unselected_mode_shortcut_single_letter(letter_shortcut, palette),
CtrlKeyMode::Selected => selected_mode_shortcut_single_letter(letter_shortcut, palette),
CtrlKeyMode::Disabled => disabled_mode_shortcut(&format!(" {}", letter_shortcut), palette),
}
}
fn key_indicators(max_len: usize, keys: &[CtrlKeyShortcut]) -> LinePart {
fn key_indicators(max_len: usize, keys: &[CtrlKeyShortcut], palette: Palette) -> LinePart {
let mut line_part = LinePart::default();
for ctrl_key in keys {
let key = full_ctrl_key(ctrl_key);
let key = full_ctrl_key(ctrl_key, palette);
line_part.part = format!("{}{}", line_part.part, key.part);
line_part.len += key.len;
}
@ -258,7 +289,7 @@ fn key_indicators(max_len: usize, keys: &[CtrlKeyShortcut]) -> LinePart {
}
line_part = LinePart::default();
for ctrl_key in keys {
let key = shortened_ctrl_key(ctrl_key);
let key = shortened_ctrl_key(ctrl_key, palette);
line_part.part = format!("{}{}", line_part.part, key.part);
line_part.len += key.len;
}
@ -267,7 +298,7 @@ fn key_indicators(max_len: usize, keys: &[CtrlKeyShortcut]) -> LinePart {
}
line_part = LinePart::default();
for ctrl_key in keys {
let key = single_letter_ctrl_key(ctrl_key);
let key = single_letter_ctrl_key(ctrl_key, palette);
line_part.part = format!("{}{}", line_part.part, key.part);
line_part.len += key.len;
}
@ -278,9 +309,13 @@ fn key_indicators(max_len: usize, keys: &[CtrlKeyShortcut]) -> LinePart {
line_part
}
pub fn superkey() -> LinePart {
pub fn superkey(palette: Palette) -> LinePart {
let prefix_text = " Ctrl + ";
let prefix = Style::new().fg(WHITE).on(GRAY).bold().paint(prefix_text);
let prefix = Style::new()
.fg(RGB(palette.fg.0, palette.fg.1, palette.fg.2))
.on(RGB(palette.bg.0, palette.bg.1, palette.bg.2))
.bold()
.paint(prefix_text);
LinePart {
part: format!("{}", prefix),
len: prefix_text.chars().count(),
@ -299,6 +334,7 @@ pub fn ctrl_keys(help: &Help, max_len: usize) -> LinePart {
CtrlKeyShortcut::new(CtrlKeyMode::Disabled, CtrlKeyAction::Scroll),
CtrlKeyShortcut::new(CtrlKeyMode::Disabled, CtrlKeyAction::Quit),
],
help.palette,
),
InputMode::Resize => key_indicators(
max_len,
@ -310,6 +346,7 @@ pub fn ctrl_keys(help: &Help, max_len: usize) -> LinePart {
CtrlKeyShortcut::new(CtrlKeyMode::Unselected, CtrlKeyAction::Scroll),
CtrlKeyShortcut::new(CtrlKeyMode::Unselected, CtrlKeyAction::Quit),
],
help.palette,
),
InputMode::Pane => key_indicators(
max_len,
@ -321,6 +358,7 @@ pub fn ctrl_keys(help: &Help, max_len: usize) -> LinePart {
CtrlKeyShortcut::new(CtrlKeyMode::Unselected, CtrlKeyAction::Scroll),
CtrlKeyShortcut::new(CtrlKeyMode::Unselected, CtrlKeyAction::Quit),
],
help.palette,
),
InputMode::Tab | InputMode::RenameTab => key_indicators(
max_len,
@ -332,6 +370,7 @@ pub fn ctrl_keys(help: &Help, max_len: usize) -> LinePart {
CtrlKeyShortcut::new(CtrlKeyMode::Unselected, CtrlKeyAction::Scroll),
CtrlKeyShortcut::new(CtrlKeyMode::Unselected, CtrlKeyAction::Quit),
],
help.palette,
),
InputMode::Scroll => key_indicators(
max_len,
@ -343,6 +382,7 @@ pub fn ctrl_keys(help: &Help, max_len: usize) -> LinePart {
CtrlKeyShortcut::new(CtrlKeyMode::Selected, CtrlKeyAction::Scroll),
CtrlKeyShortcut::new(CtrlKeyMode::Unselected, CtrlKeyAction::Quit),
],
help.palette,
),
InputMode::Normal | _ => key_indicators(
max_len,
@ -354,6 +394,7 @@ pub fn ctrl_keys(help: &Help, max_len: usize) -> LinePart {
CtrlKeyShortcut::new(CtrlKeyMode::Unselected, CtrlKeyAction::Scroll),
CtrlKeyShortcut::new(CtrlKeyMode::Unselected, CtrlKeyAction::Quit),
],
help.palette,
),
}
}

View File

@ -48,15 +48,15 @@ impl ZellijTile for State {
fn draw(&mut self, _rows: usize, cols: usize) {
let help = get_help();
let superkey = superkey();
let superkey = superkey(help.palette);
let ctrl_keys = ctrl_keys(&help, cols - superkey.len);
let first_line = format!("{}{}", superkey, ctrl_keys);
let second_line = keybinds(&help, cols);
let second_line = keybinds(&help, cols, help.palette);
// [48;5;238m is gray background, [0K is so that it fills the rest of the line
// [48;5;16m is black background, [0K is so that it fills the rest of the line
println!("{}\u{1b}[48;5;238m\u{1b}[0K", first_line);
println!("{}\u{1b}[48;5;16m\u{1b}[0K", second_line);
println!("{}\u{1b}[{};{};{}m\u{1b}[0K", first_line, help.palette.bg.0, help.palette.bg.1, help.palette.bg.2);
println!("{}\u{1b}[{};{};{}m\u{1b}[0K", second_line, help.palette.bg.0, help.palette.bg.1, help.palette.bg.2);
}
}

View File

@ -1,19 +1,41 @@
// use colored::*;
use ansi_term::{ANSIStrings, Style};
use ansi_term::{ANSIStrings, Color::RGB, Style};
use zellij_tile::*;
use crate::colors::{BLACK, GREEN, ORANGE, WHITE};
use crate::{LinePart, MORE_MSG};
fn full_length_shortcut(is_first_shortcut: bool, letter: &str, description: &str) -> LinePart {
fn full_length_shortcut(
is_first_shortcut: bool,
letter: &str,
description: &str,
palette: Palette,
) -> LinePart {
let separator = if is_first_shortcut { " " } else { " / " };
let separator = Style::new().on(BLACK).fg(WHITE).paint(separator);
let separator = Style::new()
.on(RGB(palette.bg.0, palette.bg.1, palette.bg.2))
.fg(RGB(palette.fg.0, palette.fg.1, palette.fg.2))
.paint(separator);
let shortcut_len = letter.chars().count() + 3; // 2 for <>'s around shortcut, 1 for the space
let shortcut_left_separator = Style::new().on(BLACK).fg(WHITE).paint("<");
let shortcut = Style::new().on(BLACK).fg(GREEN).bold().paint(letter);
let shortcut_right_separator = Style::new().on(BLACK).fg(WHITE).paint("> ");
let shortcut_left_separator = Style::new()
.on(RGB(palette.bg.0, palette.bg.1, palette.bg.2))
.fg(RGB(palette.fg.0, palette.fg.1, palette.fg.2))
.paint("<");
let shortcut = Style::new()
.on(RGB(palette.bg.0, palette.bg.1, palette.bg.2))
.fg(ORANGE)
.bold()
.paint(letter);
let shortcut_right_separator = Style::new()
.on(RGB(palette.bg.0, palette.bg.1, palette.bg.2))
.fg(RGB(palette.fg.0, palette.fg.1, palette.fg.2))
.paint("> ");
let description_len = description.chars().count();
let description = Style::new().on(BLACK).fg(WHITE).bold().paint(description);
let description = Style::new()
.on(RGB(palette.bg.0, palette.bg.1, palette.bg.2))
.fg(RGB(palette.fg.0, palette.fg.1, palette.fg.2))
.bold()
.paint(description);
let len = shortcut_len + description_len + separator.chars().count();
LinePart {
part: format!(
@ -30,18 +52,36 @@ fn full_length_shortcut(is_first_shortcut: bool, letter: &str, description: &str
}
}
fn first_word_shortcut(is_first_shortcut: bool, letter: &str, description: &str) -> LinePart {
fn first_word_shortcut(
is_first_shortcut: bool,
letter: &str,
description: &str,
palette: Palette,
) -> LinePart {
let separator = if is_first_shortcut { " " } else { " / " };
let separator = Style::new().on(BLACK).fg(WHITE).paint(separator);
let separator = Style::new()
.on(RGB(palette.bg.0, palette.bg.1, palette.bg.2))
.fg(RGB(palette.fg.0, palette.fg.1, palette.fg.2))
.paint(separator);
let shortcut_len = letter.chars().count() + 3; // 2 for <>'s around shortcut, 1 for the space
let shortcut_left_separator = Style::new().on(BLACK).fg(WHITE).paint("<");
let shortcut = Style::new().on(BLACK).fg(GREEN).bold().paint(letter);
let shortcut_right_separator = Style::new().on(BLACK).fg(WHITE).paint("> ");
let shortcut_left_separator = Style::new()
.on(RGB(palette.bg.0, palette.bg.1, palette.bg.2))
.fg(RGB(palette.fg.0, palette.fg.1, palette.fg.2))
.paint("<");
let shortcut = Style::new()
.on(RGB(palette.bg.0, palette.bg.1, palette.bg.2))
.fg(RGB(palette.green.0, palette.green.1, palette.green.2))
.bold()
.paint(letter);
let shortcut_right_separator = Style::new()
.on(RGB(palette.bg.0, palette.bg.1, palette.bg.2))
.fg(RGB(palette.fg.0, palette.fg.1, palette.fg.2))
.paint("> ");
let description_first_word = description.split(' ').next().unwrap_or("");
let description_first_word_length = description_first_word.chars().count();
let description_first_word = Style::new()
.on(BLACK)
.fg(WHITE)
.on(RGB(palette.bg.0, palette.bg.1, palette.bg.2))
.fg(RGB(palette.fg.0, palette.fg.1, palette.fg.2))
.bold()
.paint(description_first_word);
let len = shortcut_len + description_first_word_length + separator.chars().count();
@ -60,27 +100,48 @@ fn first_word_shortcut(is_first_shortcut: bool, letter: &str, description: &str)
}
}
fn locked_interface_indication() -> LinePart {
fn locked_interface_indication(palette: Palette) -> LinePart {
let locked_text = " -- INTERFACE LOCKED -- ";
let locked_text_len = locked_text.chars().count();
let locked_styled_text = Style::new().on(BLACK).fg(WHITE).bold().paint(locked_text);
let locked_styled_text = Style::new()
.on(RGB(palette.bg.0, palette.bg.1, palette.bg.2))
.fg(RGB(palette.fg.0, palette.fg.1, palette.fg.2))
.bold()
.paint(locked_text);
LinePart {
part: format!("{}", locked_styled_text),
len: locked_text_len,
}
}
fn select_pane_shortcut(is_first_shortcut: bool) -> LinePart {
fn select_pane_shortcut(is_first_shortcut: bool, palette: Palette) -> LinePart {
let shortcut = "ENTER";
let description = "Select pane";
let separator = if is_first_shortcut { " " } else { " / " };
let separator = Style::new().on(BLACK).fg(WHITE).paint(separator);
let separator = Style::new()
.on(RGB(palette.bg.0, palette.bg.1, palette.bg.2))
.fg(RGB(palette.fg.0, palette.fg.1, palette.fg.2))
.paint(separator);
let shortcut_len = shortcut.chars().count() + 3; // 2 for <>'s around shortcut, 1 for the space
let shortcut_left_separator = Style::new().on(BLACK).fg(WHITE).paint("<");
let shortcut = Style::new().on(BLACK).fg(ORANGE).bold().paint(shortcut);
let shortcut_right_separator = Style::new().on(BLACK).fg(WHITE).paint("> ");
let shortcut_left_separator = Style::new()
.on(RGB(palette.bg.0, palette.bg.1, palette.bg.2))
.fg(RGB(palette.fg.0, palette.fg.1, palette.fg.2))
.paint("<");
let shortcut = Style::new()
.on(RGB(palette.black.0, palette.black.1, palette.black.2))
.fg(ORANGE)
.bold()
.paint(shortcut);
let shortcut_right_separator = Style::new()
.on(RGB(palette.bg.0, palette.bg.1, palette.bg.2))
.fg(RGB(palette.fg.0, palette.fg.1, palette.fg.2))
.paint("> ");
let description_len = description.chars().count();
let description = Style::new().on(BLACK).fg(WHITE).bold().paint(description);
let description = Style::new()
.on(RGB(palette.bg.0, palette.bg.1, palette.bg.2))
.fg(RGB(palette.fg.0, palette.fg.1, palette.fg.2))
.bold()
.paint(description);
let len = shortcut_len + description_len + separator.chars().count();
LinePart {
part: format!(
@ -97,18 +158,18 @@ fn select_pane_shortcut(is_first_shortcut: bool) -> LinePart {
}
}
fn full_shortcut_list(help: &Help) -> LinePart {
fn full_shortcut_list(help: &Help, palette: Palette) -> LinePart {
match help.mode {
InputMode::Normal => LinePart::default(),
InputMode::Locked => locked_interface_indication(),
InputMode::Locked => locked_interface_indication(palette),
_ => {
let mut line_part = LinePart::default();
for (i, (letter, description)) in help.keybinds.iter().enumerate() {
let shortcut = full_length_shortcut(i == 0, &letter, &description);
let shortcut = full_length_shortcut(i == 0, &letter, &description, palette);
line_part.len += shortcut.len;
line_part.part = format!("{}{}", line_part.part, shortcut,);
}
let select_pane_shortcut = select_pane_shortcut(help.keybinds.len() == 0);
let select_pane_shortcut = select_pane_shortcut(help.keybinds.len() == 0, palette);
line_part.len += select_pane_shortcut.len;
line_part.part = format!("{}{}", line_part.part, select_pane_shortcut,);
line_part
@ -116,18 +177,18 @@ fn full_shortcut_list(help: &Help) -> LinePart {
}
}
fn shortened_shortcut_list(help: &Help) -> LinePart {
fn shortened_shortcut_list(help: &Help, palette: Palette) -> LinePart {
match help.mode {
InputMode::Normal => LinePart::default(),
InputMode::Locked => locked_interface_indication(),
InputMode::Locked => locked_interface_indication(palette),
_ => {
let mut line_part = LinePart::default();
for (i, (letter, description)) in help.keybinds.iter().enumerate() {
let shortcut = first_word_shortcut(i == 0, &letter, &description);
let shortcut = first_word_shortcut(i == 0, &letter, &description, palette);
line_part.len += shortcut.len;
line_part.part = format!("{}{}", line_part.part, shortcut,);
}
let select_pane_shortcut = select_pane_shortcut(help.keybinds.len() == 0);
let select_pane_shortcut = select_pane_shortcut(help.keybinds.len() == 0, palette);
line_part.len += select_pane_shortcut.len;
line_part.part = format!("{}{}", line_part.part, select_pane_shortcut,);
line_part
@ -135,11 +196,11 @@ fn shortened_shortcut_list(help: &Help) -> LinePart {
}
}
fn best_effort_shortcut_list(help: &Help, max_len: usize) -> LinePart {
fn best_effort_shortcut_list(help: &Help, max_len: usize, palette: Palette) -> LinePart {
match help.mode {
InputMode::Normal => LinePart::default(),
InputMode::Locked => {
let line_part = locked_interface_indication();
let line_part = locked_interface_indication(palette);
if line_part.len <= max_len {
line_part
} else {
@ -149,7 +210,7 @@ fn best_effort_shortcut_list(help: &Help, max_len: usize) -> LinePart {
_ => {
let mut line_part = LinePart::default();
for (i, (letter, description)) in help.keybinds.iter().enumerate() {
let shortcut = first_word_shortcut(i == 0, &letter, &description);
let shortcut = first_word_shortcut(i == 0, &letter, &description, palette);
if line_part.len + shortcut.len + MORE_MSG.chars().count() > max_len {
// TODO: better
line_part.part = format!("{}{}", line_part.part, MORE_MSG);
@ -159,7 +220,7 @@ fn best_effort_shortcut_list(help: &Help, max_len: usize) -> LinePart {
line_part.len += shortcut.len;
line_part.part = format!("{}{}", line_part.part, shortcut,);
}
let select_pane_shortcut = select_pane_shortcut(help.keybinds.len() == 0);
let select_pane_shortcut = select_pane_shortcut(help.keybinds.len() == 0, palette);
if line_part.len + select_pane_shortcut.len <= max_len {
line_part.len += select_pane_shortcut.len;
line_part.part = format!("{}{}", line_part.part, select_pane_shortcut,);
@ -169,14 +230,14 @@ fn best_effort_shortcut_list(help: &Help, max_len: usize) -> LinePart {
}
}
pub fn keybinds(help: &Help, max_width: usize) -> LinePart {
let full_shortcut_list = full_shortcut_list(help);
pub fn keybinds(help: &Help, max_width: usize, palette: Palette) -> LinePart {
let full_shortcut_list = full_shortcut_list(help, palette);
if full_shortcut_list.len <= max_width {
return full_shortcut_list;
}
let shortened_shortcut_list = shortened_shortcut_list(help);
let shortened_shortcut_list = shortened_shortcut_list(help, palette);
if shortened_shortcut_list.len <= max_width {
return shortened_shortcut_list;
}
return best_effort_shortcut_list(help, max_width);
return best_effort_shortcut_list(help, max_width, palette);
}

View File

@ -60,6 +60,7 @@ impl ZellijTile for State {
}
fn draw(&mut self, _rows: usize, cols: usize) {
let help = get_help();
if self.tabs.is_empty() {
return;
}
@ -77,7 +78,7 @@ impl ZellijTile for State {
} else if t.active {
active_tab_index = t.position;
}
let tab = tab_style(tabname, t.active, t.position);
let tab = tab_style(tabname, t.active, t.position, help.palette);
all_tabs.push(tab);
}
let tab_line = tab_line(all_tabs, active_tab_index, cols);
@ -85,7 +86,7 @@ impl ZellijTile for State {
for bar_part in tab_line {
s = format!("{}{}", s, bar_part.part);
}
println!("{}\u{1b}[48;5;238m\u{1b}[0K", s);
println!("{}\u{1b}[{};{};{}m\u{1b}[0K", s, help.palette.bg.0, help.palette.bg.1, help.palette.bg.2);
}
fn update_tabs(&mut self) {

View File

@ -1,16 +1,23 @@
use crate::colors::{BLACK, BRIGHT_GRAY, GRAY, GREEN};
use crate::{LinePart, ARROW_SEPARATOR};
use ansi_term::{ANSIStrings, Style};
use ansi_term::{ANSIStrings, Color::RGB, Style};
use zellij_tile::Palette;
pub fn active_tab(text: String) -> LinePart {
let left_separator = Style::new().fg(GRAY).on(GREEN).paint(ARROW_SEPARATOR);
pub fn active_tab(text: String, palette: Palette) -> LinePart {
let left_separator = Style::new()
.fg(RGB(palette.black.0, palette.black.1, palette.black.2))
.on(RGB(palette.green.0, palette.green.1, palette.green.2))
.paint(ARROW_SEPARATOR);
let tab_text_len = text.chars().count() + 4; // 2 for left and right separators, 2 for the text padding
let tab_styled_text = Style::new()
.fg(BLACK)
.on(GREEN)
.fg(RGB(palette.black.0, palette.black.1, palette.black.2))
.on(RGB(palette.green.0, palette.green.1, palette.green.2))
.bold()
.paint(format!(" {} ", text));
let right_separator = Style::new().fg(GREEN).on(GRAY).paint(ARROW_SEPARATOR);
let right_separator = Style::new()
.fg(RGB(palette.green.0, palette.green.1, palette.green.2))
.on(RGB(palette.bg.0, palette.bg.1, palette.bg.2))
.paint(ARROW_SEPARATOR);
let tab_styled_text = format!(
"{}",
ANSIStrings(&[left_separator, tab_styled_text, right_separator,])
@ -21,15 +28,21 @@ pub fn active_tab(text: String) -> LinePart {
}
}
pub fn non_active_tab(text: String) -> LinePart {
let left_separator = Style::new().fg(GRAY).on(BRIGHT_GRAY).paint(ARROW_SEPARATOR);
pub fn non_active_tab(text: String, palette: Palette) -> LinePart {
let left_separator = Style::new()
.fg(RGB(palette.fg.0, palette.fg.1, palette.fg.2))
.on(RGB(palette.bg.0, palette.bg.1, palette.bg.2))
.paint(ARROW_SEPARATOR);
let tab_text_len = text.chars().count() + 4; // 2 for left and right separators, 2 for the padding
let tab_styled_text = Style::new()
.fg(BLACK)
.on(BRIGHT_GRAY)
.fg(RGB(palette.fg.0, palette.fg.1, palette.fg.2))
.on(RGB(palette.bg.0, palette.bg.1, palette.bg.2))
.bold()
.paint(format!(" {} ", text));
let right_separator = Style::new().fg(BRIGHT_GRAY).on(GRAY).paint(ARROW_SEPARATOR);
let right_separator = Style::new()
.fg(RGB(palette.fg.0, palette.fg.1, palette.fg.2))
.on(RGB(palette.bg.0, palette.bg.1, palette.bg.2))
.paint(ARROW_SEPARATOR);
let tab_styled_text = format!(
"{}",
ANSIStrings(&[left_separator, tab_styled_text, right_separator,])
@ -40,15 +53,15 @@ pub fn non_active_tab(text: String) -> LinePart {
}
}
pub fn tab_style(text: String, is_active_tab: bool, position: usize) -> LinePart {
pub fn tab_style(text: String, is_active_tab: bool, position: usize, palette: Palette) -> LinePart {
let tab_text = if text.is_empty() {
format!("Tab #{}", position + 1)
} else {
text
};
if is_active_tab {
active_tab(tab_text)
active_tab(tab_text, palette)
} else {
non_active_tab(tab_text)
non_active_tab(tab_text, palette)
}
}

View File

@ -1,5 +1,5 @@
use crate::{common::{Palette, input::handler::InputMode}, tab::Pane};
use ansi_term::Colour;
use crate::{common::{input::handler::Palette, colors, input::handler::InputMode}, tab::Pane};
use ansi_term::Colour::RGB;
use std::collections::HashMap;
use std::fmt::{Display, Error, Formatter};
@ -18,20 +18,13 @@ pub mod boundary_type {
pub const CROSS: &str = "";
}
pub mod colors {
use ansi_term::Colour::{self, Fixed};
pub const WHITE: Colour = Fixed(255);
pub const GREEN: Colour = Fixed(154);
pub const GRAY: Colour = Fixed(238);
}
pub type BoundaryType = &'static str; // easy way to refer to boundary_type above
#[derive(Clone, Copy, Debug)]
pub struct BoundarySymbol {
boundary_type: BoundaryType,
invisible: bool,
color: Option<Colour>,
color: Option<(u8, u8, u8)>,
}
impl BoundarySymbol {
@ -46,7 +39,7 @@ impl BoundarySymbol {
self.invisible = true;
self
}
pub fn color(&mut self, color: Option<Colour>) -> Self {
pub fn color(&mut self, color: Option<(u8, u8, u8)>) -> Self {
self.color = color;
*self
}
@ -57,7 +50,7 @@ impl Display for BoundarySymbol {
match self.invisible {
true => write!(f, " "),
false => match self.color {
Some(color) => write!(f, "{}", color.paint(self.boundary_type)),
Some(color) => write!(f, "{}", RGB(color.0, color.1, color.2).paint(self.boundary_type)),
None => write!(f, "{}", self.boundary_type),
},
}

View File

@ -1,13 +1,13 @@
//! `Tab`s holds multiple panes. It tracks their coordinates (x/y) and size,
//! as well as how they should be resized
use crate::common::{AppInstruction, Palette, SenderWithContext, input::handler::InputMode};
use crate::common::{AppInstruction, SenderWithContext, input::handler::{Palette, InputMode}};
use crate::layout::Layout;
use crate::panes::{PaneId, PositionAndSize, TerminalPane};
use crate::pty_bus::{PtyInstruction, VteEvent};
use crate::wasm_vm::{PluginInputType, PluginInstruction};
use crate::{
boundaries::{colors, Boundaries},
boundaries::Boundaries,
panes::PluginPane,
};
use crate::{os_input_output::OsApi, utils::shared::pad_to_size};

View File

@ -9,6 +9,9 @@ use crate::pty_bus::PtyInstruction;
use crate::screen::ScreenInstruction;
use crate::wasm_vm::{EventType, PluginInputType, PluginInstruction};
use crate::CommandIsExecuting;
use xrdb::Colors;
use colors_transform::{Rgb, Color};
use crate::common::utils::logging::debug_log_to_file;
use serde::{Deserialize, Serialize};
use strum_macros::EnumIter;
@ -299,6 +302,7 @@ pub enum InputMode {
pub struct Help {
pub mode: InputMode,
pub keybinds: Vec<(String, String)>, // <shortcut> => <shortcut description>
pub palette: Palette
}
impl Default for InputMode {
@ -307,11 +311,89 @@ impl Default for InputMode {
}
}
pub mod colors {
pub const WHITE: (u8, u8, u8) = (238, 238, 238);
pub const GREEN: (u8, u8, u8) = (175, 255, 0);
pub const GRAY: (u8, u8, u8) = (68, 68, 68);
pub const BRIGHT_GRAY: (u8, u8, u8) = (138, 138, 138);
pub const RED: (u8, u8, u8) = (135, 0, 0);
pub const BLACK: (u8, u8, u8) = (0, 0, 0);
}
#[derive(Clone, Copy, Default, Debug, Serialize, Deserialize)]
pub struct Palette {
pub fg: (u8, u8, u8),
pub bg: (u8, u8, u8),
pub black: (u8, u8, u8),
pub red: (u8, u8, u8),
pub green: (u8, u8, u8),
pub yellow: (u8, u8, u8),
pub blue: (u8, u8, u8),
pub magenta: (u8, u8, u8),
pub cyan: (u8, u8, u8),
pub white: (u8, u8, u8),
}
impl Palette {
pub fn new() -> Self {
let palette = match Colors::new("xresources") {
Some(colors) => {
let fg = colors.fg.unwrap();
let fg_imm = &fg;
let fg_hex: &str = &fg_imm;
let fg = Rgb::from_hex_str(fg_hex).unwrap().as_tuple();
let fg = (fg.0 as u8, fg.1 as u8, fg.2 as u8);
let bg = colors.bg.unwrap();
let bg_imm = &bg;
let bg_hex: &str = &bg_imm;
let bg = Rgb::from_hex_str(bg_hex).unwrap().as_tuple();
let bg = (bg.0 as u8, bg.1 as u8, bg.2 as u8);
let colors: Vec<(u8, u8, u8)> = colors.colors.iter().map(|c| {
let c = c.clone();
let imm_str = &c.unwrap();
let hex_str: &str = &imm_str;
let rgb = Rgb::from_hex_str(hex_str).unwrap().as_tuple();
(rgb.0 as u8, rgb.1 as u8, rgb.2 as u8)
}).collect();
Self {
fg,
bg,
black: colors[0],
red: colors[1],
green: colors[2],
yellow: colors[3],
blue: colors[4],
magenta: colors[5],
cyan: colors[6],
white: colors[7]
}
},
None => {
Self {
fg: colors::BRIGHT_GRAY,
bg: colors::BLACK,
black: colors::BLACK,
red: colors::RED,
green: colors::GREEN,
yellow: colors::GRAY,
blue: colors::GRAY,
magenta: colors::GRAY,
cyan: colors::GRAY,
white: colors::WHITE
}
}
};
palette
}
}
/// Creates a [`Help`] struct indicating the current [`InputMode`] and its keybinds
/// (as pairs of [`String`]s).
// TODO this should probably be automatically generated in some way
pub fn get_help(mode: InputMode) -> Help {
let mut keybinds: Vec<(String, String)> = vec![];
let mut palette = Palette::new();
match mode {
InputMode::Normal | InputMode::Locked => {}
InputMode::Resize => {
@ -339,7 +421,7 @@ pub fn get_help(mode: InputMode) -> Help {
keybinds.push(("Enter".to_string(), "when done".to_string()));
}
}
Help { mode, keybinds }
Help { mode, keybinds, palette }
}
/// Entry point to the module. Instantiates an [`InputHandler`] and starts

View File

@ -30,13 +30,14 @@ use wasmer_wasi::{Pipe, WasiState};
use crate::cli::CliArgs;
use crate::layout::Layout;
use crate::common::input::handler::Palette;
use command_is_executing::CommandIsExecuting;
use errors::{AppContext, ContextType, ErrorContext, PluginContext, PtyContext, ScreenContext};
use input::handler::input_loop;
use os_input_output::OsApi;
use pty_bus::{PtyBus, PtyInstruction};
use screen::{Screen, ScreenInstruction};
use utils::consts::{ZELLIJ_IPC_PIPE, ZELLIJ_ROOT_PLUGIN_DIR};
use utils::{consts::{ZELLIJ_IPC_PIPE, ZELLIJ_ROOT_PLUGIN_DIR}, logging::debug_log_to_file};
use wasm_vm::{
wasi_stdout, wasi_write_string, zellij_imports, EventType, PluginInputType, PluginInstruction,
};
@ -152,62 +153,11 @@ pub enum AppInstruction {
}
pub mod colors {
use ansi_term::Colour::{self, Fixed};
pub const WHITE: Colour = Fixed(255);
pub const GREEN: Colour = Fixed(154);
pub const GRAY: Colour = Fixed(238);
pub const WHITE: (u8, u8, u8) = (238, 238, 238);
pub const GREEN: (u8, u8, u8) = (175, 255, 0);
pub const GRAY: (u8, u8, u8) = (68, 68, 68);
}
#[derive(Clone, Copy)]
pub struct Palette {
pub black: ansi_term::Color,
pub red: ansi_term::Color,
pub green: ansi_term::Color,
pub yellow: ansi_term::Color,
pub blue: ansi_term::Color,
pub magenta: ansi_term::Color,
pub cyan: ansi_term::Color,
pub white: ansi_term::Color,
}
impl Palette {
pub fn new() -> Self {
let palette = match Colors::new("xresources") {
Some(colors) => {
let colors: Vec<ansi_term::Color> = colors.colors.iter().map(|c| {
let c = c.clone();
let imm_str = &c.unwrap();
let hex_str: &str = &imm_str;
let rgb = Rgb::from_hex_str(hex_str).unwrap().as_tuple();
RGB(rgb.0 as u8, rgb.1 as u8, rgb.2 as u8)
}).collect();
Self {
black: colors[0],
red: colors[1],
green: colors[2],
yellow: colors[3],
blue: colors[4],
magenta: colors[5],
cyan: colors[6],
white: colors[7]
}
},
None => {
Self {
black: colors::GRAY,
red: colors::GRAY,
green: colors::GREEN,
yellow: colors::GRAY,
blue: colors::GRAY,
magenta: colors::GRAY,
cyan: colors::GRAY,
white: colors::WHITE
}
}
};
palette
}
}
/// Start Zellij with the specified [`OsApi`] and command-line arguments.
// FIXME this should definitely be modularized and split into different functions.
@ -342,6 +292,7 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: CliArgs) {
let send_app_instructions = send_app_instructions.clone();
let max_panes = opts.max_panes;
let colors = Palette::new();
// debug_log_to_file(format!("{:?}", colors));
move || {
let mut screen = Screen::new(
receive_screen_instructions,

View File

@ -28,6 +28,7 @@ pub enum Key {
pub struct Help {
pub mode: InputMode,
pub keybinds: Vec<(String, String)>,
pub palette: Palette
}
// TODO: use same struct from main crate?
@ -51,6 +52,20 @@ pub struct TabData {
pub active: bool,
}
#[derive(Default, Debug, Copy, Clone, Deserialize, Serialize)]
pub struct Palette {
pub fg: (u8, u8, u8),
pub bg: (u8, u8, u8),
pub black: (u8, u8, u8),
pub red: (u8, u8, u8),
pub green: (u8, u8, u8),
pub yellow: (u8, u8, u8),
pub blue: (u8, u8, u8),
pub magenta: (u8, u8, u8),
pub cyan: (u8, u8, u8),
pub white: (u8, u8, u8),
}
impl Default for InputMode {
fn default() -> InputMode {
InputMode::Normal
@ -60,6 +75,9 @@ impl Default for InputMode {
pub fn get_key() -> Key {
deserialize_from_stdin().unwrap()
}
pub fn get_palette() -> Palette {
deserialize_from_stdin().unwrap()
}
pub fn open_file(path: &Path) {
println!("{}", path.to_string_lossy());