Skip to content

Commit 115a408

Browse files
committed
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.
1 parent 0f1c742 commit 115a408

File tree

2 files changed

+54
-11
lines changed

2 files changed

+54
-11
lines changed

Diff for: src/term/cell.rs

+14
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ bitflags! {
2424
const BOLD = 0b00000010,
2525
const ITALIC = 0b00000100,
2626
const UNDERLINE = 0b00001000,
27+
const WRAPLINE = 0b00010000,
2728
}
2829
}
2930

@@ -45,6 +46,10 @@ impl LineLength for grid::Row<Cell> {
4546
fn line_length(&self) -> Column {
4647
let mut length = Column(0);
4748

49+
if self[Column(self.len() - 1)].flags.contains(WRAPLINE) {
50+
return Column(self.len());
51+
}
52+
4853
for (index, cell) in self[..].iter().rev().enumerate() {
4954
if cell.c != ' ' {
5055
length = Column(self.len() - index);
@@ -105,4 +110,13 @@ mod tests {
105110

106111
assert_eq!(row.line_length(), Column(6));
107112
}
113+
114+
#[test]
115+
fn line_length_works_with_wrapline() {
116+
let template = Cell::new(' ', Color::Indexed(0), Color::Indexed(0));
117+
let mut row = Row::new(Column(10), &template);
118+
row[Column(9)].flags.insert(super::WRAPLINE);
119+
120+
assert_eq!(row.line_length(), Column(10));
121+
}
108122
}

Diff for: src/term/mod.rs

+40-11
Original file line numberDiff line numberDiff line change
@@ -311,43 +311,63 @@ impl Term {
311311
}
312312

313313
pub fn string_from_selection(&self, span: &Span) -> String {
314-
trait Append<T> {
315-
fn append(&mut self, grid: &Grid<Cell>, line: Line, cols: T);
314+
/// Need a generic push() for the Append trait
315+
trait PushChar {
316+
fn push_char(&mut self, c: char);
317+
fn maybe_newline(&mut self, grid: &Grid<Cell>, line: Line, ending: Column) {
318+
if ending != Column(0) && !grid[line][ending - 1].flags.contains(cell::WRAPLINE) {
319+
self.push_char('\n');
320+
}
321+
}
322+
}
323+
324+
impl PushChar for String {
325+
#[inline]
326+
fn push_char(&mut self, c: char) {
327+
self.push(c);
328+
}
329+
}
330+
trait Append<T> : PushChar {
331+
fn append(&mut self, grid: &Grid<Cell>, line: Line, cols: T) -> Range<Column> ;
316332
}
317333

318334
use std::ops::{Range, RangeTo, RangeFrom, RangeFull};
319335

320336
impl Append<Range<Column>> for String {
321-
fn append(&mut self, grid: &Grid<Cell>, line: Line, cols: Range<Column>) {
337+
fn append(&mut self, grid: &Grid<Cell>, line: Line, cols: Range<Column>) -> Range<Column> {
322338
let line = &grid[line];
323339
let line_length = line.line_length();
324340
let line_end = cmp::min(line_length, cols.end + 1);
325341
for cell in &line[cols.start..line_end] {
326342
self.push(cell.c);
327343
}
344+
345+
cols.start..line_end
328346
}
329347
}
330348

331349
impl Append<RangeTo<Column>> for String {
332350
#[inline]
333-
fn append(&mut self, grid: &Grid<Cell>, line: Line, cols: RangeTo<Column>) {
334-
self.append(grid, line, Column(0)..cols.end);
351+
fn append(&mut self, grid: &Grid<Cell>, line: Line, cols: RangeTo<Column>) -> Range<Column> {
352+
self.append(grid, line, Column(0)..cols.end)
335353
}
336354
}
337355

338356
impl Append<RangeFrom<Column>> for String {
339357
#[inline]
340-
fn append(&mut self, grid: &Grid<Cell>, line: Line, cols: RangeFrom<Column>) {
341-
self.append(grid, line, cols.start..Column(usize::max_value() - 1));
342-
self.push('\n');
358+
fn append(&mut self, grid: &Grid<Cell>, line: Line, cols: RangeFrom<Column>) -> Range<Column> {
359+
let range = self.append(grid, line, cols.start..Column(usize::max_value() - 1));
360+
self.maybe_newline(grid, line, range.end);
361+
range
343362
}
344363
}
345364

346365
impl Append<RangeFull> for String {
347366
#[inline]
348-
fn append(&mut self, grid: &Grid<Cell>, line: Line, _: RangeFull) {
349-
self.append(grid, line, Column(0)..Column(usize::max_value() - 1));
350-
self.push('\n');
367+
fn append(&mut self, grid: &Grid<Cell>, line: Line, _: RangeFull) -> Range<Column> {
368+
let range = self.append(grid, line, Column(0)..Column(usize::max_value() - 1));
369+
self.maybe_newline(grid, line, range.end);
370+
range
351371
}
352372
}
353373

@@ -564,6 +584,15 @@ impl ansi::Handler for Term {
564584
fn input(&mut self, c: char) {
565585
if self.cursor.col == self.grid.num_cols() {
566586
debug_println!("wrapping");
587+
{
588+
let location = Cursor {
589+
line: self.cursor.line,
590+
col: self.cursor.col - 1
591+
};
592+
593+
let cell = &mut self.grid[&location];
594+
cell.flags.insert(cell::WRAPLINE);
595+
}
567596
if (self.cursor.line + 1) >= self.scroll_region.end {
568597
self.linefeed();
569598
} else {

0 commit comments

Comments
 (0)