From 44d67de187640b0064716050f082be2f330d8df5 Mon Sep 17 00:00:00 2001 From: Aram Drevekenin Date: Wed, 26 May 2021 18:05:43 +0200 Subject: fix(compatibility): support wide characters (#535) * fix(compatibility): support wide characters * style(fmt): rustfmt * style(fmt): make clippy happy --- src/tests/fixtures/bash_delete_wide_characters | 3 + .../fixtures/delete_wide_character_under_cursor | 1 + .../fixtures/delete_wide_characters_before_cursor | 1 + ..._before_cursor_when_cursor_is_on_wide_character | 1 + .../fixtures/fish_wide_characters_override_clock | 2 + .../fixtures/replace_wide_character_under_cursor | 1 + src/tests/fixtures/wide_characters | 2 + src/tests/fixtures/wide_characters_full | 31 ++++ src/tests/fixtures/wide_characters_line_end | 30 ++++ src/tests/fixtures/wide_characters_line_middle | 30 ++++ src/tests/fixtures/wide_characters_line_wrap | 3 + zellij-server/src/panes/grid.rs | 181 ++++++++++++++++----- zellij-server/src/panes/plugin_pane.rs | 3 - zellij-server/src/panes/terminal_character.rs | 14 +- zellij-server/src/panes/terminal_pane.rs | 3 - zellij-server/src/panes/unit/grid_tests.rs | 159 ++++++++++++++++++ ...d__grid_tests__bash_delete_wide_characters.snap | 9 + ..._tests__delete_wide_character_under_cursor.snap | 8 + ...ests__delete_wide_characters_before_cursor.snap | 7 + ...re_cursor_when_cursor_is_on_wide_character.snap | 7 + ...tests__fish_wide_characters_override_clock.snap | 8 + ...tests__replace_wide_character_under_cursor.snap | 8 + ...sts__unwrap_wide_characters_on_size_change.snap | 27 +++ ...server__panes__grid__grid_tests__vttest8_1.snap | 2 +- ...server__panes__grid__grid_tests__vttest8_2.snap | 2 +- ...server__panes__grid__grid_tests__vttest8_3.snap | 48 +++--- ...server__panes__grid__grid_tests__vttest8_4.snap | 48 +++--- ...__panes__grid__grid_tests__wide_characters.snap | 8 + ...rid__grid_tests__wide_characters_line_wrap.snap | 10 ++ ...es__grid__grid_tests__wrap_wide_characters.snap | 27 +++ ...rap_wide_characters_at_the_end_of_the_line.snap | 27 +++ ..._wide_characters_in_the_middle_of_the_line.snap | 27 +++ ...tests__wrap_wide_characters_on_size_change.snap | 27 +++ zellij-server/src/tab.rs | 11 -- 34 files changed, 659 insertions(+), 117 deletions(-) create mode 100755 src/tests/fixtures/bash_delete_wide_characters create mode 100644 src/tests/fixtures/delete_wide_character_under_cursor create mode 100644 src/tests/fixtures/delete_wide_characters_before_cursor create mode 100644 src/tests/fixtures/delete_wide_characters_before_cursor_when_cursor_is_on_wide_character create mode 100755 src/tests/fixtures/fish_wide_characters_override_clock create mode 100644 src/tests/fixtures/replace_wide_character_under_cursor create mode 100755 src/tests/fixtures/wide_characters create mode 100644 src/tests/fixtures/wide_characters_full create mode 100644 src/tests/fixtures/wide_characters_line_end create mode 100644 src/tests/fixtures/wide_characters_line_middle create mode 100755 src/tests/fixtures/wide_characters_line_wrap create mode 100644 zellij-server/src/panes/unit/snapshots/zellij_server__panes__grid__grid_tests__bash_delete_wide_characters.snap create mode 100644 zellij-server/src/panes/unit/snapshots/zellij_server__panes__grid__grid_tests__delete_wide_character_under_cursor.snap create mode 100644 zellij-server/src/panes/unit/snapshots/zellij_server__panes__grid__grid_tests__delete_wide_characters_before_cursor.snap create mode 100644 zellij-server/src/panes/unit/snapshots/zellij_server__panes__grid__grid_tests__delete_wide_characters_before_cursor_when_cursor_is_on_wide_character.snap create mode 100644 zellij-server/src/panes/unit/snapshots/zellij_server__panes__grid__grid_tests__fish_wide_characters_override_clock.snap create mode 100644 zellij-server/src/panes/unit/snapshots/zellij_server__panes__grid__grid_tests__replace_wide_character_under_cursor.snap create mode 100644 zellij-server/src/panes/unit/snapshots/zellij_server__panes__grid__grid_tests__unwrap_wide_characters_on_size_change.snap create mode 100644 zellij-server/src/panes/unit/snapshots/zellij_server__panes__grid__grid_tests__wide_characters.snap create mode 100644 zellij-server/src/panes/unit/snapshots/zellij_server__panes__grid__grid_tests__wide_characters_line_wrap.snap create mode 100644 zellij-server/src/panes/unit/snapshots/zellij_server__panes__grid__grid_tests__wrap_wide_characters.snap create mode 100644 zellij-server/src/panes/unit/snapshots/zellij_server__panes__grid__grid_tests__wrap_wide_characters_at_the_end_of_the_line.snap create mode 100644 zellij-server/src/panes/unit/snapshots/zellij_server__panes__grid__grid_tests__wrap_wide_characters_in_the_middle_of_the_line.snap create mode 100644 zellij-server/src/panes/unit/snapshots/zellij_server__panes__grid__grid_tests__wrap_wide_characters_on_size_change.snap diff --git a/src/tests/fixtures/bash_delete_wide_characters b/src/tests/fixtures/bash_delete_wide_characters new file mode 100755 index 000000000..193761916 --- /dev/null +++ b/src/tests/fixtures/bash_delete_wide_characters @@ -0,0 +1,3 @@ +⏎(B ⏎ Welcome to fish, the friendly interactive shell +[?2004h]0;fish /home/aram/code/zellij(B⋊>(B ~/c/zellij(B on wide-char(B ⨯ 15:35:20(B   b15:35:20(B  b(B15:35:20(B  ash(B15:35:20(B  ash(B15:35:20(B  sh(B15:35:20(B  h(B15:35:20(B  bash(B15:35:20(B  15:35:20(B   +(B[?2004l]0;bash /home/aram/code/zellij(B [?2004h[aram@green zellij]$ HHHHHHH \ No newline at end of file diff --git a/src/tests/fixtures/delete_wide_character_under_cursor b/src/tests/fixtures/delete_wide_character_under_cursor new file mode 100644 index 000000000..13f3e84dc --- /dev/null +++ b/src/tests/fixtures/delete_wide_character_under_cursor @@ -0,0 +1 @@ +12H4 diff --git a/src/tests/fixtures/delete_wide_characters_before_cursor b/src/tests/fixtures/delete_wide_characters_before_cursor new file mode 100644 index 000000000..dfdad4b94 --- /dev/null +++ b/src/tests/fixtures/delete_wide_characters_before_cursor @@ -0,0 +1 @@ +Hi there HiHi \ No newline at end of file diff --git a/src/tests/fixtures/delete_wide_characters_before_cursor_when_cursor_is_on_wide_character b/src/tests/fixtures/delete_wide_characters_before_cursor_when_cursor_is_on_wide_character new file mode 100644 index 000000000..4d0c1ffed --- /dev/null +++ b/src/tests/fixtures/delete_wide_characters_before_cursor_when_cursor_is_on_wide_character @@ -0,0 +1 @@ +Hi there HiHi \ No newline at end of file diff --git a/src/tests/fixtures/fish_wide_characters_override_clock b/src/tests/fixtures/fish_wide_characters_override_clock new file mode 100755 index 000000000..bad6143a4 --- /dev/null +++ b/src/tests/fixtures/fish_wide_characters_override_clock @@ -0,0 +1,2 @@ +⏎(B ⏎ Welcome to fish, the friendly interactive shell +[?2004h]0;fish /home/aram/code/zellij(B⋊>(B ~/c/zellij(B on main(B ⨯ 15:53:10(B   H15:53:10(B  H(B15:53:10(B  H(B15:53:10(B  H(B15:53:10(B  H(B15:53:10(B  H(B15:53:10(B  H(B15:53:10(B  H(B15:53:10(B  H(B15:53:10(B  H(B15:53:10(B  H(B15:53:10(B  H(B15:53:10(B  H(B15:53:10(B  H(B15:53:10(B  H(B15:53:10(B  H(B15:53:10(B  H(B15:53:10(B  H(B15:53:10(B  H(B15:53:10(B  H(B15:53:10(B  H(B15:53:10(B  H(B15:53:10(B  H(B15:53:10(B  H(B15:53:10(B  H(B15:53:10(B  H(B15:53:10(B  H(B15:53:10(B  H(B15:53:10(B  H(B15:53:10(B  H(B15:53:10(B  H(B15:53:10(B  H(B15:53:10(B  H(B15:53:10(B  H(B15:53:10(B  H(B15:53:10(B  H(B15:53:10(B  H(B15:53:10(B  H(B \ No newline at end of file diff --git a/src/tests/fixtures/replace_wide_character_under_cursor b/src/tests/fixtures/replace_wide_character_under_cursor new file mode 100644 index 000000000..1759e0848 --- /dev/null +++ b/src/tests/fixtures/replace_wide_character_under_cursor @@ -0,0 +1 @@ +12H4 diff --git a/src/tests/fixtures/wide_characters b/src/tests/fixtures/wide_characters new file mode 100755 index 000000000..ece8e61b6 --- /dev/null +++ b/src/tests/fixtures/wide_characters @@ -0,0 +1,2 @@ +⏎(B ⏎ Welcome to fish, the friendly interactive shell +[?2004h]0;fish /home/aram/code/zellij(B⋊>(B ~/c/zellij(B on main(B ⨯ 15:19:10(B   H15:19:10(B  H(B15:19:10(B  H(B15:19:10(B  H(B15:19:10(B  H(B15:19:10(B  H(B15:19:10(B  H(B15:19:10(B  H(B15:19:10(B   \ No newline at end of file diff --git a/src/tests/fixtures/wide_characters_full b/src/tests/fixtures/wide_characters_full new file mode 100644 index 000000000..a83b5eb24 --- /dev/null +++ b/src/tests/fixtures/wide_characters_full @@ -0,0 +1,31 @@ + HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH + eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee + llllllllllllllllllllllllllllllllllllllllllllll + llllllllllllllllllllllllllllllllllllllllllllll + oooooooooooooooooooooooooooooooooooooooooooooo + HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH + eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee + llllllllllllllllllllllllllllllllllllllllllllll + llllllllllllllllllllllllllllllllllllllllllllll + oooooooooooooooooooooooooooooooooooooooooooooo + HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH + eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee + llllllllllllllllllllllllllllllllllllllllllllll + llllllllllllllllllllllllllllllllllllllllllllll + oooooooooooooooooooooooooooooooooooooooooooooo + HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH + eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee + llllllllllllllllllllllllllllllllllllllllllllll + llllllllllllllllllllllllllllllllllllllllllllll + oooooooooooooooooooooooooooooooooooooooooooooo + HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH + eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee + llllllllllllllllllllllllllllllllllllllllllllll + llllllllllllllllllllllllllllllllllllllllllllll + oooooooooooooooooooooooooooooooooooooooooooooo + HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH + eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee + llllllllllllllllllllllllllllllllllllllllllllll + llllllllllllllllllllllllllllllllllllllllllllll + oooooooooooooooooooooooooooooooooooooooooooooo + diff --git a/src/tests/fixtures/wide_characters_line_end b/src/tests/fixtures/wide_characters_line_end new file mode 100644 index 000000000..a0c771453 --- /dev/null +++ b/src/tests/fixtures/wide_characters_line_end @@ -0,0 +1,30 @@ + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaH + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaae + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaal + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaal + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaao + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaH + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaae + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaal + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaal + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaao + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaH + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaae + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaal + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaal + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaao + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaH + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaae + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaal + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaal + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaao + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaH + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaae + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaal + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaal + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaao + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaH + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaae + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaal + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaal + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaao diff --git a/src/tests/fixtures/wide_characters_line_middle b/src/tests/fixtures/wide_characters_line_middle new file mode 100644 index 000000000..85629ebe6 --- /dev/null +++ b/src/tests/fixtures/wide_characters_line_middle @@ -0,0 +1,30 @@ + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaHaaaa + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaaa + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalaaaa + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalaaaa + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaoaaaa + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaHaaaa + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaaa + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalaaaa + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalaaaa + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaoaaaa + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaHaaaa + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaaa + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalaaaa + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalaaaa + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaoaaaa + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaHaaaa + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaaa + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalaaaa + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalaaaa + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaoaaaa + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaHaaaa + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaaa + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalaaaa + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalaaaa + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaoaaaa + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaHaaaa + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaaa + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalaaaa + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalaaaa + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaoaaaa diff --git a/src/tests/fixtures/wide_characters_line_wrap b/src/tests/fixtures/wide_characters_line_wrap new file mode 100755 index 000000000..2888600b8 --- /dev/null +++ b/src/tests/fixtures/wide_characters_line_wrap @@ -0,0 +1,3 @@ +⏎(B ⏎ Welcome to fish, the friendly interactive shell +[?2004h]0;fish /home/aram/code/zellij(B⋊>(B ~/c/zellij(B on main(B ⨯ 15:50:11(B   b15:50:11(B  b(B15:50:11(B  ash(B15:50:11(B  ash(B15:50:11(B  sh(B15:50:11(B  h(B15:50:11(B  bash(B15:50:11(B  15:50:11(B   +(B[?2004l]0;bash /home/aram/code/zellij(B [?2004h[aram@green zellij]$ HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH HHHHH \ No newline at end of file diff --git a/zellij-server/src/panes/grid.rs b/zellij-server/src/panes/grid.rs index ac347db0e..14bdbcd16 100644 --- a/zellij-server/src/panes/grid.rs +++ b/zellij-server/src/panes/grid.rs @@ -1,3 +1,5 @@ +use unicode_width::UnicodeWidthChar; + use std::{ cmp::Ordering, collections::{BTreeSet, VecDeque}, @@ -251,9 +253,6 @@ impl Grid { colors, } } - pub fn contains_widechar(&self) -> bool { - self.viewport.iter().any(|c| c.contains_widechar()) - } pub fn advance_to_next_tabstop(&mut self, styles: CharacterStyles) { let mut next_tabstop = None; for tabstop in self.horizontal_tabstops.iter() { @@ -421,12 +420,12 @@ impl Grid { canonical_line_parts.push(Row::new().canonical()); } while !canonical_line.columns.is_empty() { - let next_wrap = if canonical_line.len() > new_columns { - canonical_line.columns.drain(..new_columns) + let next_wrap = if canonical_line.width() > new_columns { + canonical_line.drain_until(new_columns) } else { - canonical_line.columns.drain(..) + canonical_line.columns.drain(..).collect() }; - let row = Row::from_columns(next_wrap.collect()); + let row = Row::from_columns(next_wrap); // if there are no more parts, this row is canonical as long as it originally // was canonical (it might not have been for example if it's the first row in // the viewport, and the actual canonical row is above it in the scrollback) @@ -522,9 +521,13 @@ impl Grid { .viewport .iter() .map(|r| { + let excess_width = r.excess_width(); let mut line: Vec = r.columns.iter().copied().collect(); // pad line - line.resize(self.width, EMPTY_TERMINAL_CHARACTER); + line.resize( + self.width.saturating_sub(excess_width), + EMPTY_TERMINAL_CHARACTER, + ); line }) .collect(); @@ -657,7 +660,11 @@ impl Grid { } } } - pub fn add_character_at_cursor_position(&mut self, terminal_character: TerminalCharacter) { + pub fn add_character_at_cursor_position( + &mut self, + terminal_character: TerminalCharacter, + max_width: usize, + ) { match self.viewport.get_mut(self.cursor.y) { Some(row) => { if self.insert_mode { @@ -665,6 +672,7 @@ impl Grid { } else { row.add_character_at(terminal_character, self.cursor.x); } + row.truncate(max_width); } None => { // pad lines until cursor if they do not exist @@ -678,6 +686,7 @@ impl Grid { } pub fn add_character(&mut self, terminal_character: TerminalCharacter) { // TODO: try to separate adding characters from moving the cursors in this function + let character_width = terminal_character.width; if self.cursor.x >= self.width { if self.disable_linewrap { return; @@ -703,8 +712,8 @@ impl Grid { } } } - self.add_character_at_cursor_position(terminal_character); - self.move_cursor_forward_until_edge(1); + self.add_character_at_cursor_position(terminal_character, self.width); + self.move_cursor_forward_until_edge(character_width); } pub fn move_cursor_forward_until_edge(&mut self, count: usize) { let count_to_move = std::cmp::min(count, self.width - (self.cursor.x)); @@ -714,19 +723,11 @@ impl Grid { self.viewport .get_mut(self.cursor.y) .unwrap() - .truncate(self.cursor.x); - if self.cursor.x < self.width - 1 { - let mut characters_to_append = vec![replace_with; self.width - self.cursor.x]; - self.viewport - .get_mut(self.cursor.y) - .unwrap() - .append(&mut characters_to_append); - } + .replace_and_pad_end(self.cursor.x, self.width, replace_with); } pub fn replace_characters_in_line_before_cursor(&mut self, replace_with: TerminalCharacter) { - let line_part = vec![replace_with; self.cursor.x + 1]; let row = self.viewport.get_mut(self.cursor.y).unwrap(); - row.replace_beginning_with(line_part); + row.replace_and_pad_beginning(self.cursor.x, replace_with); } pub fn clear_all_after_cursor(&mut self, replace_with: TerminalCharacter) { if let Some(cursor_row) = self.viewport.get_mut(self.cursor.y) { @@ -946,13 +947,15 @@ impl Grid { empty_character.styles = empty_char_style; let current_row = self.viewport.get_mut(self.cursor.y).unwrap(); for _ in 0..count { - current_row.delete_character(self.cursor.x); + let deleted_character = current_row.delete_and_return_character(self.cursor.x); + let excess_width = deleted_character + .map(|terminal_character| terminal_character.width) + .unwrap_or(0) + .saturating_sub(1); + for _ in 0..excess_width { + current_row.insert_character_at(empty_character, self.cursor.x); + } } - let mut empty_space_to_append = vec![empty_character; count]; - self.viewport - .get_mut(self.cursor.y) - .unwrap() - .append(&mut empty_space_to_append); } fn add_newline(&mut self) { self.add_canonical_line(); @@ -988,6 +991,7 @@ impl Perform for Grid { // is a little faster let terminal_character = TerminalCharacter { character: c, + width: c.width().unwrap_or(0), styles: self.cursor.pending_styles, }; self.set_preceding_character(terminal_character); @@ -1628,20 +1632,47 @@ impl Row { self.is_canonical = true; self } - pub fn contains_widechar(&self) -> bool { - self.columns.iter().any(|c| c.is_widechar()) + pub fn width(&self) -> usize { + let mut width = 0; + for terminal_character in self.columns.iter() { + width += terminal_character.width; + } + width + } + pub fn excess_width(&self) -> usize { + let mut acc = 0; + for terminal_character in self.columns.iter() { + if terminal_character.width > 1 { + acc += terminal_character.width - 1; + } + } + acc + } + pub fn excess_width_until(&self, x: usize) -> usize { + let mut acc = 0; + for terminal_character in self.columns.iter().take(x) { + if terminal_character.width > 1 { + acc += terminal_character.width - 1; + } + } + acc } pub fn add_character_at(&mut self, terminal_character: TerminalCharacter, x: usize) { - match self.columns.len().cmp(&x) { - Ordering::Equal => self.columns.push(terminal_character), + match self.width().cmp(&x) { + Ordering::Equal => { + self.columns.push(terminal_character); + } Ordering::Less => { - self.columns.resize(x, EMPTY_TERMINAL_CHARACTER); + let width_offset = self.excess_width_until(x); + self.columns + .resize(x.saturating_sub(width_offset), EMPTY_TERMINAL_CHARACTER); self.columns.push(terminal_character); } Ordering::Greater => { + let width_offset = self.excess_width_until(x); // this is much more performant than remove/insert self.columns.push(terminal_character); - self.columns.swap_remove(x); + self.columns.swap_remove(x.saturating_sub(width_offset)); } } } @@ -1661,7 +1692,11 @@ impl Row { // this is much more performant than remove/insert if x < self.columns.len() { self.columns.push(terminal_character); - self.columns.swap_remove(x); + let character = self.columns.swap_remove(x); + let excess_width = character.width.saturating_sub(1); + for _ in 0..excess_width { + self.columns.insert(x, terminal_character); + } } } pub fn replace_columns(&mut self, columns: Vec) { @@ -1671,12 +1706,77 @@ impl Row { self.columns.push(terminal_character); } pub fn truncate(&mut self, x: usize) { - self.columns.truncate(x); + let width_offset = self.excess_width_until(x); + let truncate_position = x.saturating_sub(width_offset); + if truncate_position < self.columns.len() { + self.columns.truncate(truncate_position); + } + } + pub fn position_accounting_for_widechars(&self, x: usize) -> usize { + let mut position = x; + for (index, terminal_character) in self.columns.iter().enumerate() { + if index == position { + break; + } + if terminal_character.width > 1 { + position = position.saturating_sub(terminal_character.width.saturating_sub(1)); + } + } + position + } + pub fn replace_and_pad_end( + &mut self, + from: usize, + to: usize, + terminal_character: TerminalCharacter, + ) { + let from_position_accounting_for_widechars = self.position_accounting_for_widechars(from); + let to_position_accounting_for_widechars = self.position_accounting_for_widechars(to); + let replacement_length = to_position_accounting_for_widechars + .saturating_sub(from_position_accounting_for_widechars); + let mut replace_with = vec![terminal_character; replacement_length]; + self.columns + .truncate(from_position_accounting_for_widechars); + self.columns.append(&mut replace_with); } pub fn append(&mut self, to_append: &mut Vec) { self.columns.append(to_append); } + pub fn drain_until(&mut self, x: usize) -> Vec { + let mut drained_part: Vec = vec![]; + let mut drained_part_len = 0; + loop { + if self.columns.is_empty() { + break; + } + let next_character_len = self.columns.get(0).unwrap().width; + if drained_part_len + next_character_len <= x { + drained_part.push(self.columns.remove(0)); + drained_part_len += next_character_len; + } else { + break; + } + } + drained_part + } + pub fn replace_and_pad_beginning(&mut self, to: usize, terminal_character: TerminalCharacter) { + let to_position_accounting_for_widechars = self.position_accounting_for_widechars(to); + let width_of_current_character = self + .columns + .get(to_position_accounting_for_widechars) + .map(|character| character.width) + .unwrap_or(1); + let mut replace_with = vec![terminal_character; to + width_of_current_character]; + if to_position_accounting_for_widechars > self.columns.len() { + self.columns.clear(); + } else { + drop(self.columns.drain(0..=to_position_accounting_for_widechars)); + } + replace_with.append(&mut self.columns); + self.columns = replace_with; + } pub fn replace_beginning_with(&mut self, mut line_part: Vec) { + // this assumes line_part has no wide characters if line_part.len() > self.columns.len() { self.columns.clear(); } else { @@ -1691,20 +1791,25 @@ impl Row { pub fn is_empty(&self) -> bool { self.columns.is_empty() } - pub fn delete_character(&mut self, x: usize) { + pub fn delete_and_return_character(&mut self, x: usize) -> Option { if x < self.columns.len() { - self.columns.remove(x); + Some(self.columns.remove(x)) + } else { + None } } pub fn split_to_rows_of_length(&mut self, max_row_length: usize) -> Vec { let mut parts: Vec = vec![]; let mut current_part: Vec = vec![]; + let mut current_part_len = 0; for character in self.columns.drain(..) { - if current_part.len() == max_row_length { + if current_part_len + character.width > max_row_length { parts.push(Row::from_columns(current_part)); current_part = vec![]; + current_part_len = 0; } current_part.push(character); + current_part_len += character.width; } if !current_part.is_empty() { parts.push(Row::from_columns(current_part)) diff --git a/zellij-server/src/panes/plugin_pane.rs b/zellij-server/src/panes/plugin_pane.rs index 5549a388f..e5c5e15de 100644 --- a/zellij-server/src/panes/plugin_pane.rs +++ b/zellij-server/src/panes/plugin_pane.rs @@ -99,9 +99,6 @@ impl Pane for PluginPane { fn position_and_size_override(&self) -> Option { self.position_and_size_override } - fn contains_widechar(&self) -> bool { - false - } fn should_render(&self) -> bool { self.should_render } diff --git a/zellij-server/src/panes/terminal_character.rs b/zellij-server/src/panes/terminal_character.rs index e6489eb42..ececb2a73 100644 --- a/zellij-server/src/panes/terminal_character.rs +++ b/zellij-server/src/panes/terminal_character.rs @@ -1,5 +1,3 @@ -use unicode_width::UnicodeWidthChar; - use std::convert::TryFrom; use std::fmt::{self, Debug, Display, Formatter}; use std::ops::{Index, IndexMut}; @@ -8,6 +6,7 @@ use zellij_utils::vte::ParamsIter; pub const EMPTY_TERMINAL_CHARACTER: TerminalCharacter = TerminalCharacter { character: ' ', + width: 1, styles: CharacterStyles { foreground: Some(AnsiCode::Reset), background: Some(AnsiCode::Reset), @@ -750,6 +749,7 @@ impl Cursor { pub struct TerminalCharacter { pub character: char, pub styles: CharacterStyles, + pub width: usize, } impl ::std::fmt::Debug for TerminalCharacter { @@ -758,16 +758,6 @@ impl ::std::fmt::Debug for TerminalCharacter { } } -impl TerminalCharacter { - pub fn width(&self) -> usize { - self.character.width().unwrap_or(0) - } - - pub fn is_widechar(&self) -> bool { - self.width() > 1 - } -} - fn parse_sgr_color(params: &mut dyn Iterator) -> Option { match params.next() { Some(2) => Some(AnsiCode::RgbCode(( diff --git a/zellij-server/src/panes/terminal_pane.rs b/zellij-server/src/panes/terminal_pane.rs index 7e45c77bb..32910618d 100644 --- a/zellij-server/src/panes/terminal_pane.rs +++ b/zellij-server/src/panes/terminal_pane.rs @@ -123,9 +123,6 @@ impl Pane for TerminalPane { fn position_and_size_override(&self) -> Option { self.position_and_size_override } - fn contains_widechar(&self) -> bool { - self.grid.contains_widechar() - } fn should_render(&self) -> bool { self.grid.should_render } diff --git a/zellij-server/src/panes/unit/grid_tests.rs b/zellij-server/src/panes/unit/grid_tests.rs index 1a1d7f5cc..bce67e062 100644 --- a/zellij-server/src/panes/unit/grid_tests.rs +++ b/zellij-server/src/panes/unit/grid_tests.rs @@ -396,3 +396,162 @@ fn terminal_reports() { } assert_snapshot!(format!("{:?}", grid.pending_messages_to_pty)); } + +#[test] +fn wide_characters() { + let mut vte_parser = vte::Parser::new(); + let mut grid = Grid::new(21, 104, Palette::default()); + let fixture_name = "wide_characters"; + let content = read_fixture(fixture_name); + for byte in content { + vte_parser.advance(&mut grid, byte); + } + assert_snapshot!(format!("{:?}", grid)); +} + +#[test] +fn wide_characters_line_wrap() { + let mut vte_parser = vte::Parser::new(); + let mut grid = Grid::new(21, 104, Palette::default()); + let fixture_name = "wide_characters_line_wrap"; + let content = read_fixture(fixture_name); + for byte in content { + vte_parser.advance(&mut grid, byte); + } + assert_snapshot!(format!("{:?}", grid)); +} + +#[test] +fn fish_wide_characters_override_clock() { + let mut vte_parser = vte::Parser::new(); + let mut grid = Grid::new(21, 104, Palette::default()); + let fixture_name = "fish_wide_characters_override_clock"; + let content = read_fixture(fixture_name); + for byte in content { + vte_parser.advance(&mut grid, byte); + } + assert_snapshot!(format!("{:?}", grid)); +} + +#[test] +fn bash_delete_wide_characters() { + let mut vte_parser = vte::Parser::new(); + let mut grid = Grid::new(21, 104, Palette::default()); + let fixture_name = "bash_delete_wide_characters"; + let content = read_fixture(fixture_name); + for byte in content { + vte_parser.advance(&mut grid, byte); + } + assert_snapshot!(format!("{:?}", grid)); +} + +#[test] +fn delete_wide_characters_before_cursor() { + let mut vte_parser = vte::Parser::new(); + let mut grid = Grid::new(21, 104, Palette::default()); + let fixture_name = "delete_wide_characters_before_cursor"; + let content = read_fixture(fixture_name); + for byte in content { + vte_parser.advance(&mut grid, byte); + } + assert_snapshot!(format!("{:?}", grid)); +} + +#[test] +fn delete_wide_characters_before_cursor_when_cursor_is_on_wide_character() { + let mut vte_parser = vte::Parser::new(); + let mut grid = Grid::new(21, 104, Palette::default()); + let fixture_name = "delete_wide_characters_before_cursor_when_cursor_is_on_wide_character"; + let content = read_fixture(fixture_name); + for byte in content { + vte_parser.advance(&mut grid, byte); + } + assert_snapshot!(format!("{:?}", grid)); +} + +#[test] +fn delete_wide_character_under_cursor() { + let mut vte_parser = vte::Parser::new(); + let mut grid = Grid::new(21, 104, Palette::default()); + let fixture_name = "delete_wide_character_under_cursor"; + let content = read_fixture(fixture_name); + for byte in content { + vte_parser.advance(&mut grid, byte); + } + assert_snapshot!(format!("{:?}", grid)); +} + +#[test] +fn replace_wide_character_under_cursor() { + let mut vte_parser = vte::Parser::new(); + let mut grid = Grid::new(21, 104, Palette::default()); + let fixture_name = "replace_wide_character_under_cursor"; + let content = read_fixture(fixture_name); + for byte in content { + vte_parser.advance(&mut grid, byte); + } + assert_snapshot!(format!("{:?}", grid)); +} + +#[test] +fn wrap_wide_characters() { + let mut vte_parser = vte::Parser::new(); + let mut grid = Grid::new(21, 90, Palette::default()); + let fixture_name = "wide_characters_full"; + let content = read_fixture(fixture_name); + for byte in content { + vte_parser.advance(&mut grid, byte); + } + assert_snapshot!(format!("{:?}", grid)); +} + +#[test] +fn wrap_wide_characters_on_size_change() { + let mut vte_parser = vte::Parser::new(); + let mut grid = Grid::new(21, 93, Palette::default()); + let fixture_name = "wide_characters_full"; + let content = read_fixture(fixture_name); + for byte in content { + vte_parser.advance(&mut grid, byte); + } + grid.change_size(21, 90); + assert_snapshot!(format!("{:?}", grid)); +} + +#[test] +fn unwrap_wide_characters_on_size_change() { + let mut vte_parser = vte::Parser::new(); + let mut grid = Grid::new(21, 93, Palette::default()); + let fixture_name = "wide_characters_full"; + let content = read_fixture(fixture_name); + for byte in content { + vte_parser.advance(&mut grid, byte); + } + grid.change_size(21, 90); + grid.change_size(21, 93); + assert_snapshot!(format!("{:?}", grid)); +} + +#[test] +fn wrap_wide_characters_in_the_middle_of_the_line() { + let mut vte_parser = vte::Parser::new(); + let mut grid = Grid::new(21, 91, Palette::default()); + let fixture_name = "wide_characters_line_middle"; + let content = read_fixture(fixture_name); + for byte in content { + vte_parser.advance(&mut grid, byte); + } + assert_snapshot!(format!("{:?}", grid)); +} + +#[test] +fn wrap_wide_characters_at_the_end_of_the_line() { + let mut vte_parser = vte::Parser::new(); + let mut grid = Grid::new(21, 90, Palette::default()); + let fixture_name = "wide_characters_line_end"; + let content = read_fixture(fixture_name); + for byte in content { + vte_parser.advance(&mut grid, byte); + } + assert_snapshot!(format!("{:?}", grid)); +} diff --git a/zellij-server/src/panes/unit/snapshots/zellij_server__panes__grid__grid_tests__bash_delete_wide_characters.snap b/zellij-server/src/panes/unit/snapshots/zellij_server__panes__grid__grid_tests__bash_delete_wide_characters.snap new file mode 100644 index 000000000..acb5a6083 --- /dev/null +++ b/zellij-server/src/panes/unit/snapshots/zellij_server__panes__grid__grid_tests__bash_delete_wide_characters.snap @@ -0,0 +1,9 @@ +--- +source: zellij-server/src/panes/./unit/grid_tests.rs +expression: "format!(\"{:?}\", grid)" + +--- +00 (C): Welcome to fish, the friendly interactive shell +01 (C): ⋊> ~/c/zellij on wide-char ⨯ bash 15:35:20 +02 (C): [aram@green zellij]$ HHHHHH + diff --git a/zellij-server/src/panes/unit/snapshots/zellij_server__panes__grid__grid_tests__delete_wide_character_under_cursor.snap b/zellij-server/src/panes/unit/snapshots/zellij_server__panes__grid__grid_tests__delete_wide_character_under_cursor.snap new file mode 100644 index 000000000..e6d26254f --- /dev/null +++ b/zellij-server/src/panes/unit/snapshots/zellij_server__panes__grid__grid_tests__delete_wide_character_under_cursor.snap @@ -0,0 +1,8 @@ +--- +source: zellij-server/src/panes/./unit/grid_tests.rs +expression: "format!(\"{:?}\", grid)" + +--- +00 (C): 12 4 +01 (C): + diff --git a/zellij-server/src/panes/unit/snapshots/zellij_server__panes__grid__grid_tests__delete_wide_characters_before_cursor.snap b/zellij-server/src/panes/unit/snapshots/zellij_server__panes__grid__grid_tests__delete_wide_characters_before_cursor.snap new file mode 100644 index 000000000..401650ad3 --- /dev/null +++ b/zellij-server/src/panes/unit/snapshots/zellij_server__panes__grid__grid_tests__delete_wide_characters_before_cursor.snap @@ -0,0 +1,7 @@ +--- +source: zellij-server/src/panes/./unit/grid_tests.rs +expression: "format!(\"{:?}\", grid)" + +--- +00 (C): Hi + diff --git a/zellij-server/src/panes/unit/snapshots/zellij_server__panes__grid__grid_tests__delete_wide_characters_before_cursor_when_cursor_is_on_wide_character.snap b/zellij-server/src/panes/unit/snapshots/zellij_server__panes__grid__grid_tests__delete_wide_characters_before_cursor_when_cursor_is_on_wide_character.snap new file mode 100644 index 000000000..ae1d8a652 --- /dev/null +++ b/zellij-server/src/panes/unit/snapshots/zellij_server__panes__grid__grid_tests__delete_wide_characters_before_cursor_when_cursor_is_on_wide_character.snap @@ -0,0 +1,7 @@ +--- +source: zellij-server/src/panes/./unit/grid_tests.rs +expression: "format!(\"{:?}\", grid)" + +--- +00 (C): i + diff --git a/zellij-server/src/panes/unit/snapshots/zellij_server__panes__grid__grid_tests__fish_wide_characters_override_clock.snap b/zellij-server/src/panes/unit/snapshots/zellij_server__panes__grid__grid_tests__fish_wide_characters_override_clock.snap new file mode 100644 index 000000000..a328b18ca --- /dev/null +++ b/zellij-server/src/panes/unit/snapshots/zellij_server__panes__grid__grid_tests__fish_wide_characters_override_clock.snap @@ -0,0 +1,8 @@ +--- +source: zellij-server/src/panes/./unit/grid_tests.rs +expression: "format!(\"{:?}\", grid)" + +--- +00 (C): Welcome to fish, the friendly interactive shell +01 (C): ⋊> ~/c/zellij on main ⨯ HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH + diff --git a/zellij-server/src/panes/unit/snapshots/zellij_server__panes__grid__grid_tests__replace_wide_character_under_cursor.snap b/zellij-server/src/panes/unit/snapshots/zellij_server__panes__grid__grid_tests__replace_wide_character_under_cursor.snap new file mode 100644 index 000000000..3b664aaf9 --- /dev/null +++ b/zellij-server/src/panes/unit/snapshots/zellij_server__panes__grid__grid_tests__replace_wide_character_under_cursor.snap @@ -0,0 +1,8 @@ +--- +source: zellij-server/src/panes/./unit/grid_tests.rs +expression: "format!(\"{:?}\", grid)" + +--- +00 (C): 12 4 +01 (C): + diff --git a/zellij-server/src/panes/unit/snapshots/zellij_server__panes__grid__grid_tests__unwrap_wide_characters_on_size_change.snap b/zellij-server/src/panes/unit/snapshots/zellij_server__panes__grid__grid_tests__unwrap_wide_characters_on_size_change.snap new file mode 100644 index 000000000..0d569d33c --- /dev/null +++ b/zellij-server/src/panes/unit/snapshots/zellij_server__panes__grid__grid_tests__unwrap_wide_characters_on_size_change.snap @@ -0,0 +1,27 @@ +--- +source: zellij-server/src/panes/./unit/grid_tests.rs +expression: "format!(\"{:?}\", grid)" + +--- +00 (C): eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee +01 (C): llllllllllllllllllllllllllllllllllllllllllllll +02 (C): llllllllllllllllllllllllllllllllllllllllllllll +03 (C): oooooooooooooooooooooooooooooooooooooooooooooo +04 (C): HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH +05 (C): eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee +06 (C): llllllllllllllllllllllllllllllllllllllllllllll +07 (C): llllllllllllllllllllllllllllllllllllllllllllll +08 (C): oooooooooooooooooooooooooooooooooooooooooooooo +09 (C): HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH +10 (C): eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee +11 (C): llllllllllllllllllllllllllllllllllllllllllllll +12 (C): llllllllllllllllllllllllllllllllllllllllllllll +13 (C): oooooooooooooooooooooooooooooooooooooooooooooo +14 (C): HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH +15 (C): eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee +16 (C): llllllllllllllllllllllllllllllllllllllllllllll +17 (C): llllllllllllllllllllllllllllllllllllllllllllll +18 (C): oooooooooooooooooooooooooooooooooooooooooooooo +19 (C): +20 (C): + diff --git a/zellij-server/src/panes/unit/snapshots/zellij_server__panes__grid__grid_tests__vttest8_1.snap b/zellij-server/src/panes/unit/snapshots/zellij_server__panes__grid__grid_tests__vttest8_1.snap index 4381306b8..812ea93de 100644 --- a/zellij-server/src/panes/unit/snapshots/zellij_server__panes__grid__grid_tests__vttest8_1.snap +++ b/zellij-server/src/panes/unit/snapshots/zellij_server__panes__grid__grid_tests__vttest8_1.snap @@ -3,7 +3,7 @@ source: zellij-server/src/panes/./unit/grid_tests.rs expression: "format!(\"{:?}\", grid)" --- -00 (C): A******************************************************************************BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +00 (C): A******************************************************************************BAAAAAAAAAAAAAAAAA 01 (C): 02 (C): 03 (C): Test of 'Insert Mode'. The top line should be 'A*** ... ***B'. Push diff --git a/zellij-server/src/panes/unit/snapshots/zellij_server__panes__grid__grid_tests__vttest8_2.snap b/zellij-server/src/panes/unit/snapshots/zellij_server__panes__grid__grid_tests__vttest8_2.snap index b65ed724f..ae9079444 100644 --- a/zellij-server/src/panes/unit/snapshots/zellij_server__panes__grid__grid_tests__vttest8_2.snap +++ b/zellij-server/src/panes/unit/snapshots/zellij_server__panes__grid__grid_tests__vttest8_2.snap @@ -3,7 +3,7 @@ source: zellij-server/src/panes/./unit/grid_tests.rs expression: "format!(\"{:?}\", grid)" --- -00 (C): ABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +00 (C): ABAAAAAAAAAAAAAAAAA 01 (C): 02 (C): 03 (C): Test of 'Delete Character'. The top line should be 'AB'. Push diff --git a/zellij-server/src/panes/unit/snapshots/zellij_server__panes__grid__grid_tests__vttest8_3.snap b/zellij-server/src/panes/unit/snapshots/zellij_server__panes__grid__grid_tests__vttest8_3.snap index d18554a86..e9dc19a61 100644 --- a/zellij-server/src/panes/unit/snapshots/zellij_server__panes__grid__grid_tests__vttest8_3.snap +++ b/zellij-server/src/panes/unit/snapshots/zellij_server__panes__grid__grid_tests__vttest8_3.snap @@ -3,30 +3,30 @@ source: zellij-server/src/panes/./unit/grid_tests.rs expression: "format!(\"{:?}\", grid)" --- -00 (C): AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -01 (C): BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB -02 (C): CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC -03 (C): The right column should be staggered DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD -04 (C): by one. Push EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE -05 (C): FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -06 (C): GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG -07 (C): HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH -08 (C): IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII -09 (C): JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ -10 (C): KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK -11 (C): LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL -12 (C): MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM -13 (C): NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -14 (C): OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO -15 (C): PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP -16 (C): QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ -17 (C): RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR -18 (C): SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS -19 (C): TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT -20 (C): UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU -21 (C): VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV -22 (C): WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW -23 (C): XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +00 (C): AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +01 (C): BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB +02 (C): CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +03 (C): The right column should be staggered DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD +04 (C): by one. Push EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE +05 (C): FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +06 (C): GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG +07 (C): HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH +08 (C): IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII +09 (C): JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ +10 (C): KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK +11 (C): LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL +12 (C): MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM +13 (C): NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +14 (C): OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO +15 (C): PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP +16 (C): QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ +17 (C): RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR +18 (C): SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS +19 (C): TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT +20 (C): UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU +21 (C): VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV +22 (C): WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW +23 (C): XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 24 (C): 25 (C): 26 (C): diff --git a/zellij-server/src/panes/unit/snapshots/zellij_server__panes__grid__grid_tests__vttest8_4.snap b/zellij-server/src/panes/unit/snapshots/zellij_server__panes__grid__grid_tests__vttest8_4.snap index c45da961f..ae820f6ac 100644 --- a/zellij-server/src/panes/unit/snapshots/zellij_server__panes__grid__grid_tests__vttest8_4.snap +++ b/zellij-server/src/panes/unit/snapshots/zellij_server__panes__grid__grid_tests__vttest8_4.snap @@ -3,30 +3,30 @@ source: zellij-server/src/panes/./unit/grid_tests.rs expression: "format!(\"{:?}\", grid)" --- -00 (C): AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -01 (C): BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB -02 (C): CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC -03 (C): The right column should be staggered -04 (C): by one. Push EEEEEEEEEEEEE -05 (C): FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -06 (C): GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG -07 (C): HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH -08 (C): IIIIIIIIIIIIIIIIIIIIIIIIIIIIIII -09 (C): JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ -10 (C): KKKKKKKKKKKKKKKKKKKKKKKKKKKKK -11 (C): LLLLLLLLLLLLLLLLLLLLLLLLLLLL -12 (C): MMMMMMMMMMMMMMMMMMMMMMMMMMM -13 (C): NNNNNNNNNNNNNNNNNNNNNNNNNN -14 (C): OOOOOOOOOOOOOOOOOOOOOOOOO -15 (C): PPPPPPPPPPPPPPPPPPPPPPPP -16 (C): QQQQQQQQQQQQQQQQQQQQQQQ -17 (C): RRRRRRRRRRRRRRRRRRRRRR -18 (C): SSSSSSSSSSSSSSSSSSSSS -19 (C): TTTTTTTTTTTTTTTTTTTT -20 (C): UUUUUUUUUUUUUUUUUUU -21 (C): VVVVVVVVVVVVVVVVVV -22 (C): WWWWWWWWWWWWWWWWW -23 (C): XXXXXXXXXXXXXXXX +00 (C): AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +01 (C): BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB +02 (C): CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +03 (C): The right column should be staggered +04 (C): by one. Push EEEEEEEEEEEEE +05 (C): FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +06 (C): GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG +07 (C): HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH +08 (C): IIIIIIIIIIIIIIIIIIIIIIIIIIIIIII +09 (C): JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ +10 (C): KKKKKKKKKKKKKKKKKKKKKKKKKKKKK +11 (C): LLLLLLLLLLLLLLLLLLLLLLLLLLLL +12 (C): MMMMMMMMMMMMMMMMMMMMMMMMMMM