aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAram Drevekenin <aram@poor.dev>2020-12-08 16:42:26 +0100
committerGitHub <noreply@github.com>2020-12-08 16:42:26 +0100
commit94d6f3dbf6c75730b69a8dbb008f6450f2c21e16 (patch)
tree0526d745900021999cc5c23178b2d58169e5ae9b /src
parentfix(compatibility): acknowledge scroll region even if the cursor is not shown... (diff)
downloadsl0ppij-94d6f3dbf6c75730b69a8dbb008f6450f2c21e16.tar.gz
sl0ppij-94d6f3dbf6c75730b69a8dbb008f6450f2c21e16.tar.xz
sl0ppij-94d6f3dbf6c75730b69a8dbb008f6450f2c21e16.zip
refactor(ansi-codes): treat ansi codes properly and also make things clearer (#85)
Diffstat (limited to 'src')
-rw-r--r--src/terminal_pane/terminal_character.rs109
-rw-r--r--src/terminal_pane/terminal_pane.rs337
2 files changed, 111 insertions, 335 deletions
diff --git a/src/terminal_pane/terminal_character.rs b/src/terminal_pane/terminal_character.rs
index 2c5fe3ac..27c09105 100644
--- a/src/terminal_pane/terminal_character.rs
+++ b/src/terminal_pane/terminal_character.rs
@@ -1,3 +1,4 @@
+use crate::utils::logging::debug_log_to_file;
use ::std::fmt::{self, Debug, Display, Formatter};
pub const EMPTY_TERMINAL_CHARACTER: TerminalCharacter = TerminalCharacter {
@@ -297,6 +298,114 @@ impl CharacterStyles {
self.hidden = Some(AnsiCode::Reset);
self.strike = Some(AnsiCode::Reset);
}
+ pub fn add_style_from_ansi_params(&mut self, ansi_params: &[i64]) {
+ let mut params_used = 1; // if there's a parameter, it is always used
+ if ansi_params.is_empty() || ansi_params[0] == 0 {
+ self.reset_all();
+ } else if ansi_params[0] == 39 {
+ *self = self.foreground(Some(AnsiCode::Reset));
+ } else if ansi_params[0] == 49 {
+ *self = self.background(Some(AnsiCode::Reset));
+ } else if ansi_params[0] == 21 {
+ *self = self.bold(Some(AnsiCode::Reset));
+ } else if ansi_params[0] == 22 {
+ *self = self.bold(Some(AnsiCode::Reset));
+ *self = self.dim(Some(AnsiCode::Reset));
+ } else if ansi_params[0] == 23 {
+ *self = self.italic(Some(AnsiCode::Reset));
+ } else if ansi_params[0] == 24 {
+ *self = self.underline(Some(AnsiCode::Reset));
+ } else if ansi_params[0] == 25 {
+ *self = self.blink_slow(Some(AnsiCode::Reset));
+ *self = self.blink_fast(Some(AnsiCode::Reset));
+ } else if ansi_params[0] == 27 {
+ *self = self.reverse(Some(AnsiCode::Reset));
+ } else if ansi_params[0] == 28 {
+ *self = self.hidden(Some(AnsiCode::Reset));
+ } else if ansi_params[0] == 29 {
+ *self = self.strike(Some(AnsiCode::Reset));
+ } else if ansi_params[0] == 38 {
+ let ansi_code = AnsiCode::Code((
+ ansi_params.get(1).map(|p| *p as u16),
+ ansi_params.get(2).map(|p| *p as u16),
+ ));
+ *self = self.foreground(Some(ansi_code));
+ if ansi_params.len() > 2 {
+ params_used += ansi_params.len() - 1;
+ }
+ } else if ansi_params[0] == 48 {
+ let ansi_code = AnsiCode::Code((
+ ansi_params.get(1).map(|p| *p as u16),
+ ansi_params.get(2).map(|p| *p as u16),
+ ));
+ *self = self.background(Some(ansi_code));
+ if ansi_params.get(1).is_some() {
+ params_used += 1;
+ }
+ if ansi_params.get(2).is_some() {
+ params_used += 1;
+ }
+ } else if ansi_params[0] == 1 {
+ *self = self.bold(Some(AnsiCode::Code((Some(1), None))));
+ } else if ansi_params[0] == 2 {
+ *self = self.dim(Some(AnsiCode::Code((Some(2), None))));
+ } else if ansi_params[0] == 3 {
+ *self = self.italic(Some(AnsiCode::Code((Some(3), None))));
+ } else if ansi_params[0] == 4 {
+ *self = self.underline(Some(AnsiCode::Code((Some(4), None))));
+ } else if ansi_params[0] == 5 {
+ *self = self.blink_slow(Some(AnsiCode::Code((Some(5), None))));
+ } else if ansi_params[0] == 6 {
+ *self = self.blink_fast(Some(AnsiCode::Code((Some(6), None))));
+ } else if ansi_params[0] == 7 {
+ *self = self.reverse(Some(AnsiCode::Code((Some(7), None))));
+ } else if ansi_params[0] == 8 {
+ *self = self.hidden(Some(AnsiCode::Code((Some(8), None))));
+ } else if ansi_params[0] == 9 {
+ *self = self.strike(Some(AnsiCode::Code((Some(9), None))));
+ } else if ansi_params[0] == 30 {
+ *self = self.foreground(Some(AnsiCode::NamedColor(NamedColor::Black)));
+ } else if ansi_params[0] == 31 {
+ *self = self.foreground(Some(AnsiCode::NamedColor(NamedColor::Red)));
+ } else if ansi_params[0] == 32 {
+ *self = self.foreground(Some(AnsiCode::NamedColor(NamedColor::Green)));
+ } else if ansi_params[0] == 33 {
+ *self = self.foreground(Some(AnsiCode::NamedColor(NamedColor::Yellow)));
+ } else if ansi_params[0] == 34 {
+ *self = self.foreground(Some(AnsiCode::NamedColor(NamedColor::Blue)));
+ } else if ansi_params[0] == 35 {
+ *self = self.foreground(Some(AnsiCode::NamedColor(NamedColor::Magenta)));
+ } else if ansi_params[0] == 36 {
+ *self = self.foreground(Some(AnsiCode::NamedColor(NamedColor::Cyan)));
+ } else if ansi_params[0] == 37 {
+ *self = self.foreground(Some(AnsiCode::NamedColor(NamedColor::White)));
+ } else if ansi_params[0] == 40 {
+ *self = self.background(Some(AnsiCode::NamedColor(NamedColor::Black)));
+ } else if ansi_params[0] == 41 {
+ *self = self.background(Some(AnsiCode::NamedColor(NamedColor::Red)));
+ } else if ansi_params[0] == 42 {
+ *self = self.background(Some(AnsiCode::NamedColor(NamedColor::Green)));
+ } else if ansi_params[0] == 43 {
+ *self = self.background(Some(AnsiCode::NamedColor(NamedColor::Yellow)));
+ } else if ansi_params[0] == 44 {
+ *self = self.background(Some(AnsiCode::NamedColor(NamedColor::Blue)));
+ } else if ansi_params[0] == 45 {
+ *self = self.background(Some(AnsiCode::NamedColor(NamedColor::Magenta)));
+ } else if ansi_params[0] == 46 {
+ *self = self.background(Some(AnsiCode::NamedColor(NamedColor::Cyan)));
+ } else if ansi_params[0] == 47 {
+ *self = self.background(Some(AnsiCode::NamedColor(NamedColor::White)));
+ } else {
+ // if this happens, it's a bug
+ let _ = debug_log_to_file(format!("unhandled csi m code {:?}", ansi_params));
+ return;
+ }
+ if let Some(next_params) = ansi_params.get(params_used..) {
+ if next_params.len() > 0 {
+ self.add_style_from_ansi_params(next_params);
+ }
+ }
+ }
}
impl Display for CharacterStyles {
diff --git a/src/terminal_pane/terminal_pane.rs b/src/terminal_pane/terminal_pane.rs
index 348a9fe0..a6b4b346 100644
--- a/src/terminal_pane/terminal_pane.rs
+++ b/src/terminal_pane/terminal_pane.rs
@@ -9,7 +9,7 @@ use crate::terminal_pane::terminal_character::{
AnsiCode, CharacterStyles, NamedColor, TerminalCharacter,
};
use crate::terminal_pane::Scroll;
-use crate::utils::logging::{debug_log_to_file, debug_log_to_file_pid_3};
+use crate::utils::logging::debug_log_to_file;
use crate::VteEvent;
#[derive(Clone, Copy, Debug)]
@@ -398,340 +398,7 @@ impl vte::Perform for TerminalPane {
fn csi_dispatch(&mut self, params: &[i64], _intermediates: &[u8], _ignore: bool, c: char) {
if c == 'm' {
- if params.is_empty() || params[0] == 0 {
- // reset all
- self.pending_styles.reset_all();
- if let Some(param1) = params.get(1) {
- // TODO: this is a case currently found in eg. htop where we get two different
- // csi 'm' codes in one event.
- // We should understand why these are happening and then make a more generic
- // solution for them
- if *param1 == 1 {
- // bold
- self.pending_styles = self
- .pending_styles
- .bold(Some(AnsiCode::Code((Some(*param1 as u16), None))));
- }
- }
- } else if params[0] == 39 {
- self.pending_styles = self.pending_styles.foreground(Some(AnsiCode::Reset));
- if let Some(param1) = params.get(1) {
- // TODO: this is a case currently found in eg. htop where we get two different
- // csi 'm' codes in one event.
- // We should understand why these are happening and then make a more generic
- // solution for them
- if *param1 == 49 {
- // TODO: if we need this to fix the bug, we need to make collecting the
- // second argument in such cases generic
- self.pending_styles = self.pending_styles.background(Some(AnsiCode::Reset));
- }
- }
- } else if params[0] == 49 {
- self.pending_styles = self.pending_styles.background(Some(AnsiCode::Reset));
- } else if params[0] == 21 {
- // reset bold
- self.pending_styles = self.pending_styles.bold(Some(AnsiCode::Reset));
- } else if params[0] == 22 {
- // reset bold and dim
- self.pending_styles = self.pending_styles.bold(Some(AnsiCode::Reset));
- self.pending_styles = self.pending_styles.dim(Some(AnsiCode::Reset));
- } else if params[0] == 23 {
- // reset italic
- self.pending_styles = self.pending_styles.italic(Some(AnsiCode::Reset));
- } else if params[0] == 24 {
- // reset underline
- self.pending_styles = self.pending_styles.underline(Some(AnsiCode::Reset));
- } else if params[0] == 25 {
- // reset blink
- self.pending_styles = self.pending_styles.blink_slow(Some(AnsiCode::Reset));
- self.pending_styles = self.pending_styles.blink_fast(Some(AnsiCode::Reset));
- } else if params[0] == 27 {
- // reset reverse
- self.pending_styles = self.pending_styles.reverse(Some(AnsiCode::Reset));
- } else if params[0] == 28 {
- // reset hidden
- self.pending_styles = self.pending_styles.hidden(Some(AnsiCode::Reset));
- } else if params[0] == 29 {
- // reset strike
- self.pending_styles = self.pending_styles.strike(Some(AnsiCode::Reset));
- } else if params[0] == 38 {
- match (params.get(1), params.get(2)) {
- (Some(param1), Some(param2)) => {
- self.pending_styles = self.pending_styles.foreground(Some(AnsiCode::Code(
- (Some(*param1 as u16), Some(*param2 as u16)),
- )));
- }
- (Some(param1), None) => {
- self.pending_styles = self
- .pending_styles
- .foreground(Some(AnsiCode::Code((Some(*param1 as u16), None))));
- }
- (_, _) => {
- self.pending_styles = self
- .pending_styles
- .foreground(Some(AnsiCode::Code((None, None))));
- }
- };
- } else if params[0] == 48 {
- match (params.get(1), params.get(2)) {
- (Some(param1), Some(param2)) => {
- self.pending_styles = self.pending_styles.background(Some(AnsiCode::Code(
- (Some(*param1 as u16), Some(*param2 as u16)),
- )));
- }
- (Some(param1), None) => {
- self.pending_styles = self
- .pending_styles
- .background(Some(AnsiCode::Code((Some(*param1 as u16), None))));
- }
- (_, _) => {
- self.pending_styles = self
- .pending_styles
- .background(Some(AnsiCode::Code((None, None))));
- }
- };
- } else if params[0] == 1 {
- // bold
- match (params.get(1), params.get(2)) {
- (Some(param1), Some(param2)) => {
- self.pending_styles = self.pending_styles.bold(Some(AnsiCode::Code((
- Some(*param1 as u16),
- Some(*param2 as u16),
- ))));
- }
- (Some(param1), None) => {
- self.pending_styles = self
- .pending_styles
- .bold(Some(AnsiCode::Code((Some(*param1 as u16), None))));
- }
- (_, _) => {
- self.pending_styles =
- self.pending_styles.bold(Some(AnsiCode::Code((None, None))));
- }
- };
- } else if params[0] == 2 {
- // dim
- match (params.get(1), params.get(2)) {
- (Some(param1), Some(param2)) => {
- self.pending_styles = self.pending_styles.dim(Some(AnsiCode::Code((
- Some(*param1 as u16),
- Some(*param2 as u16),
- ))));
- }
- (Some(param1), None) => {
- self.pending_styles = self
- .pending_styles
- .dim(Some(AnsiCode::Code((Some(*param1 as u16), None))));
- }
- (_, _) => {
- self.pending_styles =
- self.pending_styles.dim(Some(AnsiCode::Code((None, None))));
- }
- };
- } else if params[0] == 3 {
- // italic
- match (params.get(1), params.get(2)) {
- (Some(param1), Some(param2)) => {
- self.pending_styles = self.pending_styles.italic(Some(AnsiCode::Code((
- Some(*param1 as u16),
- Some(*param2 as u16),
- ))));
- }
- (Some(param1), None) => {
- self.pending_styles = self
- .pending_styles
- .italic(Some(AnsiCode::Code((Some(*param1 as u16), None))));
- }
- (_, _) => {
- self.pending_styles = self
- .pending_styles
- .italic(Some(AnsiCode::Code((None, None))));
- }
- };
- } else if params[0] == 4 {
- // underline
- match (params.get(1), params.get(2)) {
- (Some(param1), Some(param2)) => {
- self.pending_styles = self.pending_styles.underline(Some(AnsiCode::Code(
- (Some(*param1 as u16), Some(*param2 as u16)),
- )));
- }
- (Some(param1), None) => {
- self.pending_styles = self
- .pending_styles
- .underline(Some(AnsiCode::Code((Some(*param1 as u16), None))));
- }
- (_, _) => {
- self.pending_styles = self
- .pending_styles
- .underline(Some(AnsiCode::Code((None, None))));
- }
- };
- } else if params[0] == 5 {
- // blink slow
- match (params.get(1), params.get(2)) {
- (Some(param1), Some(param2)) => {
- self.pending_styles = self.pending_styles.blink_slow(Some(AnsiCode::Code(
- (Some(*param1 as u16), Some(*param2 as u16)),
- )));
- }
- (Some(param1), None) => {
- self.pending_styles = self
- .pending_styles
- .blink_slow(Some(AnsiCode::Code((Some(*param1 as u16), None))));
- }
- (_, _) => {
- self.pending_styles = self
- .pending_styles
- .blink_slow(Some(AnsiCode::Code((None, None))));
- }
- };
- } else if params[0] == 6 {
- // blink fast
- match (params.get(1), params.get(2)) {
- (Some(param1), Some(param2)) => {
- self.pending_styles = self.pending_styles.blink_fast(Some(AnsiCode::Code(
- (Some(*param1 as u16), Some(*param2 as u16)),
- )));
- }
- (Some(param1), None) => {
- self.pending_styles = self
- .pending_styles
- .blink_fast(Some(AnsiCode::Code((Some(*param1 as u16), None))));
- }
- (_, _) => {
- self.pending_styles = self
- .pending_styles
- .blink_fast(Some(AnsiCode::Code((None, None))));
- }
- };
- } else if params[0] == 7 {
- // reverse
- match (params.get(1), params.get(2)) {
- (Some(param1), Some(param2)) => {
- self.pending_styles = self.pending_styles.reverse(Some(AnsiCode::Code((
- Some(*param1 as u16),
- Some(*param2 as u16),
- ))));
- }
- (Some(param1), None) => {
- self.pending_styles = self
- .pending_styles
- .reverse(Some(AnsiCode::Code((Some(*param1 as u16), None))));
- }
- (_, _) => {
- self.pending_styles = self
- .pending_styles
- .reverse(Some(AnsiCode::Code((None, None))));
- }
- };
- } else if params[0] == 8 {
- // hidden
- match (params.get(1), params.get(2)) {
- (Some(param1), Some(param2)) => {
- self.pending_styles = self.pending_styles.hidden(Some(AnsiCode::Code((
- Some(*param1 as u16),
- Some(*param2 as u16),
- ))));
- }
- (Some(param1), None) => {
- self.pending_styles = self
- .pending_styles
- .hidden(Some(AnsiCode::Code((Some(*param1 as u16), None))));
- }
- (_, _) => {
- self.pending_styles = self
- .pending_styles
- .hidden(Some(AnsiCode::Code((None, None))));
- }
- };
- } else if params[0] == 9 {
- // strike
- match (params.get(1), params.get(2)) {
- (Some(param1), Some(param2)) => {
- self.pending_styles = self.pending_styles.strike(Some(AnsiCode::Code((
- Some(*param1 as u16),
- Some(*param2 as u16),
- ))));
- }
- (Some(param1), None) => {
- self.pending_styles = self
- .pending_styles
- .strike(Some(AnsiCode::Code((Some(*param1 as u16), None))));
- }
- (_, _) => {
- self.pending_styles = self
- .pending_styles
- .strike(Some(AnsiCode::Code((None, None))));
- }
- };
- } else if params[0] == 30 {
- self.pending_styles = self
- .pending_styles
- .foreground(Some(AnsiCode::NamedColor(NamedColor::Black)));
- } else if params[0] == 31 {
- self.pending_styles = self
- .pending_styles
- .foreground(Some(AnsiCode::NamedColor(NamedColor::Red)));
- } else if params[0] == 32 {
- self.pending_styles = self
- .pending_styles
- .foreground(Some(AnsiCode::NamedColor(NamedColor::Green)));
- } else if params[0] == 33 {
- self.pending_styles = self
- .pending_styles
- .foreground(Some(AnsiCode::NamedColor(NamedColor::Yellow)));
- } else if params[0] == 34 {
- self.pending_styles = self
- .pending_styles
- .foreground(Some(AnsiCode::NamedColor(NamedColor::Blue)));
- } else if params[0] == 35 {
- self.pending_styles = self
- .pending_styles
- .foreground(Some(AnsiCode::NamedColor(NamedColor::Magenta)));
- } else if params[0] == 36 {
- self.pending_styles = self
- .pending_styles
- .foreground(Some(AnsiCode::NamedColor(NamedColor::Cyan)));
- } else if params[0] == 37 {
- self.pending_styles = self
- .pending_styles
- .foreground(Some(AnsiCode::NamedColor(NamedColor::White)));
- } else if params[0] == 40 {
- self.pending_styles = self
- .pending_styles
- .background(Some(AnsiCode::NamedColor(NamedColor::Black)));
- } else if params[0] == 41 {
- self.pending_styles = self
- .pending_styles
- .background(Some(AnsiCode::NamedColor(NamedColor::Red)));
- } else if params[0] == 42 {
- self.pending_styles = self
- .pending_styles
- .background(Some(AnsiCode::NamedColor(NamedColor::Green)));
- } else if params[0] == 43 {
- self.pending_styles = self
- .pending_styles
- .background(Some(AnsiCode::NamedColor(NamedColor::Yellow)));
- } else if params[0] == 44 {
- self.pending_styles = self
- .pending_styles
- .background(Some(AnsiCode::NamedColor(NamedColor::Blue)));
- } else if params[0] == 45 {
- self.pending_styles = self
- .pending_styles
- .background(Some(AnsiCode::NamedColor(NamedColor::Magenta)));
- } else if params[0] == 46 {
- self.pending_styles = self
- .pending_styles
- .background(Some(AnsiCode::NamedColor(NamedColor::Cyan)));
- } else if params[0] == 47 {
- self.pending_styles = self
- .pending_styles
- .background(Some(AnsiCode::NamedColor(NamedColor::White)));
- } else {
- let _ = debug_log_to_file(format!("unhandled csi m code {:?}", params));
- }
+ self.pending_styles.add_style_from_ansi_params(params);
} else if c == 'C' {
// move cursor forward
let move_by = if params[0] == 0 {