Skip to content

Commit

Permalink
Merge branch 'main' into mac-config
Browse files Browse the repository at this point in the history
  • Loading branch information
a-kenji authored May 11, 2021
2 parents a116f6e + 20dcb3f commit 4b39699
Show file tree
Hide file tree
Showing 12 changed files with 179 additions and 13 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
* Move the sync command to tab mode (https://github.com/zellij-org/zellij/pull/412)
* Fix exit code of `dump-default-config` (https://github.com/zellij-org/zellij/pull/480)
* Feature: Switch tabs using `Alt + h/l` in normal mode if there are no panes in the direction (https://github.com/zellij-org/zellij/pull/471)
* Fix handling of $HOME `config` direcotry, especially relevant for darwin systems (https://github.com/zellij-org/zellij/pull/487)
* Terminal Compatibility: various behaviour fixes (https://github.com/zellij-org/zellij/pull/486)
* Fix handling of `$HOME` `config` directory, especially relevant for darwin systems (https://github.com/zellij-org/zellij/pull/487)


## [0.8.0] - 2021-05-07
* Terminal compatibility: pass vttest 8 (https://github.com/zellij-org/zellij/pull/461)
Expand Down
86 changes: 77 additions & 9 deletions src/client/panes/grid.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const SCROLL_BACK: usize = 10_000;
use crate::utils::logging::debug_log_to_file;

use crate::panes::terminal_character::{
CharacterStyles, CharsetIndex, Cursor, StandardCharset, TerminalCharacter,
CharacterStyles, CharsetIndex, Cursor, CursorShape, StandardCharset, TerminalCharacter,
EMPTY_TERMINAL_CHARACTER,
};

Expand Down Expand Up @@ -177,6 +177,7 @@ pub struct Grid {
saved_cursor_position: Option<Cursor>,
scroll_region: Option<(usize, usize)>,
active_charset: CharsetIndex,
preceding_char: Option<TerminalCharacter>,
pub should_render: bool,
pub cursor_key_mode: bool, // DECCKM - when set, cursor keys should send ANSI direction codes (eg. "OD") instead of the arrow keys (eg. "")
pub erasure_mode: bool, // ERM
Expand Down Expand Up @@ -210,6 +211,7 @@ impl Grid {
cursor: Cursor::new(0, 0),
saved_cursor_position: None,
scroll_region: None,
preceding_char: None,
width: columns,
height: rows,
should_render: true,
Expand Down Expand Up @@ -245,6 +247,26 @@ impl Grid {
empty_character.styles = styles;
self.pad_current_line_until(self.cursor.x);
}
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);
}
match previous_tabstop {
Some(tabstop) => {
self.cursor.x = *tabstop;
}
None => {
self.cursor.x = 0;
}
}
}
pub fn cursor_shape(&self) -> CursorShape {
self.cursor.get_shape()
}
fn set_horizontal_tabstop(&mut self) {
self.horizontal_tabstops.insert(self.cursor.x);
}
Expand Down Expand Up @@ -925,6 +947,10 @@ impl Grid {
self.active_charset = Default::default();
self.erasure_mode = false;
self.disable_linewrap = false;
self.cursor.change_shape(CursorShape::Block);
}
fn set_preceding_character(&mut self, terminal_character: TerminalCharacter) {
self.preceding_char = Some(terminal_character);
}
}

Expand All @@ -937,6 +963,7 @@ impl Perform for Grid {
character: c,
styles: self.cursor.pending_styles,
};
self.set_preceding_character(terminal_character);
self.add_character(terminal_character);
}

Expand All @@ -950,9 +977,10 @@ impl Perform for Grid {
// tab
self.advance_to_next_tabstop(self.cursor.pending_styles);
}
10 | 11 => {
10 | 11 | 12 => {
// 0a, newline
// 0b, vertical tabulation
// 0c, form feed
self.add_newline();
}
13 => {
Expand Down Expand Up @@ -985,7 +1013,7 @@ impl Perform for Grid {
// TBD
}

fn csi_dispatch(&mut self, params: &Params, _intermediates: &[u8], _ignore: bool, c: char) {
fn csi_dispatch(&mut self, params: &Params, intermediates: &[u8], _ignore: bool, c: char) {
let mut params_iter = params.iter();
let mut next_param_or = |default: u16| {
params_iter
Expand All @@ -998,7 +1026,7 @@ impl Perform for Grid {
self.cursor
.pending_styles
.add_style_from_ansi_params(&mut params_iter);
} else if c == 'C' {
} else if c == 'C' || c == 'a' {
// move cursor forward
let move_by = next_param_or(1);
self.move_cursor_forward_until_edge(move_by);
Expand Down Expand Up @@ -1031,7 +1059,6 @@ impl Perform for Grid {
self.clear_all(char_to_replace);
}
};
// TODO: implement 1
} else if c == 'H' || c == 'f' {
// goto row/col
// we subtract 1 from the row/column because these are 1 indexed
Expand All @@ -1043,7 +1070,7 @@ impl Perform for Grid {
// move cursor up until edge of screen
let move_up_count = next_param_or(1);
self.move_cursor_up(move_up_count as usize);
} else if c == 'B' {
} else if c == 'B' || c == 'e' {
// move cursor down until edge of screen
let move_down_count = next_param_or(1);
let pad_character = EMPTY_TERMINAL_CHARACTER;
Expand All @@ -1052,7 +1079,7 @@ impl Perform for Grid {
let move_back_count = next_param_or(1);
self.move_cursor_back(move_back_count);
} else if c == 'l' {
let first_intermediate_is_questionmark = match _intermediates.get(0) {
let first_intermediate_is_questionmark = match intermediates.get(0) {
Some(b'?') => true,
None => false,
_ => false,
Expand Down Expand Up @@ -1101,7 +1128,7 @@ impl Perform for Grid {
self.insert_mode = false;
}
} else if c == 'h' {
let first_intermediate_is_questionmark = match _intermediates.get(0) {
let first_intermediate_is_questionmark = match intermediates.get(0) {
Some(b'?') => true,
None => false,
_ => false,
Expand Down Expand Up @@ -1171,7 +1198,7 @@ impl Perform for Grid {
let line_count_to_add = next_param_or(1);
let pad_character = EMPTY_TERMINAL_CHARACTER;
self.add_empty_lines_in_scroll_region(line_count_to_add, pad_character);
} else if c == 'G' {
} else if c == 'G' || c == '`' {
let column = next_param_or(1).saturating_sub(1);
self.move_cursor_to_column(column);
} else if c == 'g' {
Expand Down Expand Up @@ -1216,6 +1243,46 @@ impl Perform for Grid {
// TODO: should this be styled?
self.insert_character_at_cursor_position(EMPTY_TERMINAL_CHARACTER);
}
} else if c == 'b' {
if let Some(c) = self.preceding_char {
for _ in 0..next_param_or(1) {
self.add_character(c);
}
}
} else if c == 'E' {
let count = next_param_or(1);
let pad_character = EMPTY_TERMINAL_CHARACTER;
self.move_cursor_down(count, pad_character);
} else if c == 'F' {
let count = next_param_or(1);
self.move_cursor_up(count);
self.move_cursor_to_beginning_of_line();
} else if c == 'I' {
for _ in 0..next_param_or(1) {
self.advance_to_next_tabstop(self.cursor.pending_styles);
}
} else if c == 'q' {
let first_intermediate_is_space = matches!(intermediates.get(0), Some(b' '));
if first_intermediate_is_space {
// DECSCUSR (CSI Ps SP q) -- Set Cursor Style.
let cursor_style_id = next_param_or(0);
let shape = match cursor_style_id {
0 | 2 => Some(CursorShape::Block),
1 => Some(CursorShape::BlinkingBlock),
3 => Some(CursorShape::BlinkingUnderline),
4 => Some(CursorShape::Underline),
5 => Some(CursorShape::BlinkingBeam),
6 => Some(CursorShape::Beam),
_ => None,
};
if let Some(cursor_shape) = shape {
self.cursor.change_shape(cursor_shape);
}
}
} else if c == 'Z' {
for _ in 0..next_param_or(1) {
self.move_to_previous_tabstop();
}
} else {
let result = debug_log_to_file(format!("Unhandled csi: {}->{:?}", c, params));
#[cfg(not(test))]
Expand Down Expand Up @@ -1262,6 +1329,7 @@ impl Perform for Grid {
self.move_cursor_to_beginning_of_line();
}
(b'M', None) => {
// TODO: if cursor is at the top, it should go down one
self.move_cursor_up_with_scrolling(1);
}
(b'c', None) => {
Expand Down
18 changes: 18 additions & 0 deletions src/client/panes/terminal_character.rs
Original file line number Diff line number Diff line change
Expand Up @@ -701,13 +701,24 @@ impl IndexMut<CharsetIndex> for Charsets {
}
}

#[derive(Clone, Copy, Debug)]
pub enum CursorShape {
Block,
BlinkingBlock,
Underline,
BlinkingUnderline,
Beam,
BlinkingBeam,
}

#[derive(Clone, Debug)]
pub struct Cursor {
pub x: usize,
pub y: usize,
pub is_hidden: bool,
pub pending_styles: CharacterStyles,
pub charsets: Charsets,
shape: CursorShape,
}

impl Cursor {
Expand All @@ -718,8 +729,15 @@ impl Cursor {
is_hidden: false,
pending_styles: CharacterStyles::new(),
charsets: Default::default(),
shape: CursorShape::Block,
}
}
pub fn change_shape(&mut self, shape: CursorShape) {
self.shape = shape;
}
pub fn get_shape(&self) -> CursorShape {
self.shape
}
}

#[derive(Clone, Copy)]
Expand Down
12 changes: 11 additions & 1 deletion src/client/panes/terminal_pane.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use serde::{Deserialize, Serialize};

use crate::panes::grid::Grid;
use crate::panes::terminal_character::{
CharacterStyles, TerminalCharacter, EMPTY_TERMINAL_CHARACTER,
CharacterStyles, CursorShape, TerminalCharacter, EMPTY_TERMINAL_CHARACTER,
};
use crate::pty::VteBytes;
use crate::tab::Pane;
Expand Down Expand Up @@ -291,6 +291,16 @@ impl Pane for TerminalPane {
fn set_active_at(&mut self, time: Instant) {
self.active_at = time;
}
fn cursor_shape_csi(&self) -> String {
match self.grid.cursor_shape() {
CursorShape::Block => "\u{1b}[0 q".to_string(),
CursorShape::BlinkingBlock => "\u{1b}[1 q".to_string(),
CursorShape::Underline => "\u{1b}[4 q".to_string(),
CursorShape::BlinkingUnderline => "\u{1b}[3 q".to_string(),
CursorShape::Beam => "\u{1b}[6 q".to_string(),
CursorShape::BlinkingBeam => "\u{1b}[5 q".to_string(),
}
}
}

impl TerminalPane {
Expand Down
36 changes: 36 additions & 0 deletions src/client/panes/unit/grid_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -347,3 +347,39 @@ fn vttest8_5() {
}
assert_snapshot!(format!("{:?}", grid));
}

#[test]
fn csi_b() {
let mut vte_parser = vte::Parser::new();
let mut grid = Grid::new(51, 97);
let fixture_name = "csi-b";
let content = read_fixture(fixture_name);
for byte in content {
vte_parser.advance(&mut grid, byte);
}
assert_snapshot!(format!("{:?}", grid));
}

#[test]
fn csi_capital_i() {
let mut vte_parser = vte::Parser::new();
let mut grid = Grid::new(51, 97);
let fixture_name = "csi-capital-i";
let content = read_fixture(fixture_name);
for byte in content {
vte_parser.advance(&mut grid, byte);
}
assert_snapshot!(format!("{:?}", grid));
}

#[test]
fn csi_capital_z() {
let mut vte_parser = vte::Parser::new();
let mut grid = Grid::new(51, 97);
let fixture_name = "csi-capital-z";
let content = read_fixture(fixture_name);
for byte in content {
vte_parser.advance(&mut grid, byte);
}
assert_snapshot!(format!("{:?}", grid));
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
source: src/client/panes/./unit/grid_tests.rs
expression: "format!(\"{:?}\", grid)"

---
00 (C): ffffff
01 (C):

Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
source: src/client/panes/./unit/grid_tests.rs
expression: "format!(\"{:?}\", grid)"

---
00 (C): foo
01 (C):

Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
source: src/client/panes/./unit/grid_tests.rs
expression: "format!(\"{:?}\", grid)"

---
00 (C): 12345678foo234567890
01 (C):

9 changes: 7 additions & 2 deletions src/client/tab.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,9 @@ pub trait Pane {
fn clear_scroll(&mut self);
fn active_at(&self) -> Instant;
fn set_active_at(&mut self, instant: Instant);
fn cursor_shape_csi(&self) -> String {
"\u{1b}[0 q".to_string() // default to non blinking block
}

fn right_boundary_x_coords(&self) -> usize {
self.x() + self.columns()
Expand Down Expand Up @@ -762,10 +765,12 @@ impl Tab {
match self.get_active_terminal_cursor_position() {
Some((cursor_position_x, cursor_position_y)) => {
let show_cursor = "\u{1b}[?25h";
let change_cursor_shape = self.get_active_pane().unwrap().cursor_shape_csi();
let goto_cursor_position = &format!(
"\u{1b}[{};{}H\u{1b}[m",
"\u{1b}[{};{}H\u{1b}[m{}",
cursor_position_y + 1,
cursor_position_x + 1
cursor_position_x + 1,
change_cursor_shape
); // goto row/col
output.push_str(show_cursor);
output.push_str(goto_cursor_position);
Expand Down
1 change: 1 addition & 0 deletions src/tests/fixtures/csi-b
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
f
1 change: 1 addition & 0 deletions src/tests/fixtures/csi-capital-i
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
foo
1 change: 1 addition & 0 deletions src/tests/fixtures/csi-capital-z
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
12345678901234567890foo

0 comments on commit 4b39699

Please sign in to comment.