So I'm guessing not many people use ag with inverted matching. Right now:
$ echo foo >> sample
$ echo bar >> sample
$ ag foo sample
$ ag -v foo sample
$ ag -v bar sample
$ ag -v b sample
$ mkdir test
$ cd test
$ echo foo >> sample
$ ag -v foo
Yeah, invert_matches() in util.c screws up if there are matches at the very start or end of a file. I know it's egregious, but it took 7 months for anyone else to notice.
I'm kinda busy today and tomorrow, but I think I can get around to this on Monday.
One of these Mondays....
Try master now. There's one tricky thing though: Newlines count as "not foo". I'm thinking I should change this behavior to be more intuitive. Still, it's better than it used to be.
I looked at ack --help and noticed -v is only supposed to print non-matching lines. Whoops. That makes it much more useful, but I need to change ag to behave that way.
👍 I always end up having to use grep's grep -v because the behavior of ag is way different. I'm hoping for ag to be a one-stop-shop
I use it very often to filter matching results: for example, I want all files matching foo, but ignoring any results that are in folder bar...
ag foo | grep -v bar
I'm used to grep -v and just ran into this issue with ag today. An example:
Note the extra brokenness at the end, represented by my terminal as ^@. It's a null byte in a hexdump.
I'm willing to do or help do the work to make ag behave correctly like ack/grep. @ggreer, can you give me any pointers to what needs to change before I dig in?
Hmm, I see that #88 does note that printing bugs were probably introduced. I guess the null byte is one of them.
The first thing I see is that matches, when passed into print_file_matches(), contains start and ends which correspond to matching bytes (not lines), which is reflected in the colored-printing nicely:
however, because of this, the unwanted lines are not ignored within the newline-parse/print code around print.c:114 like they are for the normal string match, since there is technically a matching byte in each line.
I have started hacking in some code which uses more looking-behind and ahead to see which lines should actually be thrown out. But I think a nicer long-term solution would be to change the matches.start and end indices to exclude the partial/matched-by-reverse lines so that the printing code can be simplified.
@ggreer any progress on this? I really miss the non-matching lines
As you correctly observed, it's a lot more useful that way.
@danielb2 all the above issues were already fixed as of today (ag version 0.24.1)
$ cat foobar.dat
$ ag 'bar' foobar.dat
$ ag -v 'bar' foobar.dat
$ ag 'bar' foobar.dat | ag -v as
$ cat test.dat
1000 2013-12-11 2013-12-11
1000 2013-12-11 2013-12-11:2013-12-10
1000 2013-12-11 2013-12-10
1000 2013-12-11 ?
$ ag '^\d+ (\S+?) \1$' test.dat
1:1000 2013-12-11 2013-12-11
$ ag -v '^\d+ (\S+?) \1$' test.dat
2:1000 2013-12-11 2013-12-11:2013-12-10
3:1000 2013-12-11 2013-12-10
4:1000 2013-12-11 ?
$ ag -v '^\d+ (\S+?) \1$' test.dat | xxd
0000000: 323a 3130 3030 2032 3031 332d 3132 2d31 2:1000 2013-12-1
0000010: 3120 3230 3133 2d31 322d 3131 3a32 3031 1 2013-12-11:201
0000020: 332d 3132 2d31 300a 333a 3130 3030 2032 3-12-10.3:1000 2
0000030: 3031 332d 3132 2d31 3120 3230 3133 2d31 013-12-11 2013-1
0000040: 322d 3130 0a34 3a31 3030 3020 3230 3133 2-10.4:1000 2013
0000050: 2d31 322d 3131 203f 0a -12-11 ?.
👍 Love it. The highlighting is a bit weird would be my only feedback.
$ echo -e "blah foo blah\nfoo bar" > out.txt
$ ag bar out.txt | ag -v blah
The whole foo bar is highlighted. It's easier to see if nothing is highlighted since usually the grep result from -v results in a lot of highlighted text.
@danielb2 I also found highlighting under -v odd, but I guess we should file a new issue, since this thread is rather long now
@nodakai good point. See #478
btw, it think this can be closed now?
I think it can. Thank you everyone for your contributions.