Osc implementation (#517)
* fix(compatibility): implement most osc methods * style(fmt): rustfmt * style(fmt): remove cargo warnings * style(fmt): make clippy happy * style(fmt): fix formatting after my clippy fixes broke it again ;P * fix(grid): fix tests
This commit is contained in:
parent
84911619b2
commit
a3f42b19a9
18 changed files with 419 additions and 113 deletions
110
Cargo.lock
generated
110
Cargo.lock
generated
|
|
@ -132,7 +132,7 @@ dependencies = [
|
||||||
"event-listener",
|
"event-listener",
|
||||||
"futures-lite",
|
"futures-lite",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"signal-hook",
|
"signal-hook 0.3.8",
|
||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
@ -451,6 +451,31 @@ dependencies = [
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crossterm"
|
||||||
|
version = "0.18.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4e86d73f2a0b407b5768d10a8c720cf5d2df49a9efc10ca09176d201ead4b7fb"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags",
|
||||||
|
"crossterm_winapi",
|
||||||
|
"lazy_static",
|
||||||
|
"libc",
|
||||||
|
"mio",
|
||||||
|
"parking_lot",
|
||||||
|
"signal-hook 0.1.17",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crossterm_winapi"
|
||||||
|
version = "0.6.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c2265c3f8e080075d9b6417aa72293fc71662f34b4af2612d8d1b074d29510db"
|
||||||
|
dependencies = [
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ctor"
|
name = "ctor"
|
||||||
version = "0.1.20"
|
version = "0.1.20"
|
||||||
|
|
@ -1016,6 +1041,28 @@ dependencies = [
|
||||||
"autocfg",
|
"autocfg",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "mio"
|
||||||
|
version = "0.7.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cf80d3e903b34e0bd7282b218398aec54e082c840d9baf8339e0080a0c542956"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"log",
|
||||||
|
"miow",
|
||||||
|
"ntapi",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "miow"
|
||||||
|
version = "0.3.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21"
|
||||||
|
dependencies = [
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "more-asserts"
|
name = "more-asserts"
|
||||||
version = "0.2.1"
|
version = "0.2.1"
|
||||||
|
|
@ -1043,6 +1090,15 @@ dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ntapi"
|
||||||
|
version = "0.3.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3f6bb902e437b6d86e03cce10a7e2af662292c5dfef23b65899ea3ac9354ad44"
|
||||||
|
dependencies = [
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num_cpus"
|
name = "num_cpus"
|
||||||
version = "1.13.0"
|
version = "1.13.0"
|
||||||
|
|
@ -1087,6 +1143,31 @@ version = "2.0.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "427c3892f9e783d91cc128285287e70a59e206ca452770ece88a76f7a3eddd72"
|
checksum = "427c3892f9e783d91cc128285287e70a59e206ca452770ece88a76f7a3eddd72"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "parking_lot"
|
||||||
|
version = "0.11.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6d7744ac029df22dca6284efe4e898991d28e3085c706c972bcd7da4a27a15eb"
|
||||||
|
dependencies = [
|
||||||
|
"instant",
|
||||||
|
"lock_api",
|
||||||
|
"parking_lot_core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "parking_lot_core"
|
||||||
|
version = "0.8.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fa7a782938e745763fe6907fc6ba86946d72f49fe7e21de074e08128a99fb018"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if 1.0.0",
|
||||||
|
"instant",
|
||||||
|
"libc",
|
||||||
|
"redox_syscall",
|
||||||
|
"smallvec",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pin-project-lite"
|
name = "pin-project-lite"
|
||||||
version = "0.2.6"
|
version = "0.2.6"
|
||||||
|
|
@ -1430,6 +1511,17 @@ dependencies = [
|
||||||
"yaml-rust",
|
"yaml-rust",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "signal-hook"
|
||||||
|
version = "0.1.17"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7e31d442c16f047a671b5a71e2161d6e68814012b7f5379d269ebd915fac2729"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"mio",
|
||||||
|
"signal-hook-registry",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "signal-hook"
|
name = "signal-hook"
|
||||||
version = "0.3.8"
|
version = "0.3.8"
|
||||||
|
|
@ -1615,6 +1707,17 @@ dependencies = [
|
||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "termbg"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "133c09f40b7a6a10616bb46d2b7d78d50cb8c6c475c84f3c02fe261957d9e0e0"
|
||||||
|
dependencies = [
|
||||||
|
"crossterm",
|
||||||
|
"thiserror",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "terminal_size"
|
name = "terminal_size"
|
||||||
version = "0.1.16"
|
version = "0.1.16"
|
||||||
|
|
@ -2204,7 +2307,8 @@ dependencies = [
|
||||||
"interprocess",
|
"interprocess",
|
||||||
"libc",
|
"libc",
|
||||||
"nix",
|
"nix",
|
||||||
"signal-hook",
|
"signal-hook 0.3.8",
|
||||||
|
"termbg",
|
||||||
"termion",
|
"termion",
|
||||||
"zellij-tile",
|
"zellij-tile",
|
||||||
"zellij-utils",
|
"zellij-utils",
|
||||||
|
|
@ -2224,7 +2328,7 @@ dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"serde_yaml",
|
"serde_yaml",
|
||||||
"signal-hook",
|
"signal-hook 0.3.8",
|
||||||
"termion",
|
"termion",
|
||||||
"unicode-width",
|
"unicode-width",
|
||||||
"vte 0.10.1",
|
"vte 0.10.1",
|
||||||
|
|
|
||||||
|
|
@ -72,55 +72,61 @@ pub struct ColoredElements {
|
||||||
// that can be defined in the config perhaps
|
// that can be defined in the config perhaps
|
||||||
fn color_elements(palette: Palette) -> ColoredElements {
|
fn color_elements(palette: Palette) -> ColoredElements {
|
||||||
match palette.source {
|
match palette.source {
|
||||||
|
// "cyan" here is used as a background as a dirty hack
|
||||||
|
// this is because the Palette struct doesn't have a "gray" section
|
||||||
|
// and we can't use its "bg" because that is now dynamically taken from the terminal
|
||||||
|
// and might often not actually fit the rest of the colorscheme
|
||||||
|
//
|
||||||
|
// to fix this, we need to restructure the Palette struct
|
||||||
PaletteSource::Default => ColoredElements {
|
PaletteSource::Default => ColoredElements {
|
||||||
selected_prefix_separator: style!(palette.bg, palette.green),
|
selected_prefix_separator: style!(palette.cyan, palette.green),
|
||||||
selected_char_left_separator: style!(palette.black, palette.green).bold(),
|
selected_char_left_separator: style!(palette.black, palette.green).bold(),
|
||||||
selected_char_shortcut: style!(palette.red, palette.green).bold(),
|
selected_char_shortcut: style!(palette.red, palette.green).bold(),
|
||||||
selected_char_right_separator: style!(palette.black, palette.green).bold(),
|
selected_char_right_separator: style!(palette.black, palette.green).bold(),
|
||||||
selected_styled_text: style!(palette.black, palette.green).bold(),
|
selected_styled_text: style!(palette.black, palette.green).bold(),
|
||||||
selected_suffix_separator: style!(palette.green, palette.bg).bold(),
|
selected_suffix_separator: style!(palette.green, palette.cyan).bold(),
|
||||||
unselected_prefix_separator: style!(palette.bg, palette.fg),
|
unselected_prefix_separator: style!(palette.cyan, palette.fg),
|
||||||
unselected_char_left_separator: style!(palette.black, palette.fg).bold(),
|
unselected_char_left_separator: style!(palette.black, palette.fg).bold(),
|
||||||
unselected_char_shortcut: style!(palette.red, palette.fg).bold(),
|
unselected_char_shortcut: style!(palette.red, palette.fg).bold(),
|
||||||
unselected_char_right_separator: style!(palette.black, palette.fg).bold(),
|
unselected_char_right_separator: style!(palette.black, palette.fg).bold(),
|
||||||
unselected_styled_text: style!(palette.black, palette.fg).bold(),
|
unselected_styled_text: style!(palette.black, palette.fg).bold(),
|
||||||
unselected_suffix_separator: style!(palette.fg, palette.bg),
|
unselected_suffix_separator: style!(palette.fg, palette.cyan),
|
||||||
disabled_prefix_separator: style!(palette.bg, palette.fg),
|
disabled_prefix_separator: style!(palette.cyan, palette.fg),
|
||||||
disabled_styled_text: style!(palette.bg, palette.fg).dimmed(),
|
disabled_styled_text: style!(palette.cyan, palette.fg).dimmed(),
|
||||||
disabled_suffix_separator: style!(palette.fg, palette.bg),
|
disabled_suffix_separator: style!(palette.fg, palette.cyan),
|
||||||
selected_single_letter_prefix_separator: style!(palette.bg, palette.green),
|
selected_single_letter_prefix_separator: style!(palette.cyan, palette.green),
|
||||||
selected_single_letter_char_shortcut: style!(palette.red, palette.green).bold(),
|
selected_single_letter_char_shortcut: style!(palette.red, palette.green).bold(),
|
||||||
selected_single_letter_suffix_separator: style!(palette.green, palette.bg),
|
selected_single_letter_suffix_separator: style!(palette.green, palette.cyan),
|
||||||
unselected_single_letter_prefix_separator: style!(palette.bg, palette.fg),
|
unselected_single_letter_prefix_separator: style!(palette.cyan, palette.fg),
|
||||||
unselected_single_letter_char_shortcut: style!(palette.red, palette.fg).bold(),
|
unselected_single_letter_char_shortcut: style!(palette.red, palette.fg).bold(),
|
||||||
unselected_single_letter_suffix_separator: style!(palette.fg, palette.bg),
|
unselected_single_letter_suffix_separator: style!(palette.fg, palette.cyan),
|
||||||
superkey_prefix: style!(palette.white, palette.bg).bold(),
|
superkey_prefix: style!(palette.white, palette.cyan).bold(),
|
||||||
superkey_suffix_separator: style!(palette.bg, palette.bg),
|
superkey_suffix_separator: style!(palette.cyan, palette.cyan),
|
||||||
},
|
},
|
||||||
PaletteSource::Xresources => ColoredElements {
|
PaletteSource::Xresources => ColoredElements {
|
||||||
selected_prefix_separator: style!(palette.bg, palette.green),
|
selected_prefix_separator: style!(palette.cyan, palette.green),
|
||||||
selected_char_left_separator: style!(palette.fg, palette.green).bold(),
|
selected_char_left_separator: style!(palette.fg, palette.green).bold(),
|
||||||
selected_char_shortcut: style!(palette.red, palette.green).bold(),
|
selected_char_shortcut: style!(palette.red, palette.green).bold(),
|
||||||
selected_char_right_separator: style!(palette.fg, palette.green).bold(),
|
selected_char_right_separator: style!(palette.fg, palette.green).bold(),
|
||||||
selected_styled_text: style!(palette.bg, palette.green).bold(),
|
selected_styled_text: style!(palette.cyan, palette.green).bold(),
|
||||||
selected_suffix_separator: style!(palette.green, palette.bg).bold(),
|
selected_suffix_separator: style!(palette.green, palette.cyan).bold(),
|
||||||
unselected_prefix_separator: style!(palette.bg, palette.fg),
|
unselected_prefix_separator: style!(palette.cyan, palette.fg),
|
||||||
unselected_char_left_separator: style!(palette.bg, palette.fg).bold(),
|
unselected_char_left_separator: style!(palette.cyan, palette.fg).bold(),
|
||||||
unselected_char_shortcut: style!(palette.red, palette.fg).bold(),
|
unselected_char_shortcut: style!(palette.red, palette.fg).bold(),
|
||||||
unselected_char_right_separator: style!(palette.bg, palette.fg).bold(),
|
unselected_char_right_separator: style!(palette.cyan, palette.fg).bold(),
|
||||||
unselected_styled_text: style!(palette.bg, palette.fg).bold(),
|
unselected_styled_text: style!(palette.cyan, palette.fg).bold(),
|
||||||
unselected_suffix_separator: style!(palette.fg, palette.bg),
|
unselected_suffix_separator: style!(palette.fg, palette.cyan),
|
||||||
disabled_prefix_separator: style!(palette.bg, palette.fg),
|
disabled_prefix_separator: style!(palette.cyan, palette.fg),
|
||||||
disabled_styled_text: style!(palette.bg, palette.fg).dimmed(),
|
disabled_styled_text: style!(palette.cyan, palette.fg).dimmed(),
|
||||||
disabled_suffix_separator: style!(palette.fg, palette.bg),
|
disabled_suffix_separator: style!(palette.fg, palette.cyan),
|
||||||
selected_single_letter_prefix_separator: style!(palette.fg, palette.green),
|
selected_single_letter_prefix_separator: style!(palette.fg, palette.green),
|
||||||
selected_single_letter_char_shortcut: style!(palette.red, palette.green).bold(),
|
selected_single_letter_char_shortcut: style!(palette.red, palette.green).bold(),
|
||||||
selected_single_letter_suffix_separator: style!(palette.green, palette.fg),
|
selected_single_letter_suffix_separator: style!(palette.green, palette.fg),
|
||||||
unselected_single_letter_prefix_separator: style!(palette.fg, palette.bg),
|
unselected_single_letter_prefix_separator: style!(palette.fg, palette.cyan),
|
||||||
unselected_single_letter_char_shortcut: style!(palette.red, palette.fg).bold(),
|
unselected_single_letter_char_shortcut: style!(palette.red, palette.fg).bold(),
|
||||||
unselected_single_letter_suffix_separator: style!(palette.fg, palette.bg),
|
unselected_single_letter_suffix_separator: style!(palette.fg, palette.cyan),
|
||||||
superkey_prefix: style!(palette.bg, palette.fg).bold(),
|
superkey_prefix: style!(palette.cyan, palette.fg).bold(),
|
||||||
superkey_suffix_separator: style!(palette.fg, palette.bg),
|
superkey_suffix_separator: style!(palette.fg, palette.cyan),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -155,7 +161,7 @@ impl ZellijPlugin for State {
|
||||||
|
|
||||||
// [48;5;238m is gray background, [0K is so that it fills the rest of the line
|
// [48;5;238m is gray background, [0K is so that it fills the rest of the line
|
||||||
// [m is background reset, [0K is so that it clears the rest of the line
|
// [m is background reset, [0K is so that it clears the rest of the line
|
||||||
match self.mode_info.palette.bg {
|
match self.mode_info.palette.cyan {
|
||||||
PaletteColor::Rgb((r, g, b)) => {
|
PaletteColor::Rgb((r, g, b)) => {
|
||||||
println!("{}\u{1b}[48;2;{};{};{}m\u{1b}[0K", first_line, r, g, b);
|
println!("{}\u{1b}[48;2;{};{};{}m\u{1b}[0K", first_line, r, g, b);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -62,11 +62,11 @@ fn left_more_message(tab_count_to_the_left: usize, palette: Palette, separator:
|
||||||
};
|
};
|
||||||
// 238
|
// 238
|
||||||
let more_text_len = more_text.chars().count() + 2; // 2 for the arrows
|
let more_text_len = more_text.chars().count() + 2; // 2 for the arrows
|
||||||
let left_separator = style!(palette.bg, palette.orange).paint(separator);
|
let left_separator = style!(palette.cyan, palette.orange).paint(separator);
|
||||||
let more_styled_text = style!(palette.black, palette.orange)
|
let more_styled_text = style!(palette.black, palette.orange)
|
||||||
.bold()
|
.bold()
|
||||||
.paint(more_text);
|
.paint(more_text);
|
||||||
let right_separator = style!(palette.orange, palette.bg).paint(separator);
|
let right_separator = style!(palette.orange, palette.cyan).paint(separator);
|
||||||
let more_styled_text = format!(
|
let more_styled_text = format!(
|
||||||
"{}",
|
"{}",
|
||||||
ANSIStrings(&[left_separator, more_styled_text, right_separator,])
|
ANSIStrings(&[left_separator, more_styled_text, right_separator,])
|
||||||
|
|
@ -94,11 +94,11 @@ fn right_more_message(
|
||||||
" +many → ".to_string()
|
" +many → ".to_string()
|
||||||
};
|
};
|
||||||
let more_text_len = more_text.chars().count() + 1; // 2 for the arrow
|
let more_text_len = more_text.chars().count() + 1; // 2 for the arrow
|
||||||
let left_separator = style!(palette.bg, palette.orange).paint(separator);
|
let left_separator = style!(palette.cyan, palette.orange).paint(separator);
|
||||||
let more_styled_text = style!(palette.black, palette.orange)
|
let more_styled_text = style!(palette.black, palette.orange)
|
||||||
.bold()
|
.bold()
|
||||||
.paint(more_text);
|
.paint(more_text);
|
||||||
let right_separator = style!(palette.orange, palette.bg).paint(separator);
|
let right_separator = style!(palette.orange, palette.cyan).paint(separator);
|
||||||
let more_styled_text = format!(
|
let more_styled_text = format!(
|
||||||
"{}",
|
"{}",
|
||||||
ANSIStrings(&[left_separator, more_styled_text, right_separator,])
|
ANSIStrings(&[left_separator, more_styled_text, right_separator,])
|
||||||
|
|
@ -147,7 +147,9 @@ fn add_next_tabs_msg(
|
||||||
fn tab_line_prefix(palette: Palette) -> LinePart {
|
fn tab_line_prefix(palette: Palette) -> LinePart {
|
||||||
let prefix_text = " Zellij ".to_string();
|
let prefix_text = " Zellij ".to_string();
|
||||||
let prefix_text_len = prefix_text.chars().count();
|
let prefix_text_len = prefix_text.chars().count();
|
||||||
let prefix_styled_text = style!(palette.white, palette.bg).bold().paint(prefix_text);
|
let prefix_styled_text = style!(palette.white, palette.cyan)
|
||||||
|
.bold()
|
||||||
|
.paint(prefix_text);
|
||||||
LinePart {
|
LinePart {
|
||||||
part: format!("{}", prefix_styled_text),
|
part: format!("{}", prefix_styled_text),
|
||||||
len: prefix_text_len,
|
len: prefix_text_len,
|
||||||
|
|
|
||||||
|
|
@ -75,7 +75,7 @@ impl ZellijPlugin for State {
|
||||||
for bar_part in tab_line {
|
for bar_part in tab_line {
|
||||||
s = format!("{}{}", s, bar_part.part);
|
s = format!("{}{}", s, bar_part.part);
|
||||||
}
|
}
|
||||||
match self.mode_info.palette.bg {
|
match self.mode_info.palette.cyan {
|
||||||
PaletteColor::Rgb((r, g, b)) => {
|
PaletteColor::Rgb((r, g, b)) => {
|
||||||
println!("{}\u{1b}[48;2;{};{};{}m\u{1b}[0K", s, r, g, b);
|
println!("{}\u{1b}[48;2;{};{};{}m\u{1b}[0K", s, r, g, b);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,12 +4,12 @@ use zellij_tile::prelude::*;
|
||||||
use zellij_tile_utils::style;
|
use zellij_tile_utils::style;
|
||||||
|
|
||||||
pub fn active_tab(text: String, palette: Palette, separator: &str) -> LinePart {
|
pub fn active_tab(text: String, palette: Palette, separator: &str) -> LinePart {
|
||||||
let left_separator = style!(palette.bg, palette.green).paint(separator);
|
let left_separator = style!(palette.cyan, palette.green).paint(separator);
|
||||||
let tab_text_len = text.chars().count() + 4; // 2 for left and right separators, 2 for the text padding
|
let tab_text_len = text.chars().count() + 4; // 2 for left and right separators, 2 for the text padding
|
||||||
let tab_styled_text = style!(palette.black, palette.green)
|
let tab_styled_text = style!(palette.black, palette.green)
|
||||||
.bold()
|
.bold()
|
||||||
.paint(format!(" {} ", text));
|
.paint(format!(" {} ", text));
|
||||||
let right_separator = style!(palette.green, palette.bg).paint(separator);
|
let right_separator = style!(palette.green, palette.cyan).paint(separator);
|
||||||
let tab_styled_text = format!(
|
let tab_styled_text = format!(
|
||||||
"{}",
|
"{}",
|
||||||
ANSIStrings(&[left_separator, tab_styled_text, right_separator,])
|
ANSIStrings(&[left_separator, tab_styled_text, right_separator,])
|
||||||
|
|
@ -21,12 +21,12 @@ pub fn active_tab(text: String, palette: Palette, separator: &str) -> LinePart {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn non_active_tab(text: String, palette: Palette, separator: &str) -> LinePart {
|
pub fn non_active_tab(text: String, palette: Palette, separator: &str) -> LinePart {
|
||||||
let left_separator = style!(palette.bg, palette.fg).paint(separator);
|
let left_separator = style!(palette.cyan, palette.fg).paint(separator);
|
||||||
let tab_text_len = text.chars().count() + 4; // 2 for left and right separators, 2 for the padding
|
let tab_text_len = text.chars().count() + 4; // 2 for left and right separators, 2 for the padding
|
||||||
let tab_styled_text = style!(palette.black, palette.fg)
|
let tab_styled_text = style!(palette.black, palette.fg)
|
||||||
.bold()
|
.bold()
|
||||||
.paint(format!(" {} ", text));
|
.paint(format!(" {} ", text));
|
||||||
let right_separator = style!(palette.fg, palette.bg).paint(separator);
|
let right_separator = style!(palette.fg, palette.cyan).paint(separator);
|
||||||
let tab_styled_text = format!(
|
let tab_styled_text = format!(
|
||||||
"{}",
|
"{}",
|
||||||
ANSIStrings(&[left_separator, tab_styled_text, right_separator,])
|
ANSIStrings(&[left_separator, tab_styled_text, right_separator,])
|
||||||
|
|
|
||||||
|
|
@ -219,6 +219,9 @@ impl ClientOsApi for FakeInputOutput {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn connect_to_server(&self, _path: &std::path::Path) {}
|
fn connect_to_server(&self, _path: &std::path::Path) {}
|
||||||
|
fn load_palette(&self) -> Palette {
|
||||||
|
default_palette()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ServerOsApi for FakeInputOutput {
|
impl ServerOsApi for FakeInputOutput {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
use zellij_server::{panes::TerminalPane, tab::Pane};
|
use zellij_server::{panes::TerminalPane, tab::Pane};
|
||||||
|
use zellij_tile::data::Palette;
|
||||||
use zellij_utils::pane_size::PositionAndSize;
|
use zellij_utils::pane_size::PositionAndSize;
|
||||||
|
|
||||||
pub fn get_output_frame_snapshots(
|
pub fn get_output_frame_snapshots(
|
||||||
|
|
@ -7,7 +8,7 @@ pub fn get_output_frame_snapshots(
|
||||||
) -> Vec<String> {
|
) -> Vec<String> {
|
||||||
let mut vte_parser = vte::Parser::new();
|
let mut vte_parser = vte::Parser::new();
|
||||||
let main_pid = 0;
|
let main_pid = 0;
|
||||||
let mut terminal_output = TerminalPane::new(main_pid, *win_size);
|
let mut terminal_output = TerminalPane::new(main_pid, *win_size, Palette::default());
|
||||||
|
|
||||||
let mut snapshots = vec![];
|
let mut snapshots = vec![];
|
||||||
for frame in output_frames.iter() {
|
for frame in output_frames.iter() {
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ signal-hook = "0.3"
|
||||||
nix = "0.19.1"
|
nix = "0.19.1"
|
||||||
interprocess = "1.1.1"
|
interprocess = "1.1.1"
|
||||||
libc = "0.2"
|
libc = "0.2"
|
||||||
|
termbg = "0.2.0"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
test = ["zellij-utils/test"]
|
test = ["zellij-utils/test"]
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ use zellij_utils::{
|
||||||
errors::{ClientContext, ContextType, ErrorInstruction},
|
errors::{ClientContext, ContextType, ErrorInstruction},
|
||||||
input::config::Config,
|
input::config::Config,
|
||||||
input::options::Options,
|
input::options::Options,
|
||||||
ipc::{ClientToServerMsg, ServerToClientMsg},
|
ipc::{ClientAttributes, ClientToServerMsg, ServerToClientMsg},
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Instructions related to the client-side application
|
/// Instructions related to the client-side application
|
||||||
|
|
@ -85,6 +85,7 @@ pub fn start_client(mut os_input: Box<dyn ClientOsApi>, opts: CliArgs, config: C
|
||||||
let take_snapshot = "\u{1b}[?1049h";
|
let take_snapshot = "\u{1b}[?1049h";
|
||||||
let bracketed_paste = "\u{1b}[?2004h";
|
let bracketed_paste = "\u{1b}[?2004h";
|
||||||
os_input.unset_raw_mode(0);
|
os_input.unset_raw_mode(0);
|
||||||
|
let palette = os_input.load_palette();
|
||||||
let _ = os_input
|
let _ = os_input
|
||||||
.get_stdout_writer()
|
.get_stdout_writer()
|
||||||
.write(take_snapshot.as_bytes())
|
.write(take_snapshot.as_bytes())
|
||||||
|
|
@ -103,9 +104,13 @@ pub fn start_client(mut os_input: Box<dyn ClientOsApi>, opts: CliArgs, config: C
|
||||||
let config_options = Options::from_cli(&config.options, opts.option.clone());
|
let config_options = Options::from_cli(&config.options, opts.option.clone());
|
||||||
|
|
||||||
let full_screen_ws = os_input.get_terminal_size_using_fd(0);
|
let full_screen_ws = os_input.get_terminal_size_using_fd(0);
|
||||||
|
let client_attributes = ClientAttributes {
|
||||||
|
position_and_size: full_screen_ws,
|
||||||
|
palette,
|
||||||
|
};
|
||||||
os_input.connect_to_server(&*ZELLIJ_IPC_PIPE);
|
os_input.connect_to_server(&*ZELLIJ_IPC_PIPE);
|
||||||
os_input.send_to_server(ClientToServerMsg::NewClient(
|
os_input.send_to_server(ClientToServerMsg::NewClient(
|
||||||
full_screen_ws,
|
client_attributes,
|
||||||
opts,
|
opts,
|
||||||
config_options,
|
config_options,
|
||||||
));
|
));
|
||||||
|
|
|
||||||
|
|
@ -7,11 +7,13 @@ use std::io::prelude::*;
|
||||||
use std::os::unix::io::RawFd;
|
use std::os::unix::io::RawFd;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
|
use zellij_tile::data::{Palette, PaletteColor};
|
||||||
use zellij_utils::errors::ErrorContext;
|
use zellij_utils::errors::ErrorContext;
|
||||||
use zellij_utils::ipc::{
|
use zellij_utils::ipc::{
|
||||||
ClientToServerMsg, IpcReceiverWithContext, IpcSenderWithContext, ServerToClientMsg,
|
ClientToServerMsg, IpcReceiverWithContext, IpcSenderWithContext, ServerToClientMsg,
|
||||||
};
|
};
|
||||||
use zellij_utils::pane_size::PositionAndSize;
|
use zellij_utils::pane_size::PositionAndSize;
|
||||||
|
use zellij_utils::shared::default_palette;
|
||||||
|
|
||||||
fn into_raw_mode(pid: RawFd) {
|
fn into_raw_mode(pid: RawFd) {
|
||||||
let mut tio = termios::tcgetattr(pid).expect("could not get terminal attribute");
|
let mut tio = termios::tcgetattr(pid).expect("could not get terminal attribute");
|
||||||
|
|
@ -77,6 +79,7 @@ pub trait ClientOsApi: Send + Sync {
|
||||||
fn handle_signals(&self, sigwinch_cb: Box<dyn Fn()>, quit_cb: Box<dyn Fn()>);
|
fn handle_signals(&self, sigwinch_cb: Box<dyn Fn()>, quit_cb: Box<dyn Fn()>);
|
||||||
/// Establish a connection with the server socket.
|
/// Establish a connection with the server socket.
|
||||||
fn connect_to_server(&self, path: &Path);
|
fn connect_to_server(&self, path: &Path);
|
||||||
|
fn load_palette(&self) -> Palette;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ClientOsApi for ClientOsInputOutput {
|
impl ClientOsApi for ClientOsInputOutput {
|
||||||
|
|
@ -155,6 +158,17 @@ impl ClientOsApi for ClientOsInputOutput {
|
||||||
*self.send_instructions_to_server.lock().unwrap() = Some(sender);
|
*self.send_instructions_to_server.lock().unwrap() = Some(sender);
|
||||||
*self.receive_instructions_from_server.lock().unwrap() = Some(receiver);
|
*self.receive_instructions_from_server.lock().unwrap() = Some(receiver);
|
||||||
}
|
}
|
||||||
|
fn load_palette(&self) -> Palette {
|
||||||
|
let timeout = std::time::Duration::from_millis(100);
|
||||||
|
let mut palette = default_palette();
|
||||||
|
if let Ok(rgb) = termbg::rgb(timeout) {
|
||||||
|
palette.bg = PaletteColor::Rgb((rgb.r as u8, rgb.g as u8, rgb.b as u8));
|
||||||
|
// TODO: also dynamically get all other colors from the user's terminal
|
||||||
|
// this should be done in the same method (OSC ]11), but there might be other
|
||||||
|
// considerations here, hence using the library
|
||||||
|
};
|
||||||
|
palette
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Clone for Box<dyn ClientOsApi> {
|
impl Clone for Box<dyn ClientOsApi> {
|
||||||
|
|
|
||||||
|
|
@ -29,15 +29,14 @@ use zellij_utils::{
|
||||||
cli::CliArgs,
|
cli::CliArgs,
|
||||||
errors::{ContextType, ErrorInstruction, ServerContext},
|
errors::{ContextType, ErrorInstruction, ServerContext},
|
||||||
input::options::Options,
|
input::options::Options,
|
||||||
ipc::{ClientToServerMsg, ServerToClientMsg},
|
ipc::{ClientAttributes, ClientToServerMsg, ServerToClientMsg},
|
||||||
pane_size::PositionAndSize,
|
|
||||||
setup::{get_default_data_dir, install::populate_data_dir},
|
setup::{get_default_data_dir, install::populate_data_dir},
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Instructions related to server-side application
|
/// Instructions related to server-side application
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub(crate) enum ServerInstruction {
|
pub(crate) enum ServerInstruction {
|
||||||
NewClient(PositionAndSize, CliArgs, Options),
|
NewClient(ClientAttributes, CliArgs, Options),
|
||||||
Render(Option<String>),
|
Render(Option<String>),
|
||||||
UnblockInputThread,
|
UnblockInputThread,
|
||||||
ClientExit,
|
ClientExit,
|
||||||
|
|
@ -173,13 +172,13 @@ pub fn start_server(os_input: Box<dyn ServerOsApi>, socket_path: PathBuf) {
|
||||||
let (instruction, mut err_ctx) = server_receiver.recv().unwrap();
|
let (instruction, mut err_ctx) = server_receiver.recv().unwrap();
|
||||||
err_ctx.add_call(ContextType::IPCServer((&instruction).into()));
|
err_ctx.add_call(ContextType::IPCServer((&instruction).into()));
|
||||||
match instruction {
|
match instruction {
|
||||||
ServerInstruction::NewClient(full_screen_ws, opts, config_options) => {
|
ServerInstruction::NewClient(client_attributes, opts, config_options) => {
|
||||||
let session_data = init_session(
|
let session_data = init_session(
|
||||||
os_input.clone(),
|
os_input.clone(),
|
||||||
opts,
|
opts,
|
||||||
config_options,
|
config_options,
|
||||||
to_server.clone(),
|
to_server.clone(),
|
||||||
full_screen_ws,
|
client_attributes,
|
||||||
);
|
);
|
||||||
*sessions.write().unwrap() = Some(session_data);
|
*sessions.write().unwrap() = Some(session_data);
|
||||||
sessions
|
sessions
|
||||||
|
|
@ -217,7 +216,7 @@ fn init_session(
|
||||||
opts: CliArgs,
|
opts: CliArgs,
|
||||||
config_options: Options,
|
config_options: Options,
|
||||||
to_server: SenderWithContext<ServerInstruction>,
|
to_server: SenderWithContext<ServerInstruction>,
|
||||||
full_screen_ws: PositionAndSize,
|
client_attributes: ClientAttributes,
|
||||||
) -> SessionMetaData {
|
) -> SessionMetaData {
|
||||||
let (to_screen, screen_receiver): ChannelWithContext<ScreenInstruction> = mpsc::channel();
|
let (to_screen, screen_receiver): ChannelWithContext<ScreenInstruction> = mpsc::channel();
|
||||||
let to_screen = SenderWithContext::new(SenderType::Sender(to_screen));
|
let to_screen = SenderWithContext::new(SenderType::Sender(to_screen));
|
||||||
|
|
@ -280,7 +279,7 @@ fn init_session(
|
||||||
let max_panes = opts.max_panes;
|
let max_panes = opts.max_panes;
|
||||||
|
|
||||||
move || {
|
move || {
|
||||||
screen_thread_main(screen_bus, max_panes, full_screen_ws, config_options);
|
screen_thread_main(screen_bus, max_panes, client_attributes, config_options);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ use std::{
|
||||||
cmp::Ordering,
|
cmp::Ordering,
|
||||||
collections::{BTreeSet, VecDeque},
|
collections::{BTreeSet, VecDeque},
|
||||||
fmt::{self, Debug, Formatter},
|
fmt::{self, Debug, Formatter},
|
||||||
|
str,
|
||||||
};
|
};
|
||||||
|
|
||||||
use vte::{Params, Perform};
|
use vte::{Params, Perform};
|
||||||
|
|
@ -9,6 +10,7 @@ use vte::{Params, Perform};
|
||||||
const TABSTOP_WIDTH: usize = 8; // TODO: is this always right?
|
const TABSTOP_WIDTH: usize = 8; // TODO: is this always right?
|
||||||
const SCROLL_BACK: usize = 10_000;
|
const SCROLL_BACK: usize = 10_000;
|
||||||
|
|
||||||
|
use zellij_tile::data::{Palette, PaletteColor};
|
||||||
use zellij_utils::{consts::VERSION, logging::debug_log_to_file, shared::version_number};
|
use zellij_utils::{consts::VERSION, logging::debug_log_to_file, shared::version_number};
|
||||||
|
|
||||||
use crate::panes::terminal_character::{
|
use crate::panes::terminal_character::{
|
||||||
|
|
@ -16,6 +18,26 @@ use crate::panes::terminal_character::{
|
||||||
EMPTY_TERMINAL_CHARACTER,
|
EMPTY_TERMINAL_CHARACTER,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// this was copied verbatim from alacritty
|
||||||
|
fn parse_number(input: &[u8]) -> Option<u8> {
|
||||||
|
if input.is_empty() {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
let mut num: u8 = 0;
|
||||||
|
for c in input {
|
||||||
|
let c = *c as char;
|
||||||
|
if let Some(digit) = c.to_digit(10) {
|
||||||
|
num = match num.checked_mul(10).and_then(|v| v.checked_add(digit as u8)) {
|
||||||
|
Some(v) => v,
|
||||||
|
None => return None,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Some(num)
|
||||||
|
}
|
||||||
|
|
||||||
fn get_top_non_canonical_rows(rows: &mut Vec<Row>) -> Vec<Row> {
|
fn get_top_non_canonical_rows(rows: &mut Vec<Row>) -> Vec<Row> {
|
||||||
let mut index_of_last_non_canonical_row = None;
|
let mut index_of_last_non_canonical_row = None;
|
||||||
for (i, row) in rows.iter().enumerate() {
|
for (i, row) in rows.iter().enumerate() {
|
||||||
|
|
@ -178,6 +200,7 @@ pub struct Grid {
|
||||||
scroll_region: Option<(usize, usize)>,
|
scroll_region: Option<(usize, usize)>,
|
||||||
active_charset: CharsetIndex,
|
active_charset: CharsetIndex,
|
||||||
preceding_char: Option<TerminalCharacter>,
|
preceding_char: Option<TerminalCharacter>,
|
||||||
|
colors: Palette,
|
||||||
pub should_render: bool,
|
pub should_render: bool,
|
||||||
pub cursor_key_mode: bool, // DECCKM - when set, cursor keys should send ANSI direction codes (eg. "OD") instead of the arrow keys (eg. "[D")
|
pub cursor_key_mode: bool, // DECCKM - when set, cursor keys should send ANSI direction codes (eg. "OD") instead of the arrow keys (eg. "[D")
|
||||||
pub erasure_mode: bool, // ERM
|
pub erasure_mode: bool, // ERM
|
||||||
|
|
@ -203,7 +226,7 @@ impl Debug for Grid {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Grid {
|
impl Grid {
|
||||||
pub fn new(rows: usize, columns: usize) -> Self {
|
pub fn new(rows: usize, columns: usize, colors: Palette) -> Self {
|
||||||
Grid {
|
Grid {
|
||||||
lines_above: VecDeque::with_capacity(SCROLL_BACK),
|
lines_above: VecDeque::with_capacity(SCROLL_BACK),
|
||||||
viewport: vec![Row::new().canonical()],
|
viewport: vec![Row::new().canonical()],
|
||||||
|
|
@ -224,6 +247,7 @@ impl Grid {
|
||||||
clear_viewport_before_rendering: false,
|
clear_viewport_before_rendering: false,
|
||||||
active_charset: Default::default(),
|
active_charset: Default::default(),
|
||||||
pending_messages_to_pty: vec![],
|
pending_messages_to_pty: vec![],
|
||||||
|
colors,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn contains_widechar(&self) -> bool {
|
pub fn contains_widechar(&self) -> bool {
|
||||||
|
|
@ -1011,8 +1035,139 @@ impl Perform for Grid {
|
||||||
// TBD
|
// TBD
|
||||||
}
|
}
|
||||||
|
|
||||||
fn osc_dispatch(&mut self, _params: &[&[u8]], _bell_terminated: bool) {
|
fn osc_dispatch(&mut self, params: &[&[u8]], bell_terminated: bool) {
|
||||||
// TBD
|
let terminator = if bell_terminated { "\x07" } else { "\x1b\\" };
|
||||||
|
|
||||||
|
if params.is_empty() || params[0].is_empty() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
match params[0] {
|
||||||
|
// Set window title.
|
||||||
|
b"0" | b"2" => {
|
||||||
|
if params.len() >= 2 {
|
||||||
|
let _title = params[1..]
|
||||||
|
.iter()
|
||||||
|
.flat_map(|x| str::from_utf8(x))
|
||||||
|
.collect::<Vec<&str>>()
|
||||||
|
.join(";")
|
||||||
|
.trim()
|
||||||
|
.to_owned();
|
||||||
|
// TBD: do something with title?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set color index.
|
||||||
|
b"4" => {
|
||||||
|
// TBD: set color index - currently unsupported
|
||||||
|
//
|
||||||
|
// this changes a terminal color index to something else
|
||||||
|
// meaning anything set to that index will be changed
|
||||||
|
// during rendering
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get/set Foreground, Background, Cursor colors.
|
||||||
|
b"10" | b"11" | b"12" => {
|
||||||
|
if params.len() >= 2 {
|
||||||
|
if let Some(mut dynamic_code) = parse_number(params[0]) {
|
||||||
|
for param in ¶ms[1..] {
|
||||||
|
// currently only getting the color sequence is supported,
|
||||||
|
// setting still isn't
|
||||||
|
if param == b"?" {
|
||||||
|
let color_response_message = match self.colors.bg {
|
||||||
|
PaletteColor::Rgb((r, g, b)) => {
|
||||||
|
format!(
|
||||||
|
"\u{1b}]{};rgb:{1:02x}{1:02x}/{2:02x}{2:02x}/{3:02x}{3:02x}{4}",
|
||||||
|
// dynamic_code, color.r, color.g, color.b, terminator
|
||||||
|
dynamic_code, r, g, b, terminator
|
||||||
|
)
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
format!(
|
||||||
|
"\u{1b}]{};rgb:{1:02x}{1:02x}/{2:02x}{2:02x}/{3:02x}{3:02x}{4}",
|
||||||
|
// dynamic_code, color.r, color.g, color.b, terminator
|
||||||
|
dynamic_code, 0, 0, 0, terminator
|
||||||
|
)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
self.pending_messages_to_pty
|
||||||
|
.push(color_response_message.as_bytes().to_vec());
|
||||||
|
}
|
||||||
|
dynamic_code += 1;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set cursor style.
|
||||||
|
b"50" => {
|
||||||
|
if params.len() >= 2
|
||||||
|
&& params[1].len() >= 13
|
||||||
|
&& params[1][0..12] == *b"CursorShape="
|
||||||
|
{
|
||||||
|
let shape = match params[1][12] as char {
|
||||||
|
'0' => Some(CursorShape::Block),
|
||||||
|
'1' => Some(CursorShape::Beam),
|
||||||
|
'2' => Some(CursorShape::Underline),
|
||||||
|
_ => None,
|
||||||
|
};
|
||||||
|
if let Some(cursor_shape) = shape {
|
||||||
|
self.cursor.change_shape(cursor_shape);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set clipboard.
|
||||||
|
b"52" => {
|
||||||
|
if params.len() < 3 {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let _clipboard = params[1].get(0).unwrap_or(&b'c');
|
||||||
|
match params[2] {
|
||||||
|
b"?" => {
|
||||||
|
// TBD: paste from own clipboard - currently unsupported
|
||||||
|
}
|
||||||
|
_base64 => {
|
||||||
|
// TBD: copy to own clipboard - currently unsupported
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset color index.
|
||||||
|
b"104" => {
|
||||||
|
// Reset all color indexes when no parameters are given.
|
||||||
|
if params.len() == 1 {
|
||||||
|
// TBD - reset all color changes - currently unsupported
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset color indexes given as parameters.
|
||||||
|
for param in ¶ms[1..] {
|
||||||
|
if let Some(_index) = parse_number(param) {
|
||||||
|
// TBD - reset color index - currently unimplemented
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset foreground color.
|
||||||
|
b"110" => {
|
||||||
|
// TBD - reset foreground color - currently unimplemented
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset background color.
|
||||||
|
b"111" => {
|
||||||
|
// TBD - reset background color - currently unimplemented
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset text cursor color.
|
||||||
|
b"112" => {
|
||||||
|
// TBD - reset text cursor color - currently unimplemented
|
||||||
|
}
|
||||||
|
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn csi_dispatch(&mut self, params: &Params, intermediates: &[u8], _ignore: bool, c: char) {
|
fn csi_dispatch(&mut self, params: &Params, intermediates: &[u8], _ignore: bool, c: char) {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
use std::os::unix::io::RawFd;
|
use std::os::unix::io::RawFd;
|
||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
|
use zellij_tile::data::Palette;
|
||||||
use zellij_utils::pane_size::PositionAndSize;
|
use zellij_utils::pane_size::PositionAndSize;
|
||||||
|
|
||||||
use crate::panes::{
|
use crate::panes::{
|
||||||
|
|
@ -27,6 +28,7 @@ pub struct TerminalPane {
|
||||||
pub max_height: Option<usize>,
|
pub max_height: Option<usize>,
|
||||||
pub max_width: Option<usize>,
|
pub max_width: Option<usize>,
|
||||||
pub active_at: Instant,
|
pub active_at: Instant,
|
||||||
|
pub colors: Palette,
|
||||||
vte_parser: vte::Parser,
|
vte_parser: vte::Parser,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -285,8 +287,8 @@ impl Pane for TerminalPane {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TerminalPane {
|
impl TerminalPane {
|
||||||
pub fn new(pid: RawFd, position_and_size: PositionAndSize) -> TerminalPane {
|
pub fn new(pid: RawFd, position_and_size: PositionAndSize, palette: Palette) -> TerminalPane {
|
||||||
let grid = Grid::new(position_and_size.rows, position_and_size.columns);
|
let grid = Grid::new(position_and_size.rows, position_and_size.columns, palette);
|
||||||
TerminalPane {
|
TerminalPane {
|
||||||
pid,
|
pid,
|
||||||
grid,
|
grid,
|
||||||
|
|
@ -297,6 +299,7 @@ impl TerminalPane {
|
||||||
max_width: None,
|
max_width: None,
|
||||||
vte_parser: vte::Parser::new(),
|
vte_parser: vte::Parser::new(),
|
||||||
active_at: Instant::now(),
|
active_at: Instant::now(),
|
||||||
|
colors: palette,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn get_x(&self) -> usize {
|
pub fn get_x(&self) -> usize {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
use super::super::Grid;
|
use super::super::Grid;
|
||||||
use ::insta::assert_snapshot;
|
use ::insta::assert_snapshot;
|
||||||
|
use zellij_tile::data::Palette;
|
||||||
|
|
||||||
fn read_fixture(fixture_name: &str) -> Vec<u8> {
|
fn read_fixture(fixture_name: &str) -> Vec<u8> {
|
||||||
let mut path_to_file = std::path::PathBuf::new();
|
let mut path_to_file = std::path::PathBuf::new();
|
||||||
|
|
@ -15,7 +16,7 @@ fn read_fixture(fixture_name: &str) -> Vec<u8> {
|
||||||
#[test]
|
#[test]
|
||||||
fn vttest1_0() {
|
fn vttest1_0() {
|
||||||
let mut vte_parser = vte::Parser::new();
|
let mut vte_parser = vte::Parser::new();
|
||||||
let mut grid = Grid::new(41, 110);
|
let mut grid = Grid::new(41, 110, Palette::default());
|
||||||
let fixture_name = "vttest1-0";
|
let fixture_name = "vttest1-0";
|
||||||
let content = read_fixture(fixture_name);
|
let content = read_fixture(fixture_name);
|
||||||
for byte in content {
|
for byte in content {
|
||||||
|
|
@ -27,7 +28,7 @@ fn vttest1_0() {
|
||||||
#[test]
|
#[test]
|
||||||
fn vttest1_1() {
|
fn vttest1_1() {
|
||||||
let mut vte_parser = vte::Parser::new();
|
let mut vte_parser = vte::Parser::new();
|
||||||
let mut grid = Grid::new(41, 110);
|
let mut grid = Grid::new(41, 110, Palette::default());
|
||||||
let fixture_name = "vttest1-1";
|
let fixture_name = "vttest1-1";
|
||||||
let content = read_fixture(fixture_name);
|
let content = read_fixture(fixture_name);
|
||||||
for byte in content {
|
for byte in content {
|
||||||
|
|
@ -39,7 +40,7 @@ fn vttest1_1() {
|
||||||
#[test]
|
#[test]
|
||||||
fn vttest1_2() {
|
fn vttest1_2() {
|
||||||
let mut vte_parser = vte::Parser::new();
|
let mut vte_parser = vte::Parser::new();
|
||||||
let mut grid = Grid::new(41, 110);
|
let mut grid = Grid::new(41, 110, Palette::default());
|
||||||
let fixture_name = "vttest1-2";
|
let fixture_name = "vttest1-2";
|
||||||
let content = read_fixture(fixture_name);
|
let content = read_fixture(fixture_name);
|
||||||
for byte in content {
|
for byte in content {
|
||||||
|
|
@ -51,7 +52,7 @@ fn vttest1_2() {
|
||||||
#[test]
|
#[test]
|
||||||
fn vttest1_3() {
|
fn vttest1_3() {
|
||||||
let mut vte_parser = vte::Parser::new();
|
let mut vte_parser = vte::Parser::new();
|
||||||
let mut grid = Grid::new(41, 110);
|
let mut grid = Grid::new(41, 110, Palette::default());
|
||||||
let fixture_name = "vttest1-3";
|
let fixture_name = "vttest1-3";
|
||||||
let content = read_fixture(fixture_name);
|
let content = read_fixture(fixture_name);
|
||||||
for byte in content {
|
for byte in content {
|
||||||
|
|
@ -63,7 +64,7 @@ fn vttest1_3() {
|
||||||
#[test]
|
#[test]
|
||||||
fn vttest1_4() {
|
fn vttest1_4() {
|
||||||
let mut vte_parser = vte::Parser::new();
|
let mut vte_parser = vte::Parser::new();
|
||||||
let mut grid = Grid::new(41, 110);
|
let mut grid = Grid::new(41, 110, Palette::default());
|
||||||
let fixture_name = "vttest1-4";
|
let fixture_name = "vttest1-4";
|
||||||
let content = read_fixture(fixture_name);
|
let content = read_fixture(fixture_name);
|
||||||
for byte in content {
|
for byte in content {
|
||||||
|
|
@ -75,7 +76,7 @@ fn vttest1_4() {
|
||||||
#[test]
|
#[test]
|
||||||
fn vttest1_5() {
|
fn vttest1_5() {
|
||||||
let mut vte_parser = vte::Parser::new();
|
let mut vte_parser = vte::Parser::new();
|
||||||
let mut grid = Grid::new(41, 110);
|
let mut grid = Grid::new(41, 110, Palette::default());
|
||||||
let fixture_name = "vttest1-5";
|
let fixture_name = "vttest1-5";
|
||||||
let content = read_fixture(fixture_name);
|
let content = read_fixture(fixture_name);
|
||||||
for byte in content {
|
for byte in content {
|
||||||
|
|
@ -87,7 +88,7 @@ fn vttest1_5() {
|
||||||
#[test]
|
#[test]
|
||||||
fn vttest2_0() {
|
fn vttest2_0() {
|
||||||
let mut vte_parser = vte::Parser::new();
|
let mut vte_parser = vte::Parser::new();
|
||||||
let mut grid = Grid::new(41, 110);
|
let mut grid = Grid::new(41, 110, Palette::default());
|
||||||
let fixture_name = "vttest2-0";
|
let fixture_name = "vttest2-0";
|
||||||
let content = read_fixture(fixture_name);
|
let content = read_fixture(fixture_name);
|
||||||
for byte in content {
|
for byte in content {
|
||||||
|
|
@ -99,7 +100,7 @@ fn vttest2_0() {
|
||||||
#[test]
|
#[test]
|
||||||
fn vttest2_1() {
|
fn vttest2_1() {
|
||||||
let mut vte_parser = vte::Parser::new();
|
let mut vte_parser = vte::Parser::new();
|
||||||
let mut grid = Grid::new(41, 110);
|
let mut grid = Grid::new(41, 110, Palette::default());
|
||||||
let fixture_name = "vttest2-1";
|
let fixture_name = "vttest2-1";
|
||||||
let content = read_fixture(fixture_name);
|
let content = read_fixture(fixture_name);
|
||||||
for byte in content {
|
for byte in content {
|
||||||
|
|
@ -111,7 +112,7 @@ fn vttest2_1() {
|
||||||
#[test]
|
#[test]
|
||||||
fn vttest2_2() {
|
fn vttest2_2() {
|
||||||
let mut vte_parser = vte::Parser::new();
|
let mut vte_parser = vte::Parser::new();
|
||||||
let mut grid = Grid::new(41, 110);
|
let mut grid = Grid::new(41, 110, Palette::default());
|
||||||
let fixture_name = "vttest2-2";
|
let fixture_name = "vttest2-2";
|
||||||
let content = read_fixture(fixture_name);
|
let content = read_fixture(fixture_name);
|
||||||
for byte in content {
|
for byte in content {
|
||||||
|
|
@ -123,7 +124,7 @@ fn vttest2_2() {
|
||||||
#[test]
|
#[test]
|
||||||
fn vttest2_3() {
|
fn vttest2_3() {
|
||||||
let mut vte_parser = vte::Parser::new();
|
let mut vte_parser = vte::Parser::new();
|
||||||
let mut grid = Grid::new(41, 110);
|
let mut grid = Grid::new(41, 110, Palette::default());
|
||||||
let fixture_name = "vttest2-3";
|
let fixture_name = "vttest2-3";
|
||||||
let content = read_fixture(fixture_name);
|
let content = read_fixture(fixture_name);
|
||||||
for byte in content {
|
for byte in content {
|
||||||
|
|
@ -135,7 +136,7 @@ fn vttest2_3() {
|
||||||
#[test]
|
#[test]
|
||||||
fn vttest2_4() {
|
fn vttest2_4() {
|
||||||
let mut vte_parser = vte::Parser::new();
|
let mut vte_parser = vte::Parser::new();
|
||||||
let mut grid = Grid::new(41, 110);
|
let mut grid = Grid::new(41, 110, Palette::default());
|
||||||
let fixture_name = "vttest2-4";
|
let fixture_name = "vttest2-4";
|
||||||
let content = read_fixture(fixture_name);
|
let content = read_fixture(fixture_name);
|
||||||
for byte in content {
|
for byte in content {
|
||||||
|
|
@ -147,7 +148,7 @@ fn vttest2_4() {
|
||||||
#[test]
|
#[test]
|
||||||
fn vttest2_5() {
|
fn vttest2_5() {
|
||||||
let mut vte_parser = vte::Parser::new();
|
let mut vte_parser = vte::Parser::new();
|
||||||
let mut grid = Grid::new(41, 110);
|
let mut grid = Grid::new(41, 110, Palette::default());
|
||||||
let fixture_name = "vttest2-5";
|
let fixture_name = "vttest2-5";
|
||||||
let content = read_fixture(fixture_name);
|
let content = read_fixture(fixture_name);
|
||||||
for byte in content {
|
for byte in content {
|
||||||
|
|
@ -159,7 +160,7 @@ fn vttest2_5() {
|
||||||
#[test]
|
#[test]
|
||||||
fn vttest2_6() {
|
fn vttest2_6() {
|
||||||
let mut vte_parser = vte::Parser::new();
|
let mut vte_parser = vte::Parser::new();
|
||||||
let mut grid = Grid::new(41, 110);
|
let mut grid = Grid::new(41, 110, Palette::default());
|
||||||
let fixture_name = "vttest2-6";
|
let fixture_name = "vttest2-6";
|
||||||
let content = read_fixture(fixture_name);
|
let content = read_fixture(fixture_name);
|
||||||
for byte in content {
|
for byte in content {
|
||||||
|
|
@ -171,7 +172,7 @@ fn vttest2_6() {
|
||||||
#[test]
|
#[test]
|
||||||
fn vttest2_7() {
|
fn vttest2_7() {
|
||||||
let mut vte_parser = vte::Parser::new();
|
let mut vte_parser = vte::Parser::new();
|
||||||
let mut grid = Grid::new(41, 110);
|
let mut grid = Grid::new(41, 110, Palette::default());
|
||||||
let fixture_name = "vttest2-7";
|
let fixture_name = "vttest2-7";
|
||||||
let content = read_fixture(fixture_name);
|
let content = read_fixture(fixture_name);
|
||||||
for byte in content {
|
for byte in content {
|
||||||
|
|
@ -183,7 +184,7 @@ fn vttest2_7() {
|
||||||
#[test]
|
#[test]
|
||||||
fn vttest2_8() {
|
fn vttest2_8() {
|
||||||
let mut vte_parser = vte::Parser::new();
|
let mut vte_parser = vte::Parser::new();
|
||||||
let mut grid = Grid::new(41, 110);
|
let mut grid = Grid::new(41, 110, Palette::default());
|
||||||
let fixture_name = "vttest2-8";
|
let fixture_name = "vttest2-8";
|
||||||
let content = read_fixture(fixture_name);
|
let content = read_fixture(fixture_name);
|
||||||
for byte in content {
|
for byte in content {
|
||||||
|
|
@ -195,7 +196,7 @@ fn vttest2_8() {
|
||||||
#[test]
|
#[test]
|
||||||
fn vttest2_9() {
|
fn vttest2_9() {
|
||||||
let mut vte_parser = vte::Parser::new();
|
let mut vte_parser = vte::Parser::new();
|
||||||
let mut grid = Grid::new(41, 110);
|
let mut grid = Grid::new(41, 110, Palette::default());
|
||||||
let fixture_name = "vttest2-9";
|
let fixture_name = "vttest2-9";
|
||||||
let content = read_fixture(fixture_name);
|
let content = read_fixture(fixture_name);
|
||||||
for byte in content {
|
for byte in content {
|
||||||
|
|
@ -207,7 +208,7 @@ fn vttest2_9() {
|
||||||
#[test]
|
#[test]
|
||||||
fn vttest2_10() {
|
fn vttest2_10() {
|
||||||
let mut vte_parser = vte::Parser::new();
|
let mut vte_parser = vte::Parser::new();
|
||||||
let mut grid = Grid::new(41, 110);
|
let mut grid = Grid::new(41, 110, Palette::default());
|
||||||
let fixture_name = "vttest2-10";
|
let fixture_name = "vttest2-10";
|
||||||
let content = read_fixture(fixture_name);
|
let content = read_fixture(fixture_name);
|
||||||
for byte in content {
|
for byte in content {
|
||||||
|
|
@ -219,7 +220,7 @@ fn vttest2_10() {
|
||||||
#[test]
|
#[test]
|
||||||
fn vttest2_11() {
|
fn vttest2_11() {
|
||||||
let mut vte_parser = vte::Parser::new();
|
let mut vte_parser = vte::Parser::new();
|
||||||
let mut grid = Grid::new(41, 110);
|
let mut grid = Grid::new(41, 110, Palette::default());
|
||||||
let fixture_name = "vttest2-11";
|
let fixture_name = "vttest2-11";
|
||||||
let content = read_fixture(fixture_name);
|
let content = read_fixture(fixture_name);
|
||||||
for byte in content {
|
for byte in content {
|
||||||
|
|
@ -231,7 +232,7 @@ fn vttest2_11() {
|
||||||
#[test]
|
#[test]
|
||||||
fn vttest2_12() {
|
fn vttest2_12() {
|
||||||
let mut vte_parser = vte::Parser::new();
|
let mut vte_parser = vte::Parser::new();
|
||||||
let mut grid = Grid::new(41, 110);
|
let mut grid = Grid::new(41, 110, Palette::default());
|
||||||
let fixture_name = "vttest2-12";
|
let fixture_name = "vttest2-12";
|
||||||
let content = read_fixture(fixture_name);
|
let content = read_fixture(fixture_name);
|
||||||
for byte in content {
|
for byte in content {
|
||||||
|
|
@ -243,7 +244,7 @@ fn vttest2_12() {
|
||||||
#[test]
|
#[test]
|
||||||
fn vttest2_13() {
|
fn vttest2_13() {
|
||||||
let mut vte_parser = vte::Parser::new();
|
let mut vte_parser = vte::Parser::new();
|
||||||
let mut grid = Grid::new(41, 110);
|
let mut grid = Grid::new(41, 110, Palette::default());
|
||||||
let fixture_name = "vttest2-13";
|
let fixture_name = "vttest2-13";
|
||||||
let content = read_fixture(fixture_name);
|
let content = read_fixture(fixture_name);
|
||||||
for byte in content {
|
for byte in content {
|
||||||
|
|
@ -255,7 +256,7 @@ fn vttest2_13() {
|
||||||
#[test]
|
#[test]
|
||||||
fn vttest2_14() {
|
fn vttest2_14() {
|
||||||
let mut vte_parser = vte::Parser::new();
|
let mut vte_parser = vte::Parser::new();
|
||||||
let mut grid = Grid::new(41, 110);
|
let mut grid = Grid::new(41, 110, Palette::default());
|
||||||
let fixture_name = "vttest2-14";
|
let fixture_name = "vttest2-14";
|
||||||
let content = read_fixture(fixture_name);
|
let content = read_fixture(fixture_name);
|
||||||
for byte in content {
|
for byte in content {
|
||||||
|
|
@ -267,7 +268,7 @@ fn vttest2_14() {
|
||||||
#[test]
|
#[test]
|
||||||
fn vttest3_0() {
|
fn vttest3_0() {
|
||||||
let mut vte_parser = vte::Parser::new();
|
let mut vte_parser = vte::Parser::new();
|
||||||
let mut grid = Grid::new(41, 110);
|
let mut grid = Grid::new(41, 110, Palette::default());
|
||||||
let fixture_name = "vttest3-0";
|
let fixture_name = "vttest3-0";
|
||||||
let content = read_fixture(fixture_name);
|
let content = read_fixture(fixture_name);
|
||||||
for byte in content {
|
for byte in content {
|
||||||
|
|
@ -279,7 +280,7 @@ fn vttest3_0() {
|
||||||
#[test]
|
#[test]
|
||||||
fn vttest8_0() {
|
fn vttest8_0() {
|
||||||
let mut vte_parser = vte::Parser::new();
|
let mut vte_parser = vte::Parser::new();
|
||||||
let mut grid = Grid::new(51, 97);
|
let mut grid = Grid::new(51, 97, Palette::default());
|
||||||
let fixture_name = "vttest8-0";
|
let fixture_name = "vttest8-0";
|
||||||
let content = read_fixture(fixture_name);
|
let content = read_fixture(fixture_name);
|
||||||
for byte in content {
|
for byte in content {
|
||||||
|
|
@ -291,7 +292,7 @@ fn vttest8_0() {
|
||||||
#[test]
|
#[test]
|
||||||
fn vttest8_1() {
|
fn vttest8_1() {
|
||||||
let mut vte_parser = vte::Parser::new();
|
let mut vte_parser = vte::Parser::new();
|
||||||
let mut grid = Grid::new(51, 97);
|
let mut grid = Grid::new(51, 97, Palette::default());
|
||||||
let fixture_name = "vttest8-1";
|
let fixture_name = "vttest8-1";
|
||||||
let content = read_fixture(fixture_name);
|
let content = read_fixture(fixture_name);
|
||||||
for byte in content {
|
for byte in content {
|
||||||
|
|
@ -303,7 +304,7 @@ fn vttest8_1() {
|
||||||
#[test]
|
#[test]
|
||||||
fn vttest8_2() {
|
fn vttest8_2() {
|
||||||
let mut vte_parser = vte::Parser::new();
|
let mut vte_parser = vte::Parser::new();
|
||||||
let mut grid = Grid::new(51, 97);
|
let mut grid = Grid::new(51, 97, Palette::default());
|
||||||
let fixture_name = "vttest8-2";
|
let fixture_name = "vttest8-2";
|
||||||
let content = read_fixture(fixture_name);
|
let content = read_fixture(fixture_name);
|
||||||
for byte in content {
|
for byte in content {
|
||||||
|
|
@ -315,7 +316,7 @@ fn vttest8_2() {
|
||||||
#[test]
|
#[test]
|
||||||
fn vttest8_3() {
|
fn vttest8_3() {
|
||||||
let mut vte_parser = vte::Parser::new();
|
let mut vte_parser = vte::Parser::new();
|
||||||
let mut grid = Grid::new(51, 97);
|
let mut grid = Grid::new(51, 97, Palette::default());
|
||||||
let fixture_name = "vttest8-3";
|
let fixture_name = "vttest8-3";
|
||||||
let content = read_fixture(fixture_name);
|
let content = read_fixture(fixture_name);
|
||||||
for byte in content {
|
for byte in content {
|
||||||
|
|
@ -327,7 +328,7 @@ fn vttest8_3() {
|
||||||
#[test]
|
#[test]
|
||||||
fn vttest8_4() {
|
fn vttest8_4() {
|
||||||
let mut vte_parser = vte::Parser::new();
|
let mut vte_parser = vte::Parser::new();
|
||||||
let mut grid = Grid::new(51, 97);
|
let mut grid = Grid::new(51, 97, Palette::default());
|
||||||
let fixture_name = "vttest8-4";
|
let fixture_name = "vttest8-4";
|
||||||
let content = read_fixture(fixture_name);
|
let content = read_fixture(fixture_name);
|
||||||
for byte in content {
|
for byte in content {
|
||||||
|
|
@ -339,7 +340,7 @@ fn vttest8_4() {
|
||||||
#[test]
|
#[test]
|
||||||
fn vttest8_5() {
|
fn vttest8_5() {
|
||||||
let mut vte_parser = vte::Parser::new();
|
let mut vte_parser = vte::Parser::new();
|
||||||
let mut grid = Grid::new(51, 97);
|
let mut grid = Grid::new(51, 97, Palette::default());
|
||||||
let fixture_name = "vttest8-5";
|
let fixture_name = "vttest8-5";
|
||||||
let content = read_fixture(fixture_name);
|
let content = read_fixture(fixture_name);
|
||||||
for byte in content {
|
for byte in content {
|
||||||
|
|
@ -351,7 +352,7 @@ fn vttest8_5() {
|
||||||
#[test]
|
#[test]
|
||||||
fn csi_b() {
|
fn csi_b() {
|
||||||
let mut vte_parser = vte::Parser::new();
|
let mut vte_parser = vte::Parser::new();
|
||||||
let mut grid = Grid::new(51, 97);
|
let mut grid = Grid::new(51, 97, Palette::default());
|
||||||
let fixture_name = "csi-b";
|
let fixture_name = "csi-b";
|
||||||
let content = read_fixture(fixture_name);
|
let content = read_fixture(fixture_name);
|
||||||
for byte in content {
|
for byte in content {
|
||||||
|
|
@ -363,7 +364,7 @@ fn csi_b() {
|
||||||
#[test]
|
#[test]
|
||||||
fn csi_capital_i() {
|
fn csi_capital_i() {
|
||||||
let mut vte_parser = vte::Parser::new();
|
let mut vte_parser = vte::Parser::new();
|
||||||
let mut grid = Grid::new(51, 97);
|
let mut grid = Grid::new(51, 97, Palette::default());
|
||||||
let fixture_name = "csi-capital-i";
|
let fixture_name = "csi-capital-i";
|
||||||
let content = read_fixture(fixture_name);
|
let content = read_fixture(fixture_name);
|
||||||
for byte in content {
|
for byte in content {
|
||||||
|
|
@ -375,7 +376,7 @@ fn csi_capital_i() {
|
||||||
#[test]
|
#[test]
|
||||||
fn csi_capital_z() {
|
fn csi_capital_z() {
|
||||||
let mut vte_parser = vte::Parser::new();
|
let mut vte_parser = vte::Parser::new();
|
||||||
let mut grid = Grid::new(51, 97);
|
let mut grid = Grid::new(51, 97, Palette::default());
|
||||||
let fixture_name = "csi-capital-z";
|
let fixture_name = "csi-capital-z";
|
||||||
let content = read_fixture(fixture_name);
|
let content = read_fixture(fixture_name);
|
||||||
for byte in content {
|
for byte in content {
|
||||||
|
|
@ -387,7 +388,7 @@ fn csi_capital_z() {
|
||||||
#[test]
|
#[test]
|
||||||
fn terminal_reports() {
|
fn terminal_reports() {
|
||||||
let mut vte_parser = vte::Parser::new();
|
let mut vte_parser = vte::Parser::new();
|
||||||
let mut grid = Grid::new(51, 97);
|
let mut grid = Grid::new(51, 97, Palette::default());
|
||||||
let fixture_name = "terminal_reports";
|
let fixture_name = "terminal_reports";
|
||||||
let content = read_fixture(fixture_name);
|
let content = read_fixture(fixture_name);
|
||||||
for byte in content {
|
for byte in content {
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,9 @@ fn route_action(action: Action, session: &SessionMetaData, os_input: &dyn Server
|
||||||
}
|
}
|
||||||
Action::SwitchToMode(mode) => {
|
Action::SwitchToMode(mode) => {
|
||||||
let palette = os_input.load_palette();
|
let palette = os_input.load_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
|
||||||
session
|
session
|
||||||
.senders
|
.senders
|
||||||
.send_to_plugin(PluginInstruction::Update(
|
.send_to_plugin(PluginInstruction::Update(
|
||||||
|
|
@ -199,7 +202,9 @@ pub(crate) fn route_thread_main(
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ClientToServerMsg::Action(action) => {
|
ClientToServerMsg::Action(action) => {
|
||||||
route_action(action, rlocked_sessions.as_ref().unwrap(), &*os_input);
|
if let Some(rlocked_sessions) = rlocked_sessions.as_ref() {
|
||||||
|
route_action(action, rlocked_sessions, &*os_input);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ClientToServerMsg::TerminalResize(new_size) => {
|
ClientToServerMsg::TerminalResize(new_size) => {
|
||||||
rlocked_sessions
|
rlocked_sessions
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ use zellij_tile::data::{Event, InputMode, ModeInfo, Palette, PluginCapabilities,
|
||||||
use zellij_utils::{
|
use zellij_utils::{
|
||||||
errors::{ContextType, ScreenContext},
|
errors::{ContextType, ScreenContext},
|
||||||
input::options::Options,
|
input::options::Options,
|
||||||
|
ipc::ClientAttributes,
|
||||||
pane_size::PositionAndSize,
|
pane_size::PositionAndSize,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -128,7 +129,7 @@ pub(crate) struct Screen {
|
||||||
/// A map between this [`Screen`]'s tabs and their ID/key.
|
/// A map between this [`Screen`]'s tabs and their ID/key.
|
||||||
tabs: BTreeMap<usize, Tab>,
|
tabs: BTreeMap<usize, Tab>,
|
||||||
/// The full size of this [`Screen`].
|
/// The full size of this [`Screen`].
|
||||||
full_screen_ws: PositionAndSize,
|
position_and_size: PositionAndSize,
|
||||||
/// The index of this [`Screen`]'s active [`Tab`].
|
/// The index of this [`Screen`]'s active [`Tab`].
|
||||||
active_tab_index: Option<usize>,
|
active_tab_index: Option<usize>,
|
||||||
mode_info: ModeInfo,
|
mode_info: ModeInfo,
|
||||||
|
|
@ -140,21 +141,20 @@ impl Screen {
|
||||||
/// Creates and returns a new [`Screen`].
|
/// Creates and returns a new [`Screen`].
|
||||||
pub fn new(
|
pub fn new(
|
||||||
bus: Bus<ScreenInstruction>,
|
bus: Bus<ScreenInstruction>,
|
||||||
full_screen_ws: &PositionAndSize,
|
client_attributes: &ClientAttributes,
|
||||||
max_panes: Option<usize>,
|
max_panes: Option<usize>,
|
||||||
mode_info: ModeInfo,
|
mode_info: ModeInfo,
|
||||||
input_mode: InputMode,
|
input_mode: InputMode,
|
||||||
colors: Palette,
|
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Screen {
|
Screen {
|
||||||
bus,
|
bus,
|
||||||
max_panes,
|
max_panes,
|
||||||
full_screen_ws: *full_screen_ws,
|
position_and_size: client_attributes.position_and_size,
|
||||||
|
colors: client_attributes.palette,
|
||||||
active_tab_index: None,
|
active_tab_index: None,
|
||||||
tabs: BTreeMap::new(),
|
tabs: BTreeMap::new(),
|
||||||
mode_info,
|
mode_info,
|
||||||
input_mode,
|
input_mode,
|
||||||
colors,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -167,7 +167,7 @@ impl Screen {
|
||||||
tab_index,
|
tab_index,
|
||||||
position,
|
position,
|
||||||
String::new(),
|
String::new(),
|
||||||
&self.full_screen_ws,
|
&self.position_and_size,
|
||||||
self.bus.os_input.as_ref().unwrap().clone(),
|
self.bus.os_input.as_ref().unwrap().clone(),
|
||||||
self.bus.senders.clone(),
|
self.bus.senders.clone(),
|
||||||
self.max_panes,
|
self.max_panes,
|
||||||
|
|
@ -274,7 +274,7 @@ impl Screen {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn resize_to_screen(&mut self, new_screen_size: PositionAndSize) {
|
pub fn resize_to_screen(&mut self, new_screen_size: PositionAndSize) {
|
||||||
self.full_screen_ws = new_screen_size;
|
self.position_and_size = new_screen_size;
|
||||||
for (_, tab) in self.tabs.iter_mut() {
|
for (_, tab) in self.tabs.iter_mut() {
|
||||||
tab.resize_whole_tab(new_screen_size);
|
tab.resize_whole_tab(new_screen_size);
|
||||||
}
|
}
|
||||||
|
|
@ -323,7 +323,7 @@ impl Screen {
|
||||||
tab_index,
|
tab_index,
|
||||||
position,
|
position,
|
||||||
String::new(),
|
String::new(),
|
||||||
&self.full_screen_ws,
|
&self.position_and_size,
|
||||||
self.bus.os_input.as_ref().unwrap().clone(),
|
self.bus.os_input.as_ref().unwrap().clone(),
|
||||||
self.bus.senders.clone(),
|
self.bus.senders.clone(),
|
||||||
self.max_panes,
|
self.max_panes,
|
||||||
|
|
@ -383,25 +383,23 @@ impl Screen {
|
||||||
pub(crate) fn screen_thread_main(
|
pub(crate) fn screen_thread_main(
|
||||||
bus: Bus<ScreenInstruction>,
|
bus: Bus<ScreenInstruction>,
|
||||||
max_panes: Option<usize>,
|
max_panes: Option<usize>,
|
||||||
full_screen_ws: PositionAndSize,
|
client_attributes: ClientAttributes,
|
||||||
config_options: Options,
|
config_options: Options,
|
||||||
) {
|
) {
|
||||||
let colors = bus.os_input.as_ref().unwrap().load_palette();
|
|
||||||
let capabilities = config_options.simplified_ui;
|
let capabilities = config_options.simplified_ui;
|
||||||
|
|
||||||
let mut screen = Screen::new(
|
let mut screen = Screen::new(
|
||||||
bus,
|
bus,
|
||||||
&full_screen_ws,
|
&client_attributes,
|
||||||
max_panes,
|
max_panes,
|
||||||
ModeInfo {
|
ModeInfo {
|
||||||
palette: colors,
|
palette: client_attributes.palette,
|
||||||
capabilities: PluginCapabilities {
|
capabilities: PluginCapabilities {
|
||||||
arrow_fonts: capabilities,
|
arrow_fonts: capabilities,
|
||||||
},
|
},
|
||||||
..ModeInfo::default()
|
..ModeInfo::default()
|
||||||
},
|
},
|
||||||
InputMode::Normal,
|
InputMode::Normal,
|
||||||
colors,
|
|
||||||
);
|
);
|
||||||
loop {
|
loop {
|
||||||
let (event, mut err_ctx) = screen
|
let (event, mut err_ctx) = screen
|
||||||
|
|
|
||||||
|
|
@ -241,7 +241,7 @@ impl Tab {
|
||||||
colors: Palette,
|
colors: Palette,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let panes = if let Some(PaneId::Terminal(pid)) = pane_id {
|
let panes = if let Some(PaneId::Terminal(pid)) = pane_id {
|
||||||
let new_terminal = TerminalPane::new(pid, *full_screen_ws);
|
let new_terminal = TerminalPane::new(pid, *full_screen_ws, colors);
|
||||||
os_api.set_terminal_size_using_fd(
|
os_api.set_terminal_size_using_fd(
|
||||||
new_terminal.pid,
|
new_terminal.pid,
|
||||||
new_terminal.columns() as u16,
|
new_terminal.columns() as u16,
|
||||||
|
|
@ -343,7 +343,7 @@ impl Tab {
|
||||||
} else {
|
} else {
|
||||||
// there are still panes left to fill, use the pids we received in this method
|
// there are still panes left to fill, use the pids we received in this method
|
||||||
let pid = new_pids.next().unwrap(); // if this crashes it means we got less pids than there are panes in this layout
|
let pid = new_pids.next().unwrap(); // if this crashes it means we got less pids than there are panes in this layout
|
||||||
let new_terminal = TerminalPane::new(*pid, *position_and_size);
|
let new_terminal = TerminalPane::new(*pid, *position_and_size, self.colors);
|
||||||
self.os_api.set_terminal_size_using_fd(
|
self.os_api.set_terminal_size_using_fd(
|
||||||
new_terminal.pid,
|
new_terminal.pid,
|
||||||
new_terminal.columns() as u16,
|
new_terminal.columns() as u16,
|
||||||
|
|
@ -371,7 +371,7 @@ impl Tab {
|
||||||
}
|
}
|
||||||
if !self.has_panes() {
|
if !self.has_panes() {
|
||||||
if let PaneId::Terminal(term_pid) = pid {
|
if let PaneId::Terminal(term_pid) = pid {
|
||||||
let new_terminal = TerminalPane::new(term_pid, self.full_screen_ws);
|
let new_terminal = TerminalPane::new(term_pid, self.full_screen_ws, self.colors);
|
||||||
self.os_api.set_terminal_size_using_fd(
|
self.os_api.set_terminal_size_using_fd(
|
||||||
new_terminal.pid,
|
new_terminal.pid,
|
||||||
new_terminal.columns() as u16,
|
new_terminal.columns() as u16,
|
||||||
|
|
@ -421,7 +421,7 @@ impl Tab {
|
||||||
{
|
{
|
||||||
if let PaneId::Terminal(term_pid) = pid {
|
if let PaneId::Terminal(term_pid) = pid {
|
||||||
let (top_winsize, bottom_winsize) = split_horizontally_with_gap(&terminal_ws);
|
let (top_winsize, bottom_winsize) = split_horizontally_with_gap(&terminal_ws);
|
||||||
let new_terminal = TerminalPane::new(term_pid, bottom_winsize);
|
let new_terminal = TerminalPane::new(term_pid, bottom_winsize, self.colors);
|
||||||
self.os_api.set_terminal_size_using_fd(
|
self.os_api.set_terminal_size_using_fd(
|
||||||
new_terminal.pid,
|
new_terminal.pid,
|
||||||
bottom_winsize.columns as u16,
|
bottom_winsize.columns as u16,
|
||||||
|
|
@ -441,7 +441,7 @@ impl Tab {
|
||||||
} else if terminal_to_split.columns() > terminal_to_split.min_width() * 2 {
|
} else if terminal_to_split.columns() > terminal_to_split.min_width() * 2 {
|
||||||
if let PaneId::Terminal(term_pid) = pid {
|
if let PaneId::Terminal(term_pid) = pid {
|
||||||
let (left_winsize, right_winsize) = split_vertically_with_gap(&terminal_ws);
|
let (left_winsize, right_winsize) = split_vertically_with_gap(&terminal_ws);
|
||||||
let new_terminal = TerminalPane::new(term_pid, right_winsize);
|
let new_terminal = TerminalPane::new(term_pid, right_winsize, self.colors);
|
||||||
self.os_api.set_terminal_size_using_fd(
|
self.os_api.set_terminal_size_using_fd(
|
||||||
new_terminal.pid,
|
new_terminal.pid,
|
||||||
right_winsize.columns as u16,
|
right_winsize.columns as u16,
|
||||||
|
|
@ -469,7 +469,7 @@ impl Tab {
|
||||||
}
|
}
|
||||||
if !self.has_panes() {
|
if !self.has_panes() {
|
||||||
if let PaneId::Terminal(term_pid) = pid {
|
if let PaneId::Terminal(term_pid) = pid {
|
||||||
let new_terminal = TerminalPane::new(term_pid, self.full_screen_ws);
|
let new_terminal = TerminalPane::new(term_pid, self.full_screen_ws, self.colors);
|
||||||
self.os_api.set_terminal_size_using_fd(
|
self.os_api.set_terminal_size_using_fd(
|
||||||
new_terminal.pid,
|
new_terminal.pid,
|
||||||
new_terminal.columns() as u16,
|
new_terminal.columns() as u16,
|
||||||
|
|
@ -499,7 +499,7 @@ impl Tab {
|
||||||
|
|
||||||
active_pane.change_pos_and_size(&top_winsize);
|
active_pane.change_pos_and_size(&top_winsize);
|
||||||
|
|
||||||
let new_terminal = TerminalPane::new(term_pid, bottom_winsize);
|
let new_terminal = TerminalPane::new(term_pid, bottom_winsize, self.colors);
|
||||||
self.os_api.set_terminal_size_using_fd(
|
self.os_api.set_terminal_size_using_fd(
|
||||||
new_terminal.pid,
|
new_terminal.pid,
|
||||||
bottom_winsize.columns as u16,
|
bottom_winsize.columns as u16,
|
||||||
|
|
@ -526,7 +526,7 @@ impl Tab {
|
||||||
}
|
}
|
||||||
if !self.has_panes() {
|
if !self.has_panes() {
|
||||||
if let PaneId::Terminal(term_pid) = pid {
|
if let PaneId::Terminal(term_pid) = pid {
|
||||||
let new_terminal = TerminalPane::new(term_pid, self.full_screen_ws);
|
let new_terminal = TerminalPane::new(term_pid, self.full_screen_ws, self.colors);
|
||||||
self.os_api.set_terminal_size_using_fd(
|
self.os_api.set_terminal_size_using_fd(
|
||||||
new_terminal.pid,
|
new_terminal.pid,
|
||||||
new_terminal.columns() as u16,
|
new_terminal.columns() as u16,
|
||||||
|
|
@ -556,7 +556,7 @@ impl Tab {
|
||||||
|
|
||||||
active_pane.change_pos_and_size(&left_winsize);
|
active_pane.change_pos_and_size(&left_winsize);
|
||||||
|
|
||||||
let new_terminal = TerminalPane::new(term_pid, right_winsize);
|
let new_terminal = TerminalPane::new(term_pid, right_winsize, self.colors);
|
||||||
self.os_api.set_terminal_size_using_fd(
|
self.os_api.set_terminal_size_using_fd(
|
||||||
new_terminal.pid,
|
new_terminal.pid,
|
||||||
right_winsize.columns as u16,
|
right_winsize.columns as u16,
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,8 @@ use std::io::{self, Write};
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::os::unix::io::{AsRawFd, FromRawFd};
|
use std::os::unix::io::{AsRawFd, FromRawFd};
|
||||||
|
|
||||||
|
use zellij_tile::data::Palette;
|
||||||
|
|
||||||
type SessionId = u64;
|
type SessionId = u64;
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, Serialize, Deserialize, Hash)]
|
#[derive(PartialEq, Eq, Serialize, Deserialize, Hash)]
|
||||||
|
|
@ -32,7 +34,14 @@ pub enum ClientType {
|
||||||
Writer,
|
Writer,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||||
|
pub struct ClientAttributes {
|
||||||
|
pub position_and_size: PositionAndSize,
|
||||||
|
pub palette: Palette,
|
||||||
|
}
|
||||||
|
|
||||||
// Types of messages sent from the client to the server
|
// Types of messages sent from the client to the server
|
||||||
|
#[allow(clippy::large_enum_variant)]
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||||
pub enum ClientToServerMsg {
|
pub enum ClientToServerMsg {
|
||||||
/*// List which sessions are available
|
/*// List which sessions are available
|
||||||
|
|
@ -47,7 +56,7 @@ pub enum ClientToServerMsg {
|
||||||
DisconnectFromSession,*/
|
DisconnectFromSession,*/
|
||||||
ClientExit,
|
ClientExit,
|
||||||
TerminalResize(PositionAndSize),
|
TerminalResize(PositionAndSize),
|
||||||
NewClient(PositionAndSize, CliArgs, Options),
|
NewClient(ClientAttributes, CliArgs, Options),
|
||||||
Action(Action),
|
Action(Action),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue