diff --git a/src/terminal_pane/scroll.rs b/src/terminal_pane/scroll.rs index f86cf5f8..20f98da0 100644 --- a/src/terminal_pane/scroll.rs +++ b/src/terminal_pane/scroll.rs @@ -284,14 +284,6 @@ impl CursorPosition { self.column_index = 0; self.line_index.1 = 0; } - pub fn move_up_by_canonical_lines(&mut self, count: usize) { - let current_canonical_line_position = self.line_index.0; - if count > current_canonical_line_position { - self.line_index = (0, 0); - } else { - self.line_index = (current_canonical_line_position - count, 0); - } - } pub fn move_down_by_canonical_lines(&mut self, count: usize) { // this method does not verify that we will not overflow let current_canonical_line_position = self.line_index.0; @@ -508,7 +500,24 @@ impl Scroll { self.cursor_position.move_backwards(count); } pub fn move_cursor_up(&mut self, count: usize) { - self.cursor_position.move_up_by_canonical_lines(count); + for _ in 0..count { + let (current_canonical_line_index, current_line_wrap_index) = + self.cursor_position.line_index; + if current_line_wrap_index > 0 { + // go up one line-wrap + self.cursor_position.line_index.1 -= 1; + } else if current_canonical_line_index > 0 { + // go up to previous canonical line + self.cursor_position.line_index.0 -= 1; + let current_canonical_line = self + .canonical_lines + .get(self.cursor_position.line_index.0) + .unwrap(); + let wraps_in_current_line = current_canonical_line.wrapped_fragments.len(); + // make sure to only go up to the last wrap of the previous line + self.cursor_position.line_index.1 = wraps_in_current_line - 1; + } + } } pub fn move_cursor_down(&mut self, count: usize) { let current_canonical_line = self.cursor_position.line_index.0; diff --git a/src/tests/fixtures/fish_paste_multiline b/src/tests/fixtures/fish_paste_multiline new file mode 100644 index 00000000..f41187f6 Binary files /dev/null and b/src/tests/fixtures/fish_paste_multiline differ diff --git a/src/tests/integration/compatibility.rs b/src/tests/integration/compatibility.rs index 65dc8da9..578e8fd2 100644 --- a/src/tests/integration/compatibility.rs +++ b/src/tests/integration/compatibility.rs @@ -388,3 +388,28 @@ pub fn bash_cursor_linewrap() { assert_snapshot!(snapshot); } } + +#[test] +pub fn fish_paste_multiline() { + // here we paste a multiline command in fish shell, making sure we support it + // going up and changing the colors of our line-wrapped pasted text + let fake_win_size = PositionAndSize { + columns: 149, + rows: 28, + x: 0, + y: 0, + }; + let fixture_name = "fish_paste_multiline"; + 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); + } +} diff --git a/src/tests/integration/snapshots/mosaic__tests__integration__compatibility__fish_paste_multiline-2.snap b/src/tests/integration/snapshots/mosaic__tests__integration__compatibility__fish_paste_multiline-2.snap new file mode 100644 index 00000000..d1c18eb2 --- /dev/null +++ b/src/tests/integration/snapshots/mosaic__tests__integration__compatibility__fish_paste_multiline-2.snap @@ -0,0 +1,32 @@ +--- +source: src/tests/integration/compatibility.rs +expression: snapshot +--- + + OS: 5.9.14-arch1-1 GNU/Linux + Uptime: 12 hours, 21 minutes + Hostname: kingdom + Disk usage: + +df: /run/user/1000/doc: Operation not permitted + / 295G / 514G 61% + /efi 27M / 96M 28% + + Network: + + wlp2s0 192.168.0.3 + +[I] [21:58] kingdom:mosaic (main) | echo -ne (\ + df -l -h | grep -E 'dev/(xvda|sd|mapper)' | \ + awk '{printf "\\\\t%s\\\\t%4s / %4s %s\\\\n\n", $6, $3, $2, $5}' | \ + sed -e 's/^\(.*\([8][5-9]\|[9][0-9]\)%.*\)$/\\\\e[0;31m\1\\\\e[0m/' -e 's/^\(.*\([7][5-9]\|[8][0-4]\)%.*\ +)$/\\\\e[0;33m\1\\\\e[0m/' | \ +) + paste -sd ''\ + )█ + + + + + + diff --git a/src/tests/integration/snapshots/mosaic__tests__integration__compatibility__fish_paste_multiline-3.snap b/src/tests/integration/snapshots/mosaic__tests__integration__compatibility__fish_paste_multiline-3.snap new file mode 100644 index 00000000..a1cb439e --- /dev/null +++ b/src/tests/integration/snapshots/mosaic__tests__integration__compatibility__fish_paste_multiline-3.snap @@ -0,0 +1,32 @@ +--- +source: src/tests/integration/compatibility.rs +expression: snapshot +--- + OS: 5.9.14-arch1-1 GNU/Linux + Uptime: 12 hours, 21 minutes + Hostname: kingdom + Disk usage: + +df: /run/user/1000/doc: Operation not permitted + / 295G / 514G 61% + /efi 27M / 96M 28% + + Network: + + wlp2s0 192.168.0.3 + +[I] [21:58] kingdom:mosaic (main) | echo -ne (\ + df -l -h | grep -E 'dev/(xvda|sd|mapper)' | \ + awk '{printf "\\\\t%s\\\\t%4s / %4s %s\\\\n\n", $6, $3, $2, $5}' | \ + sed -e 's/^\(.*\([8][5-9]\|[9][0-9]\)%.*\)$/\\\\e[0;31m\1\\\\e[0m/' -e 's/^\(.*\([7][5-9]\|[8][0-4]\)%.*\ +)$/\\\\e[0;33m\1\\\\e[0m/' | \ +) + paste -sd ''\ + ) + + + + + + +Bye from Mosaic!█ diff --git a/src/tests/integration/snapshots/mosaic__tests__integration__compatibility__fish_paste_multiline.snap b/src/tests/integration/snapshots/mosaic__tests__integration__compatibility__fish_paste_multiline.snap new file mode 100644 index 00000000..739c38e6 --- /dev/null +++ b/src/tests/integration/snapshots/mosaic__tests__integration__compatibility__fish_paste_multiline.snap @@ -0,0 +1,32 @@ +--- +source: src/tests/integration/compatibility.rs +expression: snapshot +--- +█ + + + + + + + + + + + + + + + + + + + + + + + + + + +