mirror of
https://github.com/alacritty/alacritty.git
synced 2024-11-18 13:55:23 -05:00
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.
This commit is contained in:
parent
dd8639b6cc
commit
fbefd804c8
2 changed files with 58 additions and 8 deletions
|
@ -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
|
||||
|
||||
|
|
|
@ -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"))]
|
||||
|
|
Loading…
Reference in a new issue