mirror of
https://github.com/BurntSushi/ripgrep.git
synced 2025-03-03 14:32:22 +02:00
It turned out that --vimgrep wasn't quite getting the column of each match correctly. Instead of printing column numbers relative to the current line, it was printing column numbers as byte offsets relative to where the match began. To fix this, we simply subtract the offset of the line number from the beginning of the match. If the beginning of the match came before the start of the current line, then there's really nothing sensible we can do other than to use a column number of 1, which we now document. Interestingly, existing tests were checking that the previous behavior was intended. My only defense is that I somehow tricked myself into thinking it was a byte offset instead of a column number. Kudos to @bfrg for calling this out in #1866: https://github.com/BurntSushi/ripgrep/issues/1866#issuecomment-841635553
118 lines
3.8 KiB
Rust
118 lines
3.8 KiB
Rust
use crate::hay::SHERLOCK;
|
|
use crate::util::{Dir, TestCommand};
|
|
|
|
// This tests that multiline matches that span multiple lines, but where
|
|
// multiple matches may begin and end on the same line work correctly.
|
|
rgtest!(overlap1, |dir: Dir, mut cmd: TestCommand| {
|
|
dir.create("test", "xxx\nabc\ndefxxxabc\ndefxxx\nxxx");
|
|
cmd.arg("-n").arg("-U").arg("abc\ndef").arg("test");
|
|
eqnice!("2:abc\n3:defxxxabc\n4:defxxx\n", cmd.stdout());
|
|
});
|
|
|
|
// Like overlap1, but tests the case where one match ends at precisely the same
|
|
// location at which the next match begins.
|
|
rgtest!(overlap2, |dir: Dir, mut cmd: TestCommand| {
|
|
dir.create("test", "xxx\nabc\ndefabc\ndefxxx\nxxx");
|
|
cmd.arg("-n").arg("-U").arg("abc\ndef").arg("test");
|
|
eqnice!("2:abc\n3:defabc\n4:defxxx\n", cmd.stdout());
|
|
});
|
|
|
|
// Tests that even in a multiline search, a '.' does not match a newline.
|
|
rgtest!(dot_no_newline, |dir: Dir, mut cmd: TestCommand| {
|
|
dir.create("sherlock", SHERLOCK);
|
|
cmd.args(&["-n", "-U", "of this world.+detective work", "sherlock"]);
|
|
cmd.assert_err();
|
|
});
|
|
|
|
// Tests that the --multiline-dotall flag causes '.' to match a newline.
|
|
rgtest!(dot_all, |dir: Dir, mut cmd: TestCommand| {
|
|
dir.create("sherlock", SHERLOCK);
|
|
cmd.args(&[
|
|
"-n",
|
|
"-U",
|
|
"--multiline-dotall",
|
|
"of this world.+detective work",
|
|
"sherlock",
|
|
]);
|
|
|
|
let expected = "\
|
|
1:For the Doctor Watsons of this world, as opposed to the Sherlock
|
|
2:Holmeses, success in the province of detective work must always
|
|
";
|
|
eqnice!(expected, cmd.stdout());
|
|
});
|
|
|
|
// Tests that --only-matching works in multiline mode.
|
|
rgtest!(only_matching, |dir: Dir, mut cmd: TestCommand| {
|
|
dir.create("sherlock", SHERLOCK);
|
|
cmd.args(&[
|
|
"-n",
|
|
"-U",
|
|
"--only-matching",
|
|
r"Watson|Sherlock\p{Any}+?Holmes",
|
|
"sherlock",
|
|
]);
|
|
|
|
let expected = "\
|
|
1:Watson
|
|
1:Sherlock
|
|
2:Holmes
|
|
3:Sherlock Holmes
|
|
5:Watson
|
|
";
|
|
eqnice!(expected, cmd.stdout());
|
|
});
|
|
|
|
// Tests that --vimgrep works in multiline mode.
|
|
rgtest!(vimgrep, |dir: Dir, mut cmd: TestCommand| {
|
|
dir.create("sherlock", SHERLOCK);
|
|
cmd.args(&[
|
|
"-n",
|
|
"-U",
|
|
"--vimgrep",
|
|
r"Watson|Sherlock\p{Any}+?Holmes",
|
|
"sherlock",
|
|
]);
|
|
|
|
let expected = "\
|
|
sherlock:1:16:For the Doctor Watsons of this world, as opposed to the Sherlock
|
|
sherlock:1:57:For the Doctor Watsons of this world, as opposed to the Sherlock
|
|
sherlock:2:1:Holmeses, success in the province of detective work must always
|
|
sherlock:3:49:be, to a very large extent, the result of luck. Sherlock Holmes
|
|
sherlock:5:12:but Doctor Watson has to have it taken out for him and dusted,
|
|
";
|
|
eqnice!(expected, cmd.stdout());
|
|
});
|
|
|
|
// Tests that multiline search works when reading from stdin. This is an
|
|
// important test because multiline search must read the entire contents of
|
|
// what it is searching into memory before executing the search.
|
|
rgtest!(stdin, |_: Dir, mut cmd: TestCommand| {
|
|
cmd.args(&["-n", "-U", r"of this world\p{Any}+?detective work"]);
|
|
let expected = "\
|
|
1:For the Doctor Watsons of this world, as opposed to the Sherlock
|
|
2:Holmeses, success in the province of detective work must always
|
|
";
|
|
eqnice!(expected, cmd.pipe(SHERLOCK.as_bytes()));
|
|
});
|
|
|
|
// Test that multiline search and contextual matches work.
|
|
rgtest!(context, |dir: Dir, mut cmd: TestCommand| {
|
|
dir.create("sherlock", SHERLOCK);
|
|
cmd.args(&[
|
|
"-n",
|
|
"-U",
|
|
"-C1",
|
|
r"detective work\p{Any}+?result of luck",
|
|
"sherlock",
|
|
]);
|
|
|
|
let expected = "\
|
|
1-For the Doctor Watsons of this world, as opposed to the Sherlock
|
|
2:Holmeses, success in the province of detective work must always
|
|
3:be, to a very large extent, the result of luck. Sherlock Holmes
|
|
4-can extract a clew from a wisp of straw or a flake of cigar ash;
|
|
";
|
|
eqnice!(expected, cmd.stdout());
|
|
});
|