aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Duerr <contact@christianduerr.com>2019-01-03 21:04:54 +0100
committerChristian Duerr <chrisduerr@users.noreply.github.com>2019-01-05 20:49:39 +0000
commitfbefd804c8785caa058d512a95a8e41a21c69435 (patch)
treeb83883fd2dd93820fef0a9ee5f44a12d8e40103d
parentdd8639b6cc5d635d2826a05b7449c2a10d4af4c3 (diff)
downloadalacritty-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.md1
-rw-r--r--src/term/mod.rs65
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"))]