From 115a4085b4806e289c23ab296585f2f22b42efb7 Mon Sep 17 00:00:00 2001 From: Joe Wilm Date: Thu, 29 Dec 2016 10:43:58 -0500 Subject: Fix selection copy for long lines Long lines were previously broken at the terminal width. Now, a wrapping marker is kept on the final cell so that extra newlines are not inserted. --- src/term/mod.rs | 51 ++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 40 insertions(+), 11 deletions(-) (limited to 'src/term/mod.rs') diff --git a/src/term/mod.rs b/src/term/mod.rs index 28e73b19..a3cb4ecd 100644 --- a/src/term/mod.rs +++ b/src/term/mod.rs @@ -311,43 +311,63 @@ impl Term { } pub fn string_from_selection(&self, span: &Span) -> String { - trait Append { - fn append(&mut self, grid: &Grid, line: Line, cols: T); + /// Need a generic push() for the Append trait + trait PushChar { + fn push_char(&mut self, c: char); + fn maybe_newline(&mut self, grid: &Grid, line: Line, ending: Column) { + if ending != Column(0) && !grid[line][ending - 1].flags.contains(cell::WRAPLINE) { + self.push_char('\n'); + } + } + } + + impl PushChar for String { + #[inline] + fn push_char(&mut self, c: char) { + self.push(c); + } + } + trait Append : PushChar { + fn append(&mut self, grid: &Grid, line: Line, cols: T) -> Range ; } use std::ops::{Range, RangeTo, RangeFrom, RangeFull}; impl Append> for String { - fn append(&mut self, grid: &Grid, line: Line, cols: Range) { + fn append(&mut self, grid: &Grid, line: Line, cols: Range) -> Range { let line = &grid[line]; let line_length = line.line_length(); let line_end = cmp::min(line_length, cols.end + 1); for cell in &line[cols.start..line_end] { self.push(cell.c); } + + cols.start..line_end } } impl Append> for String { #[inline] - fn append(&mut self, grid: &Grid, line: Line, cols: RangeTo) { - self.append(grid, line, Column(0)..cols.end); + fn append(&mut self, grid: &Grid, line: Line, cols: RangeTo) -> Range { + self.append(grid, line, Column(0)..cols.end) } } impl Append> for String { #[inline] - fn append(&mut self, grid: &Grid, line: Line, cols: RangeFrom) { - self.append(grid, line, cols.start..Column(usize::max_value() - 1)); - self.push('\n'); + fn append(&mut self, grid: &Grid, line: Line, cols: RangeFrom) -> Range { + let range = self.append(grid, line, cols.start..Column(usize::max_value() - 1)); + self.maybe_newline(grid, line, range.end); + range } } impl Append for String { #[inline] - fn append(&mut self, grid: &Grid, line: Line, _: RangeFull) { - self.append(grid, line, Column(0)..Column(usize::max_value() - 1)); - self.push('\n'); + fn append(&mut self, grid: &Grid, line: Line, _: RangeFull) -> Range { + let range = self.append(grid, line, Column(0)..Column(usize::max_value() - 1)); + self.maybe_newline(grid, line, range.end); + range } } @@ -564,6 +584,15 @@ impl ansi::Handler for Term { fn input(&mut self, c: char) { if self.cursor.col == self.grid.num_cols() { debug_println!("wrapping"); + { + let location = Cursor { + line: self.cursor.line, + col: self.cursor.col - 1 + }; + + let cell = &mut self.grid[&location]; + cell.flags.insert(cell::WRAPLINE); + } if (self.cursor.line + 1) >= self.scroll_region.end { self.linefeed(); } else { -- cgit