I don't particularly like the way vim's grep works. It's slow, jumps to the first match (you can suppress this) and generally just doesn't behave the way I want it to behave. I want to search, automatically jump to the first match if only one file is found or get a list of files and choose one to edit. I tried egrep, but was getting strange "too many files" errors, so I switched to ack and everything magically worked (I've no idea why).
noremapg :call MyGrep("lib/") noremap G :call MyGrep("lib/ t/ aggtests/ deps_patched/") noremap f :call MyGrep("lib/", expand(' ')) function! MyGrep(paths, ...) let pattern = a:0 ? a:1 : input("Enter pattern to search for: ") if !strlen(pattern) return endif let command = 'ack "' . pattern . '" ' . a:paths .' -l' let bufname = bufname("%") let result = filter(split( system(command), "\n" ), 'v:val != "'.bufname.'"') let lines = [] if !empty(result) if 1 == len(result) let file = 1 else " grab all the filenames, skipping the current file let lines = [ 'Choose a file to edit:' ] \ + map(range(1, len(result)), 'v:val .": ". result[v:val - 1]') let file = inputlist(lines) end if \ ( file > 0 && len(result) > 1 && file < len(lines) ) \ || \ ( 1 == len(result) && 1 == file ) execute "edit +1 " . result[ file - 1 ] execute "/\\v" . pattern endif else echomsg("No files found matching pattern: " . pattern) endif endfunction
The main drawback is that vim and perl regular expressions aren't compatible (I don't have perl integration in this vim). The '\v' switch mitigates some of the pain, but I think a primitive regex transformation tool might alleviate some of the pain.
Update: Now attempts to skip the current file in the buffer. Not really needed, but when you have two files with the thing you're searching for and you're in one, it will automatically jump to the other. I've found this common enough that it seems an obvious use case.