aboutsummaryrefslogtreecommitdiff
path: root/src/term/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/term/mod.rs')
-rw-r--r--src/term/mod.rs116
1 files changed, 50 insertions, 66 deletions
diff --git a/src/term/mod.rs b/src/term/mod.rs
index fc2b1727..89105041 100644
--- a/src/term/mod.rs
+++ b/src/term/mod.rs
@@ -17,7 +17,6 @@ use std::ops::{Range, Index, IndexMut, RangeInclusive};
use std::{ptr, io, mem};
use std::cmp::{min, max};
use std::time::{Duration, Instant};
-use std::iter::once;
use arraydeque::ArrayDeque;
use unicode_width::UnicodeWidthChar;
@@ -27,7 +26,7 @@ use font::{self, Size};
use crate::ansi::{self, Color, NamedColor, Attr, Handler, CharsetIndex, StandardCharset, CursorStyle};
use crate::grid::{
BidirectionalIterator, DisplayIter, Grid, GridCell, IndexRegion, Indexed, Scroll,
- ViewportPosition,
+ ViewportPosition
};
use crate::index::{self, Point, Column, Line, IndexRange, Contains, Linear};
use crate::selection::{self, Selection, Locations};
@@ -71,11 +70,11 @@ impl Search for Term {
break;
}
- if iter.cur().col == last_col && !cell.flags.contains(cell::Flags::WRAPLINE) {
+ if iter.cur.col == last_col && !cell.flags.contains(cell::Flags::WRAPLINE) {
break; // cut off if on new line or hit escape char
}
- point = iter.cur();
+ point = iter.cur;
}
point
@@ -93,7 +92,7 @@ impl Search for Term {
break;
}
- point = iter.cur();
+ point = iter.cur;
if point.col == last_col && !cell.flags.contains(cell::Flags::WRAPLINE) {
break; // cut off if on new line or hit escape char
@@ -120,7 +119,7 @@ impl Search for Term {
// Find URLs
let mut url_parser = UrlParser::new();
while let Some(cell) = iterb.prev() {
- if (iterb.cur().col == last_col && !cell.flags.contains(cell::Flags::WRAPLINE))
+ if (iterb.cur.col == last_col && !cell.flags.contains(cell::Flags::WRAPLINE))
|| url_parser.advance_left(cell)
{
break;
@@ -129,7 +128,7 @@ impl Search for Term {
while let Some(cell) = iterf.next() {
if url_parser.advance_right(cell)
- || (iterf.cur().col == last_col && !cell.flags.contains(cell::Flags::WRAPLINE))
+ || (iterf.cur.col == last_col && !cell.flags.contains(cell::Flags::WRAPLINE))
{
break;
}
@@ -164,6 +163,7 @@ pub struct RenderableCellsIter<'a> {
config: &'a Config,
colors: &'a color::List,
selection: Option<RangeInclusive<index::Linear>>,
+ url_highlight: &'a Option<RangeInclusive<index::Linear>>,
cursor_cells: ArrayDeque<[Indexed<Cell>; 3]>,
}
@@ -173,15 +173,14 @@ impl<'a> RenderableCellsIter<'a> {
/// The cursor and terminal mode are required for properly displaying the
/// cursor.
fn new<'b>(
- grid: &'b Grid<Cell>,
- cursor: &'b Point,
- colors: &'b color::List,
- mode: TermMode,
+ term: &'b Term,
config: &'b Config,
selection: Option<Locations>,
cursor_style: CursorStyle,
) -> RenderableCellsIter<'b> {
- let cursor_offset = grid.line_to_offset(cursor.line);
+ let grid = &term.grid;
+
+ let cursor_offset = grid.line_to_offset(term.cursor.point.line);
let inner = grid.display_iter();
let mut selection_range = None;
@@ -224,8 +223,8 @@ impl<'a> RenderableCellsIter<'a> {
}
let cols = grid.num_cols();
- let start = Linear(start.line.0 * cols.0 + start.col.0);
- let end = Linear(end.line.0 * cols.0 + end.col.0);
+ let start = Linear::from_point(cols, start.into());
+ let end = Linear::from_point(cols, end.into());
// Update the selection
selection_range = Some(RangeInclusive::new(start, end));
@@ -233,14 +232,15 @@ impl<'a> RenderableCellsIter<'a> {
}
RenderableCellsIter {
- cursor,
+ cursor: &term.cursor.point,
cursor_offset,
grid,
inner,
- mode,
+ mode: term.mode,
selection: selection_range,
+ url_highlight: &grid.url_highlight,
config,
- colors,
+ colors: &term.colors,
cursor_cells: ArrayDeque::new(),
}.initialize(cursor_style)
}
@@ -435,7 +435,7 @@ impl<'a> Iterator for RenderableCellsIter<'a> {
fn next(&mut self) -> Option<Self::Item> {
loop {
// Handle cursor
- let (cell, selected) = if self.cursor_offset == self.inner.offset() &&
+ let (cell, selected, highlighted) = if self.cursor_offset == self.inner.offset() &&
self.inner.column() == self.cursor.col
{
// Cursor cell
@@ -448,11 +448,11 @@ impl<'a> Iterator for RenderableCellsIter<'a> {
if self.cursor_cells.is_empty() {
self.inner.next();
}
- (cell, false)
+ (cell, false, false)
} else {
let cell = self.inner.next()?;
- let index = Linear(cell.line.0 * self.grid.num_cols().0 + cell.column.0);
+ let index = Linear::new(self.grid.num_cols(), cell.column, cell.line);
let selected = self.selection.as_ref()
.map(|range| range.contains_(index))
@@ -463,7 +463,12 @@ impl<'a> Iterator for RenderableCellsIter<'a> {
continue;
}
- (cell, selected)
+ // Underline URL highlights
+ let highlighted = self.url_highlight.as_ref()
+ .map(|range| range.contains_(index))
+ .unwrap_or(false);
+
+ (cell, selected, highlighted)
};
// Lookup RGB values
@@ -488,14 +493,19 @@ impl<'a> Iterator for RenderableCellsIter<'a> {
fg_rgb = col;
}
+ let mut flags = cell.flags;
+ if highlighted {
+ flags.insert(Flags::UNDERLINE);
+ }
+
return Some(RenderableCell {
line: cell.line,
column: cell.column,
- flags: cell.flags,
chars: cell.chars(),
fg: fg_rgb,
bg: bg_rgb,
bg_alpha,
+ flags,
})
}
}
@@ -824,16 +834,6 @@ pub struct Term {
/// Hint that Alacritty should be closed
should_exit: bool,
-
- /// URL highlight save state
- url_hover_save: Option<UrlHoverSaveState>,
-}
-
-/// Temporary save state for restoring mouse cursor and underline after unhovering a URL.
-pub struct UrlHoverSaveState {
- pub mouse_cursor: MouseCursor,
- pub underlined: Vec<bool>,
- pub start: Point<usize>,
}
/// Terminal size info
@@ -910,8 +910,10 @@ impl Term {
self.next_title.take()
}
+ #[inline]
pub fn scroll_display(&mut self, scroll: Scroll) {
self.grid.scroll_display(scroll);
+ self.reset_url_highlight();
self.dirty = true;
}
@@ -966,7 +968,6 @@ impl Term {
auto_scroll: config.scrolling().auto_scroll,
message_buffer,
should_exit: false,
- url_hover_save: None,
}
}
@@ -1162,7 +1163,8 @@ impl Term {
&self.grid
}
- /// Mutable access to the raw grid data structure
+ /// Mutable access for swapping out the grid during tests
+ #[cfg(test)]
pub fn grid_mut(&mut self) -> &mut Grid<Cell> {
&mut self.grid
}
@@ -1191,10 +1193,7 @@ impl Term {
};
RenderableCellsIter::new(
- &self.grid,
- &self.cursor.point,
- &self.colors,
- self.mode,
+ &self,
config,
selection,
cursor,
@@ -1212,8 +1211,6 @@ impl Term {
return;
}
- self.reset_url_highlight();
-
let old_cols = self.grid.num_cols();
let old_lines = self.grid.num_lines();
let mut num_cols = size.cols();
@@ -1232,6 +1229,7 @@ impl Term {
self.grid.selection = None;
self.alt_grid.selection = None;
+ self.grid.url_highlight = None;
// Should not allow less than 1 col, causes all sorts of checks to be required.
if num_cols <= Column(1) {
@@ -1381,37 +1379,22 @@ impl Term {
}
#[inline]
- pub fn set_url_highlight(&mut self, hover_save: UrlHoverSaveState) {
- self.url_hover_save = Some(hover_save);
+ pub fn set_url_highlight(&mut self, hl: RangeInclusive<index::Linear>) {
+ self.grid.url_highlight = Some(hl);
}
#[inline]
- pub fn url_highlight_start(&self) -> Option<Point<usize>> {
- self.url_hover_save.as_ref().map(|hs| hs.start)
- }
-
- /// Remove the URL highlight and restore the previous mouse cursor and underline state.
pub fn reset_url_highlight(&mut self) {
- let hover_save = match self.url_hover_save.take() {
- Some(hover_save) => hover_save,
- _ => return,
+ let mouse_mode =
+ TermMode::MOUSE_MOTION | TermMode::MOUSE_DRAG | TermMode::MOUSE_REPORT_CLICK;
+ let mouse_cursor = if self.mode().intersects(mouse_mode) {
+ MouseCursor::Default
+ } else {
+ MouseCursor::Text
};
+ self.set_mouse_cursor(mouse_cursor);
- // Reset the mouse cursor
- self.set_mouse_cursor(hover_save.mouse_cursor);
-
- let last_line = self.size_info.lines().0 - 1;
- let last_col = self.size_info.cols() - 1;
-
- // Reset the underline state after unhovering a URL
- let mut iter = once(hover_save.start).chain(hover_save.start.iter(last_col, last_line));
- for underlined in &hover_save.underlined {
- if let (Some(point), false) = (iter.next(), underlined) {
- let cell = &mut self.grid[point.line][point.col];
- cell.flags.remove(Flags::UNDERLINE);
- }
- }
-
+ self.grid.url_highlight = None;
self.dirty = true;
}
}
@@ -1961,8 +1944,9 @@ impl ansi::Handler for Term {
let mut template = self.cursor.template;
template.flags ^= template.flags;
- // Remove active selections
+ // Remove active selections and URL highlights
self.grid.selection = None;
+ self.grid.url_highlight = None;
match mode {
ansi::ClearMode::Below => {