Creating your own ag.vim
Vim provides built-in mechanisms to search through projects in the form of the
However, on large projects, grep is known to be slow; and hence people have been switching to simpler searchers like ack, and faster, parallel (metal?) searchers like ag and pt.
Correspondingly, several plugins have been created that integrate these tools in vim: ack.vim, ag.vim, etc.
However, it's actually very easy to get the functionalities these plugins provide (faster search, results in quickfix-window, jumps, previews, and so on) in vanilla Vim itself; in fact, Vim already populates the grep-search results in a quickfix window. We just need to tell Vim to do the following things (use-case: ag):
- Use ag as the default grep program
- Open quickfix window by default
- Create mappings to easily navigate among the search-results
So let us build our ag-based lightweight grepper. Note that ag (aka 'the silver searcher') needs to be installed on your PC.
Set ag as the default grep program
This just requires adding the following simple lines to your vimrc:
if executable('ag') set grepprg=ag\ --nogroup\ --nocolor endif
That's it! The next time you do a 'grep', Vim will actually use 'ag' (if installed on your PC) and show the results blazingly fast.
If you wish to display column numbers like
vimgrep (a built-in but slightly slower grep), you can add
--vimgrep to the
grepprg option, and modify the
grepformat option to display the column numbers properly.
Thus, the updated version will look as follows:
if executable('ag') set grepprg=ag\ --nogroup\ --nocolor\ --vimgrep set grepformat^=%f:%l:%c:%m " file:line:column:message endif
Open quickfix window by default
Let us do this in an elegant way using a function.
Say we wish to define a new command called
Search that takes a word, greps it, and shows the results in a quickfix-window.
The function to do the same can be something like this:
function! MySearch() let grep_term = input("Enter search term: ") if !empty(grep_term) execute 'silent grep' grep_term | copen else echo "Empty search term" endif redraw! endfunction
- prompts for the term to be grepped
- checks whether the user pressed Enter without giving a search term; if yes, displays an error
- if the search-term is valid, greps it using the default grep-program
- opens the result in a quickfix-window
- redraws the screen in order to avoid any distortion
Note that you can navigate across the results of the quickfix-window using
:cprevious, and close it using
Or, you can move to the quickfix-window and jump to any of the results using the arrow (or any vim-movement) keys and pressing Enter.
The next task is to define a command to call the above function:
command! Search call MySearch()
Done! Now just type
:Search in Vim's command-line, and press Enter to grep a term using ag.
You can also create a custom mapping for the Search command:
nnoremap <leader>s :Search<CR> " Default leader is '\' (backslash)
If you have used ack.vim and ag.vim, and want custom mappings for the quickfix-window, such as closing it using
q and jumping to a result directly whie closing the quickfix-window using
O, then add the following mappings to the file .vim/ftplugin/qf.vim:
nnoremap <buffer><silent> q :cclose<CR> nnoremap <buffer><silent> O <CR>:cclose<CR>
You can similarly create maps to open a result in a new tab, in a new split, etc., as the plugins do, if you need.
Grep the word under cursor
There are two ways to achieve this:
- Vim allows the word under the cursor to be put in the command-line mode using
Ctrl-W. Thus, typing this sequence after
:Search<CR>, and pressing Enter, will allow you to search the word under the cursor.
- The word under the cursor can be referred using
<cword>in Vimscript. Thus, you can grep the word under the cursor using the map
nnoremap <leader>* :silent grep <cword> \| copen<CR><C-l> " <C-l> redraws the screen
This finishes your personal, Vim-native, lightweight ag.vim script.