From 7c498feb85dc6d704036f8a9f6dcda12da3b8a0c Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Tue, 29 Aug 2023 10:40:20 +0300 Subject: [PATCH] Trim off surrounding `[]` when parsing terminal hover links Terminal has to accept `[` and `]` as valid word parts, due to `[slug].tsx` being a valid file name. Yet, terminal has to exclude these to match paths in strings like `[/some/path/[slug].tsx]`. --- crates/terminal/src/terminal.rs | 37 ++++++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/crates/terminal/src/terminal.rs b/crates/terminal/src/terminal.rs index 83ba056485..ea919c8f84 100644 --- a/crates/terminal/src/terminal.rs +++ b/crates/terminal/src/terminal.rs @@ -8,7 +8,7 @@ use alacritty_terminal::{ event::{Event as AlacTermEvent, EventListener, Notify, WindowSize}, event_loop::{EventLoop, Msg, Notifier}, grid::{Dimensions, Scroll as AlacScroll}, - index::{Column, Direction as AlacDirection, Line, Point}, + index::{Boundary, Column, Direction as AlacDirection, Line, Point}, selection::{Selection, SelectionRange, SelectionType}, sync::FairMutex, term::{ @@ -724,14 +724,13 @@ impl Terminal { self.last_content.size, term.grid().display_offset(), ) - .grid_clamp(term, alacritty_terminal::index::Boundary::Grid); + .grid_clamp(term, Boundary::Grid); let link = term.grid().index(point).hyperlink(); let found_word = if link.is_some() { let mut min_index = point; loop { - let new_min_index = - min_index.sub(term, alacritty_terminal::index::Boundary::Cursor, 1); + let new_min_index = min_index.sub(term, Boundary::Cursor, 1); if new_min_index == min_index { break; } else if term.grid().index(new_min_index).hyperlink() != link { @@ -743,8 +742,7 @@ impl Terminal { let mut max_index = point; loop { - let new_max_index = - max_index.add(term, alacritty_terminal::index::Boundary::Cursor, 1); + let new_max_index = max_index.add(term, Boundary::Cursor, 1); if new_max_index == max_index { break; } else if term.grid().index(new_max_index).hyperlink() != link { @@ -761,11 +759,34 @@ impl Terminal { } else if let Some(word_match) = regex_match_at(term, point, &WORD_REGEX) { let maybe_url_or_path = term.bounds_to_string(*word_match.start(), *word_match.end()); + let original_match = word_match.clone(); + let (sanitized_match, sanitized_word) = + if maybe_url_or_path.starts_with('[') && maybe_url_or_path.ends_with(']') { + ( + Match::new( + word_match.start().add(term, Boundary::Cursor, 1), + word_match.end().sub(term, Boundary::Cursor, 1), + ), + maybe_url_or_path[1..maybe_url_or_path.len() - 1].to_owned(), + ) + } else { + (word_match, maybe_url_or_path) + }; + let is_url = match regex_match_at(term, point, &URL_REGEX) { - Some(url_match) => url_match == word_match, + Some(url_match) => { + // `]` is a valid symbol in the `file://` URL, so the regex match will include it + // consider that when ensuring that the URL match is the same as the original word + if sanitized_match != original_match { + url_match.start() == sanitized_match.start() + && url_match.end() == original_match.end() + } else { + url_match == sanitized_match + } + } None => false, }; - Some((maybe_url_or_path, is_url, word_match)) + Some((sanitized_word, is_url, sanitized_match)) } else { None };