First things first, I want to use ag to search through my project files. Coming from fzf, I like to have two bindings for this -- one that respects my projects .gitignore
and one that does not. The latter is helpful if I want to examine a built file or look at a node_module dependency while working on my js project.
I use an alias for file_rec
source to toggle the -u
flag on ag
. Now, <C-P>
searches in my git files, and <C-O>
searches everything.
" denite file search (c-p uses gitignore, c-o looks at everything)
map <C-P> :DeniteProjectDir -buffer-name=git -direction=top file_rec/git<CR>
map <C-O> :DeniteProjectDir -buffer-name=files -direction=top file_rec<CR>
" -u flag to unrestrict (see ag docs)
call denite#custom#var('file_rec', 'command',
\ ['ag', '--follow', '--nocolor', '--nogroup', '-u', '-g', ''])
call denite#custom#alias('source', 'file_rec/git', 'file_rec')
call denite#custom#var('file_rec/git', 'command',
\ ['ag', '--follow', '--nocolor', '--nogroup', '-g', ''])
Next is searching over file contents. Working in js, code analysis tools are pretty weak. So, I often want to find all of the instances where a particular string appears within my project. Denite allows me to do this in a nice and interactive way.
" denite content search
map <leader>a :DeniteProjectDir -buffer-name=grep -default-action=quickfix grep:::!<CR>
call denite#custom#source(
\ 'grep', 'matchers', ['matcher_regexp'])
" use ag for content search
call denite#custom#var('grep', 'command', ['ag'])
call denite#custom#var('grep', 'default_opts',
\ ['-i', '--vimgrep'])
call denite#custom#var('grep', 'recursive_opts', [])
call denite#custom#var('grep', 'pattern_opt', [])
call denite#custom#var('grep', 'separator', ['--'])
call denite#custom#var('grep', 'final_opts', [])
Here's how it works.
- you start by pressing
<leader>a
(for ag).grep:::!
will invoke thegrep
source in an interactive window. Which means that you will re-query the source as you type. - The bottom half of the config is taken straight from
:help denite
and binds the grep source to use ag - I overwrite the matcher to be
matcher_regexp
because I find fuzzy matching to be too forgiving for the purpose of finding strings in the source. This also has the benefit of speeding up the update cycle. - I set the default action to
quickfix
. This way, when I tag multiple files in the denite buffer and press enter, those locations go into my quickfix list. I can then use]q
and[q
from unimpaired to quickly look through the matches and make corrections where necessary.
Here's a video of it in action! https://asciinema.org/a/93i6c5y2mz60juq8xt2a3svdz
What you see in the video:
- I enter
vi
(for me that's an alias for nvim) in the root of my git repo - I press
<leader>a
. This brings up an Denite buffer that's piping my commands to ag - I try a few regexes to get the set of results that I want
- I press
<Ctrl-O>
to enter normal mode (this is a default denite keybinding for insert mode) - I press
*
to select all Enter
to invoke the default action, which moves all matches into the quickfix window]q
and[q
to move around quickfix results using unimpaired