mirror of
https://github.com/zed-industries/zed.git
synced 2024-11-08 07:35:01 +03:00
Fix search/replace start of line anchor (#13920)
This is related to #9428 I noticed that doing a search and replace for the beginning of a line `^` results in the trailing line being included in the search. This seems to be because of the way the range is generated for generating matches being the up to the start of the trailing line rather than up to the end of the last line. I added a test and took a stab at fixing it but it is a bit yolo as this is the first time I've seen this codebase.
This commit is contained in:
parent
09e7b481b8
commit
c093bc8aa8
@ -2,6 +2,7 @@ use std::{ops::Range, sync::OnceLock, time::Duration};
|
||||
|
||||
use gpui::{actions, impl_actions, ViewContext};
|
||||
use language::Point;
|
||||
use multi_buffer::MultiBufferRow;
|
||||
use regex::Regex;
|
||||
use search::{buffer_search, BufferSearchBar, SearchOptions};
|
||||
use serde_derive::Deserialize;
|
||||
@ -362,9 +363,11 @@ fn replace_command(
|
||||
if let Some(editor) = editor.as_mut() {
|
||||
editor.update(cx, |editor, cx| {
|
||||
let snapshot = &editor.snapshot(cx).buffer_snapshot;
|
||||
let end_row = MultiBufferRow(range.end.saturating_sub(1) as u32);
|
||||
let end_point = Point::new(end_row.0, snapshot.line_len(end_row));
|
||||
let range = snapshot
|
||||
.anchor_before(Point::new(range.start.saturating_sub(1) as u32, 0))
|
||||
..snapshot.anchor_before(Point::new(range.end as u32, 0));
|
||||
..snapshot.anchor_after(end_point);
|
||||
editor.set_search_within_ranges(&[range], cx)
|
||||
})
|
||||
}
|
||||
@ -727,6 +730,50 @@ mod test {
|
||||
});
|
||||
}
|
||||
|
||||
// cargo test -p vim --features neovim test_replace_with_range_at_start
|
||||
#[gpui::test]
|
||||
async fn test_replace_with_range_at_start(cx: &mut gpui::TestAppContext) {
|
||||
let mut cx = NeovimBackedTestContext::new(cx).await;
|
||||
|
||||
cx.set_shared_state(indoc! {
|
||||
"ˇa
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
"
|
||||
})
|
||||
.await;
|
||||
cx.simulate_shared_keystrokes(": 2 , 5 s / ^ / b").await;
|
||||
cx.simulate_shared_keystrokes("enter").await;
|
||||
cx.shared_state().await.assert_eq(indoc! {
|
||||
"a
|
||||
ba
|
||||
ba
|
||||
ba
|
||||
ˇba
|
||||
a
|
||||
a
|
||||
"
|
||||
});
|
||||
cx.executor().advance_clock(Duration::from_millis(250));
|
||||
cx.run_until_parked();
|
||||
|
||||
cx.simulate_shared_keystrokes("/ a enter").await;
|
||||
cx.shared_state().await.assert_eq(indoc! {
|
||||
"a
|
||||
ba
|
||||
ba
|
||||
ba
|
||||
bˇa
|
||||
a
|
||||
a
|
||||
"
|
||||
});
|
||||
}
|
||||
|
||||
// cargo test -p vim --features neovim test_replace_with_range
|
||||
#[gpui::test]
|
||||
async fn test_replace_with_range(cx: &mut gpui::TestAppContext) {
|
||||
|
16
crates/vim/test_data/test_replace_with_range_at_start.json
Normal file
16
crates/vim/test_data/test_replace_with_range_at_start.json
Normal file
@ -0,0 +1,16 @@
|
||||
{"Put":{"state":"ˇa\na\na\na\na\na\na\n "}}
|
||||
{"Key":":"}
|
||||
{"Key":"2"}
|
||||
{"Key":","}
|
||||
{"Key":"5"}
|
||||
{"Key":"s"}
|
||||
{"Key":"/"}
|
||||
{"Key":"^"}
|
||||
{"Key":"/"}
|
||||
{"Key":"b"}
|
||||
{"Key":"enter"}
|
||||
{"Get":{"state":"a\nba\nba\nba\nˇba\na\na\n ","mode":"Normal"}}
|
||||
{"Key":"/"}
|
||||
{"Key":"a"}
|
||||
{"Key":"enter"}
|
||||
{"Get":{"state":"a\nba\nba\nba\nbˇa\na\na\n ","mode":"Normal"}}
|
Loading…
Reference in New Issue
Block a user