" NOTE: You must, of course, install ag / the_silver_searcher " FIXME: Delete deprecated options below on or after 2016-4 (6 months from when the deprecation warning was added) {{{ if exists("g:agprg") let g:ag_prg = g:agprg echohl WarningMsg call input('g:agprg is deprecated and will be removed. Please use g:ag_prg') echohl None endif if exists("g:aghighlight") let g:ag_highlight = g:aghighlight echohl WarningMsg call input('g:aghighlight is deprecated and will be removed. Please use g:ag_highlight') echohl None endif if exists("g:agformat") let g:ag_format = g:agformat echohl WarningMsg call input('g:agformat is deprecated and will be removed. Please use g:ag_format') echohl None endif " }}} FIXME: Delete the deprecated options above on or after 15-7 (6 months from when they were changed) " Location of the ag utility if !exists("g:ag_prg") " --vimgrep (consistent output we can parse) is available from version 0.25.0+ if split(system("ag --version"), "[ \n\r\t]")[2] =~ '\d\+.\(\(2[5-9]\)\|\([3-9][0-9]\)\)\(.\d\+\)\?' let g:ag_prg="ag --vimgrep" else " --noheading seems odd here, but see https://github.com/ggreer/the_silver_searcher/issues/361 let g:ag_prg="ag --column --nogroup --noheading" endif endif if !exists("g:ag_apply_qmappings") let g:ag_apply_qmappings=1 endif if !exists("g:ag_apply_lmappings") let g:ag_apply_lmappings=1 endif if !exists("g:ag_qhandler") let g:ag_qhandler="botright copen" endif if !exists("g:ag_lhandler") let g:ag_lhandler="botright lopen" endif if !exists("g:ag_mapping_message") let g:ag_mapping_message=1 endif if !exists("g:ag_working_path_mode") let g:ag_working_path_mode = 'c' endif function! ag#AgBuffer(cmd, args) let l:bufs = filter(range(1, bufnr('$')), 'buflisted(v:val)') let l:files = [] for buf in l:bufs let l:file = fnamemodify(bufname(buf), ':p') if !isdirectory(l:file) call add(l:files, l:file) endif endfor call ag#Ag(a:cmd, a:args . ' ' . join(l:files, ' ')) endfunction function! ag#Ag(cmd, args) let l:ag_executable = get(split(g:ag_prg, " "), 0) " Ensure that `ag` is installed if !executable(l:ag_executable) echoe "Ag command '" . l:ag_executable . "' was not found. Is the silver searcher installed and on your $PATH?" return endif " If no pattern is provided, search for the word under the cursor if empty(a:args) let l:grepargs = expand("") else let l:grepargs = a:args . join(a:000, ' ') end if empty(l:grepargs) echo "Usage: ':Ag {pattern}' (or just :Ag to search for the word under the cursor). See ':help :Ag' for more information." return endif " Format, used to manage column jump if a:cmd =~# '-g$' let s:ag_format_backup=g:ag_format let g:ag_format="%f" elseif exists("s:ag_format_backup") let g:ag_format=s:ag_format_backup elseif !exists("g:ag_format") let g:ag_format="%f:%l:%c:%m" endif let l:grepprg_bak=&grepprg let l:grepformat_bak=&grepformat let l:t_ti_bak=&t_ti let l:t_te_bak=&t_te try let &grepprg=g:ag_prg let &grepformat=g:ag_format set t_ti= set t_te= if g:ag_working_path_mode ==? 'r' " Try to find the projectroot for current buffer let l:cwd_back = getcwd() let l:cwd = s:guessProjectRoot() try exe "lcd ".l:cwd catch echom 'Failed to change directory to:'.l:cwd finally silent! execute a:cmd . " " . escape(l:grepargs, '|') exe "lcd ".l:cwd_back endtry else " Someone chose an undefined value or 'c' so we revert to the default silent! execute a:cmd . " " . escape(l:grepargs, '|') endif finally let &grepprg=l:grepprg_bak let &grepformat=l:grepformat_bak let &t_ti=l:t_ti_bak let &t_te=l:t_te_bak endtry if a:cmd =~# '^l' let l:match_count = len(getloclist(winnr())) else let l:match_count = len(getqflist()) endif if a:cmd =~# '^l' && l:match_count exe g:ag_lhandler let l:apply_mappings = g:ag_apply_lmappings let l:matches_window_prefix = 'l' " we're using the location list elseif l:match_count exe g:ag_qhandler let l:apply_mappings = g:ag_apply_qmappings let l:matches_window_prefix = 'c' " we're using the quickfix window endif " If highlighting is on, highlight the search keyword. if exists('g:ag_highlight') let @/ = matchstr(a:args, "\\v(-)\@", 'n') end redraw! if l:match_count if l:apply_mappings nnoremap h K nnoremap H Kb nnoremap o nnoremap t T nnoremap T TgT nnoremap v HbJt exe 'nnoremap e :' . l:matches_window_prefix .'close' exe 'nnoremap go :' . l:matches_window_prefix . 'open' exe 'nnoremap q :' . l:matches_window_prefix . 'close' exe 'nnoremap gv :let b:height=winheight(0)H:' . l:matches_window_prefix . 'openJ:exe printf(":normal %d\c-w>_", b:height)' " Interpretation: " :let b:height=winheight(0) Get the height of the quickfix/location list window " Open the current item in a new split " H Slam the newly opened window against the left edge " :copen -or- :lopen Open either the quickfix window or the location list (whichever we were using) " J Slam the quickfix/location list window against the bottom edge " :exe printf(":normal %d\c-w>_", b:height) Restore the quickfix/location list window's height from before we opened the match if g:ag_mapping_message && l:apply_mappings echom "ag.vim keys: q=quit /e/t/h/v=enter/edit/tab/split/vsplit go/T/H/gv=preview versions of same" endif endif else " Close the split window automatically: cclose lclose echohl WarningMsg echom 'No matches for "'.a:args.'"' echohl None endif endfunction function! ag#AgFromSearch(cmd, args) let search = getreg('/') " translate vim regular expression to perl regular expression. let search = substitute(search,'\(\\<\|\\>\)','\\b','g') call ag#Ag(a:cmd, '"' . search .'" '. a:args) endfunction function! ag#GetDocLocations() let dp = '' for p in split(&runtimepath,',') let p = p.'doc/' if isdirectory(p) let dp = p.'*.txt '.dp endif endfor return dp endfunction function! ag#AgHelp(cmd,args) let args = a:args.' '.ag#GetDocLocations() call ag#Ag(a:cmd,args) endfunction function! s:guessProjectRoot() let l:splitsearchdir = split(getcwd(), "/") while len(l:splitsearchdir) > 2 let l:searchdir = '/'.join(l:splitsearchdir, '/').'/' for l:marker in ['.rootdir', '.git', '.hg', '.svn', 'bzr', '_darcs', 'build.xml'] " found it! Return the dir if filereadable(l:searchdir.l:marker) || isdirectory(l:searchdir.l:marker) return l:searchdir endif endfor let l:splitsearchdir = l:splitsearchdir[0:-2] " Splice the list to get rid of the tail directory endwhile " Nothing found, fallback to current working dir return getcwd() endfunction