Skip to content

Commit

Permalink
fix(copy): rejoin wrapped lines (#1069)
Browse files Browse the repository at this point in the history
When copying wrapped lines do not treat them as separate lines.
  • Loading branch information
tlinford authored Feb 21, 2022
1 parent 0ac524b commit a3e69fe
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 14 deletions.
10 changes: 10 additions & 0 deletions src/tests/fixtures/grid_copy_wrapped
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
Welcome to fish, the friendly interactive shell
Type `help` for instructions on how to use fish
[?2004h]0;fish /home/thomas/Projects/zellij(B
zellij on  main [$!?] is 📦 v0.25.0 via 🦀 v1.58.1 
❯ cc(Bargo make run --debug(Bargo make run --debug(Bt(Bcat(B lorem.txt(B lorem.txt(B lorem.txt(B
(B[?2004l]0;cat lorem.txt /home/thomas/Projects/zellij(BLorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
⏎(B ⏎ [?2004h]0;fish /home/thomas/Projects/zellij(B
zellij on  main [$!?] is 📦 v0.25.0 via 🦀 v1.58.1 
❯ 
(B(B[?2004l
Expand Down
34 changes: 20 additions & 14 deletions zellij-server/src/panes/grid.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1291,27 +1291,27 @@ impl Grid {
self.preceding_char = Some(terminal_character);
}
pub fn start_selection(&mut self, start: &Position) {
let old_selection = self.selection.clone();
let old_selection = self.selection;
self.selection.start(*start);
self.update_selected_lines(&old_selection, &self.selection.clone());
self.mark_for_rerender();
}
pub fn update_selection(&mut self, to: &Position) {
let old_selection = self.selection.clone();
let old_selection = self.selection;
self.selection.to(*to);
self.update_selected_lines(&old_selection, &self.selection.clone());
self.mark_for_rerender();
}

pub fn end_selection(&mut self, end: Option<&Position>) {
let old_selection = self.selection.clone();
let old_selection = self.selection;
self.selection.end(end);
self.update_selected_lines(&old_selection, &self.selection.clone());
self.mark_for_rerender();
}

pub fn reset_selection(&mut self) {
let old_selection = self.selection.clone();
let old_selection = self.selection;
self.selection.reset();
self.update_selected_lines(&old_selection, &self.selection.clone());
self.mark_for_rerender();
Expand Down Expand Up @@ -1366,25 +1366,31 @@ impl Grid {
continue;
};

let excess_width = row.excess_width();
let mut line: Vec<TerminalCharacter> = row.columns.iter().copied().collect();
// pad line
line.resize(
self.width.saturating_sub(excess_width),
EMPTY_TERMINAL_CHARACTER,
);

let mut terminal_col = 0;
for terminal_character in line {
for terminal_character in &row.columns {
if (start_column..end_column).contains(&terminal_col) {
line_selection.push(terminal_character.character);
}

terminal_col += terminal_character.width;
}
selection.push(String::from(line_selection.trim_end()));

if row.is_canonical {
selection.push(line_selection);
} else {
// rejoin wrapped lines if possible
match selection.last_mut() {
Some(previous_line) => previous_line.push_str(&line_selection),
None => selection.push(line_selection),
}
}
}

// TODO: distinguish whitespace that was output explicitly vs implicitly (e.g add_newline)
// for example: echo " " vs empty lines
// for now trim after building the selection to handle whitespace in wrapped lines
let selection: Vec<_> = selection.iter().map(|l| l.trim_end()).collect();

Some(selection.join("\n"))
}

Expand Down
24 changes: 24 additions & 0 deletions zellij-server/src/panes/unit/grid_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -859,6 +859,30 @@ fn copy_selected_text_from_viewport() {
);
}

#[test]
fn copy_wrapped_selected_text_from_viewport() {
let mut vte_parser = vte::Parser::new();
let mut grid = Grid::new(
22,
73,
Palette::default(),
Rc::new(RefCell::new(LinkHandler::new())),
);
let fixture_name = "grid_copy_wrapped";
let content = read_fixture(fixture_name);
for byte in content {
vte_parser.advance(&mut grid, byte);
}

grid.start_selection(&Position::new(5, 0));
grid.end_selection(Some(&Position::new(8, 42)));
let text = grid.get_selected_text();
assert_eq!(
text.unwrap(),
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."
);
}

#[test]
fn copy_selected_text_from_lines_above() {
let mut vte_parser = vte::Parser::new();
Expand Down

0 comments on commit a3e69fe

Please sign in to comment.