diff options
author | Christian Duerr <chrisduerr@users.noreply.github.com> | 2019-03-30 09:23:48 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-03-30 09:23:48 +0000 |
commit | 91aa683bcd060b2ac2f621a388a6448f564d0537 (patch) | |
tree | 924c9a0759a84be19e397eae8cc28cbd3500d553 /src/url.rs | |
parent | 28636923e02a6cfac0fc950b963623cbcad5fda9 (diff) | |
download | alacritty-91aa683bcd060b2ac2f621a388a6448f564d0537.tar.gz alacritty-91aa683bcd060b2ac2f621a388a6448f564d0537.zip |
Rework URL highlighting
This completely reworks URL highlighting to fix two issues which were
caused by the original approach.
The primary issues that were not straight-forward to resolve with the
previous implementation were about handling the URL highlighted content
moving while the highlight is active.
This lead to issues with highlighting with scrolling and when the
display offset was not 0.
The new approach sticks closely to prior art done for the selection,
where the selection is tracked on the grid and updated whenever the
buffer is rotated.
The truncation of URLs was incorrectly assuming input to be just a
single codepoint wide to truncate the end of URLs with unmatching
closing parenthesis. This is now handled properly using Rust's built-in
Unicode support.
This fixes #2231.
This fixes #2225.
Diffstat (limited to 'src/url.rs')
-rw-r--r-- | src/url.rs | 42 |
1 files changed, 11 insertions, 31 deletions
@@ -13,6 +13,7 @@ // limitations under the License. use url; +use unicode_width::UnicodeWidthChar; use crate::term::cell::{Cell, Flags}; @@ -28,14 +29,12 @@ const URL_SCHEMES: [&str; 8] = [ pub struct Url { pub text: String, pub origin: usize, - pub len: usize, } /// Parser for streaming inside-out detection of URLs. pub struct UrlParser { state: String, origin: usize, - len: usize, } impl UrlParser { @@ -43,7 +42,6 @@ impl UrlParser { UrlParser { state: String::new(), origin: 0, - len: 0, } } @@ -51,7 +49,6 @@ impl UrlParser { pub fn advance_left(&mut self, cell: &Cell) -> bool { if cell.flags.contains(Flags::WIDE_CHAR_SPACER) { self.origin += 1; - self.len += 1; return false; } @@ -59,7 +56,6 @@ impl UrlParser { true } else { self.origin += 1; - self.len += 1; false } } @@ -67,16 +63,10 @@ impl UrlParser { /// Advance the parser one character to the right. pub fn advance_right(&mut self, cell: &Cell) -> bool { if cell.flags.contains(Flags::WIDE_CHAR_SPACER) { - self.len += 1; return false; } - if self.advance(cell.c, self.state.len()) { - true - } else { - self.len += 1; - false - } + self.advance(cell.c, self.state.len()) } /// Returns the URL if the parser has found any. @@ -93,7 +83,7 @@ impl UrlParser { match c { 'a'...'z' | 'A'...'Z' => (), _ => { - self.origin = self.origin.saturating_sub(byte_index + 1); + self.origin = self.origin.saturating_sub(byte_index + c.width().unwrap_or(1)); self.state = self.state.split_off(byte_index + c.len_utf8()); break; } @@ -104,7 +94,7 @@ impl UrlParser { // Remove non-matching parenthesis and brackets let mut open_parens_count: isize = 0; let mut open_bracks_count: isize = 0; - for (i, c) in self.state.chars().enumerate() { + for (i, c) in self.state.char_indices() { match c { '(' => open_parens_count += 1, ')' if open_parens_count > 0 => open_parens_count -= 1, @@ -140,7 +130,6 @@ impl UrlParser { Some(Url { origin: self.origin - 1, text: self.state, - len: self.len, }) } else { None @@ -247,25 +236,14 @@ mod tests { let term = url_create_term("https://全.org"); let url = term.url_search(Point::new(0, Column(9))); assert_eq!(url.map(|u| u.origin), Some(9)); - } - - #[test] - fn url_len() { - let term = url_create_term(" test https://example.org "); - let url = term.url_search(Point::new(0, Column(10))); - assert_eq!(url.map(|u| u.len), Some(19)); - let term = url_create_term("https://全.org"); - let url = term.url_search(Point::new(0, Column(0))); - assert_eq!(url.map(|u| u.len), Some(14)); - - let term = url_create_term("https://全.org"); - let url = term.url_search(Point::new(0, Column(10))); - assert_eq!(url.map(|u| u.len), Some(14)); + let term = url_create_term("test@https://example.org"); + let url = term.url_search(Point::new(0, Column(9))); + assert_eq!(url.map(|u| u.origin), Some(4)); - let term = url_create_term("https://全.org"); + let term = url_create_term("test全https://example.org"); let url = term.url_search(Point::new(0, Column(9))); - assert_eq!(url.map(|u| u.len), Some(14)); + assert_eq!(url.map(|u| u.origin), Some(3)); } #[test] @@ -288,6 +266,8 @@ mod tests { url_test("'https://example.org'", "https://example.org"); url_test("'https://example.org", "https://example.org"); url_test("https://example.org'", "https://example.org"); + + url_test("(https://example.org/test全)", "https://example.org/test全"); } #[test] |