aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAram Drevekenin <aram@poor.dev>2021-10-26 16:43:56 +0200
committerGitHub <noreply@github.com>2021-10-26 16:43:56 +0200
commit685b51efbb4f2670c504e80e663dcf1fb4890863 (patch)
treef210a16dca730e6b41313ee404340cefea0ef852
parentdocs(changelog): Rotate Pane locations (#802) (diff)
downloadsl0ppij-685b51efbb4f2670c504e80e663dcf1fb4890863.tar.gz
sl0ppij-685b51efbb4f2670c504e80e663dcf1fb4890863.tar.xz
sl0ppij-685b51efbb4f2670c504e80e663dcf1fb4890863.zip
fix(compatibility): improve handling of wide characters inserted in the middle of existing lines (#806)
* fix(compatibility): handle wide characters inserted in line middle * fix(compatibility): more wide char handling * style(fmt): make rustfmt happy * style(fmt): make clippy happy * style(fmt): make clippyt happy * style(fmt): make rustfmt happy... again
-rw-r--r--src/tests/fixtures/chinese_characters_line_middle14
-rw-r--r--zellij-server/src/panes/grid.rs45
-rw-r--r--zellij-server/src/panes/unit/grid_tests.rs12
-rw-r--r--zellij-server/src/panes/unit/snapshots/zellij_server__panes__grid__grid_tests__insert_wide_characters_in_existing_line.snap27
-rw-r--r--zellij-server/src/panes/unit/snapshots/zellij_server__panes__grid__grid_tests__vttest3_0.snap10
5 files changed, 93 insertions, 15 deletions
diff --git a/src/tests/fixtures/chinese_characters_line_middle b/src/tests/fixtures/chinese_characters_line_middle
new file mode 100644
index 00000000..5c3d1966
--- /dev/null
+++ b/src/tests/fixtures/chinese_characters_line_middle
@@ -0,0 +1,14 @@
+% 
+Temp/zellij/Chinese
+❯ [?2004h 
+Temp/zellij/Chinese
+❯ ttput lines[?2004l
+21
+% 
+Temp/zellij/Chinese
+❯ [?2004httput cols[?2004l
+86
+% 
+Temp/zellij/Chinese
+❯ [?2004hrranger[?2004l
+[?1049h(B[?7h[?1h[?25l[?1000h(Bloading...kranger\[?1h[?1000hkranger\ (Bjinho@pochita /home/jinho/Documents/Temp/zellij/Chinese/第一 (B Chinese (B (B 第一 0 (B ...(B 第三 0  第二 0  第五 0  第四 0  zellij-11.log 1.85 K  (Bzellij.log979 B drwxr-xr-x 2 jinho jinho 0 2021-10-13 10:312.8K sum, 933G free 1/7 Al[?7ll[?7h(Bempty(B(B三 第一 0 (B ...(B (B 第三 0 (B2(Bempty(B(B二(B...(B (B 第三 0 (B 第二 0 (B3(Bempty(B(B五(B...(B (B 第二 0 (B 第五 0 (B4(Bempty(B(B四(B...(B (B 第五 0 (B 第四 0 (B5(Bempty(B(B五(B 第五 0 (B 第四 0 (B4(B(B二(B 第二 0 (B 第五 0 (B3(B
diff --git a/zellij-server/src/panes/grid.rs b/zellij-server/src/panes/grid.rs
index 75f349cf..acbd6d91 100644
--- a/zellij-server/src/panes/grid.rs
+++ b/zellij-server/src/panes/grid.rs
@@ -2087,6 +2087,19 @@ impl Row {
}
acc
}
+ pub fn absolute_character_index(&self, x: usize) -> usize {
+ // return x's width aware index
+ let mut absolute_index = x;
+ for (i, terminal_character) in self.columns.iter().enumerate().take(x) {
+ if i == absolute_index {
+ break;
+ }
+ if terminal_character.width > 1 {
+ absolute_index = absolute_index.saturating_sub(1);
+ }
+ }
+ absolute_index
+ }
pub fn add_character_at(&mut self, terminal_character: TerminalCharacter, x: usize) {
match self.width().cmp(&x) {
Ordering::Equal => {
@@ -2099,18 +2112,30 @@ impl Row {
self.columns.push(terminal_character);
}
Ordering::Greater => {
- let width_offset = self.excess_width_until(x);
+ // wide-character-aware index, where each character is counted once
+ let absolute_x_index = self.absolute_character_index(x);
let character_width = terminal_character.width;
- let replaced_character = std::mem::replace(
- &mut self.columns[x.saturating_sub(width_offset)],
- terminal_character,
- );
- if character_width > replaced_character.width {
- // this is done in a verbose manner because of performance
- let width_difference = character_width - replaced_character.width;
- for _ in 0..width_difference {
- self.columns.pop();
+ let replaced_character =
+ std::mem::replace(&mut self.columns[absolute_x_index], terminal_character);
+ match character_width.cmp(&replaced_character.width) {
+ Ordering::Greater => {
+ // this is done in a verbose manner because of performance
+ let width_difference = character_width - replaced_character.width;
+ for _ in 0..width_difference {
+ let position_to_remove = absolute_x_index + 1;
+ if self.columns.get(position_to_remove).is_some() {
+ self.columns.remove(position_to_remove);
+ }
+ }
}
+ Ordering::Less => {
+ let width_difference = replaced_character.width - character_width;
+ for _ in 0..width_difference {
+ self.columns
+ .insert(absolute_x_index + 1, EMPTY_TERMINAL_CHARACTER);
+ }
+ }
+ _ => {}
}
}
}
diff --git a/zellij-server/src/panes/unit/grid_tests.rs b/zellij-server/src/panes/unit/grid_tests.rs
index 1ecc10a9..57ebf405 100644
--- a/zellij-server/src/panes/unit/grid_tests.rs
+++ b/zellij-server/src/panes/unit/grid_tests.rs
@@ -1010,3 +1010,15 @@ pub fn move_cursor_below_scroll_region() {
}
assert_snapshot!(format!("{:?}", grid));
}
+
+#[test]
+pub fn insert_wide_characters_in_existing_line() {
+ let mut vte_parser = vte::Parser::new();
+ let mut grid = Grid::new(21, 86, Palette::default());
+ let fixture_name = "chinese_characters_line_middle";
+ 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__insert_wide_characters_in_existing_line.snap b/zellij-server/src/panes/unit/snapshots/zellij_server__panes__grid__grid_tests__insert_wide_characters_in_existing_line.snap
new file mode 100644
index 00000000..766079c8
--- /dev/null
+++ b/zellij-server/src/panes/unit/snapshots/zellij_server__panes__grid__grid_tests__insert_wide_characters_in_existing_line.snap
@@ -0,0 +1,27 @@
+---
+source: zellij-server/src/panes/./unit/grid_tests.rs
+expression: "format!(\"{:?}\", grid)"
+
+---
+00 (C): jinho@pochita /home/jinho/Documents/Temp/zellij/Chinese/第二
+01 (C): Chinese 第一 0 empty
+02 (C): 第三 0
+03 (C): 第二 0
+04 (C): 第五 0
+05 (C): 第四 0
+06 (C): zellij-11.log 1.85 K
+07 (C): zellij.log 979 B
+08 (C):
+09 (C):
+10 (C):
+11 (C):
+12 (C):
+13 (C):
+14 (C):
+15 (C):
+16 (C):
+17 (C):
+18 (C):
+19 (C):
+20 (C): drwxr-xr-x 2 jinho jinho 0 2021-10-13 10:31 2.8K sum, 933G free 3/7 All
+
diff --git a/zellij-server/src/panes/unit/snapshots/zellij_server__panes__grid__grid_tests__vttest3_0.snap b/zellij-server/src/panes/unit/snapshots/zellij_server__panes__grid__grid_tests__vttest3_0.snap
index 0f9c5ce6..58818569 100644
--- a/zellij-server/src/panes/unit/snapshots/zellij_server__panes__grid__grid_tests__vttest3_0.snap
+++ b/zellij-server/src/panes/unit/snapshots/zellij_server__panes__grid__grid_tests__vttest3_0.snap
@@ -8,23 +8,23 @@ expression: "format!(\"{:?}\", grid)"
02 (C): Character set B (US ASCII)
03 (C): !"#$%&'()*+,-./0123456789:;<=>? !"#$%&'()*+,-./0123456789:;<=>?
04 (C): @ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_ @ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_
-05 (C): `abcdefghijklmnopqrstuvwxyz{|}~ `abcdefghijklmnopqrstuvwxyz{|}~
+05 (C): `abcdefghijklmnopqrstuvwxyz{|}~ `abcdefghijklmnopqrstuvwxyz{|}~
06 (C): Character set A (British)
07 (C): !"#$%&'()*+,-./0123456789:;<=>? !"#$%&'()*+,-./0123456789:;<=>?
08 (C): @ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_ @ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_
-09 (C): `abcdefghijklmnopqrstuvwxyz{|}~ `abcdefghijklmnopqrstuvwxyz{|}~
+09 (C): `abcdefghijklmnopqrstuvwxyz{|}~ `abcdefghijklmnopqrstuvwxyz{|}~
10 (C): Character set 0 (DEC Special graphics and line drawing)
11 (C): !"#$%&'()*+,-./0123456789:;<=>? !"#$%&'()*+,-./0123456789:;<=>?
12 (C): @ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_ @ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_
-13 (C): ◆▒␉␌␍␊°±␤␋┘┐┌└┼⎺⎻─⎼⎽├┤┴┬│≤≥π≠£· ◆▒␉␌␍␊°±␤␋┘┐┌└┼⎺⎻─⎼⎽├┤┴┬│≤≥π≠£·
+13 (C): ◆▒␉␌␍␊°±␤␋┘┐┌└┼⎺⎻─⎼⎽├┤┴┬│≤≥π≠£· ◆▒␉␌␍␊°±␤␋┘┐┌└┼⎺⎻─⎼⎽├┤┴┬│≤≥π≠£·
14 (C): Character set 1 (DEC Alternate character ROM standard characters)
15 (C): !"#$%&'()*+,-./0123456789:;<=>? !"#$%&'()*+,-./0123456789:;<=>?
16 (C): @ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_ @ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_
-17 (C): `abcdefghijklmnopqrstuvwxyz{|}~ `abcdefghijklmnopqrstuvwxyz{|}~
+17 (C): `abcdefghijklmnopqrstuvwxyz{|}~ `abcdefghijklmnopqrstuvwxyz{|}~
18 (C): Character set 2 (DEC Alternate character ROM special graphics)
19 (C): !"#$%&'()*+,-./0123456789:;<=>? !"#$%&'()*+,-./0123456789:;<=>?
20 (C): @ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_ @ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_
-21 (C): `abcdefghijklmnopqrstuvwxyz{|}~ `abcdefghijklmnopqrstuvwxyz{|}~
+21 (C): `abcdefghijklmnopqrstuvwxyz{|}~ `abcdefghijklmnopqrstuvwxyz{|}~
22 (C):
23 (C): These are the installed character sets. Push <RETURN>
24 (C):