fix(compatibility): htop horizontal scrolling (#81)
* fix(compatibility): htop horizontal scrolling * style(format): make rustfmt happy
This commit is contained in:
parent
b7b3ff74cf
commit
a56cb3c9ad
6 changed files with 179 additions and 28 deletions
|
|
@ -40,33 +40,9 @@ impl CanonicalLine {
|
||||||
self.wrapped_fragments.push(new_fragment);
|
self.wrapped_fragments.push(new_fragment);
|
||||||
}
|
}
|
||||||
pub fn change_width(&mut self, new_width: usize) {
|
pub fn change_width(&mut self, new_width: usize) {
|
||||||
let mut characters: Vec<TerminalCharacter> = self
|
let characters = self.flattened_characters();
|
||||||
.wrapped_fragments
|
let wrapped_fragments =
|
||||||
.iter()
|
CanonicalLine::fill_fragments_up_to_width(characters, new_width, None);
|
||||||
.fold(
|
|
||||||
Vec::with_capacity(self.wrapped_fragments.len()),
|
|
||||||
|mut characters, wrapped_fragment| {
|
|
||||||
characters.push(wrapped_fragment.characters.iter().copied());
|
|
||||||
characters
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.into_iter()
|
|
||||||
.flatten()
|
|
||||||
.collect();
|
|
||||||
let mut wrapped_fragments = Vec::with_capacity(characters.len() / new_width);
|
|
||||||
|
|
||||||
while !characters.is_empty() {
|
|
||||||
if characters.len() > new_width {
|
|
||||||
wrapped_fragments.push(WrappedFragment::from_vec(
|
|
||||||
characters.drain(..new_width).collect(),
|
|
||||||
));
|
|
||||||
} else {
|
|
||||||
wrapped_fragments.push(WrappedFragment::from_vec(characters.drain(..).collect()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if wrapped_fragments.is_empty() {
|
|
||||||
wrapped_fragments.push(WrappedFragment::new());
|
|
||||||
}
|
|
||||||
self.wrapped_fragments = wrapped_fragments;
|
self.wrapped_fragments = wrapped_fragments;
|
||||||
}
|
}
|
||||||
pub fn clear_after(&mut self, fragment_index: usize, column_index: usize) {
|
pub fn clear_after(&mut self, fragment_index: usize, column_index: usize) {
|
||||||
|
|
@ -113,6 +89,28 @@ impl CanonicalLine {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pub fn erase_chars(
|
||||||
|
&mut self,
|
||||||
|
fragment_index: usize,
|
||||||
|
from_col: usize,
|
||||||
|
count: usize,
|
||||||
|
style_of_empty_space: CharacterStyles,
|
||||||
|
) {
|
||||||
|
let mut empty_character = EMPTY_TERMINAL_CHARACTER;
|
||||||
|
empty_character.styles = style_of_empty_space;
|
||||||
|
let current_width = self.wrapped_fragments.get(0).unwrap().characters.len();
|
||||||
|
let mut characters = self.flattened_characters();
|
||||||
|
let absolute_position_of_character = fragment_index * current_width + from_col;
|
||||||
|
for _ in 0..count {
|
||||||
|
characters.remove(absolute_position_of_character);
|
||||||
|
}
|
||||||
|
let wrapped_fragments = CanonicalLine::fill_fragments_up_to_width(
|
||||||
|
characters,
|
||||||
|
current_width,
|
||||||
|
Some(empty_character),
|
||||||
|
);
|
||||||
|
self.wrapped_fragments = wrapped_fragments;
|
||||||
|
}
|
||||||
pub fn replace_with_empty_chars_after_cursor(
|
pub fn replace_with_empty_chars_after_cursor(
|
||||||
&mut self,
|
&mut self,
|
||||||
fragment_index: usize,
|
fragment_index: usize,
|
||||||
|
|
@ -157,6 +155,49 @@ impl CanonicalLine {
|
||||||
current_fragment.add_character(empty_char_character, i);
|
current_fragment.add_character(empty_char_character, i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fn flattened_characters(&self) -> Vec<TerminalCharacter> {
|
||||||
|
self.wrapped_fragments
|
||||||
|
.iter()
|
||||||
|
.fold(
|
||||||
|
Vec::with_capacity(self.wrapped_fragments.len()),
|
||||||
|
|mut characters, wrapped_fragment| {
|
||||||
|
characters.push(wrapped_fragment.characters.iter().copied());
|
||||||
|
characters
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.into_iter()
|
||||||
|
.flatten()
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
fn fill_fragments_up_to_width(
|
||||||
|
mut characters: Vec<TerminalCharacter>,
|
||||||
|
width: usize,
|
||||||
|
padding: Option<TerminalCharacter>,
|
||||||
|
) -> Vec<WrappedFragment> {
|
||||||
|
let mut wrapped_fragments = vec![];
|
||||||
|
while !characters.is_empty() {
|
||||||
|
if characters.len() > width {
|
||||||
|
wrapped_fragments.push(WrappedFragment::from_vec(
|
||||||
|
characters.drain(..width).collect(),
|
||||||
|
));
|
||||||
|
} else {
|
||||||
|
let mut last_fragment = WrappedFragment::from_vec(characters.drain(..).collect());
|
||||||
|
let last_fragment_len = last_fragment.characters.len();
|
||||||
|
if let Some(empty_char_character) = padding {
|
||||||
|
if last_fragment_len < width {
|
||||||
|
for _ in last_fragment_len..width {
|
||||||
|
last_fragment.characters.push(empty_char_character);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
wrapped_fragments.push(last_fragment);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if wrapped_fragments.is_empty() {
|
||||||
|
wrapped_fragments.push(WrappedFragment::new());
|
||||||
|
}
|
||||||
|
wrapped_fragments
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Debug for CanonicalLine {
|
impl Debug for CanonicalLine {
|
||||||
|
|
@ -538,6 +579,21 @@ impl Scroll {
|
||||||
style_of_empty_space,
|
style_of_empty_space,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
pub fn erase_characters(&mut self, count: usize, style_of_empty_space: CharacterStyles) {
|
||||||
|
let (current_canonical_line_index, current_line_wrap_position) =
|
||||||
|
self.cursor_position.line_index;
|
||||||
|
let current_cursor_column_position = self.cursor_position.column_index;
|
||||||
|
let current_canonical_line = self
|
||||||
|
.canonical_lines
|
||||||
|
.get_mut(current_canonical_line_index)
|
||||||
|
.expect("cursor out of bounds");
|
||||||
|
current_canonical_line.erase_chars(
|
||||||
|
current_line_wrap_position,
|
||||||
|
current_cursor_column_position,
|
||||||
|
count,
|
||||||
|
style_of_empty_space,
|
||||||
|
);
|
||||||
|
}
|
||||||
pub fn clear_all(&mut self) {
|
pub fn clear_all(&mut self) {
|
||||||
self.canonical_lines.clear();
|
self.canonical_lines.clear();
|
||||||
self.canonical_lines.push(CanonicalLine::new());
|
self.canonical_lines.push(CanonicalLine::new());
|
||||||
|
|
|
||||||
|
|
@ -868,13 +868,21 @@ impl vte::Perform for TerminalPane {
|
||||||
params[0] as usize
|
params[0] as usize
|
||||||
};
|
};
|
||||||
self.scroll.move_cursor_to_line(line);
|
self.scroll.move_cursor_to_line(line);
|
||||||
} else if c == 'X' || c == 'P' {
|
} else if c == 'P' {
|
||||||
// erase characters
|
// erase characters
|
||||||
let count = if params[0] == 0 {
|
let count = if params[0] == 0 {
|
||||||
1
|
1
|
||||||
} else {
|
} else {
|
||||||
params[0] as usize
|
params[0] as usize
|
||||||
};
|
};
|
||||||
|
self.scroll.erase_characters(count, self.pending_styles);
|
||||||
|
} else if c == 'X' {
|
||||||
|
// erase characters and replace with empty characters of current style
|
||||||
|
let count = if params[0] == 0 {
|
||||||
|
1
|
||||||
|
} else {
|
||||||
|
params[0] as usize
|
||||||
|
};
|
||||||
self.scroll
|
self.scroll
|
||||||
.replace_with_empty_chars(count, self.pending_styles);
|
.replace_with_empty_chars(count, self.pending_styles);
|
||||||
} else if c == 'T' {
|
} else if c == 'T' {
|
||||||
|
|
|
||||||
BIN
src/tests/fixtures/htop_right_scrolling
vendored
Normal file
BIN
src/tests/fixtures/htop_right_scrolling
vendored
Normal file
Binary file not shown.
|
|
@ -237,3 +237,26 @@ pub fn htop_scrolling() {
|
||||||
assert_snapshot!(snapshot);
|
assert_snapshot!(snapshot);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
pub fn htop_right_scrolling() {
|
||||||
|
let fake_win_size = PositionAndSize {
|
||||||
|
columns: 116,
|
||||||
|
rows: 28,
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
};
|
||||||
|
let fixture_name = "htop_right_scrolling";
|
||||||
|
let mut fake_input_output = get_fake_os_input(&fake_win_size, fixture_name);
|
||||||
|
fake_input_output.add_terminal_input(&[&COMMAND_TOGGLE, &COMMAND_TOGGLE, &QUIT]);
|
||||||
|
start(Box::new(fake_input_output.clone()), Opt::default());
|
||||||
|
let output_frames = fake_input_output
|
||||||
|
.stdout_writer
|
||||||
|
.output_frames
|
||||||
|
.lock()
|
||||||
|
.unwrap();
|
||||||
|
let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size);
|
||||||
|
for snapshot in snapshots {
|
||||||
|
assert_snapshot!(snapshot);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
---
|
||||||
|
source: src/tests/integration/compatibility.rs
|
||||||
|
expression: snapshot
|
||||||
|
---
|
||||||
|
1 [|||||||||| 16.9%] Tasks: 110, 512 thr; 1 running
|
||||||
|
2 [|||||||||| 17.1%] Load average: 1.04 1.30 1.29
|
||||||
|
3 [||||||| 13.9%] Uptime: 6 days, 07:01:39
|
||||||
|
4 [||||||||| 14.9%]
|
||||||
|
Mem[|||||||||||||||||||||||||||||||||||||8.80G/15.3G]
|
||||||
|
Swp[| 2.82M/16.0G]
|
||||||
|
|
||||||
|
PRI NI VIRT RES SHR S CPU% MEM% TIME+ Command
|
||||||
|
20 0 8576 4508 3356 R 1.3 0.0 0:00.11 htop
|
||||||
|
20 0 171M 10868 7804 S 0.0 0.1 2:08.38 /sbin/init
|
||||||
|
20 0 107M 29364 28092 S 0.0 0.2 0:03.42 /usr/lib/systemd/systemd-journald
|
||||||
|
20 0 32648 9568 6616 S 0.0 0.1 0:01.87 /usr/lib/systemd/systemd-udevd
|
||||||
|
20 0 78060 992 856 S 0.0 0.0 0:00.00 /usr/bin/lvmetad -f
|
||||||
|
20 0 6952 4356 3492 S 0.0 0.0 0:57.67 /usr/bin/dbus-daemon --system --address=systemd: --nofork --nopidf
|
||||||
|
20 0 14824 7552 5984 S 0.0 0.0 0:12.93 /usr/bin/connmand -n --nodnsproxy
|
||||||
|
20 0 17696 7940 6696 S 0.0 0.0 0:01.25 /usr/lib/systemd/systemd-logind
|
||||||
|
20 0 1635M 56148 20460 S 0.0 0.3 1:27.24 /usr/bin/dockerd -H fd://
|
||||||
|
20 0 1635M 56148 20460 S 0.0 0.3 0:38.37 /usr/bin/dockerd -H fd://
|
||||||
|
20 0 1635M 56148 20460 S 0.0 0.3 0:00.01 /usr/bin/dockerd -H fd://
|
||||||
|
20 0 1635M 56148 20460 S 0.0 0.3 0:00.00 /usr/bin/dockerd -H fd://
|
||||||
|
20 0 1635M 56148 20460 S 0.0 0.3 0:00.00 /usr/bin/dockerd -H fd://
|
||||||
|
20 0 1635M 56148 20460 S 0.0 0.3 0:00.00 /usr/bin/dockerd -H fd://
|
||||||
|
20 0 1635M 56148 20460 S 0.0 0.3 1:47.55 /usr/bin/dockerd -H fd://
|
||||||
|
20 0 1635M 56148 20460 S 0.0 0.3 1:26.19 /usr/bin/dockerd -H fd://
|
||||||
|
20 0 1635M 56148 20460 S 0.0 0.3 1:40.77 /usr/bin/dockerd -H fd://
|
||||||
|
20 0 1635M 56148 20460 S 0.0 0.3 1:47.26 /usr/bin/dockerd -H fd://
|
||||||
|
F1Help F2Setup F3SearchF4FilterF5Tree F6SortByF7Nice -F8Nice +F9Kill F10Quit
|
||||||
|
Bye from Mosaic!█
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
---
|
||||||
|
source: src/tests/integration/compatibility.rs
|
||||||
|
expression: snapshot
|
||||||
|
---
|
||||||
|
|
||||||
|
1 [|||||||||| 16.9%] Tasks: 110, 512 thr; 1 running
|
||||||
|
2 [|||||||||| 17.1%] Load average: 1.04 1.30 1.29
|
||||||
|
3 [||||||| 13.9%] Uptime: 6 days, 07:01:39
|
||||||
|
4 [||||||||| 14.9%]
|
||||||
|
Mem[|||||||||||||||||||||||||||||||||||||8.80G/15.3G]
|
||||||
|
Swp[| 2.82M/16.0G]
|
||||||
|
|
||||||
|
PRI NI VIRT RES SHR S CPU% MEM% TIME+ Command
|
||||||
|
20 0 8576 4508 3356 R 1.3 0.0 0:00.11 htop
|
||||||
|
20 0 171M 10868 7804 S 0.0 0.1 2:08.38 /sbin/init
|
||||||
|
20 0 107M 29364 28092 S 0.0 0.2 0:03.42 /usr/lib/systemd/systemd-journald
|
||||||
|
20 0 32648 9568 6616 S 0.0 0.1 0:01.87 /usr/lib/systemd/systemd-udevd
|
||||||
|
20 0 78060 992 856 S 0.0 0.0 0:00.00 /usr/bin/lvmetad -f
|
||||||
|
20 0 6952 4356 3492 S 0.0 0.0 0:57.67 /usr/bin/dbus-daemon --system --address=systemd: --nofork --nopidf
|
||||||
|
20 0 14824 7552 5984 S 0.0 0.0 0:12.93 /usr/bin/connmand -n --nodnsproxy
|
||||||
|
20 0 17696 7940 6696 S 0.0 0.0 0:01.25 /usr/lib/systemd/systemd-logind
|
||||||
|
20 0 1635M 56148 20460 S 0.0 0.3 1:27.24 /usr/bin/dockerd -H fd://
|
||||||
|
20 0 1635M 56148 20460 S 0.0 0.3 0:38.37 /usr/bin/dockerd -H fd://
|
||||||
|
20 0 1635M 56148 20460 S 0.0 0.3 0:00.01 /usr/bin/dockerd -H fd://
|
||||||
|
20 0 1635M 56148 20460 S 0.0 0.3 0:00.00 /usr/bin/dockerd -H fd://
|
||||||
|
20 0 1635M 56148 20460 S 0.0 0.3 0:00.00 /usr/bin/dockerd -H fd://
|
||||||
|
20 0 1635M 56148 20460 S 0.0 0.3 0:00.00 /usr/bin/dockerd -H fd://
|
||||||
|
20 0 1635M 56148 20460 S 0.0 0.3 1:47.55 /usr/bin/dockerd -H fd://
|
||||||
|
20 0 1635M 56148 20460 S 0.0 0.3 1:26.19 /usr/bin/dockerd -H fd://
|
||||||
|
20 0 1635M 56148 20460 S 0.0 0.3 1:40.77 /usr/bin/dockerd -H fd://
|
||||||
|
20 0 1635M 56148 20460 S 0.0 0.3 1:47.26 /usr/bin/dockerd -H fd://
|
||||||
|
F1Help F2Setup F3SearchF4FilterF5Tree F6SortByF7Nice -F8Nice +F9Kill F10Quit
|
||||||
Loading…
Add table
Reference in a new issue