diff options
author | Christian Duerr <contact@christianduerr.com> | 2019-01-03 21:04:54 +0100 |
---|---|---|
committer | Christian Duerr <chrisduerr@users.noreply.github.com> | 2019-01-05 20:49:39 +0000 |
commit | fbefd804c8785caa058d512a95a8e41a21c69435 (patch) | |
tree | b83883fd2dd93820fef0a9ee5f44a12d8e40103d | |
parent | dd8639b6cc5d635d2826a05b7449c2a10d4af4c3 (diff) | |
download | alacritty-fbefd804c8785caa058d512a95a8e41a21c69435.tar.gz alacritty-fbefd804c8785caa058d512a95a8e41a21c69435.zip |
Fix removal of trailing URL characters
Some characters were not correctly stripped from the end of URLs with
the URL launching feature. The list of URL separator characters has been
extended to include '<', '>', '"', ' ', '{', '}', '|', '\\', '^' and
'`', following the URL specification defined here:
https://tools.ietf.org/html/rfc3987#page-13
Additionally, a list of characters which are always stripped from the
end of URLs has been setup to contain '.', ',', ';', ':', '?', '!', and
'/'.
This fixes #1753.
-rw-r--r-- | CHANGELOG.md | 1 | ||||
-rw-r--r-- | src/term/mod.rs | 65 |
2 files changed, 58 insertions, 8 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 25175656..30d3a483 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Fixed rendering non default mouse cursors in terminal mouse mode (linux) - Fix the `Copy` `mouse_bindings` action ([#1963](https://github.com/jwilm/alacritty/issues/1963)) - URLs are only launched when left-clicking +- Removal of extra characters (like `,`) at the end of URLs has been improved ## Version 0.2.4 diff --git a/src/term/mod.rs b/src/term/mod.rs index bb65fba6..c699adc9 100644 --- a/src/term/mod.rs +++ b/src/term/mod.rs @@ -38,7 +38,9 @@ pub mod color; pub use self::cell::Cell; use self::cell::LineLength; -const URL_SEPARATOR_CHARS: [char; 3] = [' ', '"', '\'']; +// See https://tools.ietf.org/html/rfc3987#page-13 +const URL_SEPARATOR_CHARS: [char; 10] = ['<', '>', '"', ' ', '{', '}', '|', '\\', '^', '`']; +const URL_DENY_END_CHARS: [char; 7] = ['.', ',', ';', ':', '?', '!', '/']; /// A type that can expand a given point to a region /// @@ -124,17 +126,24 @@ impl Search for Term { buf.push(cell.c); } - // Heuristic to remove all leading '(' + // Remove all leading '(' while buf.starts_with('(') { buf.remove(0); } - // Heuristic to remove all ')' from end of URLs without matching '(' - let str_count = |text: &str, c: char| { - text.chars().filter(|tc| *tc == c).count() - }; - while buf.ends_with(')') && str_count(&buf, '(') < str_count(&buf, ')') { - buf.pop(); + // Remove all ')' from end of URLs without matching '(' + let open_count = buf.chars().filter(|&c| c == '(').count(); + let closed_count = buf.chars().filter(|&c| c == ')').count(); + let mut parens_diff = closed_count - open_count; + + // Remove all characters which aren't allowed at the end of a URL + while !buf.is_empty() + && (URL_DENY_END_CHARS.contains(&buf.chars().last().unwrap()) + || (parens_diff > 0 && buf.ends_with(')'))) + { + if buf.pop().unwrap() == ')' { + parens_diff -= 1; + } } // Check if string is valid url @@ -2467,6 +2476,46 @@ mod tests { assert_eq!(url, None); } + + // `ftp://a.de.,;:)!/?` -> `Some("ftp://a.de")` + #[test] + fn url_remove_end_chars() { + let size = SizeInfo { + width: 21.0, + height: 51.0, + cell_width: 3.0, + cell_height: 3.0, + padding_x: 0.0, + padding_y: 0.0, + dpr: 1.0, + }; + let mut term = Term::new(&Default::default(), size); + let mut grid: Grid<Cell> = Grid::new(Line(1), Column(18), 0, Cell::default()); + grid[Line(0)][Column(0)].c = 'f'; + grid[Line(0)][Column(1)].c = 't'; + grid[Line(0)][Column(2)].c = 'p'; + grid[Line(0)][Column(3)].c = ':'; + grid[Line(0)][Column(4)].c = '/'; + grid[Line(0)][Column(5)].c = '/'; + grid[Line(0)][Column(6)].c = 'a'; + grid[Line(0)][Column(7)].c = '.'; + grid[Line(0)][Column(8)].c = 'd'; + grid[Line(0)][Column(9)].c = 'e'; + grid[Line(0)][Column(10)].c = '.'; + grid[Line(0)][Column(11)].c = ','; + grid[Line(0)][Column(12)].c = ';'; + grid[Line(0)][Column(13)].c = ':'; + grid[Line(0)][Column(14)].c = ')'; + grid[Line(0)][Column(15)].c = '!'; + grid[Line(0)][Column(16)].c = '/'; + grid[Line(0)][Column(17)].c = '?'; + mem::swap(&mut term.grid, &mut grid); + + // Search for URL in grid + let url = term.url_search(Point::new(0, Column(4))); + + assert_eq!(url, Some("ftp://a.de".into())); + } } #[cfg(all(test, feature = "bench"))] |