Merge pull request #676 from nick1udwig/handle-osc-8-links
handle osc 8 links
This commit is contained in:
commit
dae3e28ff4
2 changed files with 82 additions and 6 deletions
|
|
@ -246,6 +246,7 @@ pub struct Terminal {
|
|||
pub url_regex_search: RegexSearch,
|
||||
pub regex_matches: Vec<alacritty_terminal::term::search::Match>,
|
||||
pub active_regex_match: Option<alacritty_terminal::term::search::Match>,
|
||||
pub active_hyperlink_id: Option<String>,
|
||||
bold_font_weight: Weight,
|
||||
buffer: Arc<Buffer>,
|
||||
is_focused: bool,
|
||||
|
|
@ -335,6 +336,7 @@ impl Terminal {
|
|||
|
||||
Ok(Self {
|
||||
active_regex_match: None,
|
||||
active_hyperlink_id: None,
|
||||
url_regex_search: url_regex_search(),
|
||||
regex_matches: Vec::new(),
|
||||
bold_font_weight: Weight(bold_font_weight),
|
||||
|
|
@ -887,6 +889,28 @@ impl Terminal {
|
|||
flags |= Flags::UNDERLINE;
|
||||
}
|
||||
}
|
||||
if let Some(active_id) = &self.active_hyperlink_id {
|
||||
let mut matches_active = indexed
|
||||
.cell
|
||||
.hyperlink()
|
||||
.is_some_and(|link| link.id() == active_id);
|
||||
if !matches_active
|
||||
&& indexed.cell.flags.intersects(
|
||||
Flags::WIDE_CHAR_SPACER | Flags::LEADING_WIDE_CHAR_SPACER,
|
||||
)
|
||||
&& indexed.point.column.0 > 0
|
||||
{
|
||||
matches_active = grid[Point::new(
|
||||
indexed.point.line,
|
||||
Column(indexed.point.column.0 - 1),
|
||||
)]
|
||||
.hyperlink()
|
||||
.is_some_and(|link| link.id() == active_id);
|
||||
}
|
||||
if matches_active {
|
||||
flags |= Flags::UNDERLINE;
|
||||
}
|
||||
}
|
||||
|
||||
let metadata = Metadata::new(bg, fg)
|
||||
.with_flags(flags)
|
||||
|
|
|
|||
|
|
@ -336,11 +336,7 @@ where
|
|||
|
||||
let location = terminal
|
||||
.viewport_to_point(TermPoint::new(row as usize, TermColumn(col as usize)));
|
||||
if terminal
|
||||
.regex_matches
|
||||
.iter()
|
||||
.any(|bounds| bounds.contains(&location))
|
||||
{
|
||||
if get_hyperlink(&terminal, location).is_some() {
|
||||
return mouse::Interaction::Pointer;
|
||||
}
|
||||
}
|
||||
|
|
@ -1002,7 +998,10 @@ where
|
|||
Event::Keyboard(KeyEvent::ModifiersChanged(modifiers)) => {
|
||||
state.modifiers = modifiers;
|
||||
|
||||
if modifiers.contains(Modifiers::CTRL) || terminal.active_regex_match.is_some() {
|
||||
if modifiers.contains(Modifiers::CTRL)
|
||||
|| terminal.active_regex_match.is_some()
|
||||
|| terminal.active_hyperlink_id.is_some()
|
||||
{
|
||||
//Might need to update the url regex highlight,
|
||||
//so we need to calculate the mouse position
|
||||
let location = if let Some(p) = cursor_position.position() {
|
||||
|
|
@ -1451,6 +1450,9 @@ fn get_hyperlink(
|
|||
terminal: &std::sync::MutexGuard<'_, Terminal>,
|
||||
location: TermPoint,
|
||||
) -> Option<String> {
|
||||
if let Some(link) = osc8_hyperlink_at(terminal, location) {
|
||||
return Some(link.uri().to_string());
|
||||
}
|
||||
if let Some(match_) = terminal
|
||||
.regex_matches
|
||||
.iter()
|
||||
|
|
@ -1463,6 +1465,32 @@ fn get_hyperlink(
|
|||
}
|
||||
}
|
||||
|
||||
fn get_hyperlink_id(
|
||||
terminal: &std::sync::MutexGuard<'_, Terminal>,
|
||||
location: TermPoint,
|
||||
) -> Option<String> {
|
||||
osc8_hyperlink_at(terminal, location).map(|link| link.id().to_string())
|
||||
}
|
||||
|
||||
fn osc8_hyperlink_at(
|
||||
terminal: &std::sync::MutexGuard<'_, Terminal>,
|
||||
location: TermPoint,
|
||||
) -> Option<alacritty_terminal::term::cell::Hyperlink> {
|
||||
let term = terminal.term.lock();
|
||||
let grid = term.grid();
|
||||
let cell = &grid[location];
|
||||
if let Some(link) = cell.hyperlink() {
|
||||
return Some(link);
|
||||
}
|
||||
if cell.flags.intersects(Flags::WIDE_CHAR_SPACER | Flags::LEADING_WIDE_CHAR_SPACER)
|
||||
&& location.column.0 > 0
|
||||
{
|
||||
let left = TermPoint::new(location.line, TermColumn(location.column.0 - 1));
|
||||
return grid[left].hyperlink();
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
fn update_active_regex_match(
|
||||
terminal: &mut std::sync::MutexGuard<'_, Terminal>,
|
||||
location: Option<TermPoint>,
|
||||
|
|
@ -1475,6 +1503,9 @@ fn update_active_regex_match(
|
|||
return;
|
||||
}
|
||||
|
||||
let allow_hyperlink = modifiers
|
||||
.map(|mods| mods.contains(Modifiers::CTRL))
|
||||
.unwrap_or(false);
|
||||
//Require CTRL for keyboard and mouse interaction
|
||||
if let Some(modifiers) = modifiers {
|
||||
if !modifiers.contains(Modifiers::CTRL) {
|
||||
|
|
@ -1482,16 +1513,37 @@ fn update_active_regex_match(
|
|||
terminal.active_regex_match = None;
|
||||
terminal.needs_update = true;
|
||||
}
|
||||
if terminal.active_hyperlink_id.is_some() {
|
||||
terminal.active_hyperlink_id = None;
|
||||
terminal.needs_update = true;
|
||||
}
|
||||
return;
|
||||
}
|
||||
} else if terminal.active_hyperlink_id.is_some() {
|
||||
terminal.active_hyperlink_id = None;
|
||||
terminal.needs_update = true;
|
||||
}
|
||||
let Some(location) = location else {
|
||||
if terminal.active_regex_match.is_some() {
|
||||
terminal.active_regex_match = None;
|
||||
terminal.needs_update = true;
|
||||
}
|
||||
if terminal.active_hyperlink_id.is_some() {
|
||||
terminal.active_hyperlink_id = None;
|
||||
terminal.needs_update = true;
|
||||
}
|
||||
return;
|
||||
};
|
||||
if allow_hyperlink {
|
||||
let next_hyperlink_id = get_hyperlink_id(terminal, location);
|
||||
if terminal.active_hyperlink_id != next_hyperlink_id {
|
||||
terminal.active_hyperlink_id = next_hyperlink_id;
|
||||
terminal.needs_update = true;
|
||||
}
|
||||
} else if terminal.active_hyperlink_id.is_some() {
|
||||
terminal.active_hyperlink_id = None;
|
||||
terminal.needs_update = true;
|
||||
}
|
||||
if let Some(match_) = terminal
|
||||
.regex_matches
|
||||
.iter()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue