« Back to home

Ack and Vim integration

Posted on

I’m a fan of Andy Lester’s App::Ack module. This a is a perl program that you can use as a replacement of grep.

Today I wrote a little Vim plugin that integrate ack with Vim. This is a quick hack, it works for me with vim7/ubuntu and vim6.3/fedora.

Just copy/paste the following lines in ~/.vim/plugin/ack.vim

 " usage:
 " (the same as ack, except that the path is required)
 " examples: 
 " :Ack TODO .
 " :Ack sub Util.pm

 function! Ack(args)
   let cmd = "ack -H --nocolor --nogroup " . a:args
   echo "running: " . cmd
 
   let tmpfile = tempname()
   let cmd = cmd . " > " . tmpfile
   call system(cmd)
 
   let efm_bak = &efm
   set efm=%f:%l:%m
   execute "silent! cgetfile " . tmpfile
   let &efm = efm_bak
   botright copen
 
   call delete(tmpfile)
 endfunction
 
 command! -nargs=* -complete=file Ack call Ack(<q-args>)

UPDATE:

ack-1.60 is out, and the documentation mentions another way to integrate ack and vim by using the :grep function of vim:

set grepprg=ack

I think this is a better solution, and to make it nicely integrated with
vim, I wrote this new little function:

 function! Ack(args)
   let grepprg_bak=&grepprg
   set grepprg=ack\ -H\ --nocolor\ --nogroup
   execute "silent! grep " . a:args
   botright copen
   let &grepprg=grepprg_bak
 endfunction
 
 command! -nargs=* -complete=file Ack call Ack(<q-args>)

Just replace the old code by the new one in ~/.vim/plugin/ack.vim

This time it works even if you don't specify the path, and you can still use the :grep function as before, grepprg is saved and restored.

And as Yann says, "then :cnext is your friend"