1
1
mirror of https://github.com/wez/wezterm.git synced 2024-12-24 13:52:55 +03:00

speculatively apply hyperlinks to logical lines

This might be all that is needed to make multiline implicit hyperlinks
function, but I need to transfer this commit to another machine to try
it.

refs: https://github.com/wez/wezterm/issues/527
refs: https://github.com/wez/wezterm/issues/408
This commit is contained in:
Wez Furlong 2021-03-26 13:47:27 -07:00
parent 57b0911504
commit d827be990d
4 changed files with 54 additions and 4 deletions

View File

@ -10,6 +10,7 @@ use serde::{Deserialize, Serialize};
use std::cell::RefMut; use std::cell::RefMut;
use std::ops::Range; use std::ops::Range;
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use termwiz::hyperlink::Rule;
use termwiz::surface::Line; use termwiz::surface::Line;
use url::Url; use url::Url;
use wezterm_term::color::ColorPalette; use wezterm_term::color::ColorPalette;
@ -95,6 +96,23 @@ impl LogicalLine {
self.logical.cells().len() self.logical.cells().len()
); );
} }
pub fn apply_hyperlink_rules(&mut self, rules: &[Rule]) {
self.logical.invalidate_implicit_hyperlinks();
self.logical.scan_and_create_hyperlinks(rules);
if !self.logical.has_hyperlink() {
return;
}
// Re-compute the physical lines
let mut line = self.logical.clone();
let num_phys = self.physical_lines.len();
for (idx, phys) in self.physical_lines.iter_mut().enumerate() {
let len = phys.cells().len();
*phys = line.split_off(len);
phys.set_last_cell_was_wrapped(idx == num_phys - 1);
}
}
} }
/// A Pane represents a view on a terminal /// A Pane represents a view on a terminal
@ -190,6 +208,31 @@ pub trait Pane: Downcast {
lines lines
} }
fn get_lines_with_hyperlinks_applied(
&self,
lines: Range<StableRowIndex>,
rules: &[Rule],
) -> (StableRowIndex, Vec<Line>) {
let requested_first = lines.start;
let logical = self.get_logical_lines(lines);
let mut first = None;
let mut phys_lines = vec![];
for mut log_line in logical {
log_line.apply_hyperlink_rules(rules);
for (idx, phys) in log_line.physical_lines.into_iter().enumerate() {
if log_line.first_row + idx as StableRowIndex >= requested_first {
if first.is_none() {
first.replace(log_line.first_row + idx as StableRowIndex);
}
phys_lines.push(phys);
}
}
}
(first.unwrap(), phys_lines)
}
/// Returns render related dimensions /// Returns render related dimensions
fn get_dimensions(&self) -> RenderableDimensions; fn get_dimensions(&self) -> RenderableDimensions;

View File

@ -1,4 +1,3 @@
use config::configuration;
use luahelper::impl_lua_conversion; use luahelper::impl_lua_conversion;
use rangeset::RangeSet; use rangeset::RangeSet;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -77,7 +76,6 @@ pub fn terminal_get_lines(
) -> (StableRowIndex, Vec<Line>) { ) -> (StableRowIndex, Vec<Line>) {
let screen = term.screen_mut(); let screen = term.screen_mut();
let phys_range = screen.stable_range(&lines); let phys_range = screen.stable_range(&lines);
let config = configuration();
( (
screen.phys_to_stable_row_index(phys_range.start), screen.phys_to_stable_row_index(phys_range.start),
screen screen
@ -86,7 +84,6 @@ pub fn terminal_get_lines(
.skip(phys_range.start) .skip(phys_range.start)
.take(phys_range.end - phys_range.start) .take(phys_range.end - phys_range.start)
.map(|line| { .map(|line| {
line.scan_and_create_hyperlinks(&config.hyperlink_rules);
let cloned = line.clone(); let cloned = line.clone();
line.clear_dirty(); line.clear_dirty();
cloned cloned

View File

@ -235,6 +235,14 @@ impl Line {
s s
} }
pub fn split_off(&mut self, idx: usize) -> Self {
let cells = self.cells.split_off(idx);
Self {
bits: self.bits,
cells,
}
}
pub fn compute_double_click_range<F: Fn(&str) -> bool>( pub fn compute_double_click_range<F: Fn(&str) -> bool>(
&self, &self,
click_col: usize, click_col: usize,

View File

@ -172,7 +172,9 @@ impl super::TermWindow {
None => dims.physical_top..dims.physical_top + dims.viewport_rows as StableRowIndex, None => dims.physical_top..dims.physical_top + dims.viewport_rows as StableRowIndex,
}; };
let (top, vp_lines) = pos.pane.get_lines(stable_range); let (top, vp_lines) = pos
.pane
.get_lines_with_hyperlinks_applied(stable_range, &self.config.hyperlink_rules);
stable_top = top; stable_top = top;
lines = vp_lines; lines = vp_lines;
} }