-
-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Files with matches #42
Files with matches #42
Conversation
@BurntSushi So I think, if I'm understanding this code correctly, to terminate early for mmap searching I could just break out of for m in self.grep.iter(self.buf) {
if self.opts.invert_match {
self.print_inverted_matches(last_end, m.start());
} else {
self.print_match(m.start(), m.end());
}
last_end = m.end();
} t the first match. Is this loop "for matches in lazy iter"? I could use some pointers for sure 😉 (pun totally intended). For now I'm going to eat some dinner and get to those video games, but this was fun! |
You got it, that's right. Breaking out of that loop is perfect. Note that you'll also need to do this in |
@andschwa Thanks for working on this by the way! Enjoy the video games. :-) |
@@ -203,6 +213,9 @@ impl<'a, R: io::Read, W: Terminal + Send> Searcher<'a, R, W> { | |||
break; | |||
} | |||
while self.inp.pos < self.inp.lastnl { | |||
if self.opts.files_with_matches && self.match_count > 0 { | |||
break; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@BurntSushi in my experimentation, this seemed to work correctly to terminate after one match. However, I expected to be able to just break at the first match further down in the loop... but when I tried that I found that the match_count was > 1 at the top of the loop, which was unexpected. I'm missing something.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
match_count
could increase by more than than you might expect if you're doing inverted
matching. For regular searching, match_count
should only be incremented by 1
at most on each iteration.
I would probably move this check to right after the call to read_match
. i.e., if self.opts.files_with_matches && matched { break; }
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It can't be right after it because the first match needs to be handled. But what's odd is that if I put it at the end of the while loop, I get this:
loop {
println!("{:?} {}", self.path, self.match_count);
...
while ... {
...
if self.opts.files_with_matches && matched {
break;
}
}
}
"src/args.rs" 1
"src/args.rs" 2
"src/args.rs" 3
"src/args.rs" 3
I think I have to break out of both loops maybe.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, yes, indeed you do. The outer loop corresponds to refilling the buffer with data from the file and the inner loop corresponds to iterating over all matches within that buffer. Breaking out of the inner loop won't cause the outer loop to stop.
You might consider changing loop
to while !self.opts.files_with_matches || self.match_count == 0
or something similar. (With the case unfortunately repeated inside the while
loop as well.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added a small terminate()
function; it's working just grand.
@@ -281,7 +297,7 @@ impl<'a, R: io::Read, W: Terminal + Send> Searcher<'a, R, W> { | |||
|
|||
#[inline(always)] | |||
fn print_before_context(&mut self, upto: usize) { | |||
if self.opts.count || self.opts.before_context == 0 { | |||
if self.opts.count || self.opts.files_with_matches || self.opts.before_context == 0 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@BurntSushi I think it might not be a bad refactor to add an opts.just_file = self.opts.count || self.opts.files_with_matches
, which can replace four instances of this or statement; eh?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's fine, but I wouldn't add a new field. I'd just add a method on the Options
struct. :-)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added opts.skip_matches()
, definitely feels better.
8c3b62b
to
7e83fa2
Compare
Just FYI I'm already using this; I wanted to rename a function I'd plumbed through: ./target/debug/rg -l just_file | xargs gsed -i 's/just_file/skip_matches/g' 🎉 |
7e83fa2
to
7373738
Compare
So either |
616f51f
to
83d5720
Compare
@BurntSushi okay this is ready for review! |
Hm my test failures are due to a few runners swapping the order in which the output was written. |
Run with -j1. On Sep 24, 2016 11:03 PM, "Andrew Schwartzmeyer" notifications@github.com
|
deef5b5
to
f18cb54
Compare
Sadly, while Since I don't actually need to test with multiple files... I'm going the simpler route and just testing with |
f18cb54
to
6869ec0
Compare
Sounds good to me! On Sep 24, 2016 11:23 PM, "Andrew Schwartzmeyer" notifications@github.com
|
So, this is admittedly strange, but Travis CI appears to be caching the built targets (and so left around my created test file |
That's fine sure, although I haven't seen that happen before! On Sep 24, 2016 11:48 PM, "Andrew Schwartzmeyer" notifications@github.com
|
Closes BurntSushi#26. Acts like --count but emits only the paths of files with matches, suitable for piping to xargs. Both mmap and no-mmap searches terminate after the first match is found. Documentation updated and tests added.
31ba079
to
a8f3d9e
Compare
I just reviewed it and this is high quality work. Thank you so much. :-) Your code refactoring is also going to help fix #77. Yay! |
Thank you! I really wanted this feature, and missed programming in Rust a lot. Cheers! |
Files with matches
Resolves #26 (or at least starts to).