diff options
| author | denis <denismaximov98@gmail.com> | 2021-04-09 14:14:50 +0300 |
|---|---|---|
| committer | denis <denismaximov98@gmail.com> | 2021-04-09 14:14:50 +0300 |
| commit | 748a7ffa6ea4cf3b2093adb30e27bea9117d40d6 (patch) | |
| tree | 2e906db54b01ec1ce47f77ad2406690242d63c45 /src/client | |
| parent | wip: need to figure out how to clear lines (diff) | |
| parent | feat(controls): add quick navigation (#260) (diff) | |
| download | sl0ppij-748a7ffa6ea4cf3b2093adb30e27bea9117d40d6.tar.gz sl0ppij-748a7ffa6ea4cf3b2093adb30e27bea9117d40d6.tar.xz sl0ppij-748a7ffa6ea4cf3b2093adb30e27bea9117d40d6.zip | |
wip: cleaning up a bit, need to map the colors to the right places in the palette
Diffstat (limited to 'src/client')
| -rw-r--r-- | src/client/boundaries.rs | 9 | ||||
| -rw-r--r-- | src/client/panes/terminal_character.rs | 64 | ||||
| -rw-r--r-- | src/client/panes/terminal_pane.rs | 21 | ||||
| -rw-r--r-- | src/client/tab.rs | 178 |
4 files changed, 218 insertions, 54 deletions
diff --git a/src/client/boundaries.rs b/src/client/boundaries.rs index cd489be0..7a6a2b2b 100644 --- a/src/client/boundaries.rs +++ b/src/client/boundaries.rs @@ -1,5 +1,5 @@ -use crate::common::colors; use crate::tab::Pane; +use crate::utils::shared::colors; use ansi_term::Colour::RGB; use std::collections::HashMap; use zellij_tile::data::{InputMode, Palette}; @@ -19,6 +19,13 @@ pub mod boundary_type { pub const CROSS: &str = "┼"; } +// pub mod colors { +// use ansi_term::Colour::{self, Fixed}; +// pub const GREEN: Colour = Fixed(154); +// pub const GRAY: Colour = Fixed(238); +// pub const ORANGE: Colour = Fixed(166); +// } + pub type BoundaryType = &'static str; // easy way to refer to boundary_type above #[derive(Clone, Copy, Debug)] diff --git a/src/client/panes/terminal_character.rs b/src/client/panes/terminal_character.rs index 053ebd3f..ce967ef8 100644 --- a/src/client/panes/terminal_character.rs +++ b/src/client/panes/terminal_character.rs @@ -37,6 +37,14 @@ pub enum NamedColor { Magenta, Cyan, White, + BrightBlack, + BrightRed, + BrightGreen, + BrightYellow, + BrightBlue, + BrightMagenta, + BrightCyan, + BrightWhite, } impl NamedColor { @@ -50,6 +58,14 @@ impl NamedColor { 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), } } fn to_background_ansi_code(&self) -> String { @@ -62,6 +78,14 @@ impl NamedColor { 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), } } } @@ -383,6 +407,46 @@ impl CharacterStyles { params_used += 1; // even if it's a bug, let's not create an endless loop, eh? } [49, ..] => *self = self.background(Some(AnsiCode::Reset)), + [90, ..] => { + *self = self.foreground(Some(AnsiCode::NamedColor(NamedColor::BrightBlack))) + } + [91, ..] => *self = self.foreground(Some(AnsiCode::NamedColor(NamedColor::BrightRed))), + [92, ..] => { + *self = self.foreground(Some(AnsiCode::NamedColor(NamedColor::BrightGreen))) + } + [93, ..] => { + *self = self.foreground(Some(AnsiCode::NamedColor(NamedColor::BrightYellow))) + } + [94, ..] => *self = self.foreground(Some(AnsiCode::NamedColor(NamedColor::BrightBlue))), + [95, ..] => { + *self = self.foreground(Some(AnsiCode::NamedColor(NamedColor::BrightMagenta))) + } + [96, ..] => *self = self.foreground(Some(AnsiCode::NamedColor(NamedColor::BrightCyan))), + [97, ..] => { + *self = self.foreground(Some(AnsiCode::NamedColor(NamedColor::BrightWhite))) + } + [100, ..] => { + *self = self.background(Some(AnsiCode::NamedColor(NamedColor::BrightBlack))) + } + [101, ..] => *self = self.background(Some(AnsiCode::NamedColor(NamedColor::BrightRed))), + [102, ..] => { + *self = self.background(Some(AnsiCode::NamedColor(NamedColor::BrightGreen))) + } + [103, ..] => { + *self = self.background(Some(AnsiCode::NamedColor(NamedColor::BrightYellow))) + } + [104, ..] => { + *self = self.background(Some(AnsiCode::NamedColor(NamedColor::BrightBlue))) + } + [105, ..] => { + *self = self.background(Some(AnsiCode::NamedColor(NamedColor::BrightMagenta))) + } + [106, ..] => { + *self = self.background(Some(AnsiCode::NamedColor(NamedColor::BrightCyan))) + } + [107, ..] => { + *self = self.background(Some(AnsiCode::NamedColor(NamedColor::BrightWhite))) + } _ => { // if this happens, it's a bug let _ = debug_log_to_file(format!("unhandled csi m code {:?}", ansi_params)); diff --git a/src/client/panes/terminal_pane.rs b/src/client/panes/terminal_pane.rs index 463a33e3..13575475 100644 --- a/src/client/panes/terminal_pane.rs +++ b/src/client/panes/terminal_pane.rs @@ -380,8 +380,7 @@ impl TerminalPane { self.mark_for_rerender(); } fn add_newline(&mut self) { - let mut pad_character = EMPTY_TERMINAL_CHARACTER; - pad_character.styles = self.pending_styles; + let pad_character = EMPTY_TERMINAL_CHARACTER; self.grid.add_canonical_line(pad_character); self.mark_for_rerender(); } @@ -497,8 +496,7 @@ impl vte::Perform for TerminalPane { } else { (params[0] as usize - 1, params[1] as usize - 1) }; - let mut pad_character = EMPTY_TERMINAL_CHARACTER; - pad_character.styles = self.pending_styles; + let pad_character = EMPTY_TERMINAL_CHARACTER; self.grid.move_cursor_to(col, row, pad_character); } else if c == 'A' { // move cursor up until edge of screen @@ -507,8 +505,7 @@ impl vte::Perform for TerminalPane { } else if c == 'B' { // move cursor down until edge of screen let move_down_count = if params[0] == 0 { 1 } else { params[0] }; - let mut pad_character = EMPTY_TERMINAL_CHARACTER; - pad_character.styles = self.pending_styles; + let pad_character = EMPTY_TERMINAL_CHARACTER; self.grid .move_cursor_down(move_down_count as usize, pad_character); } else if c == 'D' { @@ -600,8 +597,7 @@ impl vte::Perform for TerminalPane { } else { params[0] as usize }; - let mut pad_character = EMPTY_TERMINAL_CHARACTER; - pad_character.styles = self.pending_styles; + let pad_character = EMPTY_TERMINAL_CHARACTER; self.grid .delete_lines_in_scroll_region(line_count_to_delete, pad_character); } else if c == 'L' { @@ -611,8 +607,7 @@ impl vte::Perform for TerminalPane { } else { params[0] as usize }; - let mut pad_character = EMPTY_TERMINAL_CHARACTER; - pad_character.styles = self.pending_styles; + let pad_character = EMPTY_TERMINAL_CHARACTER; self.grid .add_empty_lines_in_scroll_region(line_count_to_add, pad_character); } else if c == 'q' { @@ -632,8 +627,7 @@ impl vte::Perform for TerminalPane { // minus 1 because this is 1 indexed params[0] as usize - 1 }; - let mut pad_character = EMPTY_TERMINAL_CHARACTER; - pad_character.styles = self.pending_styles; + let pad_character = EMPTY_TERMINAL_CHARACTER; self.grid.move_cursor_to_line(line, pad_character); } else if c == 'P' { // erase characters @@ -672,8 +666,7 @@ impl vte::Perform for TerminalPane { } else { params[0] as usize }; - let mut pad_character = EMPTY_TERMINAL_CHARACTER; - pad_character.styles = self.pending_styles; + let pad_character = EMPTY_TERMINAL_CHARACTER; self.grid .delete_lines_in_scroll_region(count, pad_character); // TODO: since delete_lines_in_scroll_region also adds lines, is the below redundant? diff --git a/src/client/tab.rs b/src/client/tab.rs index 9f769252..08135499 100644 --- a/src/client/tab.rs +++ b/src/client/tab.rs @@ -17,7 +17,7 @@ use std::{ collections::{BTreeMap, HashSet}, }; use std::{io::Write, sync::mpsc::channel}; -use zellij_tile::data::{Event, InputMode, ModeInfo, Palette, colors}; +use zellij_tile::data::{colors, Event, InputMode, ModeInfo, Palette}; const CURSOR_HEIGHT_WIDTH_RATIO: usize = 4; // this is not accurate and kind of a magic number, TODO: look into this const MIN_TERMINAL_HEIGHT: usize = 2; @@ -71,7 +71,7 @@ pub struct Tab { should_clear_display_before_rendering: bool, pub mode_info: ModeInfo, pub input_mode: InputMode, - pub colors: Palette + pub colors: Palette, } #[derive(Clone, Debug, Default, Serialize, Deserialize)] @@ -568,6 +568,9 @@ impl Tab { None } } + pub fn has_terminal_pid(&self, pid: RawFd) -> bool { + self.panes.contains_key(&PaneId::Terminal(pid)) + } pub fn handle_pty_event(&mut self, pid: RawFd, event: VteEvent) { // if we don't have the terminal in self.terminals it's probably because // of a race condition where the terminal was created in pty_bus but has not @@ -638,8 +641,17 @@ impl Tab { } }); self.panes_to_hide = pane_ids_to_hide.collect(); - let active_terminal = self.panes.get_mut(&active_pane_id).unwrap(); - active_terminal.override_size_and_position(expand_to.x, expand_to.y, &expand_to); + if self.panes_to_hide.is_empty() { + // nothing to do, pane is already as fullscreen as it can be, let's bail + return; + } else { + let active_terminal = self.panes.get_mut(&active_pane_id).unwrap(); + active_terminal.override_size_and_position( + expand_to.x, + expand_to.y, + &expand_to, + ); + } } let active_terminal = self.panes.get(&active_pane_id).unwrap(); if let PaneId::Terminal(active_pid) = active_pane_id { @@ -1804,6 +1816,62 @@ impl Tab { } self.render(); } + pub fn focus_next_pane(&mut self) { + if !self.has_selectable_panes() { + return; + } + if self.fullscreen_is_active { + return; + } + let active_pane_id = self.get_active_pane_id().unwrap(); + let mut panes: Vec<(&PaneId, &Box<dyn Pane>)> = self.get_selectable_panes().collect(); + panes.sort_by(|(_a_id, a_pane), (_b_id, b_pane)| { + if a_pane.y() == b_pane.y() { + a_pane.x().cmp(&b_pane.x()) + } else { + a_pane.y().cmp(&b_pane.y()) + } + }); + let first_pane = panes.get(0).unwrap(); + let active_pane_position = panes + .iter() + .position(|(id, _)| *id == &active_pane_id) // TODO: better + .unwrap(); + if let Some(next_pane) = panes.get(active_pane_position + 1) { + self.active_terminal = Some(*next_pane.0); + } else { + self.active_terminal = Some(*first_pane.0); + } + self.render(); + } + pub fn focus_previous_pane(&mut self) { + if !self.has_selectable_panes() { + return; + } + if self.fullscreen_is_active { + return; + } + let active_pane_id = self.get_active_pane_id().unwrap(); + let mut panes: Vec<(&PaneId, &Box<dyn Pane>)> = self.get_selectable_panes().collect(); + panes.sort_by(|(_a_id, a_pane), (_b_id, b_pane)| { + if a_pane.y() == b_pane.y() { + a_pane.x().cmp(&b_pane.x()) + } else { + a_pane.y().cmp(&b_pane.y()) + } + }); + let last_pane = panes.last().unwrap(); + let active_pane_position = panes + .iter() + .position(|(id, _)| *id == &active_pane_id) // TODO: better + .unwrap(); + if active_pane_position == 0 { + self.active_terminal = Some(*last_pane.0); + } else { + self.active_terminal = Some(*panes.get(active_pane_position - 1).unwrap().0); + } + self.render(); + } pub fn move_focus_left(&mut self) { if !self.has_selectable_panes() { return; @@ -2071,47 +2139,79 @@ impl Tab { } } pub fn close_pane_without_rerender(&mut self, id: PaneId) { - if let Some(terminal_to_close) = self.panes.get(&id) { - let terminal_to_close_width = terminal_to_close.columns(); - let terminal_to_close_height = terminal_to_close.rows(); - if let Some(terminals) = self.panes_to_the_left_between_aligning_borders(id) { - for terminal_id in terminals.iter() { - self.increase_pane_width_right(&terminal_id, terminal_to_close_width + 1); - // 1 for the border - } - if self.active_terminal == Some(id) { - self.active_terminal = self.next_active_pane(terminals); - } - } else if let Some(terminals) = self.panes_to_the_right_between_aligning_borders(id) { - for terminal_id in terminals.iter() { - self.increase_pane_width_left(&terminal_id, terminal_to_close_width + 1); - // 1 for the border - } - if self.active_terminal == Some(id) { - self.active_terminal = self.next_active_pane(terminals); - } - } else if let Some(terminals) = self.panes_above_between_aligning_borders(id) { - for terminal_id in terminals.iter() { - self.increase_pane_height_down(&terminal_id, terminal_to_close_height + 1); - // 1 for the border + if self.fullscreen_is_active { + self.toggle_active_pane_fullscreen(); + } + if let Some(pane_to_close) = self.panes.get(&id) { + let pane_to_close_width = pane_to_close.columns(); + let pane_to_close_height = pane_to_close.rows(); + if let Some(panes) = self.panes_to_the_left_between_aligning_borders(id) { + if panes.iter().all(|p| { + let pane = self.panes.get(p).unwrap(); + pane.can_increase_width_by(pane_to_close_width + 1) + }) { + for pane_id in panes.iter() { + self.increase_pane_width_right(&pane_id, pane_to_close_width + 1); + // 1 for the border + } + self.panes.remove(&id); + if self.active_terminal == Some(id) { + self.active_terminal = self.next_active_pane(panes); + } + return; } - if self.active_terminal == Some(id) { - self.active_terminal = self.next_active_pane(terminals); + } + if let Some(panes) = self.panes_to_the_right_between_aligning_borders(id) { + if panes.iter().all(|p| { + let pane = self.panes.get(p).unwrap(); + pane.can_increase_width_by(pane_to_close_width + 1) + }) { + for pane_id in panes.iter() { + self.increase_pane_width_left(&pane_id, pane_to_close_width + 1); + // 1 for the border + } + self.panes.remove(&id); + if self.active_terminal == Some(id) { + self.active_terminal = self.next_active_pane(panes); + } + return; } - } else if let Some(terminals) = self.panes_below_between_aligning_borders(id) { - for terminal_id in terminals.iter() { - self.increase_pane_height_up(&terminal_id, terminal_to_close_height + 1); - // 1 for the border + } + if let Some(panes) = self.panes_above_between_aligning_borders(id) { + if panes.iter().all(|p| { + let pane = self.panes.get(p).unwrap(); + pane.can_increase_height_by(pane_to_close_height + 1) + }) { + for pane_id in panes.iter() { + self.increase_pane_height_down(&pane_id, pane_to_close_height + 1); + // 1 for the border + } + self.panes.remove(&id); + if self.active_terminal == Some(id) { + self.active_terminal = self.next_active_pane(panes); + } + return; } - if self.active_terminal == Some(id) { - self.active_terminal = self.next_active_pane(terminals); + } + if let Some(panes) = self.panes_below_between_aligning_borders(id) { + if panes.iter().all(|p| { + let pane = self.panes.get(p).unwrap(); + pane.can_increase_height_by(pane_to_close_height + 1) + }) { + for pane_id in panes.iter() { + self.increase_pane_height_up(&pane_id, pane_to_close_height + 1); + // 1 for the border + } + self.panes.remove(&id); + if self.active_terminal == Some(id) { + self.active_terminal = self.next_active_pane(panes); + } + return; } - } else { } + // if we reached here, this is either the last pane or there's some sort of + // configuration error (eg. we're trying to close a pane surrounded by fixed panes) self.panes.remove(&id); - if self.active_terminal.is_none() { - self.active_terminal = self.next_active_pane(self.get_pane_ids()); - } } } pub fn close_focused_pane(&mut self) { |
