aboutsummaryrefslogtreecommitdiffstats
path: root/src/client
diff options
context:
space:
mode:
authordenis <denismaximov98@gmail.com>2021-04-09 14:14:50 +0300
committerdenis <denismaximov98@gmail.com>2021-04-09 14:14:50 +0300
commit748a7ffa6ea4cf3b2093adb30e27bea9117d40d6 (patch)
tree2e906db54b01ec1ce47f77ad2406690242d63c45 /src/client
parentwip: need to figure out how to clear lines (diff)
parentfeat(controls): add quick navigation (#260) (diff)
downloadsl0ppij-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.rs9
-rw-r--r--src/client/panes/terminal_character.rs64
-rw-r--r--src/client/panes/terminal_pane.rs21
-rw-r--r--src/client/tab.rs178
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) {