From 5cd365a73ce83991b98a92b41a5e1994afaa1688 Mon Sep 17 00:00:00 2001 From: Aram Drevekenin Date: Mon, 5 Oct 2020 16:46:40 +0200 Subject: [PATCH] feat(compatibility): vim working! --- src/terminal_pane.rs | 184 +++++++++++++++++- src/tests/fixtures/vim_ctrl_d | Bin 0 -> 3698 bytes src/tests/fixtures/vim_ctrl_u | Bin 0 -> 4994 bytes src/tests/fixtures/vim_scroll_region_down | Bin 0 -> 3829 bytes src/tests/integration/compatibility.rs | 77 ++++++++ ...egration__compatibility__vim_ctrl_d-2.snap | 32 +++ ...ntegration__compatibility__vim_ctrl_d.snap | 32 +++ ...egration__compatibility__vim_ctrl_u-2.snap | 32 +++ ...ntegration__compatibility__vim_ctrl_u.snap | 32 +++ ...mpatibility__vim_scroll_region_down-2.snap | 32 +++ ...compatibility__vim_scroll_region_down.snap | 32 +++ 11 files changed, 452 insertions(+), 1 deletion(-) create mode 100644 src/tests/fixtures/vim_ctrl_d create mode 100644 src/tests/fixtures/vim_ctrl_u create mode 100644 src/tests/fixtures/vim_scroll_region_down create mode 100644 src/tests/integration/snapshots/mosaic__tests__integration__compatibility__vim_ctrl_d-2.snap create mode 100644 src/tests/integration/snapshots/mosaic__tests__integration__compatibility__vim_ctrl_d.snap create mode 100644 src/tests/integration/snapshots/mosaic__tests__integration__compatibility__vim_ctrl_u-2.snap create mode 100644 src/tests/integration/snapshots/mosaic__tests__integration__compatibility__vim_ctrl_u.snap create mode 100644 src/tests/integration/snapshots/mosaic__tests__integration__compatibility__vim_scroll_region_down-2.snap create mode 100644 src/tests/integration/snapshots/mosaic__tests__integration__compatibility__vim_scroll_region_down.snap diff --git a/src/terminal_pane.rs b/src/terminal_pane.rs index 555d92b4..2fbde328 100644 --- a/src/terminal_pane.rs +++ b/src/terminal_pane.rs @@ -159,6 +159,7 @@ pub struct TerminalOutput { cursor_position: usize, newline_indices: Vec, // canonical line breaks we get from the vt interpreter linebreak_indices: Vec, // linebreaks from line wrapping + scroll_region: (usize, usize), // top line index / bottom line index reset_foreground_ansi_code: bool, // this is a performance optimization, rather than placing and looking for the ansi reset code in pending_ansi_codes reset_background_ansi_code: bool, // this is a performance optimization, rather than placing and looking for the ansi reset code in pending_ansi_codes reset_misc_ansi_code: bool, // this is a performance optimization, rather than placing and looking for the ansi reset code in pending_ansi_codes @@ -175,6 +176,7 @@ impl TerminalOutput { cursor_position: 0, newline_indices: Vec::new(), linebreak_indices: Vec::new(), + scroll_region: (1, ws.ws_row as usize), display_rows: ws.ws_row, display_cols: ws.ws_col, should_render: true, @@ -440,21 +442,168 @@ impl TerminalOutput { let last_linebreak_index = self.linebreak_indices.iter().rev().find(|&&l_i| l_i <= index_in_line).unwrap_or(&0); max(*last_newline_index, *last_linebreak_index) } + fn scroll_region_line_indices (&self) -> (usize, usize) { + let mut newline_indices = self.newline_indices.iter().rev(); + let mut linebreak_indices = self.linebreak_indices.iter().rev(); + + let mut next_newline = newline_indices.next(); + let mut next_linebreak = linebreak_indices.next(); + + let mut lines_from_end = 0; + + let scroll_end_index_from_screen_bottom = self.display_rows as usize - self.scroll_region.1; + let scroll_start_index_from_screen_bottom = scroll_end_index_from_screen_bottom + (self.scroll_region.1 - self.scroll_region.0); + + let mut scroll_region_start_index = None; + let mut scroll_region_end_index = None; + + loop { + match max(next_newline, next_linebreak) { + Some(next_line_index) => { + if lines_from_end == scroll_start_index_from_screen_bottom { + scroll_region_start_index = Some(next_line_index); + } + if lines_from_end == scroll_end_index_from_screen_bottom { + scroll_region_end_index = Some(next_line_index); + } + if scroll_region_start_index.is_some() && scroll_region_end_index.is_some() { + break; + } + if Some(next_line_index) == next_newline { + next_newline = newline_indices.next(); + } else if Some(next_line_index) == next_linebreak { + next_linebreak = linebreak_indices.next(); + } + lines_from_end += 1; + }, + None => break, + } + } + (*scroll_region_start_index.unwrap_or(&0), *scroll_region_end_index.unwrap_or(&0)) + } + fn index_of_next_line_after(&self, index_in_line: usize) -> usize { + let last_newline_index = self.newline_indices.iter().find(|&&n_i| n_i >= index_in_line).unwrap_or(&0); + let last_linebreak_index = self.linebreak_indices.iter().find(|&&l_i| l_i >= index_in_line).unwrap_or(&0); + max(*last_newline_index, *last_linebreak_index) + } + fn insert_empty_lines_at_cursor(&mut self, count: usize) { + for _ in 0..count { + self.delete_last_line_in_scroll_region(); + let start_of_current_line = self.index_of_beginning_of_line(self.cursor_position); + let end_of_current_line = self.index_of_next_line_after(self.cursor_position); + for i in 0..end_of_current_line - start_of_current_line { + self.characters.insert(start_of_current_line + i, EMPTY_TERMINAL_CHARACTER.clone()) + } + } + + } + fn delete_last_line_in_scroll_region(&mut self) { + if let Some(newline_index_of_scroll_region_end) = self.get_line_position_on_screen(self.scroll_region.1) { + let end_of_last_scroll_region_line = self.get_line_position_on_screen(self.scroll_region.1 + 1).unwrap(); + &self.characters.drain(newline_index_of_scroll_region_end..end_of_last_scroll_region_line); + } + } + fn delete_first_line_in_scroll_region(&mut self) { + if let Some(newline_index_of_scroll_region_start) = self.get_line_position_on_screen(self.scroll_region.0) { + let end_of_first_scroll_region_line = self.get_line_position_on_screen(self.scroll_region.0 + 1).unwrap(); + let removed_count = { + let removed_line = &self.characters.drain(newline_index_of_scroll_region_start..end_of_first_scroll_region_line); + removed_line.len() + }; + let newline_index_of_scroll_region_end = self.get_line_position_on_screen(self.scroll_region.1).unwrap(); + for i in 0..removed_count { + self.characters.insert(newline_index_of_scroll_region_end + i, EMPTY_TERMINAL_CHARACTER.clone()) + } + // TODO: if removed_count is larger than the line it was inserted it, recalculate all + // newline_indices after it + } + } + fn get_line_position_on_screen(&self, index_on_screen: usize) -> Option { + let mut newline_indices = self.newline_indices.iter().rev(); + let mut linebreak_indices = self.linebreak_indices.iter().rev(); + + let mut next_newline = newline_indices.next(); + let mut next_linebreak = linebreak_indices.next(); + + let mut lines_from_end = 0; // 1 because we're counting and not indexing TODO: fix this + loop { + match max(next_newline, next_linebreak) { + Some(next_line_index) => { + if index_on_screen == self.display_rows as usize - lines_from_end { + return Some(*next_line_index); + } else { + lines_from_end += 1; + } + if lines_from_end > self.display_rows as usize { + return None; + } + if Some(next_line_index) == next_newline { + next_newline = newline_indices.next(); + } else if Some(next_line_index) == next_linebreak { + next_linebreak = linebreak_indices.next(); + } + }, + None => { + if index_on_screen == self.display_rows as usize - lines_from_end { + return Some(0); + } else { + return None; + } + } + } + } + } + // TODO: better naming of these two functions + fn get_line_index_on_screen (&self, position_in_characters: usize) -> Option { + let mut newline_indices = self.newline_indices.iter().rev(); + let mut linebreak_indices = self.linebreak_indices.iter().rev(); + + let mut next_newline = newline_indices.next(); + let mut next_linebreak = linebreak_indices.next(); + + let mut lines_from_end = 0; + loop { + match max(next_newline, next_linebreak) { + Some(next_line_index) => { + if *next_line_index <= position_in_characters { + break; + } else { + lines_from_end += 1; + if Some(next_line_index) == next_newline { + next_newline = newline_indices.next(); + } else if Some(next_line_index) == next_linebreak { + next_linebreak = linebreak_indices.next(); + } + } + }, + None => break, + } + } + if lines_from_end > self.display_rows as usize { + None + } else { + Some(self.display_rows as usize - lines_from_end) + } + } fn add_newline (&mut self) { let nearest_line_end = self.index_of_end_of_canonical_line(self.cursor_position); + let current_line_index_on_screen = self.get_line_index_on_screen(self.cursor_position); if nearest_line_end == self.characters.len() { self.newline_indices.push(nearest_line_end); self.cursor_position = nearest_line_end; + } else if current_line_index_on_screen == Some(self.scroll_region.1) { // end of scroll region + // shift all lines in scroll region up + self.delete_first_line_in_scroll_region(); } else { // we shouldn't add a new line in the middle of the text // in this case, we'll move to the next existing line and it // will be overriden as we print on it self.cursor_position = nearest_line_end; } - self.should_render = true; self.pending_foreground_ansi_codes.clear(); self.pending_background_ansi_codes.clear(); self.pending_misc_ansi_codes.clear(); + self.should_render = true; } fn move_to_beginning_of_line (&mut self) { let last_newline_index = self.index_of_beginning_of_line(self.cursor_position); @@ -463,8 +612,18 @@ impl TerminalOutput { } } +fn debug_log_to_file (message: String) { + use std::fs::OpenOptions; + use std::io::prelude::*; + let mut file = OpenOptions::new().append(true).create(true).open("/tmp/mosaic-log.txt").unwrap(); + file.write_all(message.as_bytes()).unwrap(); + file.write_all("\n".as_bytes()).unwrap(); +} + impl vte::Perform for TerminalOutput { fn print(&mut self, c: char) { + + // while not ideal that we separate the reset and actual code logic here, // combining them is a question of rendering performance and not refactoring, // so will be addressed separately @@ -673,6 +832,29 @@ impl vte::Perform for TerminalOutput { // TBD } else if c == 'h' { // TBD + } else if c == 'r' { + debug_log_to_file(format!("\rparams {:?}", params)); + if params.len() > 1 { + // TODO: why do we need this if? what does a 1 parameter 'r' mean? + self.scroll_region = (params[0] as usize, params[1] as usize); + } + } else if c == 't' { + // TBD - title? + } else if c == 'n' { + // TBD - device status report + } else if c == 'c' { + // TBD - identify terminal + } else if c == 'M' { + // delete lines if currently inside scroll region + let line_count_to_delete = params[0]; + for _ in 0..line_count_to_delete { + // TODO: better, do this in bulk + self.delete_first_line_in_scroll_region() + } + } else if c == 'L' { + // insert blank lines if inside scroll region + let line_count_to_add = params[0]; + self.insert_empty_lines_at_cursor(line_count_to_add as usize); } else { println!("unhandled csi: {:?}->{:?}", c, params); panic!("aaa!!!"); diff --git a/src/tests/fixtures/vim_ctrl_d b/src/tests/fixtures/vim_ctrl_d new file mode 100644 index 0000000000000000000000000000000000000000..1f4929b8574bfd8f7778e1628a428e0863ef53f8 GIT binary patch literal 3698 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 literal 0 HcmV?d00001 diff --git a/src/tests/integration/compatibility.rs b/src/tests/integration/compatibility.rs index e5e10061..cd04d354 100644 --- a/src/tests/integration/compatibility.rs +++ b/src/tests/integration/compatibility.rs @@ -88,3 +88,80 @@ pub fn fish_select_tab_completion_options() { assert_snapshot!(snapshot); } } + +#[test] +pub fn vim_scroll_region_down () { + // here we test a case where vim defines the scroll region as lesser than the screen row count + // and then scrolls down + // the region is defined here by vim as 1-26 (there are 28 rows) + // then the cursor is moved to line 26 and a new line is added + // what should happen is that the first line in the scroll region (1) is deleted + // and an empty line is inserted in the last scroll region line (26) + // this tests also has other steps afterwards that fills the line with the next line in the + // file + // experience appear to the user + let fake_win_size = Winsize { + ws_col: 116, + ws_row: 28, + ws_xpixel: 0, + ws_ypixel: 0, + }; + let fixture_name = "vim_scroll_region_down"; + let mut fake_input_output = get_fake_os_input(&fake_win_size, fixture_name); + fake_input_output.add_terminal_input(&[17]); // quit (ctrl-q) + start(Box::new(fake_input_output.clone())); + 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); + } +} + +#[test] +pub fn vim_ctrl_d() { + // in vim ctrl-d moves down half a page + // in this case, it sends the terminal the csi 'M' directive, which tells it to delete X (13 in + // this case) lines inside the scroll region and push the other lines up + // what happens here is that 13 lines are deleted and instead 13 empty lines are added at the + // end of the scroll region + // vim makes sure to fill these empty lines with the rest of the file + let fake_win_size = Winsize { + ws_col: 116, + ws_row: 28, + ws_xpixel: 0, + ws_ypixel: 0, + }; + let fixture_name = "vim_ctrl_d"; + let mut fake_input_output = get_fake_os_input(&fake_win_size, fixture_name); + fake_input_output.add_terminal_input(&[17]); // quit (ctrl-q) + start(Box::new(fake_input_output.clone())); + 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); + } +} + +#[test] +pub fn vim_ctrl_u() { + // in vim ctrl-u moves up half a page + // in this case, it sends the terminal the csi 'L' directive, which tells it to insert X (13 in + // this case) lines at the cursor, pushing away (deleting) the last line in the scroll region + // this causes the effect of scrolling up X lines (vim replaces the lines with the ones in the + // file above the current content) + let fake_win_size = Winsize { + ws_col: 116, + ws_row: 28, + ws_xpixel: 0, + ws_ypixel: 0, + }; + let fixture_name = "vim_ctrl_u"; + let mut fake_input_output = get_fake_os_input(&fake_win_size, fixture_name); + fake_input_output.add_terminal_input(&[17]); // quit (ctrl-q) + start(Box::new(fake_input_output.clone())); + 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__vim_ctrl_d-2.snap b/src/tests/integration/snapshots/mosaic__tests__integration__compatibility__vim_ctrl_d-2.snap new file mode 100644 index 00000000..5a3f7ce5 --- /dev/null +++ b/src/tests/integration/snapshots/mosaic__tests__integration__compatibility__vim_ctrl_d-2.snap @@ -0,0 +1,32 @@ +--- +source: src/tests/integration/compatibility.rs +expression: snapshot +--- + 2 line15 + 1 line16 +17 line17 + 1 line18 + 2 line19 + 3 line20 + 4 line21 + 5 line22 + 6 line23 + 7 line24 + 8 line25 + 9 line26 + 10 line27 + 11 line28 + 12 line29 + 13 line30 + 14 line31 + 15 line32 + 16 line33 + 17 line34 + 18 line35 + 19 line36 + 20 line37 + 21 line38 + 22 line39 + NORMAL testfile.rs unix | utf-8 | rust 40% 17:1 +"/tmp/testfile.rs" 42L, 285C +Bye from Mosaic!█ diff --git a/src/tests/integration/snapshots/mosaic__tests__integration__compatibility__vim_ctrl_d.snap b/src/tests/integration/snapshots/mosaic__tests__integration__compatibility__vim_ctrl_d.snap new file mode 100644 index 00000000..b4eee2ea --- /dev/null +++ b/src/tests/integration/snapshots/mosaic__tests__integration__compatibility__vim_ctrl_d.snap @@ -0,0 +1,32 @@ +--- +source: src/tests/integration/compatibility.rs +expression: snapshot +--- + 3 line14 + 2 line15 + 1 line16 +17 █ine17 + 1 line18 + 2 line19 + 3 line20 + 4 line21 + 5 line22 + 6 line23 + 7 line24 + 8 line25 + 9 line26 + 10 line27 + 11 line28 + 12 line29 + 13 line30 + 14 line31 + 15 line32 + 16 line33 + 17 line34 + 18 line35 + 19 line36 + 20 line37 + 21 line38 + 22 line39 + NORMAL testfile.rs unix | utf-8 | rust 40% 17:1 +"/tmp/testfile.rs" 42L, 285C diff --git a/src/tests/integration/snapshots/mosaic__tests__integration__compatibility__vim_ctrl_u-2.snap b/src/tests/integration/snapshots/mosaic__tests__integration__compatibility__vim_ctrl_u-2.snap new file mode 100644 index 00000000..82d924a0 --- /dev/null +++ b/src/tests/integration/snapshots/mosaic__tests__integration__compatibility__vim_ctrl_u-2.snap @@ -0,0 +1,32 @@ +--- +source: src/tests/integration/compatibility.rs +expression: snapshot +--- + 21 line5 + 20 line6 + 19 line7 + 18 line8 + 17 line9 + 16 line10 + 15 line11 + 14 line12 + 13 line13 + 12 line14 + 11 line15 + 10 line16 + 9 line17 + 8 line18 + 7 line19 + 6 line20 + 5 line21 + 4 line22 + 3 line23 + 2 line24 + 1 line25 +26 line26 + 1 line27 + 2 line28 + 3 line29 + NORMAL testfile.rs unix | utf-8 | rust 61% 26:1 +"/tmp/testfile.rs" 42L, 285C +Bye from Mosaic!█ diff --git a/src/tests/integration/snapshots/mosaic__tests__integration__compatibility__vim_ctrl_u.snap b/src/tests/integration/snapshots/mosaic__tests__integration__compatibility__vim_ctrl_u.snap new file mode 100644 index 00000000..cdb821f9 --- /dev/null +++ b/src/tests/integration/snapshots/mosaic__tests__integration__compatibility__vim_ctrl_u.snap @@ -0,0 +1,32 @@ +--- +source: src/tests/integration/compatibility.rs +expression: snapshot +--- + 22 line4 + 21 line5 + 20 line6 + 19 line7 + 18 line8 + 17 line9 + 16 line10 + 15 line11 + 14 line12 + 13 line13 + 12 line14 + 11 line15 + 10 line16 + 9 line17 + 8 line18 + 7 line19 + 6 line20 + 5 line21 + 4 line22 + 3 line23 + 2 line24 + 1 line25 +26 █ine26 + 1 line27 + 2 line28 + 3 line29 + NORMAL testfile.rs unix | utf-8 | rust 61% 26:1 +"/tmp/testfile.rs" 42L, 285C diff --git a/src/tests/integration/snapshots/mosaic__tests__integration__compatibility__vim_scroll_region_down-2.snap b/src/tests/integration/snapshots/mosaic__tests__integration__compatibility__vim_scroll_region_down-2.snap new file mode 100644 index 00000000..a897b376 --- /dev/null +++ b/src/tests/integration/snapshots/mosaic__tests__integration__compatibility__vim_scroll_region_down-2.snap @@ -0,0 +1,32 @@ +--- +source: src/tests/integration/compatibility.rs +expression: snapshot +--- + 21 line3 + 20 line4 + 19 line5 + 18 line6 + 17 line7 + 16 line8 + 15 line9 + 14 line10 + 13 line11 + 12 line12 + 11 line13 + 10 line14 + 9 line15 + 8 line16 + 7 line17 + 6 line18 + 5 line19 + 4 line20 + 3 line21 + 2 line22 + 1 line23 +24 line24 + 1 line25 + 2 line26 + 3 line27 + NORMAL testfile.rs unix | utf-8 | rust 57% 24:1 +"/tmp/testfile.rs" 42L, 285C +Bye from Mosaic!█ diff --git a/src/tests/integration/snapshots/mosaic__tests__integration__compatibility__vim_scroll_region_down.snap b/src/tests/integration/snapshots/mosaic__tests__integration__compatibility__vim_scroll_region_down.snap new file mode 100644 index 00000000..3ca2370e --- /dev/null +++ b/src/tests/integration/snapshots/mosaic__tests__integration__compatibility__vim_scroll_region_down.snap @@ -0,0 +1,32 @@ +--- +source: src/tests/integration/compatibility.rs +expression: snapshot +--- + 22 line2 + 21 line3 + 20 line4 + 19 line5 + 18 line6 + 17 line7 + 16 line8 + 15 line9 + 14 line10 + 13 line11 + 12 line12 + 11 line13 + 10 line14 + 9 line15 + 8 line16 + 7 line17 + 6 line18 + 5 line19 + 4 line20 + 3 line21 + 2 line22 + 1 line23 +24 █ine24 + 1 line25 + 2 line26 + 3 line27 + NORMAL testfile.rs unix | utf-8 | rust 57% 24:1 +"/tmp/testfile.rs" 42L, 285C