mirror of
https://github.com/zellij-org/zellij.git
synced 2024-12-27 03:04:16 +03:00
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
This commit is contained in:
parent
829882d556
commit
685b51efbb
14
src/tests/fixtures/chinese_characters_line_middle
vendored
Normal file
14
src/tests/fixtures/chinese_characters_line_middle
vendored
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
[1m[7m%[27m[1m[0m
[0m[27m[24m[J
|
||||||
|
[1;36mTemp/zellij/Chinese[0m
|
||||||
|
[1;32m❯[0m [K[?2004h
[A[A[0m[27m[24m[J
|
||||||
|
[1;36mTemp/zellij/Chinese[0m
|
||||||
|
[1;32m❯[0m ttput lines[?2004l
|
||||||
|
21
|
||||||
|
[1m[7m%[27m[1m[0m
[0m[27m[24m[J
|
||||||
|
[1;36mTemp/zellij/Chinese[0m
|
||||||
|
[1;32m❯[0m [K[?2004httput cols[?2004l
|
||||||
|
86
|
||||||
|
[1m[7m%[27m[1m[0m
[0m[27m[24m[J
|
||||||
|
[1;36mTemp/zellij/Chinese[0m
|
||||||
|
[1;32m❯[0m [K[?2004hrranger[?2004l
|
||||||
|
[?1049h[1;21r(B[m[4l[?7h[?1h[?25l[39;49m[?1000h[39;49m(B[m[H[2J[2d[J[Aloading...[Kkranger\[?1h[?1000hkranger\
(B[0;1m[32mjinho@pochita [34m/home/jinho/Documents/Temp/zellij/Chinese/[39;49m第一[K
[2d(B[0;1;7m[94m Chinese [39;49m(B[m (B[0;1;7m[94m 第一 0 [39;49m(B[m ...[3;11H(B[0;1m[91m [94m第三 0 [4;11H[91m [94m第二 0 [5;11H[91m [94m第五 0 [6;11H[91m [94m第四 0 [7;11H[91m [92mzellij-11.log 1.85 K [8;11H[91m (B[0mzellij.log[8;36H979 B
[21d[36mdrwxr-xr-x[39;49m 2 jinho jinho 0 2021-10-13 10:31[21;58H2.8K sum, 933G free 1/7 Al[?7ll[?7h[1;11H(B[m[2d[2;43H[41mempty[2;11H[39;49m(B[m[1;59H(B[0;1m三[2;11H[91m [94m第一 0 [39;49m(B[m ...(B[m [3;11H(B[0;1;7m[94m 第三 0 [21;79H(B[0m2[2;11H(B[m[3d[2;43H[41mempty[3;11H[39;49m(B[m[1;59H(B[0;1m二[2;43H(B[0m...(B[m [3;11H(B[0;1m[91m [94m第三 0 [4;11H(B[0;1;7m[94m 第二 0 [21;79H(B[0m3[3;11H(B[m[4d[2;43H[41mempty[4;11H[39;49m(B[m[1;59H(B[0;1m五[2;43H(B[0m...(B[m [4;11H(B[0;1m[91m [94m第二 0 [5;11H(B[0;1;7m[94m 第五 0 [21;79H(B[0m4[4;11H(B[m[5d[2;43H[41mempty[5;11H[39;49m(B[m[1;59H(B[0;1m四[2;43H(B[0m...(B[m [5;11H(B[0;1m[91m [94m第五 0 [6;11H(B[0;1;7m[94m 第四 0 [21;79H(B[0m5[5;11H(B[m[6d[2;43H[41mempty[6;11H[39;49m(B[m[1;59H(B[0;1m五[5;11H(B[0;1;7m[94m 第五 0 [6;11H(B[0;1m[91m [94m第四 0 [21;79H(B[0m4[6;11H(B[m[A[1;59H(B[0;1m二[4;11H(B[0;1;7m[94m 第二 0 [5;11H(B[0;1m[91m [94m第五 0 [21;79H(B[0m3[5;11H(B[m[A
|
@ -2087,6 +2087,19 @@ impl Row {
|
|||||||
}
|
}
|
||||||
acc
|
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) {
|
pub fn add_character_at(&mut self, terminal_character: TerminalCharacter, x: usize) {
|
||||||
match self.width().cmp(&x) {
|
match self.width().cmp(&x) {
|
||||||
Ordering::Equal => {
|
Ordering::Equal => {
|
||||||
@ -2099,18 +2112,30 @@ impl Row {
|
|||||||
self.columns.push(terminal_character);
|
self.columns.push(terminal_character);
|
||||||
}
|
}
|
||||||
Ordering::Greater => {
|
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 character_width = terminal_character.width;
|
||||||
let replaced_character = std::mem::replace(
|
let replaced_character =
|
||||||
&mut self.columns[x.saturating_sub(width_offset)],
|
std::mem::replace(&mut self.columns[absolute_x_index], terminal_character);
|
||||||
terminal_character,
|
match character_width.cmp(&replaced_character.width) {
|
||||||
);
|
Ordering::Greater => {
|
||||||
if character_width > replaced_character.width {
|
// this is done in a verbose manner because of performance
|
||||||
// this is done in a verbose manner because of performance
|
let width_difference = character_width - replaced_character.width;
|
||||||
let width_difference = character_width - replaced_character.width;
|
for _ in 0..width_difference {
|
||||||
for _ in 0..width_difference {
|
let position_to_remove = absolute_x_index + 1;
|
||||||
self.columns.pop();
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1010,3 +1010,15 @@ pub fn move_cursor_below_scroll_region() {
|
|||||||
}
|
}
|
||||||
assert_snapshot!(format!("{:?}", grid));
|
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));
|
||||||
|
}
|
||||||
|
@ -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
|
||||||
|
|
@ -8,23 +8,23 @@ expression: "format!(\"{:?}\", grid)"
|
|||||||
02 (C): Character set B (US ASCII)
|
02 (C): Character set B (US ASCII)
|
||||||
03 (C): !"#$%&'()*+,-./0123456789:;<=>? !"#$%&'()*+,-./0123456789:;<=>?
|
03 (C): !"#$%&'()*+,-./0123456789:;<=>? !"#$%&'()*+,-./0123456789:;<=>?
|
||||||
04 (C): @ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_ @ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_
|
04 (C): @ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_ @ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_
|
||||||
05 (C): `abcdefghijklmnopqrstuvwxyz{|}~ `abcdefghijklmnopqrstuvwxyz{|}~
|
05 (C): `abcdefghijklmnopqrstuvwxyz{|}~ `abcdefghijklmnopqrstuvwxyz{|}~
|
||||||
06 (C): Character set A (British)
|
06 (C): Character set A (British)
|
||||||
07 (C): !"#$%&'()*+,-./0123456789:;<=>? !"#$%&'()*+,-./0123456789:;<=>?
|
07 (C): !"#$%&'()*+,-./0123456789:;<=>? !"#$%&'()*+,-./0123456789:;<=>?
|
||||||
08 (C): @ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_ @ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_
|
08 (C): @ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_ @ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_
|
||||||
09 (C): `abcdefghijklmnopqrstuvwxyz{|}~ `abcdefghijklmnopqrstuvwxyz{|}~
|
09 (C): `abcdefghijklmnopqrstuvwxyz{|}~ `abcdefghijklmnopqrstuvwxyz{|}~
|
||||||
10 (C): Character set 0 (DEC Special graphics and line drawing)
|
10 (C): Character set 0 (DEC Special graphics and line drawing)
|
||||||
11 (C): !"#$%&'()*+,-./0123456789:;<=>? !"#$%&'()*+,-./0123456789:;<=>?
|
11 (C): !"#$%&'()*+,-./0123456789:;<=>? !"#$%&'()*+,-./0123456789:;<=>?
|
||||||
12 (C): @ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_ @ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_
|
12 (C): @ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_ @ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_
|
||||||
13 (C): ◆▒␉␌␍␊°±␋┘┐┌└┼⎺⎻─⎼⎽├┤┴┬│≤≥π≠£· ◆▒␉␌␍␊°±␋┘┐┌└┼⎺⎻─⎼⎽├┤┴┬│≤≥π≠£·
|
13 (C): ◆▒␉␌␍␊°±␋┘┐┌└┼⎺⎻─⎼⎽├┤┴┬│≤≥π≠£· ◆▒␉␌␍␊°±␋┘┐┌└┼⎺⎻─⎼⎽├┤┴┬│≤≥π≠£·
|
||||||
14 (C): Character set 1 (DEC Alternate character ROM standard characters)
|
14 (C): Character set 1 (DEC Alternate character ROM standard characters)
|
||||||
15 (C): !"#$%&'()*+,-./0123456789:;<=>? !"#$%&'()*+,-./0123456789:;<=>?
|
15 (C): !"#$%&'()*+,-./0123456789:;<=>? !"#$%&'()*+,-./0123456789:;<=>?
|
||||||
16 (C): @ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_ @ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_
|
16 (C): @ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_ @ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_
|
||||||
17 (C): `abcdefghijklmnopqrstuvwxyz{|}~ `abcdefghijklmnopqrstuvwxyz{|}~
|
17 (C): `abcdefghijklmnopqrstuvwxyz{|}~ `abcdefghijklmnopqrstuvwxyz{|}~
|
||||||
18 (C): Character set 2 (DEC Alternate character ROM special graphics)
|
18 (C): Character set 2 (DEC Alternate character ROM special graphics)
|
||||||
19 (C): !"#$%&'()*+,-./0123456789:;<=>? !"#$%&'()*+,-./0123456789:;<=>?
|
19 (C): !"#$%&'()*+,-./0123456789:;<=>? !"#$%&'()*+,-./0123456789:;<=>?
|
||||||
20 (C): @ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_ @ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_
|
20 (C): @ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_ @ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_
|
||||||
21 (C): `abcdefghijklmnopqrstuvwxyz{|}~ `abcdefghijklmnopqrstuvwxyz{|}~
|
21 (C): `abcdefghijklmnopqrstuvwxyz{|}~ `abcdefghijklmnopqrstuvwxyz{|}~
|
||||||
22 (C):
|
22 (C):
|
||||||
23 (C): These are the installed character sets. Push <RETURN>
|
23 (C): These are the installed character sets. Push <RETURN>
|
||||||
24 (C):
|
24 (C):
|
||||||
|
Loading…
Reference in New Issue
Block a user