mirror of
https://github.com/alacritty/alacritty.git
synced 2024-11-18 13:55:23 -05:00
Add support for double-click bracket-pair selection
This commit is contained in:
parent
ca9724a5ef
commit
1656aff85e
3 changed files with 57 additions and 2 deletions
|
@ -25,6 +25,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
- Config option `working_directory`
|
||||
- Config group `debug` with the options `debug.log_level`, `debug.print_events`
|
||||
and `debug.ref_test`
|
||||
- Select until next matching bracket when double-clicking a bracket
|
||||
|
||||
### Changed
|
||||
|
||||
|
|
|
@ -188,14 +188,20 @@ impl Selection {
|
|||
Selection::alt_screen_clamp(&mut start, &mut end, lines, cols)?;
|
||||
}
|
||||
|
||||
let (mut start, mut end) = if start < end && start.line == end.line {
|
||||
let (mut start, mut end) = if start == end {
|
||||
if let Some(end) = grid.bracket_search(start.into()) {
|
||||
(start.into(), end)
|
||||
} else {
|
||||
(grid.semantic_search_right(start.into()), grid.semantic_search_left(end.into()))
|
||||
}
|
||||
} else if start < end && start.line == end.line {
|
||||
(grid.semantic_search_left(start.into()), grid.semantic_search_right(end.into()))
|
||||
} else {
|
||||
(grid.semantic_search_right(start.into()), grid.semantic_search_left(end.into()))
|
||||
};
|
||||
|
||||
if start > end {
|
||||
::std::mem::swap(&mut start, &mut end);
|
||||
std::mem::swap(&mut start, &mut end);
|
||||
}
|
||||
|
||||
Some(Span { start, end })
|
||||
|
|
|
@ -46,6 +46,9 @@ use crate::tty;
|
|||
pub mod cell;
|
||||
pub mod color;
|
||||
|
||||
/// Used to match equal brackets, when performing a bracket-pair selection.
|
||||
const BRACKET_PAIRS: [(char, char); 4] = [('(', ')'), ('[', ']'), ('{', '}'), ('<', '>')];
|
||||
|
||||
/// A type that can expand a given point to a region
|
||||
///
|
||||
/// Usually this is implemented for some 2-D array type since
|
||||
|
@ -57,6 +60,8 @@ pub trait Search {
|
|||
fn semantic_search_right(&self, _: Point<usize>) -> Point<usize>;
|
||||
/// Find the nearest URL boundary in both directions.
|
||||
fn url_search(&self, _: Point<usize>) -> Option<Url>;
|
||||
/// Find the nearest matching bracket.
|
||||
fn bracket_search(&self, _: Point<usize>) -> Option<Point<usize>>;
|
||||
}
|
||||
|
||||
impl Search for Term {
|
||||
|
@ -137,6 +142,49 @@ impl Search for Term {
|
|||
}
|
||||
url_parser.url()
|
||||
}
|
||||
|
||||
fn bracket_search(&self, point: Point<usize>) -> Option<Point<usize>> {
|
||||
let start_char = self.grid[point.line][point.col].c;
|
||||
|
||||
// Find the matching bracket we're looking for
|
||||
let (forwards, end_char) = BRACKET_PAIRS.iter().find_map(|(open, close)| {
|
||||
if open == &start_char {
|
||||
Some((true, *close))
|
||||
} else if close == &start_char {
|
||||
Some((false, *open))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})?;
|
||||
|
||||
let mut iter = self.grid.iter_from(point);
|
||||
|
||||
// For every character match that equals the starting bracket, we
|
||||
// ignore one bracket of the opposite type.
|
||||
let mut skip_pairs = 0;
|
||||
|
||||
loop {
|
||||
// Check the next cell
|
||||
let cell = if forwards { iter.next() } else { iter.prev() };
|
||||
|
||||
// Break if there are no more cells
|
||||
let c = match cell {
|
||||
Some(cell) => cell.c,
|
||||
None => break,
|
||||
};
|
||||
|
||||
// Check if the bracket matches
|
||||
if c == end_char && skip_pairs == 0 {
|
||||
return Some(iter.cur);
|
||||
} else if c == start_char {
|
||||
skip_pairs += 1;
|
||||
} else if c == end_char {
|
||||
skip_pairs -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
impl selection::Dimensions for Term {
|
||||
|
|
Loading…
Reference in a new issue