Move modifier check before URL search

This makes sure that the URL search is only initiated when all required
modifiers are held down. This should improve performance with long URLs.
This commit is contained in:
Christian Duerr 2019-08-03 13:19:33 +00:00 committed by GitHub
parent 9dddf649a1
commit 5a40149069
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 39 additions and 50 deletions

View File

@ -119,13 +119,6 @@ pub enum Scroll {
Bottom, Bottom,
} }
#[derive(Copy, Clone)]
enum ViewportPosition {
Visible(Line),
Above,
Below,
}
impl<T: GridCell + Copy + Clone> Grid<T> { impl<T: GridCell + Copy + Clone> Grid<T> {
pub fn new(lines: index::Line, cols: index::Column, scrollback: usize, template: T) -> Grid<T> { pub fn new(lines: index::Line, cols: index::Column, scrollback: usize, template: T) -> Grid<T> {
let raw = Storage::with_capacity(lines, Row::new(cols, &template)); let raw = Storage::with_capacity(lines, Row::new(cols, &template));
@ -144,32 +137,21 @@ impl<T: GridCell + Copy + Clone> Grid<T> {
pub fn buffer_to_visible(&self, point: impl Into<Point<usize>>) -> Point<usize> { pub fn buffer_to_visible(&self, point: impl Into<Point<usize>>) -> Point<usize> {
let mut point = point.into(); let mut point = point.into();
match self.buffer_line_to_visible(point.line) { let offset = point.line.saturating_sub(self.display_offset);
ViewportPosition::Visible(line) => point.line = line.0,
ViewportPosition::Above => { if point.line < self.display_offset {
point.col = Column(0); point.col = self.num_cols();
point.line = 0; point.line = self.num_lines().0 - 1;
}, } else if offset >= *self.num_lines() {
ViewportPosition::Below => { point.col = Column(0);
point.col = self.num_cols(); point.line = 0;
point.line = self.num_lines().0 - 1; } else {
}, point.line = self.lines.0 - offset - 1;
} }
point point
} }
fn buffer_line_to_visible(&self, line: usize) -> ViewportPosition {
let offset = line.saturating_sub(self.display_offset);
if line < self.display_offset {
ViewportPosition::Below
} else if offset >= *self.num_lines() {
ViewportPosition::Above
} else {
ViewportPosition::Visible(self.lines - offset - 1)
}
}
pub fn visible_to_buffer(&self, point: Point) -> Point<usize> { pub fn visible_to_buffer(&self, point: Point) -> Point<usize> {
Point { line: self.visible_line_to_buffer(point.line), col: point.col } Point { line: self.visible_line_to_buffer(point.line), col: point.col }
} }

View File

@ -389,23 +389,34 @@ enum MousePosition {
} }
impl<'a, A: ActionContext + 'a> Processor<'a, A> { impl<'a, A: ActionContext + 'a> Processor<'a, A> {
fn mouse_position(&mut self, point: Point) -> MousePosition { fn mouse_position(&mut self, point: Point, modifiers: ModifiersState) -> MousePosition {
let mouse_mode =
TermMode::MOUSE_MOTION | TermMode::MOUSE_DRAG | TermMode::MOUSE_REPORT_CLICK;
let buffer_point = self.ctx.terminal().visible_to_buffer(point); let buffer_point = self.ctx.terminal().visible_to_buffer(point);
// Check message bar before URL to ignore URLs in the message bar // Check message bar before URL to ignore URLs in the message bar
if let Some(message) = self.message_at_point(Some(point)) { if let Some(message) = self.message_at_point(Some(point)) {
if self.message_close_at_point(point, message) { if self.message_close_at_point(point, message) {
MousePosition::MessageBarButton return MousePosition::MessageBarButton;
} else { } else {
MousePosition::MessageBar return MousePosition::MessageBar;
} }
} else if let Some(url) =
self.ctx.terminal().urls().drain(..).find(|url| url.contains(buffer_point))
{
MousePosition::Url(url)
} else {
MousePosition::Terminal
} }
// Check for URL at point with required modifiers held
if self.mouse_config.url.mods().relaxed_eq(modifiers)
&& (!self.ctx.terminal().mode().intersects(mouse_mode) || modifiers.shift)
&& self.mouse_config.url.launcher.is_some()
{
if let Some(url) =
self.ctx.terminal().urls().drain(..).find(|url| url.contains(buffer_point))
{
return MousePosition::Url(url);
}
}
MousePosition::Terminal
} }
#[inline] #[inline]
@ -435,20 +446,12 @@ impl<'a, A: ActionContext + 'a> Processor<'a, A> {
// Don't launch URLs if mouse has moved // Don't launch URLs if mouse has moved
self.ctx.mouse_mut().block_url_launcher = true; self.ctx.mouse_mut().block_url_launcher = true;
match self.mouse_position(point) { match self.mouse_position(point, modifiers) {
MousePosition::Url(url) => { MousePosition::Url(url) => {
let mouse_mode = let url_bounds = url.linear_bounds(self.ctx.terminal());
TermMode::MOUSE_MOTION | TermMode::MOUSE_DRAG | TermMode::MOUSE_REPORT_CLICK; self.ctx.terminal_mut().set_url_highlight(url_bounds);
self.ctx.terminal_mut().set_mouse_cursor(MouseCursor::Hand);
if self.mouse_config.url.mods().relaxed_eq(modifiers) self.ctx.terminal_mut().dirty = true;
&& (!self.ctx.terminal().mode().intersects(mouse_mode) || modifiers.shift)
&& self.mouse_config.url.launcher.is_some()
{
let url_bounds = url.linear_bounds(self.ctx.terminal());
self.ctx.terminal_mut().set_url_highlight(url_bounds);
self.ctx.terminal_mut().set_mouse_cursor(MouseCursor::Hand);
self.ctx.terminal_mut().dirty = true;
}
}, },
MousePosition::MessageBar => { MousePosition::MessageBar => {
self.ctx.terminal_mut().reset_url_highlight(); self.ctx.terminal_mut().reset_url_highlight();

View File

@ -1350,6 +1350,7 @@ impl Term {
parser.reset(); parser.reset();
} }
// Advance parser
match parser.advance(cell.c) { match parser.advance(cell.c) {
ParserState::Url(length) => { ParserState::Url(length) => {
urls.push(Url::new(point, length + extra_url_len, num_cols)) urls.push(Url::new(point, length + extra_url_len, num_cols))

View File

@ -18,14 +18,17 @@ impl Url {
Url { end: Point::new(end_line, Column(end_col)), start } Url { end: Point::new(end_line, Column(end_col)), start }
} }
/// Check if point is within this URL
pub fn contains(&self, point: impl Into<Point<usize>>) -> bool { pub fn contains(&self, point: impl Into<Point<usize>>) -> bool {
let point = point.into(); let point = point.into();
point.line <= self.start.line point.line <= self.start.line
&& point.line >= self.end.line && point.line >= self.end.line
&& (point.line != self.start.line || point.col >= self.start.col) && (point.line != self.start.line || point.col >= self.start.col)
&& (point.line != self.end.line || point.col <= self.end.col) && (point.line != self.end.line || point.col <= self.end.col)
} }
/// Convert URLs bounding points to linear indices
pub fn linear_bounds(&self, terminal: &Term) -> RangeInclusive<Linear> { pub fn linear_bounds(&self, terminal: &Term) -> RangeInclusive<Linear> {
let mut start = self.start; let mut start = self.start;
let mut end = self.end; let mut end = self.end;