@@ -14,7 +14,7 @@ use alacritty_terminal::{
selection::{Selection, SelectionRange, SelectionType},
sync::FairMutex,
term::{
- cell::{Cell, Hyperlink},
+ cell::Cell,
color::Rgb,
search::{Match, RegexIter, RegexSearch},
RenderableCursor, TermMode,
@@ -43,7 +43,7 @@ use std::{
collections::{HashMap, VecDeque},
fmt::Display,
io,
- ops::{Deref, Range, RangeInclusive, Sub},
+ ops::{Deref, RangeInclusive, Sub},
os::unix::{prelude::AsRawFd, process::CommandExt},
path::PathBuf,
process::Command,
@@ -77,16 +77,14 @@ pub fn init(cx: &mut MutableAppContext) {
///Scroll multiplier that is set to 3 by default. This will be removed when I
///Implement scroll bars.
const SCROLL_MULTIPLIER: f32 = 4.;
-// const MAX_SEARCH_LINES: usize = 100;
+const MAX_SEARCH_LINES: usize = 100;
const DEBUG_TERMINAL_WIDTH: f32 = 500.;
const DEBUG_TERMINAL_HEIGHT: f32 = 30.;
const DEBUG_CELL_WIDTH: f32 = 5.;
const DEBUG_LINE_HEIGHT: f32 = 5.;
/// Copied from alacritty's ui_config.rs
-const URL_REGEX: &str =
- "(ipfs:|ipns:|magnet:|mailto:|gemini:|gopher:|https:|http:|news:|file:|git:|ssh:|ftp:)\
- [^\u{0000}-\u{001F}\u{007F}-\u{009F}<>\"\\s{-}\\^⟨⟩`]+";
+static URL_REGEX: RegexSearch = RegexSearch::new("(ipfs:|ipns:|magnet:|mailto:|gemini:|gopher:|https:|http:|news:|file:|git:|ssh:|ftp:)[^\u{0000}-\u{001F}\u{007F}-\u{009F}<>\"\\s{-}\\^⟨⟩`]+").unwrap();
///Upward flowing events, for changing the title and such
#[derive(Clone, Copy, Debug)]
@@ -500,7 +498,7 @@ pub struct Terminal {
pub matches: Vec<RangeInclusive<Point>>,
last_content: TerminalContent,
last_synced: Instant,
- last_hovered_hyperlink: Option<(Hyperlink, Range<Point>)>,
+ last_hovered_hyperlink: Option<(String, RangeInclusive<Point>)>,
sync_task: Option<Task<()>>,
selection_head: Option<Point>,
breadcrumb_text: String,
@@ -651,14 +649,23 @@ impl Terminal {
}
InternalEvent::ScrollToPoint(point) => term.scroll_to_point(*point),
InternalEvent::Hyperlink(position, open) => {
+ self.last_hovered_hyperlink = None;
+
let point = grid_point(
*position,
self.last_content.size,
term.grid().display_offset(),
);
- let side = mouse_side(*position, self.last_content.size);
- println!("Hyperlink hover | click ")
+ if let Some(url_match) = regex_match_at(term, point, &URL_REGEX) {
+ let url = term.bounds_to_string(*url_match.start(), *url_match.end());
+
+ if *open {
+ open_uri(&url).log_err();
+ } else {
+ self.last_hovered_hyperlink = Some((url, url_match));
+ }
+ }
}
}
}
@@ -872,9 +879,9 @@ impl Terminal {
self.last_hovered_hyperlink = link.map(|link| {
(
- link,
+ link.uri().to_owned(),
self.last_content.cells[min_index].point
- ..self.last_content.cells[max_index].point,
+ ..=self.last_content.cells[max_index].point,
)
});
} else {
@@ -1112,6 +1119,30 @@ impl Entity for Terminal {
type Event = Event;
}
+/// Based on alacritty/src/display/hint.rs > regex_match_at
+/// Retrieve the match, if the specified point is inside the content matching the regex.
+fn regex_match_at<T>(term: &Term<T>, point: Point, regex: &RegexSearch) -> Option<Match> {
+ visible_regex_match_iter(term, regex).find(|rm| rm.contains(&point))
+}
+
+/// Copied from alacritty/src/display/hint.rs:
+/// Iterate over all visible regex matches.
+pub fn visible_regex_match_iter<'a, T>(
+ term: &'a Term<T>,
+ regex: &'a RegexSearch,
+) -> impl Iterator<Item = Match> + 'a {
+ let viewport_start = Line(-(term.grid().display_offset() as i32));
+ let viewport_end = viewport_start + term.bottommost_line();
+ let mut start = term.line_search_left(Point::new(viewport_start, Column(0)));
+ let mut end = term.line_search_right(Point::new(viewport_end, Column(0)));
+ start.line = start.line.max(viewport_start - MAX_SEARCH_LINES);
+ end.line = end.line.min(viewport_end + MAX_SEARCH_LINES);
+
+ RegexIter::new(start, end, AlacDirection::Right, term, regex)
+ .skip_while(move |rm| rm.end().line < viewport_start)
+ .take_while(move |rm| rm.start().line <= viewport_end)
+}
+
fn make_selection(range: &RangeInclusive<Point>) -> Selection {
let mut selection = Selection::new(SelectionType::Simple, *range.start(), AlacDirection::Left);
selection.update(*range.end(), AlacDirection::Right);