use more predictable rules for selecting which bracket to jump to and where
This commit is contained in:
parent
5041300b52
commit
0ba051a754
15 changed files with 457 additions and 217 deletions
|
@ -4752,27 +4752,52 @@ impl Editor {
|
|||
_: &MoveToEnclosingBracket,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) {
|
||||
let buffer = self.buffer.read(cx).snapshot(cx);
|
||||
let mut selections = self.selections.all::<usize>(cx);
|
||||
for selection in &mut selections {
|
||||
if let Some((open_range, close_range)) =
|
||||
buffer.enclosing_bracket_ranges(selection.start..selection.end)
|
||||
{
|
||||
let close_range = close_range.to_inclusive();
|
||||
let destination = if close_range.contains(&selection.start)
|
||||
&& close_range.contains(&selection.end)
|
||||
{
|
||||
open_range.end
|
||||
} else {
|
||||
*close_range.start()
|
||||
};
|
||||
selection.start = destination;
|
||||
selection.end = destination;
|
||||
}
|
||||
}
|
||||
|
||||
self.change_selections(Some(Autoscroll::fit()), cx, |s| {
|
||||
s.select(selections);
|
||||
s.move_offsets_with(|snapshot, selection| {
|
||||
let Some(enclosing_bracket_ranges) = snapshot.enclosing_bracket_ranges(selection.start..selection.end) else { return; };
|
||||
|
||||
let mut best_length = usize::MAX;
|
||||
let mut best_inside = false;
|
||||
let mut best_in_bracket_range = false;
|
||||
let mut best_destination = None;
|
||||
for (open, close) in enclosing_bracket_ranges {
|
||||
let close = close.to_inclusive();
|
||||
let length = close.end() - open.start;
|
||||
let inside = selection.start >= open.end && selection.end <= *close.start();
|
||||
let in_bracket_range = open.to_inclusive().contains(&selection.head()) || close.contains(&selection.head());
|
||||
|
||||
// If best is next to a bracket and current isn't, skip
|
||||
if !in_bracket_range && best_in_bracket_range {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Prefer smaller lengths unless best is inside and current isn't
|
||||
if length > best_length && (best_inside || !inside) {
|
||||
continue;
|
||||
}
|
||||
|
||||
best_length = length;
|
||||
best_inside = inside;
|
||||
best_in_bracket_range = in_bracket_range;
|
||||
best_destination = Some(if close.contains(&selection.start) && close.contains(&selection.end) {
|
||||
if inside {
|
||||
open.end
|
||||
} else {
|
||||
open.start
|
||||
}
|
||||
} else {
|
||||
if inside {
|
||||
*close.start()
|
||||
} else {
|
||||
*close.end()
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if let Some(destination) = best_destination {
|
||||
selection.collapse_to(destination, SelectionGoal::None);
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue