tags:

views:

554

answers:

4

Note: marked as community wiki

I code in vim.

I use git; and love git grep.

Does anyone have a particularly nice set of techniques / scripts for using git grep in side of vim?

Readers: please upvote answers involving vim + git grep; please downvote answers involving non-vim editors, and editors referring to external tools besides git grep.

+6  A: 

You do have this VIM extension (created by Timo Hirvonen back in 2006!)

git grep <pattern> searches for a pattern in a currently selected git branch.
This adds :G <pattern> command to run the command from within Vim.

func GitGrep(...)
  let save = &grepprg
  set grepprg=git\ grep\ -n\ $*
  let s = 'grep'
  for i in a:000
    let s = s . ' ' . i
  endfor
  exe s
  let &grepprg = save
endfun
command -nargs=? G call GitGrep(<f-args>)

You can also limit searching to files matching a pattern (git will do the pattern matching):

:G <pattern> -- '*.c'

Additions:

The following addition will run git grep on the word under the cursor when Ctrl+X G is pressed.

func GitGrepWord()
  normal! "zyiw
  call GitGrep('-w -e ', getreg('z'))
endf
nmap <C-x>G :call GitGrepWord()<CR>
VonC
This is awesome. Can you post more / everything you have on this? Even if you post 9 "useless" vim/git-grep interface lines, it's worth it for the 1 trick that I do use.
anon
@anon: added another Vim plugin, as requested (see my second answer)
VonC
When I use, this GitGrep, it first hides my vim screen, shows the result of git grep, then after I press a key, throws me back into vim at the first line -- is there a way to just jump to the first line (and hide the git grep output)
anon
@anon: I am not sure, but I have found another Vim Git encapsulation thatat could be worth checking out. See my third answer below.
VonC
wow, -w does "word" matching as it rejects a match to a subpart of a word? that's amazing. this deserves more +1
anon
@anon: true (for the `-w` option), although `git grep` has many more options (http://www.kernel.org/pub/software/scm/git/docs/git-grep.html)
VonC
+1  A: 

You also have this set of vim commands, from the Git project git grep vim, from tjennings.
(inspired from the ack.vim : Plugin for the Perl module / CLI script 'ack' from Miles Sterrett)

let g:gitgrepprg="git\\ grep\\ -n"

function! GitGrep(args)
    let grepprg_bak=&grepprg
    exec "set grepprg=" . g:gitgrepprg
    execute "silent! grep " . a:args
    botright copen
    let &grepprg=grepprg_bak
    exec "redraw!"
endfunction

function! GitGrepAdd(args)
    let grepprg_bak=&grepprg
    exec "set grepprg=" . g:gitgrepprg
    execute "silent! grepadd " . a:args
    botright copen
    let &grepprg=grepprg_bak
    exec "redraw!"
endfunction

function! LGitGrep(args)
    let grepprg_bak=&grepprg
    exec "set grepprg=" . g:gitgrepprg
    execute "silent! lgrep " . a:args
    botright lopen
    let &grepprg=grepprg_bak
    exec "redraw!"
endfunction

function! LGitGrepAdd(args)
    let grepprg_bak=&grepprg
    exec "set grepprg=" . g:gitgrepprg
    execute "silent! lgrepadd " . a:args
    botright lopen
    let &grepprg=grepprg_bak
    exec "redraw!"
endfunction

command! -nargs=* -complete=file GitGrep call GitGrep(<q-args>)
command! -nargs=* -complete=file GitGrepAdd call GitGrepAdd(<q-args>)
command! -nargs=* -complete=file LGitGrep call LGitGrep(<q-args>)
command! -nargs=* -complete=file LGitGrepAdd call LGitGrepAdd(<q-args>)
VonC
+2  A: 

Check also fugitive.vim - A Git wrapper so awesome, it should be illegal
(that is its official tag-line ;) ), from Tim Pope (see the Git repo project):

It includes, amongst many other commands, one for a git grep:

call s:command("-bar -bang -nargs=? -complete=customlist,s:EditComplete Ggrep :execute s:Grep(<bang>0,<q-args>)")
call s:command("-bar -bang -nargs=* -complete=customlist,s:EditComplete Glog :execute s:Log('grep<bang>',<f-args>)")

function! s:Grep(bang,arg) abort
  let grepprg = &grepprg
  let grepformat = &grepformat
  let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd '
  let dir = getcwd()
  try
    execute cd.'`=s:repo().tree()`'
    let &grepprg = s:repo().git_command('--no-pager', 'grep', '-n')
    let &grepformat = '%f:%l:%m'
    exe 'grep! '.a:arg
    let list = getqflist()
    for entry in list
      if bufname(entry.bufnr) =~ ':'
        let entry.filename = s:repo().translate(bufname(entry.bufnr))
        unlet! entry.bufnr
      elseif a:arg =~# '\%(^\| \)--cached\>'
        let entry.filename = s:repo().translate(':0:'.bufname(entry.bufnr))
        unlet! entry.bufnr
      endif
    endfor
    call setqflist(list,'r')
    if !a:bang && !empty(list)
      return 'cfirst'
    else
      return ''
    endif
  finally
    let &grepprg = grepprg
    let &grepformat = grepformat
    execute cd.'`=dir`'
  endtry
endfunction
VonC
+2  A: 

Still in the same set of Git encapsulation (including git grep), you have:

MinSCM : An abstract front-end for Mercurial/Git/Bazaar , from Takeshi NISHIDA:
See his Git repo

alt text

:MinSCMGrep[!]                  (Default mapping: \sg)

Searches for specified pattern and creates a |quickfix| list.

Used SCM commands ~

  • hg : grep -n
  • git : grep -n -e
  • bzr : (unavailable)
VonC