fix(style): various internal refactorings

This commit is contained in:
Marcin Puc 2021-12-07 11:24:42 +01:00 committed by GitHub
parent d34e624010
commit 56e85f87d6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
39 changed files with 358 additions and 360 deletions

View file

@ -93,7 +93,7 @@ fn selected_mode_shortcut(
) -> LinePart {
let prefix_separator = palette.selected_prefix_separator.paint(separator);
let char_left_separator = palette.selected_char_left_separator.paint(" <".to_string());
let char_shortcut = palette.selected_char_shortcut.paint(format!("{}", letter));
let char_shortcut = palette.selected_char_shortcut.paint(letter.to_string());
let char_right_separator = palette.selected_char_right_separator.paint(">".to_string());
let styled_text = palette.selected_styled_text.paint(format!("{} ", text));
let suffix_separator = palette.selected_suffix_separator.paint(separator);

View file

@ -176,7 +176,7 @@ impl ZellijPlugin for State {
let first_line = format!("{}{}", superkey, ctrl_keys);
let mut second_line = LinePart::default();
for t in self.tabs.iter_mut() {
for t in &mut self.tabs {
if t.active {
match self.mode_info.mode {
InputMode::Normal => {

View file

@ -31,16 +31,14 @@ fn full_length_shortcut(
let description = Style::new().fg(white_color).bold().paint(description);
let len = shortcut_len + description_len + separator.chars().count();
LinePart {
part: format!(
"{}",
ANSIStrings(&[
separator,
shortcut_left_separator,
shortcut,
shortcut_right_separator,
description
])
),
part: ANSIStrings(&[
separator,
shortcut_left_separator,
shortcut,
shortcut_right_separator,
description,
])
.to_string(),
len,
}
}
@ -73,16 +71,14 @@ fn first_word_shortcut(
.paint(description_first_word);
let len = shortcut_len + description_first_word_length + separator.chars().count();
LinePart {
part: format!(
"{}",
ANSIStrings(&[
separator,
shortcut_left_separator,
shortcut,
shortcut_right_separator,
description_first_word,
])
),
part: ANSIStrings(&[
separator,
shortcut_left_separator,
shortcut,
shortcut_right_separator,
description_first_word,
])
.to_string(),
len,
}
}
@ -284,7 +280,7 @@ fn locked_interface_indication(palette: Palette) -> LinePart {
};
let locked_styled_text = Style::new().fg(white_color).bold().paint(locked_text);
LinePart {
part: format!("{}", locked_styled_text),
part: locked_styled_text.to_string(),
len: locked_text_len,
}
}
@ -310,16 +306,14 @@ fn select_pane_shortcut(is_first_shortcut: bool, palette: Palette) -> LinePart {
let description = Style::new().fg(white_color).bold().paint(description);
let len = shortcut_len + description_len + separator.chars().count();
LinePart {
part: format!(
"{}",
ANSIStrings(&[
separator,
shortcut_left_separator,
shortcut,
shortcut_right_separator,
description
])
),
part: ANSIStrings(&[
separator,
shortcut_left_separator,
shortcut,
shortcut_right_separator,
description,
])
.to_string(),
len,
}
}
@ -422,7 +416,7 @@ pub fn text_copied_hint(palette: &Palette) -> LinePart {
PaletteColor::EightBit(color) => Fixed(color),
};
LinePart {
part: format!("{}", Style::new().fg(green_color).bold().paint(hint)),
part: Style::new().fg(green_color).bold().paint(hint).to_string(),
len: hint.len(),
}
}

View file

@ -107,10 +107,8 @@ fn left_more_message(tab_count_to_the_left: usize, palette: Palette, separator:
.bold()
.paint(more_text);
let right_separator = style!(palette.orange, palette.gray).paint(separator);
let more_styled_text = format!(
"{}",
ANSIStrings(&[left_separator, more_styled_text, right_separator,])
);
let more_styled_text =
ANSIStrings(&[left_separator, more_styled_text, right_separator]).to_string();
LinePart {
part: more_styled_text,
len: more_text_len,
@ -137,10 +135,8 @@ fn right_more_message(
.bold()
.paint(more_text);
let right_separator = style!(palette.orange, palette.gray).paint(separator);
let more_styled_text = format!(
"{}",
ANSIStrings(&[left_separator, more_styled_text, right_separator,])
);
let more_styled_text =
ANSIStrings(&[left_separator, more_styled_text, right_separator]).to_string();
LinePart {
part: more_styled_text,
len: more_text_len,
@ -155,7 +151,7 @@ fn tab_line_prefix(session_name: Option<&str>, palette: Palette, cols: usize) ->
.bold()
.paint(prefix_text);
let mut parts = vec![LinePart {
part: format!("{}", prefix_styled_text),
part: prefix_styled_text.to_string(),
len: prefix_text_len,
}];
if let Some(name) = session_name {
@ -164,7 +160,7 @@ fn tab_line_prefix(session_name: Option<&str>, palette: Palette, cols: usize) ->
let name_part_styled_text = style!(palette.white, palette.gray).bold().paint(name_part);
if cols.saturating_sub(prefix_text_len) >= name_part_len {
parts.push(LinePart {
part: format!("{}", name_part_styled_text),
part: name_part_styled_text.to_string(),
len: name_part_len,
})
}

View file

@ -43,7 +43,7 @@ impl ZellijPlugin for State {
Event::ModeUpdate(mode_info) => self.mode_info = mode_info,
Event::TabUpdate(tabs) => {
// tabs are indexed starting from 1 so we need to add 1
self.active_tab_idx = (&tabs).iter().position(|t| t.active).unwrap() + 1;
self.active_tab_idx = tabs.iter().position(|t| t.active).unwrap() + 1;
self.tabs = tabs;
}
Event::Mouse(me) => match me {
@ -69,7 +69,7 @@ impl ZellijPlugin for State {
}
let mut all_tabs: Vec<LinePart> = vec![];
let mut active_tab_index = 0;
for t in self.tabs.iter_mut() {
for t in &mut self.tabs {
let mut tabname = t.name.clone();
if t.active && self.mode_info.mode == InputMode::RenameTab {
if tabname.is_empty() {

View file

@ -11,10 +11,8 @@ pub fn active_tab(text: String, palette: Palette, separator: &str) -> LinePart {
.bold()
.paint(format!(" {} ", text));
let right_separator = style!(palette.green, palette.gray).paint(separator);
let tab_styled_text = format!(
"{}",
ANSIStrings(&[left_separator, tab_styled_text, right_separator,])
);
let tab_styled_text =
ANSIStrings(&[left_separator, tab_styled_text, right_separator]).to_string();
LinePart {
part: tab_styled_text,
len: tab_text_len,
@ -28,10 +26,8 @@ pub fn non_active_tab(text: String, palette: Palette, separator: &str) -> LinePa
.bold()
.paint(format!(" {} ", text));
let right_separator = style!(palette.fg, palette.gray).paint(separator);
let tab_styled_text = format!(
"{}",
ANSIStrings(&[left_separator, tab_styled_text, right_separator,])
);
let tab_styled_text =
ANSIStrings(&[left_separator, tab_styled_text, right_separator]).to_string();
LinePart {
part: tab_styled_text,
len: tab_text_len,

View file

@ -40,7 +40,7 @@ pub(crate) fn kill_all_sessions(yes: bool) {
process::exit(1);
}
}
for session in sessions.iter() {
for session in &sessions {
kill_session_impl(session);
}
process::exit(0);
@ -131,7 +131,7 @@ fn attach_with_session_name(
config_options: Options,
create: bool,
) -> ClientInfo {
match session_name.as_ref() {
match &session_name {
Some(session) if create => {
if !session_exists(session).unwrap() {
ClientInfo::New(session_name.unwrap())

View file

@ -5,6 +5,7 @@ use zellij_utils::{pane_size::Size, position::Position};
use rand::Rng;
use std::fmt::Write;
use std::path::Path;
use super::remote_runner::{RemoteRunner, RemoteTerminal, Step};
@ -231,26 +232,26 @@ pub fn scrolling_inside_a_pane() {
if remote_terminal.cursor_position_is(63, 2) && remote_terminal.tip_appears() {
// cursor is in the newly opened second pane
let mut content_to_send = String::new();
content_to_send.push_str(&format!("{:0<56}", "line1 "));
content_to_send.push_str(&format!("{:0<58}", "line2 "));
content_to_send.push_str(&format!("{:0<58}", "line3 "));
content_to_send.push_str(&format!("{:0<58}", "line4 "));
content_to_send.push_str(&format!("{:0<58}", "line5 "));
content_to_send.push_str(&format!("{:0<58}", "line6 "));
content_to_send.push_str(&format!("{:0<58}", "line7 "));
content_to_send.push_str(&format!("{:0<58}", "line8 "));
content_to_send.push_str(&format!("{:0<58}", "line9 "));
content_to_send.push_str(&format!("{:0<58}", "line10 "));
content_to_send.push_str(&format!("{:0<58}", "line11 "));
content_to_send.push_str(&format!("{:0<58}", "line12 "));
content_to_send.push_str(&format!("{:0<58}", "line13 "));
content_to_send.push_str(&format!("{:0<58}", "line14 "));
content_to_send.push_str(&format!("{:0<58}", "line15 "));
content_to_send.push_str(&format!("{:0<58}", "line16 "));
content_to_send.push_str(&format!("{:0<58}", "line17 "));
content_to_send.push_str(&format!("{:0<58}", "line18 "));
content_to_send.push_str(&format!("{:0<58}", "line19 "));
content_to_send.push_str(&format!("{:0<57}", "line20 "));
write!(&mut content_to_send, "{:0<56}", "line1 ").unwrap();
write!(&mut content_to_send, "{:0<58}", "line2 ").unwrap();
write!(&mut content_to_send, "{:0<58}", "line3 ").unwrap();
write!(&mut content_to_send, "{:0<58}", "line4 ").unwrap();
write!(&mut content_to_send, "{:0<58}", "line5 ").unwrap();
write!(&mut content_to_send, "{:0<58}", "line6 ").unwrap();
write!(&mut content_to_send, "{:0<58}", "line7 ").unwrap();
write!(&mut content_to_send, "{:0<58}", "line8 ").unwrap();
write!(&mut content_to_send, "{:0<58}", "line9 ").unwrap();
write!(&mut content_to_send, "{:0<58}", "line10 ").unwrap();
write!(&mut content_to_send, "{:0<58}", "line11 ").unwrap();
write!(&mut content_to_send, "{:0<58}", "line12 ").unwrap();
write!(&mut content_to_send, "{:0<58}", "line13 ").unwrap();
write!(&mut content_to_send, "{:0<58}", "line14 ").unwrap();
write!(&mut content_to_send, "{:0<58}", "line15 ").unwrap();
write!(&mut content_to_send, "{:0<58}", "line16 ").unwrap();
write!(&mut content_to_send, "{:0<58}", "line17 ").unwrap();
write!(&mut content_to_send, "{:0<58}", "line18 ").unwrap();
write!(&mut content_to_send, "{:0<58}", "line19 ").unwrap();
write!(&mut content_to_send, "{:0<57}", "line20 ").unwrap();
remote_terminal.send_key(content_to_send.as_bytes());

View file

@ -45,14 +45,12 @@ fn setup_remote_environment(channel: &mut ssh2::Channel, win_size: Size) {
.request_pty("xterm", None, Some((columns, rows, 0, 0)))
.unwrap();
channel.shell().unwrap();
channel.write_all("export PS1=\"$ \"\n".as_bytes()).unwrap();
channel.write_all(b"export PS1=\"$ \"\n").unwrap();
channel.flush().unwrap();
}
fn stop_zellij(channel: &mut ssh2::Channel) {
channel
.write_all("killall -KILL zellij\n".as_bytes())
.unwrap();
channel.write_all(b"killall -KILL zellij\n").unwrap();
}
fn start_zellij(channel: &mut ssh2::Channel) {

View file

@ -299,9 +299,9 @@ pub fn start_client(
os_input.send_to_server(ClientToServerMsg::ClientExited);
if let ExitReason::Error(_) = reason {
handle_error(format!("{}", reason));
handle_error(reason.to_string());
}
exit_msg = format!("{}", reason);
exit_msg = reason.to_string();
break;
}
ClientInstruction::Error(backtrace) => {

View file

@ -66,14 +66,14 @@ pub(crate) fn stdin_loop(
&& stdin_buffer
.iter()
.take(bracketed_paste_start.len())
.eq(bracketed_paste_start.iter()))
.eq(&bracketed_paste_start))
{
match bracketed_paste_end_position(&stdin_buffer) {
Some(paste_end_position) => {
let starts_with_bracketed_paste_start = stdin_buffer
.iter()
.take(bracketed_paste_start.len())
.eq(bracketed_paste_start.iter());
.eq(&bracketed_paste_start);
let ends_with_bracketed_paste_end = true;
@ -97,7 +97,7 @@ pub(crate) fn stdin_loop(
let starts_with_bracketed_paste_start = stdin_buffer
.iter()
.take(bracketed_paste_start.len())
.eq(bracketed_paste_start.iter());
.eq(&bracketed_paste_start);
if starts_with_bracketed_paste_start {
drop(stdin_buffer.drain(..6)); // bracketed paste start
}

View file

@ -451,9 +451,8 @@ pub fn start_server(mut os_input: Box<dyn ServerOsApi>, socket_path: PathBuf) {
// Here the output is of the type Option<String> sent by screen thread.
// If `Some(_)`- unwrap it and forward it to the clients to render.
// If `None`- Send an exit instruction. This is the case when a user closes the last Tab/Pane.
if let Some(op) = output.as_mut() {
for (client_id, client_render_instruction) in
op.client_render_instructions.iter_mut()
if let Some(op) = &mut output {
for (client_id, client_render_instruction) in &mut op.client_render_instructions
{
os_input.send_to_client(
*client_id,

View file

@ -147,7 +147,7 @@ mod logging_pipe_test {
fn write_without_endl_does_not_consume_buffer_after_flush() {
let mut pipe = LoggingPipe::new("TestPipe", 0);
let test_buffer = "Testing write".as_bytes();
let test_buffer = b"Testing write";
pipe.write_all(test_buffer).expect("Err write");
pipe.flush().expect("Err flush");
@ -159,7 +159,7 @@ mod logging_pipe_test {
fn write_with_single_endl_at_the_end_consumes_whole_buffer_after_flush() {
let mut pipe = LoggingPipe::new("TestPipe", 0);
let test_buffer = "Testing write \n".as_bytes();
let test_buffer = b"Testing write \n";
pipe.write_all(test_buffer).expect("Err write");
pipe.flush().expect("Err flush");
@ -171,8 +171,8 @@ mod logging_pipe_test {
fn write_with_endl_in_the_middle_consumes_buffer_up_to_endl_after_flush() {
let mut pipe = LoggingPipe::new("TestPipe", 0);
let test_buffer = "Testing write \n".as_bytes();
let test_buffer2 = "And the rest".as_bytes();
let test_buffer = b"Testing write \n";
let test_buffer2: &[_] = b"And the rest";
pipe.write_all(
[
@ -195,7 +195,7 @@ mod logging_pipe_test {
fn write_with_many_endl_consumes_whole_buffer_after_flush() {
let mut pipe = LoggingPipe::new("TestPipe", 0);
let test_buffer = "Testing write \n".as_bytes();
let test_buffer: &[_] = b"Testing write \n";
pipe.write_all(
[
@ -235,7 +235,7 @@ mod logging_pipe_test {
#[test]
fn write_with_many_endls_consumes_everything_after_flush() {
let mut pipe = LoggingPipe::new("TestPipe", 0);
let test_buffer = "Testing write \n".as_bytes();
let test_buffer: &[_] = b"Testing write \n";
pipe.write_all(
[test_buffer, test_buffer, b"\n", b"\n", b"\n"]

View file

@ -456,16 +456,14 @@ impl Grid {
self.output_buffer.update_line(line_index);
}
pub fn advance_to_next_tabstop(&mut self, styles: CharacterStyles) {
let mut next_tabstop = None;
for tabstop in self.horizontal_tabstops.iter() {
if *tabstop > self.cursor.x {
next_tabstop = Some(tabstop);
break;
}
}
let next_tabstop = self
.horizontal_tabstops
.iter()
.copied()
.find(|&tabstop| tabstop > self.cursor.x);
match next_tabstop {
Some(tabstop) => {
self.cursor.x = *tabstop;
self.cursor.x = tabstop;
}
None => {
self.cursor.x = self.width.saturating_sub(1);
@ -477,16 +475,15 @@ impl Grid {
self.output_buffer.update_line(self.cursor.y);
}
pub fn move_to_previous_tabstop(&mut self) {
let mut previous_tabstop = None;
for tabstop in self.horizontal_tabstops.iter() {
if *tabstop >= self.cursor.x {
break;
}
previous_tabstop = Some(tabstop);
}
let previous_tabstop = self
.horizontal_tabstops
.iter()
.rev()
.copied()
.find(|&tabstop| tabstop < self.cursor.x);
match previous_tabstop {
Some(tabstop) => {
self.cursor.x = *tabstop;
self.cursor.x = tabstop;
}
None => {
self.cursor.x = 0;
@ -506,7 +503,7 @@ impl Grid {
fn recalculate_scrollback_buffer_count(&self) -> usize {
let mut scrollback_buffer_count = 0;
for row in self.lines_above.iter() {
for row in &self.lines_above {
let row_width = row.width();
// rows in lines_above are unwrapped, so we need to account for that
if row_width > self.width {
@ -531,7 +528,7 @@ impl Grid {
self.saved_cursor_position = Some(self.cursor.clone());
}
fn restore_cursor_position(&mut self) {
if let Some(saved_cursor_position) = self.saved_cursor_position.as_ref() {
if let Some(saved_cursor_position) = &self.saved_cursor_position {
self.cursor = saved_cursor_position.clone();
}
}
@ -701,7 +698,7 @@ impl Grid {
// trim lines after the last empty space that has no following character, because
// terminals don't trim empty lines
for line in viewport_canonical_lines.iter_mut() {
for line in &mut viewport_canonical_lines {
let mut trim_at = None;
for (index, character) in line.columns.iter().enumerate() {
if character.character != EMPTY_TERMINAL_CHARACTER.character {
@ -1134,7 +1131,7 @@ impl Grid {
pub fn clear_all(&mut self, replace_with: TerminalCharacter) {
let replace_with_columns = VecDeque::from(vec![replace_with; self.width]);
self.replace_characters_in_line_after_cursor(replace_with);
for row in self.viewport.iter_mut() {
for row in &mut self.viewport {
row.replace_columns(replace_with_columns.clone());
}
self.output_buffer.update_all_lines();
@ -1481,7 +1478,7 @@ impl Grid {
if self.title_stack.len() > MAX_TITLE_STACK_SIZE {
self.title_stack.remove(0);
}
if let Some(title) = self.title.as_ref() {
if let Some(title) = &self.title {
self.title_stack.push(title.clone());
}
}
@ -1793,7 +1790,7 @@ impl Perform for Grid {
alternative_lines_above,
alternative_viewport,
alternative_cursor,
)) = self.alternative_lines_above_viewport_and_cursor.as_mut()
)) = &mut self.alternative_lines_above_viewport_and_cursor
{
std::mem::swap(&mut self.lines_above, alternative_lines_above);
std::mem::swap(&mut self.viewport, alternative_viewport);
@ -2159,7 +2156,7 @@ impl Row {
Row::new(width)
} else {
let mut first_row = rows.remove(0);
for row in rows.iter_mut() {
for row in &mut rows {
first_row.append(&mut row.columns);
}
first_row
@ -2175,14 +2172,14 @@ impl Row {
}
pub fn width(&self) -> usize {
let mut width = 0;
for terminal_character in self.columns.iter() {
for terminal_character in &self.columns {
width += terminal_character.width;
}
width
}
pub fn excess_width(&self) -> usize {
let mut acc = 0;
for terminal_character in self.columns.iter() {
for terminal_character in &self.columns {
if terminal_character.width > 1 {
acc += terminal_character.width - 1;
}

View file

@ -99,7 +99,7 @@ mod tests {
#[test]
fn dispatch_osc8_link_end() {
let mut link_handler = LinkHandler::default();
let params = vec!["8".as_bytes(), &[], &[]];
let params: Vec<&[_]> = vec![b"8", b"", b""];
let anchor = link_handler.dispatch_osc8(&params);

View file

@ -1,3 +1,4 @@
use std::fmt::Write;
use std::sync::mpsc::channel;
use std::time::Instant;
use std::unimplemented;
@ -165,12 +166,14 @@ impl Pane for PluginPane {
.concat()
};
vte_output.push_str(&format!(
write!(
&mut vte_output,
"\u{1b}[{};{}H\u{1b}[m{}",
self.get_content_y() + 1 + index,
self.get_content_x() + 1,
line_to_print,
)); // goto row/col and reset styles
)
.unwrap(); // goto row/col and reset styles
let line_len = line_to_print.len();
if line_len < self.get_content_columns() {
// pad line
@ -185,11 +188,13 @@ impl Pane for PluginPane {
for line_index in total_line_count..self.get_content_rows() {
let x = self.get_content_x();
let y = self.get_content_y();
vte_output.push_str(&format!(
write!(
&mut vte_output,
"\u{1b}[{};{}H\u{1b}[m",
y + line_index + 1,
x + 1
)); // goto row/col and reset styles
)
.unwrap(); // goto row/col and reset styles
for _col_index in 0..self.get_content_columns() {
vte_output.push(' ');
}

View file

@ -68,44 +68,48 @@ pub enum NamedColor {
impl NamedColor {
fn to_foreground_ansi_code(self) -> String {
match self {
NamedColor::Black => format!("{}", 30),
NamedColor::Red => format!("{}", 31),
NamedColor::Green => format!("{}", 32),
NamedColor::Yellow => format!("{}", 33),
NamedColor::Blue => format!("{}", 34),
NamedColor::Magenta => format!("{}", 35),
NamedColor::Cyan => format!("{}", 36),
NamedColor::White => format!("{}", 37),
NamedColor::BrightBlack => format!("{}", 90),
NamedColor::BrightRed => format!("{}", 91),
NamedColor::BrightGreen => format!("{}", 92),
NamedColor::BrightYellow => format!("{}", 93),
NamedColor::BrightBlue => format!("{}", 94),
NamedColor::BrightMagenta => format!("{}", 95),
NamedColor::BrightCyan => format!("{}", 96),
NamedColor::BrightWhite => format!("{}", 97),
}
let v = match self {
NamedColor::Black => 30,
NamedColor::Red => 31,
NamedColor::Green => 32,
NamedColor::Yellow => 33,
NamedColor::Blue => 34,
NamedColor::Magenta => 35,
NamedColor::Cyan => 36,
NamedColor::White => 37,
NamedColor::BrightBlack => 90,
NamedColor::BrightRed => 91,
NamedColor::BrightGreen => 92,
NamedColor::BrightYellow => 93,
NamedColor::BrightBlue => 94,
NamedColor::BrightMagenta => 95,
NamedColor::BrightCyan => 96,
NamedColor::BrightWhite => 97,
};
v.to_string()
}
fn to_background_ansi_code(self) -> String {
match self {
NamedColor::Black => format!("{}", 40),
NamedColor::Red => format!("{}", 41),
NamedColor::Green => format!("{}", 42),
NamedColor::Yellow => format!("{}", 43),
NamedColor::Blue => format!("{}", 44),
NamedColor::Magenta => format!("{}", 45),
NamedColor::Cyan => format!("{}", 46),
NamedColor::White => format!("{}", 47),
NamedColor::BrightBlack => format!("{}", 100),
NamedColor::BrightRed => format!("{}", 101),
NamedColor::BrightGreen => format!("{}", 102),
NamedColor::BrightYellow => format!("{}", 103),
NamedColor::BrightBlue => format!("{}", 104),
NamedColor::BrightMagenta => format!("{}", 105),
NamedColor::BrightCyan => format!("{}", 106),
NamedColor::BrightWhite => format!("{}", 107),
}
let v = match self {
NamedColor::Black => 40,
NamedColor::Red => 41,
NamedColor::Green => 42,
NamedColor::Yellow => 43,
NamedColor::Blue => 44,
NamedColor::Magenta => 45,
NamedColor::Cyan => 46,
NamedColor::White => 47,
NamedColor::BrightBlack => 100,
NamedColor::BrightRed => 101,
NamedColor::BrightGreen => 102,
NamedColor::BrightYellow => 103,
NamedColor::BrightBlue => 104,
NamedColor::BrightMagenta => 105,
NamedColor::BrightCyan => 106,
NamedColor::BrightWhite => 107,
};
v.to_string()
}
}

View file

@ -9,7 +9,7 @@ use crate::pty::VteBytes;
use crate::tab::Pane;
use crate::ClientId;
use std::collections::{HashMap, HashSet};
use std::fmt::Debug;
use std::fmt::{Debug, Write};
use std::os::unix::io::RawFd;
use std::time::{self, Instant};
use zellij_utils::pane_size::Offset;
@ -93,8 +93,8 @@ impl Pane for TerminalPane {
self.reflow_lines();
}
fn handle_pty_bytes(&mut self, bytes: VteBytes) {
for byte in bytes.iter() {
self.vte_parser.advance(&mut self.grid, *byte);
for &byte in &bytes {
self.vte_parser.advance(&mut self.grid, byte);
}
self.set_should_render(true);
}
@ -191,11 +191,13 @@ impl Pane for TerminalPane {
let content_y = self.get_content_y();
if self.grid.clear_viewport_before_rendering {
for line_index in 0..self.grid.height {
vte_output.push_str(&format!(
write!(
&mut vte_output,
"\u{1b}[{};{}H\u{1b}[m",
content_y + line_index + 1,
content_x + 1
)); // goto row/col and reset styles
)
.unwrap(); // goto row/col and reset styles
for _col_index in 0..self.grid.width {
vte_output.push(EMPTY_TERMINAL_CHARACTER.character);
}
@ -212,8 +214,14 @@ impl Pane for TerminalPane {
self.grid.update_line_for_rendering(y);
let x = content_x + x;
let y = content_y + y;
vte_output.push_str(&format!("\u{1b}[{};{}H\u{1b}[m", y + 1, x + 1));
vte_output.push(EMPTY_TERMINAL_CHARACTER.character);
write!(
&mut vte_output,
"\u{1b}[{};{}H\u{1b}[m{}",
y + 1,
x + 1,
EMPTY_TERMINAL_CHARACTER.character
)
.unwrap();
}
let max_width = self.get_content_columns();
for character_chunk in self.grid.read_changes() {
@ -222,11 +230,13 @@ impl Pane for TerminalPane {
let chunk_absolute_x = pane_x + character_chunk.x;
let chunk_absolute_y = pane_y + character_chunk.y;
let terminal_characters = character_chunk.terminal_characters;
vte_output.push_str(&format!(
write!(
&mut vte_output,
"\u{1b}[{};{}H\u{1b}[m",
chunk_absolute_y + 1,
chunk_absolute_x + 1
)); // goto row/col and reset styles
)
.unwrap(); // goto row/col and reset styles
let mut chunk_width = character_chunk.x;
for mut t_character in terminal_characters {
@ -248,9 +258,13 @@ impl Pane for TerminalPane {
if let Some(new_styles) = character_styles
.update_and_return_diff(&t_character.styles, self.grid.changed_colors)
{
vte_output.push_str(&new_styles.to_string());
vte_output
.push_str(&self.grid.link_handler.output_osc8(new_styles.link_anchor))
write!(
&mut vte_output,
"{}{}",
new_styles,
self.grid.link_handler.output_osc8(new_styles.link_anchor)
)
.unwrap();
}
vte_output.push(t_character.character);

View file

@ -4,6 +4,8 @@ use ::insta::assert_snapshot;
use zellij_utils::pane_size::PaneGeom;
use zellij_utils::zellij_tile::data::Palette;
use std::fmt::Write;
#[test]
pub fn scrolling_inside_a_pane() {
let mut fake_win_size = PaneGeom::default();
@ -15,9 +17,9 @@ pub fn scrolling_inside_a_pane() {
let mut terminal_pane = TerminalPane::new(pid, fake_win_size, palette, 0); // 0 is the pane index
let mut text_to_fill_pane = String::new();
for i in 0..30 {
text_to_fill_pane.push_str(&format!("\rline {}\n", i + 1));
writeln!(&mut text_to_fill_pane, "\rline {}", i + 1).unwrap();
}
terminal_pane.handle_pty_bytes(text_to_fill_pane.as_bytes().to_vec());
terminal_pane.handle_pty_bytes(text_to_fill_pane.into_bytes());
terminal_pane.scroll_up(10);
assert_snapshot!(format!("{:?}", terminal_pane.grid));
terminal_pane.scroll_down(3);

View file

@ -284,13 +284,12 @@ impl Pty {
PaneId::Plugin(..) => None,
PaneId::Terminal(id) => self.id_to_child_pid.get(id),
})
.and_then(|id| {
.and_then(|&id| {
self.bus
.os_input
.as_ref()
.map(|input| input.get_cwd(Pid::from_raw(*id)))
})
.flatten();
.and_then(|input| input.get_cwd(Pid::from_raw(id)))
});
};
};
}

View file

@ -55,7 +55,7 @@ fn route_action(
.senders
.send_to_screen(ScreenInstruction::ClearScroll(client_id))
.unwrap();
let val = Vec::from(val.as_bytes());
let val = val.into_bytes();
session
.senders
.send_to_screen(ScreenInstruction::WriteCharacter(val, client_id))

View file

@ -268,7 +268,7 @@ impl Screen {
// currently all clients are just mirrors, so we perform the action for every entry in
// tab_history
// TODO: receive a client_id and only do it for the client
for (client_id, tab_history) in self.tab_history.iter_mut() {
for (client_id, tab_history) in &mut self.tab_history {
let old_active_index = self.active_tab_indices.remove(client_id).unwrap();
self.active_tab_indices.insert(*client_id, new_tab_index);
tab_history.retain(|&e| e != new_tab_pos);
@ -348,7 +348,7 @@ impl Screen {
pub fn resize_to_screen(&mut self, new_screen_size: Size) {
self.size = new_screen_size;
for (_, tab) in self.tabs.iter_mut() {
for tab in self.tabs.values_mut() {
tab.resize_whole_tab(new_screen_size);
tab.set_force_render();
}
@ -361,7 +361,7 @@ impl Screen {
let mut tabs_to_close = vec![];
let size = self.size;
let overlay = self.overlay.clone();
for (tab_index, tab) in self.tabs.iter_mut() {
for (tab_index, tab) in &mut self.tabs {
if tab.has_active_panes() {
let vte_overlay = overlay.generate_overlay(size);
tab.render(&mut output, Some(vte_overlay));
@ -442,7 +442,7 @@ impl Screen {
let connected_clients = active_tab.drain_connected_clients();
tab.add_multiple_clients(&connected_clients);
}
for (client_id, tab_history) in self.tab_history.iter_mut() {
for (client_id, tab_history) in &mut self.tab_history {
let old_active_index = self.active_tab_indices.remove(client_id).unwrap();
self.active_tab_indices.insert(*client_id, tab_index);
tab_history.retain(|&e| e != tab_index);
@ -941,8 +941,8 @@ pub(crate) fn screen_thread_main(
screen.get_active_tab_mut(client_id).unwrap().close_pane(id);
}
None => {
for (_index, tab) in screen.tabs.iter_mut() {
if tab.get_pane_ids().iter().any(|pid| *pid == id) {
for tab in screen.tabs.values_mut() {
if tab.get_pane_ids().contains(&id) {
tab.close_pane(id);
break;
}
@ -962,7 +962,7 @@ pub(crate) fn screen_thread_main(
}
ScreenInstruction::TogglePaneFrames => {
screen.draw_pane_frames = !screen.draw_pane_frames;
for (_, tab) in screen.tabs.iter_mut() {
for tab in screen.tabs.values_mut() {
tab.set_pane_frames(screen.draw_pane_frames);
}
screen.render();

View file

@ -360,7 +360,7 @@ impl Tab {
let positions_in_layout = layout.position_panes_in_space(&free_space);
let mut positions_and_size = positions_in_layout.iter();
for (pane_kind, terminal_pane) in self.panes.iter_mut() {
for (pane_kind, terminal_pane) in &mut self.panes {
// for now the layout only supports terminal panes
if let PaneId::Terminal(pid) = pane_kind {
match positions_and_size.next() {
@ -774,7 +774,7 @@ impl Tab {
if self.fullscreen_is_active {
let first_client_id = self.connected_clients.iter().next().unwrap(); // this is a temporary hack until we fix the ui for multiple clients
let active_pane_id = self.active_panes.get(first_client_id).unwrap();
for terminal_id in self.panes_to_hide.iter() {
for terminal_id in &self.panes_to_hide {
let pane = self.panes.get_mut(terminal_id).unwrap();
pane.set_should_render(true);
pane.set_should_render_boundaries(true);
@ -908,11 +908,11 @@ impl Tab {
fn update_active_panes_in_pty_thread(&self) {
// this is a bit hacky and we should ideally not keep this state in two different places at
// some point
for connected_client in self.connected_clients.iter() {
for &connected_client in &self.connected_clients {
self.senders
.send_to_pty(PtyInstruction::UpdateActivePane(
self.active_panes.get(connected_client).copied(),
*connected_client,
self.active_panes.get(&connected_client).copied(),
connected_client,
))
.unwrap();
}
@ -936,28 +936,27 @@ impl Tab {
self.mode_info.mode,
);
pane_contents_and_ui.render_pane_contents_for_all_clients();
for client_id in self.connected_clients.iter() {
for &client_id in &self.connected_clients {
if self.draw_pane_frames {
pane_contents_and_ui
.render_pane_frame(*client_id, self.session_is_mirrored);
pane_contents_and_ui.render_pane_frame(client_id, self.session_is_mirrored);
} else {
let boundaries = client_id_to_boundaries
.entry(*client_id)
.entry(client_id)
.or_insert_with(|| Boundaries::new(self.viewport));
pane_contents_and_ui.render_pane_boundaries(
*client_id,
client_id,
boundaries,
self.session_is_mirrored,
);
}
// this is done for panes that don't have their own cursor (eg. panes of
// another user)
pane_contents_and_ui.render_fake_cursor_if_needed(*client_id);
pane_contents_and_ui.render_fake_cursor_if_needed(client_id);
}
}
}
// render boundaries if needed
for (client_id, boundaries) in client_id_to_boundaries.iter_mut() {
for (client_id, boundaries) in &mut client_id_to_boundaries {
output.push_to_client(*client_id, &boundaries.vte_output());
}
// FIXME: Once clients can be distinguished
@ -976,24 +975,24 @@ impl Tab {
}
}
fn render_cursor(&self, output: &mut Output) {
for client_id in self.connected_clients.iter() {
match self.get_active_terminal_cursor_position(*client_id) {
for &client_id in &self.connected_clients {
match self.get_active_terminal_cursor_position(client_id) {
Some((cursor_position_x, cursor_position_y)) => {
let show_cursor = "\u{1b}[?25h";
let change_cursor_shape =
self.get_active_pane(*client_id).unwrap().cursor_shape_csi();
self.get_active_pane(client_id).unwrap().cursor_shape_csi();
let goto_cursor_position = &format!(
"\u{1b}[{};{}H\u{1b}[m{}",
cursor_position_y + 1,
cursor_position_x + 1,
change_cursor_shape
); // goto row/col
output.push_to_client(*client_id, show_cursor);
output.push_to_client(*client_id, goto_cursor_position);
output.push_to_client(client_id, show_cursor);
output.push_to_client(client_id, goto_cursor_position);
}
None => {
let hide_cursor = "\u{1b}[?25l";
output.push_to_client(*client_id, hide_cursor);
output.push_to_client(client_id, hide_cursor);
}
}
}
@ -1509,10 +1508,7 @@ impl Tab {
// FIXME: This checks that we aren't violating the resize constraints of the aligned panes
// above and below this one. This should be moved to a `can_resize` function eventually.
for terminal_id in terminals_to_the_left
.iter()
.chain(terminals_to_the_right.iter())
{
for terminal_id in terminals_to_the_left.iter().chain(&terminals_to_the_right) {
let pane = self.panes.get(terminal_id).unwrap();
if pane.current_geom().rows.as_percent().unwrap() - percent < RESIZE_PERCENT {
return;
@ -1523,10 +1519,7 @@ impl Tab {
for terminal_id in terminals_below {
self.increase_pane_height(&terminal_id, percent);
}
for terminal_id in terminals_to_the_left
.iter()
.chain(terminals_to_the_right.iter())
{
for terminal_id in terminals_to_the_left.iter().chain(&terminals_to_the_right) {
self.reduce_pane_height(terminal_id, percent);
}
}
@ -1548,10 +1541,7 @@ impl Tab {
// FIXME: This checks that we aren't violating the resize constraints of the aligned panes
// above and below this one. This should be moved to a `can_resize` function eventually.
for terminal_id in terminals_to_the_left
.iter()
.chain(terminals_to_the_right.iter())
{
for terminal_id in terminals_to_the_left.iter().chain(&terminals_to_the_right) {
let pane = self.panes.get(terminal_id).unwrap();
if pane.current_geom().rows.as_percent().unwrap() - percent < RESIZE_PERCENT {
return;
@ -1562,10 +1552,7 @@ impl Tab {
for terminal_id in terminals_above {
self.increase_pane_height(&terminal_id, percent);
}
for terminal_id in terminals_to_the_left
.iter()
.chain(terminals_to_the_right.iter())
{
for terminal_id in terminals_to_the_left.iter().chain(&terminals_to_the_right) {
self.reduce_pane_height(terminal_id, percent);
}
}
@ -1587,7 +1574,7 @@ impl Tab {
// FIXME: This checks that we aren't violating the resize constraints of the aligned panes
// above and below this one. This should be moved to a `can_resize` function eventually.
for terminal_id in terminals_above.iter().chain(terminals_below.iter()) {
for terminal_id in terminals_above.iter().chain(&terminals_below) {
let pane = self.panes.get(terminal_id).unwrap();
if pane.current_geom().cols.as_percent().unwrap() - percent < RESIZE_PERCENT {
return;
@ -1598,7 +1585,7 @@ impl Tab {
for terminal_id in terminals_to_the_left {
self.increase_pane_width(&terminal_id, percent);
}
for terminal_id in terminals_above.iter().chain(terminals_below.iter()) {
for terminal_id in terminals_above.iter().chain(&terminals_below) {
self.reduce_pane_width(terminal_id, percent);
}
}
@ -1620,7 +1607,7 @@ impl Tab {
// FIXME: This checks that we aren't violating the resize constraints of the aligned panes
// above and below this one. This should be moved to a `can_resize` function eventually.
for terminal_id in terminals_above.iter().chain(terminals_below.iter()) {
for terminal_id in terminals_above.iter().chain(&terminals_below) {
let pane = self.panes.get(terminal_id).unwrap();
if pane.current_geom().cols.as_percent().unwrap() - percent < RESIZE_PERCENT {
return;
@ -1631,7 +1618,7 @@ impl Tab {
for terminal_id in terminals_to_the_right {
self.increase_pane_width(&terminal_id, percent);
}
for terminal_id in terminals_above.iter().chain(terminals_below.iter()) {
for terminal_id in terminals_above.iter().chain(&terminals_below) {
self.reduce_pane_width(terminal_id, percent);
}
}
@ -1654,10 +1641,7 @@ impl Tab {
for terminal_id in terminals_above {
self.reduce_pane_height(&terminal_id, percent);
}
for terminal_id in terminals_to_the_left
.iter()
.chain(terminals_to_the_right.iter())
{
for terminal_id in terminals_to_the_left.iter().chain(&terminals_to_the_right) {
self.increase_pane_height(terminal_id, percent);
}
}
@ -1680,10 +1664,7 @@ impl Tab {
for terminal_id in terminals_below {
self.reduce_pane_height(&terminal_id, percent);
}
for terminal_id in terminals_to_the_left
.iter()
.chain(terminals_to_the_right.iter())
{
for terminal_id in terminals_to_the_left.iter().chain(&terminals_to_the_right) {
self.increase_pane_height(terminal_id, percent);
}
}
@ -1708,7 +1689,7 @@ impl Tab {
for terminal_id in terminals_to_the_right {
self.reduce_pane_width(&terminal_id, percent);
}
for terminal_id in terminals_above.iter().chain(terminals_below.iter()) {
for terminal_id in terminals_above.iter().chain(&terminals_below) {
self.increase_pane_width(terminal_id, percent);
}
}
@ -1731,7 +1712,7 @@ impl Tab {
for terminal_id in terminals_to_the_left {
self.reduce_pane_width(&terminal_id, percent);
}
for terminal_id in terminals_above.iter().chain(terminals_below.iter()) {
for terminal_id in terminals_above.iter().chain(&terminals_below) {
self.increase_pane_width(terminal_id, percent);
}
}
@ -2180,7 +2161,7 @@ impl Tab {
})
}
pub fn relayout_tab(&mut self, direction: Direction) {
let mut resizer = PaneResizer::new(self.panes.iter_mut());
let mut resizer = PaneResizer::new(&mut self.panes);
let result = match direction {
Direction::Horizontal => resizer.layout(direction, self.display_area.cols),
Direction::Vertical => resizer.layout(direction, self.display_area.rows),
@ -3119,12 +3100,12 @@ impl Tab {
fn grow_panes(&mut self, panes: &[PaneId], direction: Direction, (width, height): (f64, f64)) {
match direction {
Direction::Horizontal => {
for pane_id in panes.iter() {
for pane_id in panes {
self.increase_pane_width(pane_id, width);
}
}
Direction::Vertical => {
for pane_id in panes.iter() {
for pane_id in panes {
self.increase_pane_height(pane_id, height);
}
}

View file

@ -3,6 +3,7 @@ use zellij_utils::{pane_size::Viewport, zellij_tile};
use crate::tab::Pane;
use ansi_term::Colour::{Fixed, RGB};
use std::collections::HashMap;
use std::fmt::Write;
use zellij_tile::data::PaletteColor;
use zellij_utils::shared::colors;
@ -513,12 +514,14 @@ impl Boundaries {
pub fn vte_output(&self) -> String {
let mut vte_output = String::new();
for (coordinates, boundary_character) in &self.boundary_characters {
vte_output.push_str(&format!(
write!(
&mut vte_output,
"\u{1b}[{};{}H\u{1b}[m{}",
coordinates.y + 1,
coordinates.x + 1,
boundary_character
)); // goto row/col + boundary character
)
.unwrap(); // goto row/col + boundary character
}
vte_output
}

View file

@ -3,6 +3,8 @@ use zellij_utils::pane_size::Size;
use super::{Overlay, OverlayType, Overlayable};
use crate::{ClientId, ServerInstruction};
use std::fmt::Write;
#[derive(Clone, Debug)]
pub struct Prompt {
pub message: String,
@ -37,7 +39,14 @@ impl Overlayable for Prompt {
let mut vte_output = self.message.clone();
Overlay::pad_cols(&mut vte_output, size.cols);
for (x, h) in vte_output.chars().enumerate() {
output.push_str(&format!("\u{1b}[{};{}H\u{1b}[48;5;238m{}", rows, x + 1, h,));
write!(
&mut output,
"\u{1b}[{};{}H\u{1b}[48;5;238m{}",
rows,
x + 1,
h,
)
.unwrap();
}
output
}

View file

@ -7,29 +7,25 @@ use zellij_utils::zellij_tile::prelude::{Palette, PaletteColor};
use unicode_width::{UnicodeWidthChar, UnicodeWidthStr};
use std::fmt::Write;
fn color_string(character: &str, color: Option<PaletteColor>) -> String {
match color {
Some(color) => match color {
PaletteColor::Rgb((r, g, b)) => {
format!("{}", RGB(r, g, b).bold().paint(character))
}
PaletteColor::EightBit(color) => {
format!("{}", Fixed(color).bold().paint(character))
}
},
None => format!("{}", Style::new().bold().paint(character)),
Some(PaletteColor::Rgb((r, g, b))) => RGB(r, g, b).bold().paint(character).to_string(),
Some(PaletteColor::EightBit(color)) => Fixed(color).bold().paint(character).to_string(),
None => Style::new().bold().paint(character).to_string(),
}
}
fn background_color(character: &str, color: Option<PaletteColor>) -> String {
match color {
Some(PaletteColor::Rgb((r, g, b))) => {
format!("{}", Style::new().on(RGB(r, g, b)).paint(character))
Style::new().on(RGB(r, g, b)).paint(character).to_string()
}
Some(PaletteColor::EightBit(color)) => {
format!("{}", Style::new().on(Fixed(color)).paint(character))
Style::new().on(Fixed(color)).paint(character).to_string()
}
None => String::from(character),
None => character.to_string(),
}
}
@ -475,7 +471,7 @@ impl PaneFrame {
let mut left_side = self.render_title_left_side(length_of_each_side);
let mut right_side = self.render_title_right_side(length_of_each_side);
match (left_side.as_mut(), right_side.as_mut()) {
match (&mut left_side, &mut right_side) {
(Some((left_side, left_side_len)), Some((right_side, right_side_len))) => self
.three_part_title_line(
left_side,
@ -511,23 +507,26 @@ impl PaneFrame {
fn render_title(&self, vte_output: &mut String) {
let total_title_length = self.geom.cols.saturating_sub(2); // 2 for the left and right corners
if let Some((middle, middle_length)) = self.render_title_middle(total_title_length).as_mut()
{
if let Some((middle, middle_length)) = &self.render_title_middle(total_title_length) {
let title_text = self.title_line_with_middle(middle, middle_length);
vte_output.push_str(&format!(
write!(
vte_output,
"\u{1b}[{};{}H\u{1b}[m{}",
self.geom.y + 1, // +1 because goto is 1 indexed
self.geom.x + 1, // +1 because goto is 1 indexed
color_string(&title_text, self.color),
)); // goto row/col + boundary character
)
.unwrap(); // goto row/col + boundary character
} else {
let title_text = self.title_line_without_middle();
vte_output.push_str(&format!(
write!(
vte_output,
"\u{1b}[{};{}H\u{1b}[m{}",
self.geom.y + 1, // +1 because goto is 1 indexed
self.geom.x + 1, // +1 because goto is 1 indexed
color_string(&title_text, self.color),
)); // goto row/col + boundary character
)
.unwrap(); // goto row/col + boundary character
}
}
pub fn render(&self) -> String {
@ -539,44 +538,43 @@ impl PaneFrame {
} else if row == self.geom.y + self.geom.rows - 1 {
// bottom row
for col in self.geom.x..(self.geom.x + self.geom.cols) {
if col == self.geom.x {
let boundary = if col == self.geom.x {
// bottom left corner
vte_output.push_str(&format!(
"\u{1b}[{};{}H\u{1b}[m{}",
row + 1, // +1 because goto is 1 indexed
col + 1,
color_string(boundary_type::BOTTOM_LEFT, self.color),
)); // goto row/col + boundary character
boundary_type::BOTTOM_LEFT
} else if col == self.geom.x + self.geom.cols - 1 {
// bottom right corner
vte_output.push_str(&format!(
"\u{1b}[{};{}H\u{1b}[m{}",
row + 1, // +1 because goto is 1 indexed
col + 1,
color_string(boundary_type::BOTTOM_RIGHT, self.color),
)); // goto row/col + boundary character
boundary_type::BOTTOM_RIGHT
} else {
vte_output.push_str(&format!(
"\u{1b}[{};{}H\u{1b}[m{}",
row + 1, // +1 because goto is 1 indexed
col + 1,
color_string(boundary_type::HORIZONTAL, self.color),
)); // goto row/col + boundary character
}
boundary_type::HORIZONTAL
};
let boundary_rendered = color_string(boundary, self.color);
write!(
&mut vte_output,
"\u{1b}[{};{}H\u{1b}[m{}",
row + 1,
col + 1,
boundary_rendered
)
.unwrap();
}
} else {
vte_output.push_str(&format!(
write!(
&mut vte_output,
"\u{1b}[{};{}H\u{1b}[m{}",
row + 1, // +1 because goto is 1 indexed
self.geom.x + 1,
color_string(boundary_type::VERTICAL, self.color),
)); // goto row/col + boundary character
vte_output.push_str(&format!(
)
.unwrap(); // goto row/col + boundary character
write!(
&mut vte_output,
"\u{1b}[{};{}H\u{1b}[m{}",
row + 1, // +1 because goto is 1 indexed
self.geom.x + self.geom.cols,
color_string(boundary_type::VERTICAL, self.color),
)); // goto row/col + boundary character
)
.unwrap(); // goto row/col + boundary character
}
}
vte_output

View file

@ -55,14 +55,14 @@ impl<'a> PaneContentsAndUi<'a> {
let pane_focused_for_different_client = self
.focused_clients
.iter()
.filter(|c_id| **c_id != client_id)
.filter(|&&c_id| c_id != client_id)
.count()
> 0;
if pane_focused_for_different_client && !pane_focused_for_client_id {
let fake_cursor_client_id = self
.focused_clients
.iter()
.find(|c_id| **c_id != client_id)
.find(|&&c_id| c_id != client_id)
.unwrap();
if let Some(colors) = client_id_to_colors(*fake_cursor_client_id, self.colors) {
if let Some(vte_output) = self.pane.render_fake_cursor(colors.0, colors.1) {
@ -84,7 +84,7 @@ impl<'a> PaneContentsAndUi<'a> {
let other_focused_clients: Vec<ClientId> = self
.focused_clients
.iter()
.filter(|c_id| **c_id != client_id)
.filter(|&&c_id| c_id != client_id)
.copied()
.collect();
let pane_focused_for_differet_client = !other_focused_clients.is_empty();

View file

@ -30,8 +30,8 @@ struct Span {
type Grid = Vec<Vec<Span>>;
impl<'a> PaneResizer<'a> {
pub fn new(panes: impl Iterator<Item = (&'a PaneId, &'a mut Box<dyn Pane>)>) -> Self {
let panes: HashMap<_, _> = panes.collect();
pub fn new(panes: impl IntoIterator<Item = (&'a PaneId, &'a mut Box<dyn Pane>)>) -> Self {
let panes: HashMap<_, _> = panes.into_iter().collect();
let mut vars = HashMap::new();
for &&k in panes.keys() {
vars.insert(k, Variable::new());
@ -84,7 +84,7 @@ impl<'a> PaneResizer<'a> {
// Round f64 pane sizes to usize without gaps or overlap
let mut finalised = Vec::new();
for spans in grid.iter_mut() {
for spans in &mut grid {
let rounded_size: isize = spans.iter().map(|s| rounded_sizes[&s.size_var]).sum();
let mut error = space as isize - rounded_size;
let mut flex_spans: Vec<_> = spans
@ -105,9 +105,9 @@ impl<'a> PaneResizer<'a> {
}
// Update span positions based on their rounded sizes
for spans in grid.iter_mut() {
for spans in &mut grid {
let mut offset = 0;
for span in spans.iter_mut() {
for span in spans {
span.pos = offset;
let sz = rounded_sizes[&span.size_var];
if sz < 1 {

View file

@ -307,7 +307,7 @@ pub fn toggle_to_previous_tab_create_tabs_only() {
assert_eq!(
screen.tab_history.get(&1).unwrap(),
&vec![0, 1],
&[0, 1],
"Tab history is invalid"
);
@ -319,7 +319,7 @@ pub fn toggle_to_previous_tab_create_tabs_only() {
);
assert_eq!(
screen.tab_history.get(&1).unwrap(),
&vec![0, 2],
&[0, 2],
"Tab history is invalid"
);
@ -331,7 +331,7 @@ pub fn toggle_to_previous_tab_create_tabs_only() {
);
assert_eq!(
screen.tab_history.get(&1).unwrap(),
&vec![0, 1],
&[0, 1],
"Tab history is invalid"
);
@ -358,7 +358,7 @@ pub fn toggle_to_previous_tab_delete() {
assert_eq!(
screen.tab_history.get(&1).unwrap(),
&vec![0, 1, 2],
&[0, 1, 2],
"Tab history is invalid"
);
assert_eq!(
@ -370,7 +370,7 @@ pub fn toggle_to_previous_tab_delete() {
screen.toggle_tab(1);
assert_eq!(
screen.tab_history.get(&1).unwrap(),
&vec![0, 1, 3],
&[0, 1, 3],
"Tab history is invalid"
);
assert_eq!(
@ -382,7 +382,7 @@ pub fn toggle_to_previous_tab_delete() {
screen.toggle_tab(1);
assert_eq!(
screen.tab_history.get(&1).unwrap(),
&vec![0, 1, 2],
&[0, 1, 2],
"Tab history is invalid"
);
assert_eq!(
@ -394,7 +394,7 @@ pub fn toggle_to_previous_tab_delete() {
screen.switch_tab_prev(1);
assert_eq!(
screen.tab_history.get(&1).unwrap(),
&vec![0, 1, 3],
&[0, 1, 3],
"Tab history is invalid"
);
assert_eq!(
@ -405,7 +405,7 @@ pub fn toggle_to_previous_tab_delete() {
screen.switch_tab_prev(1);
assert_eq!(
screen.tab_history.get(&1).unwrap(),
&vec![0, 3, 2],
&[0, 3, 2],
"Tab history is invalid"
);
assert_eq!(
@ -417,7 +417,7 @@ pub fn toggle_to_previous_tab_delete() {
screen.close_tab(1);
assert_eq!(
screen.tab_history.get(&1).unwrap(),
&vec![0, 3],
&[0, 3],
"Tab history is invalid"
);
assert_eq!(
@ -434,7 +434,7 @@ pub fn toggle_to_previous_tab_delete() {
);
assert_eq!(
screen.tab_history.get(&1).unwrap(),
&vec![0, 2],
&[0, 2],
"Tab history is invalid"
);
}

View file

@ -83,7 +83,7 @@ pub(crate) fn wasm_thread_main(
let mut plugin_map = HashMap::new();
let plugin_dir = data_dir.join("plugins/");
let plugin_global_data_dir = plugin_dir.join("data");
fs::create_dir_all(plugin_global_data_dir.as_path()).unwrap();
fs::create_dir_all(&plugin_global_data_dir).unwrap();
for plugin in plugins.iter() {
if let PluginType::Headless = plugin.run {
@ -160,7 +160,7 @@ pub(crate) fn wasm_thread_main(
}
}
info!("wasm main thread exits");
fs::remove_dir_all(plugin_global_data_dir.as_path()).unwrap();
fs::remove_dir_all(&plugin_global_data_dir).unwrap();
}
fn start_plugin(
@ -210,7 +210,7 @@ fn start_plugin(
.env("CLICOLOR_FORCE", "1")
.map_dir("/host", ".")
.unwrap()
.map_dir("/data", plugin_own_data_dir.as_path())
.map_dir("/data", &plugin_own_data_dir)
.unwrap()
.stdin(Box::new(input))
.stdout(Box::new(output))

View file

@ -47,8 +47,7 @@ lazy_static! {
sock_dir.push(envs::get_session_name().unwrap());
sock_dir
};
pub static ref ZELLIJ_TMP_DIR: PathBuf =
PathBuf::from("/tmp/zellij-".to_string() + &format!("{}", *UID));
pub static ref ZELLIJ_TMP_DIR: PathBuf = PathBuf::from(format!("/tmp/zellij-{}", *UID));
pub static ref ZELLIJ_TMP_LOG_DIR: PathBuf = ZELLIJ_TMP_DIR.join("zellij-log");
pub static ref ZELLIJ_TMP_LOG_FILE: PathBuf = ZELLIJ_TMP_LOG_DIR.join("zellij.log");
}

View file

@ -121,8 +121,8 @@ impl ErrorContext {
/// Adds a call to this [`ErrorContext`]'s call stack representation.
pub fn add_call(&mut self, call: ContextType) {
for ctx in self.calls.iter_mut() {
if *ctx == ContextType::Empty {
for ctx in &mut self.calls {
if let ContextType::Empty = ctx {
*ctx = call;
break;
}

View file

@ -149,7 +149,7 @@ impl Config {
// once serde-yaml supports zero-copy
pub fn from_default_assets() -> ConfigResult {
let cfg = String::from_utf8(setup::DEFAULT_CONFIG.to_vec())?;
Self::from_yaml(cfg.as_str())
Self::from_yaml(&cfg)
}
/// Merges two Config structs into one Config struct

View file

@ -109,7 +109,7 @@ impl Keybinds {
for mode in InputMode::iter() {
if let Some(keybinds) = keybinds_from_yaml.get(&mode) {
for keybind in keybinds.iter() {
for keybind in keybinds {
match keybind {
KeyActionUnbind::Unbind(unbind) => {
unbind_config.insert(mode, unbind.unbind.clone());
@ -242,8 +242,8 @@ impl From<KeybindsFromYaml> for Keybinds {
for mode in InputMode::iter() {
let mut mode_keybinds = ModeKeybinds::new();
for key_action in keybinds_from_yaml.keybinds.get(&mode).iter() {
for keybind in key_action.iter() {
if let Some(key_action) = keybinds_from_yaml.keybinds.get(&mode) {
for keybind in key_action {
mode_keybinds = mode_keybinds.merge(ModeKeybinds::from(keybind.clone()));
}
}

View file

@ -254,8 +254,8 @@ impl LayoutFromYamlIntermediate {
) -> LayoutFromYamlIntermediateResult {
match layout_dir {
Some(dir) => Self::from_path(&dir.join(layout))
.or_else(|_| LayoutFromYamlIntermediate::from_default_assets(layout.as_path())),
None => LayoutFromYamlIntermediate::from_default_assets(layout.as_path()),
.or_else(|_| LayoutFromYamlIntermediate::from_default_assets(layout)),
None => LayoutFromYamlIntermediate::from_default_assets(layout),
}
}
// Currently still needed but on nightly
@ -277,19 +277,19 @@ impl LayoutFromYamlIntermediate {
// once serde-yaml supports zero-copy
pub fn default_from_assets() -> LayoutFromYamlIntermediateResult {
let layout: LayoutFromYamlIntermediate =
serde_yaml::from_str(String::from_utf8(setup::DEFAULT_LAYOUT.to_vec())?.as_str())?;
serde_yaml::from_str(&String::from_utf8(setup::DEFAULT_LAYOUT.to_vec())?)?;
Ok(layout)
}
pub fn strider_from_assets() -> LayoutFromYamlIntermediateResult {
let layout: LayoutFromYamlIntermediate =
serde_yaml::from_str(String::from_utf8(setup::STRIDER_LAYOUT.to_vec())?.as_str())?;
serde_yaml::from_str(&String::from_utf8(setup::STRIDER_LAYOUT.to_vec())?)?;
Ok(layout)
}
pub fn disable_status_from_assets() -> LayoutFromYamlIntermediateResult {
let layout: LayoutFromYamlIntermediate =
serde_yaml::from_str(String::from_utf8(setup::NO_STATUS_LAYOUT.to_vec())?.as_str())?;
serde_yaml::from_str(&String::from_utf8(setup::NO_STATUS_LAYOUT.to_vec())?)?;
Ok(layout)
}
}
@ -331,9 +331,10 @@ impl LayoutFromYaml {
#[allow(clippy::ptr_arg)]
pub fn from_dir(layout: &PathBuf, layout_dir: Option<&PathBuf>) -> LayoutFromYamlResult {
match layout_dir {
Some(dir) => Self::new(&dir.join(layout))
.or_else(|_| Self::from_default_assets(layout.as_path())),
None => Self::from_default_assets(layout.as_path()),
Some(dir) => {
Self::new(&dir.join(layout)).or_else(|_| Self::from_default_assets(layout))
}
None => Self::from_default_assets(layout),
}
}
@ -372,19 +373,19 @@ impl LayoutFromYaml {
// once serde-yaml supports zero-copy
pub fn default_from_assets() -> LayoutFromYamlResult {
let layout: LayoutFromYaml =
serde_yaml::from_str(String::from_utf8(setup::DEFAULT_LAYOUT.to_vec())?.as_str())?;
serde_yaml::from_str(&String::from_utf8(setup::DEFAULT_LAYOUT.to_vec())?)?;
Ok(layout)
}
pub fn strider_from_assets() -> LayoutFromYamlResult {
let layout: LayoutFromYaml =
serde_yaml::from_str(String::from_utf8(setup::STRIDER_LAYOUT.to_vec())?.as_str())?;
serde_yaml::from_str(&String::from_utf8(setup::STRIDER_LAYOUT.to_vec())?)?;
Ok(layout)
}
pub fn disable_status_from_assets() -> LayoutFromYamlResult {
let layout: LayoutFromYaml =
serde_yaml::from_str(String::from_utf8(setup::NO_STATUS_LAYOUT.to_vec())?.as_str())?;
serde_yaml::from_str(&String::from_utf8(setup::NO_STATUS_LAYOUT.to_vec())?)?;
Ok(layout)
}
}
@ -465,7 +466,7 @@ pub struct TabLayout {
impl TabLayout {
fn check(&self) -> Result<TabLayout, ConfigError> {
for part in self.parts.iter() {
for part in &self.parts {
part.check()?;
if !part.name.is_empty() {
return Err(ConfigError::LayoutNameInTab(LayoutNameInTabError));
@ -479,7 +480,7 @@ impl Layout {
pub fn total_terminal_panes(&self) -> usize {
let mut total_panes = 0;
total_panes += self.parts.len();
for part in self.parts.iter() {
for part in &self.parts {
match part.run {
Some(Run::Command(_)) | None => {
total_panes += part.total_terminal_panes();
@ -493,7 +494,7 @@ impl Layout {
pub fn total_borderless_panes(&self) -> usize {
let mut total_borderless_panes = 0;
total_borderless_panes += self.parts.iter().filter(|p| p.borderless).count();
for part in self.parts.iter() {
for part in &self.parts {
total_borderless_panes += part.total_borderless_panes();
}
total_borderless_panes
@ -503,7 +504,7 @@ impl Layout {
if self.parts.is_empty() {
run_instructions.push(self.run.clone());
}
for part in self.parts.iter() {
for part in &self.parts {
let mut current_runnables = part.extract_run_instructions();
run_instructions.append(&mut current_runnables);
}
@ -549,7 +550,7 @@ fn layout_size(direction: Direction, layout: &Layout) -> usize {
.parts
.iter()
.map(|p| child_layout_size(direction, layout.direction, p))
.sum::<usize>();
.sum();
max(size, children_size)
}
}

View file

@ -18,7 +18,7 @@ pub use zellij_tile::data::PluginTag;
lazy_static! {
static ref DEFAULT_CONFIG_PLUGINS: PluginsConfig = {
let cfg = String::from_utf8(setup::DEFAULT_CONFIG.to_vec()).unwrap();
let cfg_yaml: ConfigFromYaml = serde_yaml::from_str(cfg.as_str()).unwrap();
let cfg_yaml: ConfigFromYaml = serde_yaml::from_str(&cfg).unwrap();
PluginsConfig::try_from(cfg_yaml.plugins).unwrap()
};
}
@ -271,7 +271,7 @@ mod tests {
)?;
let plugins = PluginsConfig::get_plugins_with_default(plugins.try_into()?);
assert_eq!(plugins.iter().collect::<Vec<_>>().len(), 4);
assert_eq!(plugins.iter().count(), 4);
Ok(())
}

View file

@ -92,7 +92,7 @@ pub fn atomic_create_dir(dir_name: &Path) -> io::Result<()> {
pub fn debug_to_file(message: &[u8], pid: RawFd) -> io::Result<()> {
let mut path = PathBuf::new();
path.push(&*ZELLIJ_TMP_LOG_DIR);
path.push(format!("zellij-{}.log", pid.to_string()));
path.push(format!("zellij-{}.log", pid));
let mut file = fs::OpenOptions::new()
.append(true)

View file

@ -12,7 +12,9 @@ use crate::{
};
use directories_next::BaseDirs;
use serde::{Deserialize, Serialize};
use std::{convert::TryFrom, io::Write, path::Path, path::PathBuf, process};
use std::{
convert::TryFrom, fmt::Write as FmtWrite, io::Write, path::Path, path::PathBuf, process,
};
use structopt::StructOpt;
const CONFIG_LOCATION: &str = ".config/zellij";
@ -47,7 +49,7 @@ fn default_config_dirs() -> Vec<Option<PathBuf>> {
/// Looks for an existing dir, uses that, else returns a
/// dir matching the config spec.
pub fn get_default_data_dir() -> PathBuf {
vec![
[
xdg_data_dir(),
Path::new(SYSTEM_DEFAULT_DATA_DIR_PREFIX).join("share/zellij"),
]
@ -300,9 +302,9 @@ impl Setup {
let mut message = String::new();
message.push_str(&format!("[Version]: {:?}\n", VERSION));
writeln!(&mut message, "[Version]: {:?}", VERSION).unwrap();
if let Some(config_dir) = config_dir {
message.push_str(&format!("[CONFIG DIR]: {:?}\n", config_dir));
writeln!(&mut message, "[CONFIG DIR]: {:?}", config_dir).unwrap();
} else {
message.push_str("[CONFIG DIR]: Not Found\n");
let mut default_config_dirs = default_config_dirs()
@ -314,32 +316,34 @@ impl Setup {
" On your system zellij looks in the following config directories by default:\n",
);
for dir in default_config_dirs {
message.push_str(&format!(" {:?}\n", dir));
writeln!(&mut message, " {:?}", dir).unwrap();
}
}
if let Some(config_file) = config_file {
message.push_str(&format!("[CONFIG FILE]: {:?}\n", config_file));
writeln!(&mut message, "[CONFIG FILE]: {:?}", config_file).unwrap();
match Config::new(&config_file) {
Ok(_) => message.push_str("[CONFIG FILE]: Well defined.\n"),
Err(e) => message.push_str(&format!("[CONFIG ERROR]: {}\n", e)),
Err(e) => writeln!(&mut message, "[CONFIG ERROR]: {}", e).unwrap(),
}
} else {
message.push_str("[CONFIG FILE]: Not Found\n");
message.push_str(&format!(
" By default zellij looks for a file called [{}] in the configuration directory\n",
writeln!(
&mut message,
" By default zellij looks for a file called [{}] in the configuration directory",
CONFIG_NAME
));
)
.unwrap();
}
message.push_str(&format!("[DATA DIR]: {:?}\n", data_dir));
writeln!(&mut message, "[DATA DIR]: {:?}", data_dir).unwrap();
message.push_str(&format!("[PLUGIN DIR]: {:?}\n", plugin_dir));
if let Some(layout_dir) = layout_dir {
message.push_str(&format!("[LAYOUT DIR]: {:?}\n", layout_dir));
writeln!(&mut message, "[LAYOUT DIR]: {:?}", layout_dir).unwrap();
} else {
message.push_str("[LAYOUT DIR]: Not Found\n");
}
message.push_str(&format!("[SYSTEM DATA DIR]: {:?}\n", system_data_dir));
writeln!(&mut message, "[SYSTEM DATA DIR]: {:?}", system_data_dir).unwrap();
message.push_str(&format!("[ARROW SEPARATOR]: {}\n", ARROW_SEPARATOR));
writeln!(&mut message, "[ARROW SEPARATOR]: {}", ARROW_SEPARATOR).unwrap();
message.push_str(" Is the [ARROW_SEPARATOR] displayed correctly?\n");
message.push_str(" If not you may want to either start zellij with a compatible mode: 'zellij options --simplified-ui true'\n");
let mut hyperlink_compat = String::new();
@ -348,22 +352,24 @@ impl Setup {
hyperlink_compat.push_str(hyperlink_mid);
hyperlink_compat.push_str("https://zellij.dev/documentation/compatibility.html#the-status-bar-fonts-dont-render-correctly");
hyperlink_compat.push_str(hyperlink_end);
message.push_str(&format!(
write!(
&mut message,
" Or check the font that is in use:\n {}\n",
hyperlink_compat
));
)
.unwrap();
message.push_str("[MOUSE INTERACTION]: \n");
message.push_str(" Can be temporarily disabled through pressing the [SHIFT] key.\n");
message.push_str(" If that doesn't fix any issues consider to disable the mouse handling of zellij: 'zellij options --disable-mouse-mode'\n");
message.push_str(&format!("[FEATURES]: {:?}\n", FEATURES));
writeln!(&mut message, "[FEATURES]: {:?}", FEATURES).unwrap();
let mut hyperlink = String::new();
hyperlink.push_str(hyperlink_start);
hyperlink.push_str("https://www.zellij.dev/documentation/");
hyperlink.push_str(hyperlink_mid);
hyperlink.push_str("zellij.dev/documentation");
hyperlink.push_str(hyperlink_end);
message.push_str(&format!("[DOCUMENTATION]: {}\n", hyperlink));
writeln!(&mut message, "[DOCUMENTATION]: {}", hyperlink).unwrap();
//printf '\e]8;;http://example.com\e\\This is a link\e]8;;\e\\\n'
std::io::stdout().write_all(message.as_bytes())?;
@ -371,14 +377,10 @@ impl Setup {
Ok(())
}
fn generate_completion(shell: String) {
let shell = match shell.as_ref() {
"bash" => structopt::clap::Shell::Bash,
"fish" => structopt::clap::Shell::Fish,
"zsh" => structopt::clap::Shell::Zsh,
"powerShell" => structopt::clap::Shell::PowerShell,
"elvish" => structopt::clap::Shell::Elvish,
other => {
eprintln!("Unsupported shell: {}", other);
let shell = match shell.parse() {
Ok(shell) => shell,
_ => {
eprintln!("Unsupported shell: {}", shell);
std::process::exit(1);
}
};
@ -400,8 +402,8 @@ mod setup_test {
config: &str,
layout: &str,
) -> Result<(Config, LayoutFromYamlIntermediate), ConfigError> {
let config = Config::from_yaml(&config)?;
let layout = LayoutFromYamlIntermediate::from_yaml(&layout)?;
let config = Config::from_yaml(config)?;
let layout = LayoutFromYamlIntermediate::from_yaml(layout)?;
Ok((config, layout))
}

View file

@ -19,7 +19,7 @@ pub fn set_permissions(path: &Path) -> io::Result<()> {
}
pub fn ansi_len(s: &str) -> usize {
from_utf8(&strip(s.as_bytes()).unwrap()).unwrap().width()
from_utf8(&strip(s).unwrap()).unwrap().width()
}
pub fn adjust_to_size(s: &str, rows: usize, columns: usize) -> String {