Show HN: Tag – instantly jump to your ag matches
github.com
github.com
(Ag = Chemical symbol for silver)
Still, I will check out ag. Maybe this time I will stick with it.
On a side note: People often say that C is just for legacy, and today everything new should be written in a higher level language unless it's a kernel or otherwise inherently low-level. Yet ag is basically a rewrite of ack in C.
Side note: originally, ag was single-threaded. When I added pthreads, it only gave a 15% speedup in my test benchmark.[1] The speedup is larger if checking a file for matches requires more CPU usage (such as when using a complex regex).
1. http://geoff.greer.fm/2012/09/07/the-silver-searcher-adding-...
I don't understand the I/O part of the whole deal. AFAIK you can't read multiple files at once off the drive, so are the files read sequentially to memory and then searched in parallel in memory? Does memory allow you to read multiple places at once, even with multiple threads? Surely the files are too large for the processor caches to be of any effect. So if you'd entertain my curiosity a bit more, is what's happening the fact that multiple files are cached in memory and memory is so fast that loading bits of the files to the processor cache takes less time than regexing those bits, moving the balance of this process to the CPU-bound side? Is the actual parallelism in the fact that multiple cores can search their individual caches at the same time and loading those caches from the RAM is fast enough to not become a bottleneck? Sorry for possibly amateurish question, I've never dug deep enough when it comes to parallelism to understand this, but I spent a good amount of time thinking about parallelising I/O stuff and came to the conclusion that I/O must be magnitudes slower and thus always is a bottleneck and any sort of I/O-bound problem (which file search surely is) must be non-parallelizable and instead can only be sped up by keeping indexes the way some OS's do.
As an example, we have a server that can saturate 40 cores of CPU during load if fed data quickly enough. On the first load after cold boot, it takes about 2 minutes to run (fed by SSDs). Second boot, about 30 seconds.
If we run a sequential data load off SSD, it's more like 8 minutes on the cold run. So, even off non-RAM storage, parallel reads can help a lot.
While coding, your overall system is really just idling and it wouldn't be unusual for many of your projects header files and source files to be cached in memory because of your last compile. This effect is more pronounced on machines with a lot of memory of course. The cost savings from careful disk management is very important overall, but will it speed up the ag application? I'm surprised that ag only gets a 15% speed up with threads, but naturally it will depend on many factors.
https://msdn.microsoft.com/en-us/library/windows/desktop/aa3...
See: https://github.com/rking/ag.vim
or see: http://codeinthehole.com/writing/using-the-silver-searcher-w...
> Inside vim, vim-grepper or ag.vim is probably the way to go. Outside vim (or inside a Neovim :terminal), tag is your best friend.
:cex system('grep_or_ag_or_whatever -flags pattern') | copen
With proper ':set errorformat=...', you can call your compiler with this, or 'go test', or much more various stuff (even Go panic stacktraces).
The worst are new editor packages; trying to follow what's going on in a Vim session or an Emacs session with the author flying through the features of his or her new package without commentary is always frustrating to me.
EDITOR="FOO"
$EDITOR $FILE
Are there issues with this? I can't imagine a reason they'd need to export $EDITOR to the parent shell process. ~/badcode$ echo "func" > badfile.go\;\ echo\ \"Gotcha\!\"
~/badcode$ ls
badfile.go; echo "Gotcha!"
~/badcode$ tag func
badfile.go; echo "Gotcha!"
[1] 1:func
~/badcode$ e1
Gotcha! +1
In case that's not clear, I was able to create a file with a name that contains potentially malicious shell commands that is now bound to an alias via tag.Other ways to implement the shortcuts: create a flag or subcommand to look up an hit from the results file and jump to it (I can alias this command to suit my taste) or prompt me for input before returning to the command line.
[alias]
grepgvim = "!f() { git grep -l \"$@\" | xargs gvim -p; }; f"
It seems "Tag" is a little fancier in that it lets you go to specific matching lines, for the specific match. Tag is a command-line equivalent to `git cola grep <pattern>`, where you can select the matches visually in a GUI (with keyboard shortcuts) and then launch $EDITOR (e.g. gvim) on the matching line.To the Tag author, maybe users would find this tidier if `tag` let you edit matches directly by invoking e.g. `tag func -e 96` and tag will do the rest?
In such a scheme someone could even set the alias file to `/dev/null` and it'd allow both the current workflow and a new one that didn't rely on aliases.
Maybe you can pipe ag to the venerable "dialog" (yes that thing is garbage and reminds me of old school RedHat installs) but I wonder if someone has something better.
$ tag func # returns e1..e4, e5, e6 and dumps them in .tag-locations
$ tagopen e4 # uses .tag-locations to open $EDITOR
you still have scary global state, but at least it's limited to the `tag/opentag` command.
Plus, you can do `tagopen` without arguments and show a menu :)For source code I've had a really good experience with ctags[1].
but that hardly qualifies as "being able to google".
RTFM
The progression is grep with a ton of flags (or even find | xargs grep) -> ack -> ag.
ag is faster than ack, automatically understands .gitignore, gives you .agignore as well, and is just a really nice piece of software.
Does seem like there is hope, as a BSD licensed version exists. My fingers are crossed that this is solved soon :)
I often need to search only on a subset of the files checked in git. Example, I don't search the min.js files but I need them for the deploys.
It would be nice if they could share the same format.
$ time grep -r some_token .
real 0m0.467s
user 0m0.252s
sys 0m0.215s
$ time ag some_token
real 0m2.948s
user 0m0.112s
sys 0m3.083s
(Both run twice to ensure the disk cache was warm).Am I doing something wrong?
$ time grep -r f_admin .
35.87s user 6.50s system 65% cpu 1:04.47 total
$ time ag f_admin
1.51s user 4.94s system 196% cpu 3.284 total