fix vim percent motion to better match the docs and observed behavior
This commit is contained in:
parent
eac33d732e
commit
57a7ff9a6f
8 changed files with 150 additions and 78 deletions
|
@ -3,7 +3,7 @@ use std::sync::Arc;
|
|||
use editor::{
|
||||
char_kind,
|
||||
display_map::{DisplaySnapshot, ToDisplayPoint},
|
||||
movement, Bias, CharKind, DisplayPoint,
|
||||
movement, Bias, CharKind, DisplayPoint, ToOffset,
|
||||
};
|
||||
use gpui::{actions, impl_actions, MutableAppContext};
|
||||
use language::{Point, Selection, SelectionGoal};
|
||||
|
@ -450,19 +450,53 @@ fn end_of_document(map: &DisplaySnapshot, point: DisplayPoint, line: usize) -> D
|
|||
map.clip_point(new_point, Bias::Left)
|
||||
}
|
||||
|
||||
fn matching(map: &DisplaySnapshot, point: DisplayPoint) -> DisplayPoint {
|
||||
let offset = point.to_offset(map, Bias::Left);
|
||||
if let Some((open_range, close_range)) = map
|
||||
.buffer_snapshot
|
||||
.innermost_enclosing_bracket_ranges(offset..offset)
|
||||
{
|
||||
if open_range.contains(&offset) {
|
||||
close_range.start.to_display_point(map)
|
||||
} else {
|
||||
open_range.start.to_display_point(map)
|
||||
fn matching(map: &DisplaySnapshot, display_point: DisplayPoint) -> DisplayPoint {
|
||||
// https://github.com/vim/vim/blob/1d87e11a1ef201b26ed87585fba70182ad0c468a/runtime/doc/motion.txt#L1200
|
||||
let point = display_point.to_point(map);
|
||||
let offset = point.to_offset(&map.buffer_snapshot);
|
||||
|
||||
// Ensure the range is contained by the current line.
|
||||
let mut line_end = map.next_line_boundary(point).0;
|
||||
if line_end == point {
|
||||
line_end = map.max_point().to_point(map);
|
||||
}
|
||||
line_end.column = line_end.column.saturating_sub(1);
|
||||
|
||||
let line_range = map.prev_line_boundary(point).0..line_end;
|
||||
let ranges = map.buffer_snapshot.bracket_ranges(line_range.clone());
|
||||
if let Some(ranges) = ranges {
|
||||
let line_range = line_range.start.to_offset(&map.buffer_snapshot)
|
||||
..line_range.end.to_offset(&map.buffer_snapshot);
|
||||
let mut closest_pair_destination = None;
|
||||
let mut closest_distance = usize::MAX;
|
||||
|
||||
for (open_range, close_range) in ranges {
|
||||
if open_range.start >= offset && line_range.contains(&open_range.start) {
|
||||
let distance = open_range.start - offset;
|
||||
if distance < closest_distance {
|
||||
closest_pair_destination = Some(close_range.start);
|
||||
closest_distance = distance;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if close_range.start >= offset && line_range.contains(&close_range.start) {
|
||||
let distance = close_range.start - offset;
|
||||
if distance < closest_distance {
|
||||
closest_pair_destination = Some(open_range.start);
|
||||
closest_distance = distance;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
closest_pair_destination
|
||||
.map(|destination| destination.to_display_point(map))
|
||||
.unwrap_or(display_point)
|
||||
} else {
|
||||
point
|
||||
display_point
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -824,17 +824,34 @@ mod test {
|
|||
ˇ
|
||||
brown fox"})
|
||||
.await;
|
||||
cx.assert(indoc! {"
|
||||
|
||||
cx.assert_manual(
|
||||
indoc! {"
|
||||
fn test() {
|
||||
println!(ˇ);
|
||||
}
|
||||
"})
|
||||
.await;
|
||||
cx.assert(indoc! {"
|
||||
}"},
|
||||
Mode::Normal,
|
||||
indoc! {"
|
||||
fn test() {
|
||||
println!();
|
||||
ˇ
|
||||
}"},
|
||||
Mode::Insert,
|
||||
);
|
||||
|
||||
cx.assert_manual(
|
||||
indoc! {"
|
||||
fn test(ˇ) {
|
||||
println!();
|
||||
}"})
|
||||
.await;
|
||||
}"},
|
||||
Mode::Normal,
|
||||
indoc! {"
|
||||
fn test() {
|
||||
ˇ
|
||||
println!();
|
||||
}"},
|
||||
Mode::Insert,
|
||||
);
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
|
@ -996,14 +1013,14 @@ mod test {
|
|||
#[gpui::test]
|
||||
async fn test_capital_f_and_capital_t(cx: &mut gpui::TestAppContext) {
|
||||
let mut cx = NeovimBackedTestContext::new(cx).await;
|
||||
for count in 1..=3 {
|
||||
let test_case = indoc! {"
|
||||
ˇaaaˇbˇ ˇbˇ ˇbˇbˇ aˇaaˇbaaa
|
||||
ˇ ˇbˇaaˇa ˇbˇbˇb
|
||||
ˇ
|
||||
ˇb
|
||||
let test_case = indoc! {"
|
||||
ˇaaaˇbˇ ˇbˇ ˇbˇbˇ aˇaaˇbaaa
|
||||
ˇ ˇbˇaaˇa ˇbˇbˇb
|
||||
ˇ
|
||||
ˇb
|
||||
"};
|
||||
|
||||
for count in 1..=3 {
|
||||
cx.assert_binding_matches_all([&count.to_string(), "shift-f", "b"], test_case)
|
||||
.await;
|
||||
|
||||
|
@ -1014,10 +1031,10 @@ mod test {
|
|||
|
||||
#[gpui::test]
|
||||
async fn test_percent(cx: &mut gpui::TestAppContext) {
|
||||
let mut cx = NeovimBackedTestContext::new(cx).await;
|
||||
for count in 1..=2 {
|
||||
// let test_case = indoc! {"
|
||||
// "}
|
||||
}
|
||||
let mut cx = NeovimBackedTestContext::new(cx).await.binding(["%"]);
|
||||
cx.assert_all("ˇconsole.logˇ(ˇvaˇrˇ)ˇ;").await;
|
||||
cx.assert_all("ˇconsole.logˇ(ˇ'var', ˇ[ˇ1, ˇ2, 3ˇ]ˇ)ˇ;")
|
||||
.await;
|
||||
cx.assert_all("let result = curried_funˇ(ˇ)ˇ(ˇ)ˇ;").await;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1 +1 @@
|
|||
[{"Text":"\n"},{"Mode":"Insert"},{"Selection":{"start":[1,0],"end":[1,0]}},{"Mode":"Insert"},{"Text":"The quick\n"},{"Mode":"Insert"},{"Selection":{"start":[1,0],"end":[1,0]}},{"Mode":"Insert"},{"Text":"The quick\n\nbrown fox\njumps over"},{"Mode":"Insert"},{"Selection":{"start":[1,0],"end":[1,0]}},{"Mode":"Insert"},{"Text":"The quick\nbrown fox\n\njumps over"},{"Mode":"Insert"},{"Selection":{"start":[2,0],"end":[2,0]}},{"Mode":"Insert"},{"Text":"The quick\nbrown fox\njumps over\n"},{"Mode":"Insert"},{"Selection":{"start":[3,0],"end":[3,0]}},{"Mode":"Insert"},{"Text":"The quick\n\n\nbrown fox"},{"Mode":"Insert"},{"Selection":{"start":[2,0],"end":[2,0]}},{"Mode":"Insert"},{"Text":"fn test() {\n println!();\n \n}\n"},{"Mode":"Insert"},{"Selection":{"start":[2,4],"end":[2,4]}},{"Mode":"Insert"},{"Text":"fn test() {\n\n println!();\n}"},{"Mode":"Insert"},{"Selection":{"start":[1,0],"end":[1,0]}},{"Mode":"Insert"}]
|
||||
[{"Text":"\n"},{"Mode":"Insert"},{"Selection":{"start":[1,0],"end":[1,0]}},{"Mode":"Insert"},{"Text":"The quick\n"},{"Mode":"Insert"},{"Selection":{"start":[1,0],"end":[1,0]}},{"Mode":"Insert"},{"Text":"The quick\n\nbrown fox\njumps over"},{"Mode":"Insert"},{"Selection":{"start":[1,0],"end":[1,0]}},{"Mode":"Insert"},{"Text":"The quick\nbrown fox\n\njumps over"},{"Mode":"Insert"},{"Selection":{"start":[2,0],"end":[2,0]}},{"Mode":"Insert"},{"Text":"The quick\nbrown fox\njumps over\n"},{"Mode":"Insert"},{"Selection":{"start":[3,0],"end":[3,0]}},{"Mode":"Insert"},{"Text":"The quick\n\n\nbrown fox"},{"Mode":"Insert"},{"Selection":{"start":[2,0],"end":[2,0]}},{"Mode":"Insert"}]
|
1
crates/vim/test_data/test_percent.json
Normal file
1
crates/vim/test_data/test_percent.json
Normal file
|
@ -0,0 +1 @@
|
|||
[{"Text":"console.log(var);"},{"Mode":"Normal"},{"Selection":{"start":[0,15],"end":[0,15]}},{"Mode":"Normal"},{"Text":"console.log(var);"},{"Mode":"Normal"},{"Selection":{"start":[0,15],"end":[0,15]}},{"Mode":"Normal"},{"Text":"console.log(var);"},{"Mode":"Normal"},{"Selection":{"start":[0,11],"end":[0,11]}},{"Mode":"Normal"},{"Text":"console.log(var);"},{"Mode":"Normal"},{"Selection":{"start":[0,11],"end":[0,11]}},{"Mode":"Normal"},{"Text":"console.log(var);"},{"Mode":"Normal"},{"Selection":{"start":[0,11],"end":[0,11]}},{"Mode":"Normal"},{"Text":"console.log(var);"},{"Mode":"Normal"},{"Selection":{"start":[0,16],"end":[0,16]}},{"Mode":"Normal"},{"Text":"console.log('var', [1, 2, 3]);"},{"Mode":"Normal"},{"Selection":{"start":[0,28],"end":[0,28]}},{"Mode":"Normal"},{"Text":"console.log('var', [1, 2, 3]);"},{"Mode":"Normal"},{"Selection":{"start":[0,28],"end":[0,28]}},{"Mode":"Normal"},{"Text":"console.log('var', [1, 2, 3]);"},{"Mode":"Normal"},{"Selection":{"start":[0,27],"end":[0,27]}},{"Mode":"Normal"},{"Text":"console.log('var', [1, 2, 3]);"},{"Mode":"Normal"},{"Selection":{"start":[0,27],"end":[0,27]}},{"Mode":"Normal"},{"Text":"console.log('var', [1, 2, 3]);"},{"Mode":"Normal"},{"Selection":{"start":[0,19],"end":[0,19]}},{"Mode":"Normal"},{"Text":"console.log('var', [1, 2, 3]);"},{"Mode":"Normal"},{"Selection":{"start":[0,19],"end":[0,19]}},{"Mode":"Normal"},{"Text":"console.log('var', [1, 2, 3]);"},{"Mode":"Normal"},{"Selection":{"start":[0,19],"end":[0,19]}},{"Mode":"Normal"},{"Text":"console.log('var', [1, 2, 3]);"},{"Mode":"Normal"},{"Selection":{"start":[0,11],"end":[0,11]}},{"Mode":"Normal"},{"Text":"console.log('var', [1, 2, 3]);"},{"Mode":"Normal"},{"Selection":{"start":[0,29],"end":[0,29]}},{"Mode":"Normal"},{"Text":"let result = curried_fun()();"},{"Mode":"Normal"},{"Selection":{"start":[0,25],"end":[0,25]}},{"Mode":"Normal"},{"Text":"let result = curried_fun()();"},{"Mode":"Normal"},{"Selection":{"start":[0,24],"end":[0,24]}},{"Mode":"Normal"},{"Text":"let result = curried_fun()();"},{"Mode":"Normal"},{"Selection":{"start":[0,27],"end":[0,27]}},{"Mode":"Normal"},{"Text":"let result = curried_fun()();"},{"Mode":"Normal"},{"Selection":{"start":[0,26],"end":[0,26]}},{"Mode":"Normal"},{"Text":"let result = curried_fun()();"},{"Mode":"Normal"},{"Selection":{"start":[0,28],"end":[0,28]}},{"Mode":"Normal"}]
|
Loading…
Add table
Add a link
Reference in a new issue