diff options
author | Joe Wilm <joe@jwilm.com> | 2016-12-22 13:43:06 -0500 |
---|---|---|
committer | Joe Wilm <joe@jwilm.com> | 2016-12-22 13:44:13 -0500 |
commit | 6e708d2119ce0c839a89858a42a6b124a5cf48f4 (patch) | |
tree | a4ea2078153d136536587e04922f4ec841860298 /src/term/mod.rs | |
parent | fd11660c0a714852a3f477a6730d49b9694e1345 (diff) | |
download | r-alacritty-6e708d2119ce0c839a89858a42a6b124a5cf48f4.tar.gz r-alacritty-6e708d2119ce0c839a89858a42a6b124a5cf48f4.tar.bz2 r-alacritty-6e708d2119ce0c839a89858a42a6b124a5cf48f4.zip |
Implement visual component of mouse selections
This adds the ability to click and drag with the mouse and have the
effect of visually selecting text. The ability to copy the selection
into a clipboard buffer is not yet implemented.
Diffstat (limited to 'src/term/mod.rs')
-rw-r--r-- | src/term/mod.rs | 38 |
1 files changed, 26 insertions, 12 deletions
diff --git a/src/term/mod.rs b/src/term/mod.rs index 777c3bce..b25e8382 100644 --- a/src/term/mod.rs +++ b/src/term/mod.rs @@ -13,15 +13,15 @@ // limitations under the License. // //! Exports the `Term` type which is a high-level API for the Grid -use std::ops::{Deref, Range}; +use std::ops::{Deref, Range, RangeInclusive}; use std::ptr; use std::cmp; use std::io; -use ansi::{self, Attr, Handler}; -use grid::{Grid, ClearRegion}; -use index::{Cursor, Column, Line}; -use ansi::{Color, NamedColor}; +use ansi::{self, Color, NamedColor, Attr, Handler}; +use grid::{Grid, ClearRegion, ToRange}; +use index::{self, Cursor, Column, Line, Linear}; +use selection::Selection; pub mod cell; pub use self::cell::Cell; @@ -40,9 +40,9 @@ pub struct RenderableCellsIter<'a> { mode: TermMode, line: Line, column: Column, + selection: Option<RangeInclusive<index::Linear>>, } - impl<'a> RenderableCellsIter<'a> { /// Create the renderable cells iterator /// @@ -51,14 +51,19 @@ impl<'a> RenderableCellsIter<'a> { fn new<'b>( grid: &'b mut Grid<Cell>, cursor: &'b Cursor, - mode: TermMode + mode: TermMode, + selection: &Selection, ) -> RenderableCellsIter<'b> { + let selection = selection.span() + .map(|span| span.to_range(grid.num_cols())); + RenderableCellsIter { grid: grid, cursor: cursor, mode: mode, line: Line(0), column: Column(0), + selection: selection, }.initialize() } @@ -117,16 +122,24 @@ impl<'a> Iterator for RenderableCellsIter<'a> { let column = self.column; let cell = &self.grid[line][column]; + let index = Linear(line.0 * self.grid.num_cols().0 + column.0); + // Update state for next iteration self.column += 1; + let selected = self.selection.as_ref() + .map(|range| range.contains(index)) + .unwrap_or(false); + // Skip empty cells - if cell.is_empty() { + if cell.is_empty() && !selected { continue; } // fg, bg are dependent on INVERSE flag - let (fg, bg) = if cell.flags.contains(cell::INVERSE) { + let invert = cell.flags.contains(cell::INVERSE) || selected; + + let (fg, bg) = if invert { (&cell.bg, &cell.fg) } else { (&cell.fg, &cell.bg) @@ -319,8 +332,8 @@ impl Term { /// A renderable cell is any cell which has content other than the default /// background color. Cells with an alternate background color are /// considered renderable as are cells with any text content. - pub fn renderable_cells(&mut self) -> RenderableCellsIter { - RenderableCellsIter::new(&mut self.grid, &self.cursor, self.mode) + pub fn renderable_cells(&mut self, selection: &Selection) -> RenderableCellsIter { + RenderableCellsIter::new(&mut self.grid, &self.cursor, self.mode, selection) } /// Resize terminal to new dimensions @@ -932,6 +945,7 @@ mod bench { use std::path::Path; use grid::Grid; + use selection::Selection; use super::{SizeInfo, Term}; use super::cell::Cell; @@ -972,7 +986,7 @@ mod bench { mem::swap(&mut terminal.grid, &mut grid); b.iter(|| { - let iter = terminal.renderable_cells(); + let iter = terminal.renderable_cells(&Selection::Empty); for cell in iter { test::black_box(cell); } |