diff options
author | Christian Duerr <chrisduerr@users.noreply.github.com> | 2019-03-30 09:23:48 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-03-30 09:23:48 +0000 |
commit | 91aa683bcd060b2ac2f621a388a6448f564d0537 (patch) | |
tree | 924c9a0759a84be19e397eae8cc28cbd3500d553 /src/input.rs | |
parent | 28636923e02a6cfac0fc950b963623cbcad5fda9 (diff) | |
download | r-alacritty-91aa683bcd060b2ac2f621a388a6448f564d0537.tar.gz r-alacritty-91aa683bcd060b2ac2f621a388a6448f564d0537.tar.bz2 r-alacritty-91aa683bcd060b2ac2f621a388a6448f564d0537.zip |
Rework URL highlighting
This completely reworks URL highlighting to fix two issues which were
caused by the original approach.
The primary issues that were not straight-forward to resolve with the
previous implementation were about handling the URL highlighted content
moving while the highlight is active.
This lead to issues with highlighting with scrolling and when the
display offset was not 0.
The new approach sticks closely to prior art done for the selection,
where the selection is tracked on the grid and updated whenever the
buffer is rotated.
The truncation of URLs was incorrectly assuming input to be just a
single codepoint wide to truncate the end of URLs with unmatching
closing parenthesis. This is now handled properly using Rust's built-in
Unicode support.
This fixes #2231.
This fixes #2225.
Diffstat (limited to 'src/input.rs')
-rw-r--r-- | src/input.rs | 59 |
1 files changed, 22 insertions, 37 deletions
diff --git a/src/input.rs b/src/input.rs index 9fe8e6bc..51e4e712 100644 --- a/src/input.rs +++ b/src/input.rs @@ -21,9 +21,10 @@ use std::borrow::Cow; use std::mem; use std::time::Instant; -use std::iter::once; +use std::ops::RangeInclusive; use copypasta::{Clipboard, Load, Buffer as ClipboardBuffer}; +use unicode_width::UnicodeWidthStr; use glutin::{ ElementState, KeyboardInput, ModifiersState, MouseButton, MouseCursor, MouseScrollDelta, TouchPhase, @@ -32,10 +33,9 @@ use glutin::{ use crate::config::{self, Key}; use crate::grid::Scroll; use crate::event::{ClickState, Mouse}; -use crate::index::{Line, Column, Side, Point}; -use crate::term::{Term, SizeInfo, Search, UrlHoverSaveState}; +use crate::index::{Line, Column, Side, Point, Linear}; +use crate::term::{Term, SizeInfo, Search}; use crate::term::mode::TermMode; -use crate::term::cell::Flags; use crate::util::fmt::Red; use crate::util::start_daemon; use crate::message_bar::{self, Message}; @@ -448,45 +448,30 @@ impl<'a, A: ActionContext + 'a> Processor<'a, A> { None }; - if let Some(Url { origin, len, .. }) = url { - let mouse_cursor = if self.ctx.terminal().mode().intersects(mouse_mode) { - MouseCursor::Default - } else { - MouseCursor::Text - }; - + if let Some(Url { origin, text }) = url { let cols = self.ctx.size_info().cols().0; - let last_line = self.ctx.size_info().lines().0 - 1; // Calculate the URL's start position - let col = (cols + point.col.0 - origin % cols) % cols; - let line = last_line - point.line.0 + (origin + cols - point.col.0 - 1) / cols; - let start = Point::new(line, Column(col)); - - // Update URLs only on change, so they don't all get marked as underlined - if self.ctx.terminal().url_highlight_start() == Some(start) { - return; - } - - // Since the URL changed without reset, we need to clear the previous underline - self.ctx.terminal_mut().reset_url_highlight(); + let lines_before = (origin + cols - point.col.0 - 1) / cols; + let (start_col, start_line) = if lines_before > point.line.0 { + (0, 0) + } else { + let start_col = (cols + point.col.0 - origin % cols) % cols; + let start_line = point.line.0 - lines_before; + (start_col, start_line) + }; + let start = Point::new(start_line, Column(start_col)); - // Underline all cells and store their current underline state - let mut underlined = Vec::with_capacity(len); - let iter = once(start).chain(start.iter(Column(cols - 1), last_line)); - for point in iter.take(len) { - let cell = &mut self.ctx.terminal_mut().grid_mut()[point.line][point.col]; - underlined.push(cell.flags.contains(Flags::UNDERLINE)); - cell.flags.insert(Flags::UNDERLINE); - } + // Calculate the URL's end position + let len = text.width(); + let end_col = (point.col.0 + len - origin) % cols - 1; + let end_line = point.line.0 + (point.col.0 + len - origin) / cols; + let end = Point::new(end_line, Column(end_col)); - // Save the higlight state for restoring it again - self.ctx.terminal_mut().set_url_highlight(UrlHoverSaveState { - mouse_cursor, - underlined, - start, - }); + let start = Linear::from_point(Column(cols), start); + let end = Linear::from_point(Column(cols), end); + self.ctx.terminal_mut().set_url_highlight(RangeInclusive::new(start, end)); self.ctx.terminal_mut().set_mouse_cursor(MouseCursor::Hand); self.ctx.terminal_mut().dirty = true; } else { |