mirror of
https://github.com/alacritty/alacritty.git
synced 2025-04-14 17:53:03 -04:00
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.
This commit is contained in:
parent
0f1c742857
commit
115a4085b4
2 changed files with 54 additions and 11 deletions
|
@ -24,6 +24,7 @@ bitflags! {
|
|||
const BOLD = 0b00000010,
|
||||
const ITALIC = 0b00000100,
|
||||
const UNDERLINE = 0b00001000,
|
||||
const WRAPLINE = 0b00010000,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -45,6 +46,10 @@ impl LineLength for grid::Row<Cell> {
|
|||
fn line_length(&self) -> Column {
|
||||
let mut length = Column(0);
|
||||
|
||||
if self[Column(self.len() - 1)].flags.contains(WRAPLINE) {
|
||||
return Column(self.len());
|
||||
}
|
||||
|
||||
for (index, cell) in self[..].iter().rev().enumerate() {
|
||||
if cell.c != ' ' {
|
||||
length = Column(self.len() - index);
|
||||
|
@ -105,4 +110,13 @@ mod tests {
|
|||
|
||||
assert_eq!(row.line_length(), Column(6));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn line_length_works_with_wrapline() {
|
||||
let template = Cell::new(' ', Color::Indexed(0), Color::Indexed(0));
|
||||
let mut row = Row::new(Column(10), &template);
|
||||
row[Column(9)].flags.insert(super::WRAPLINE);
|
||||
|
||||
assert_eq!(row.line_length(), Column(10));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -311,43 +311,63 @@ impl Term {
|
|||
}
|
||||
|
||||
pub fn string_from_selection(&self, span: &Span) -> String {
|
||||
trait Append<T> {
|
||||
fn append(&mut self, grid: &Grid<Cell>, 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<Cell>, 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<T> : PushChar {
|
||||
fn append(&mut self, grid: &Grid<Cell>, line: Line, cols: T) -> Range<Column> ;
|
||||
}
|
||||
|
||||
use std::ops::{Range, RangeTo, RangeFrom, RangeFull};
|
||||
|
||||
impl Append<Range<Column>> for String {
|
||||
fn append(&mut self, grid: &Grid<Cell>, line: Line, cols: Range<Column>) {
|
||||
fn append(&mut self, grid: &Grid<Cell>, line: Line, cols: Range<Column>) -> Range<Column> {
|
||||
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<RangeTo<Column>> for String {
|
||||
#[inline]
|
||||
fn append(&mut self, grid: &Grid<Cell>, line: Line, cols: RangeTo<Column>) {
|
||||
self.append(grid, line, Column(0)..cols.end);
|
||||
fn append(&mut self, grid: &Grid<Cell>, line: Line, cols: RangeTo<Column>) -> Range<Column> {
|
||||
self.append(grid, line, Column(0)..cols.end)
|
||||
}
|
||||
}
|
||||
|
||||
impl Append<RangeFrom<Column>> for String {
|
||||
#[inline]
|
||||
fn append(&mut self, grid: &Grid<Cell>, line: Line, cols: RangeFrom<Column>) {
|
||||
self.append(grid, line, cols.start..Column(usize::max_value() - 1));
|
||||
self.push('\n');
|
||||
fn append(&mut self, grid: &Grid<Cell>, line: Line, cols: RangeFrom<Column>) -> Range<Column> {
|
||||
let range = self.append(grid, line, cols.start..Column(usize::max_value() - 1));
|
||||
self.maybe_newline(grid, line, range.end);
|
||||
range
|
||||
}
|
||||
}
|
||||
|
||||
impl Append<RangeFull> for String {
|
||||
#[inline]
|
||||
fn append(&mut self, grid: &Grid<Cell>, line: Line, _: RangeFull) {
|
||||
self.append(grid, line, Column(0)..Column(usize::max_value() - 1));
|
||||
self.push('\n');
|
||||
fn append(&mut self, grid: &Grid<Cell>, line: Line, _: RangeFull) -> Range<Column> {
|
||||
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 {
|
||||
|
|
Loading…
Add table
Reference in a new issue