I'm using defx as filer, and denite and ag to search files on Neovim.
My current configuration searches files under the current working directory.
defx supports auto-cd
option which changes the working directory automatically while navigating with it.
It allows you to quickly search files under the directory where you are viewing on defx, which is handy because you don't need to filter files in other directories which you are not currently interested in.
It basically works great, but my problem is that tools that work in the project root directory don't work when the current directory got changed.
In my case, eslint
and flow
can't be invoked via coc.nvim, causing error like this:
[coc.nvim] Definition provider not found for current document
So, I want to search files under the directory I am currently working without changing the actual working directory.
Fig. using defx
Use defx#get_candidate()
to get the currently selected file path
First off, I need to know the path where defx is displaying.
I found that defx#get_candidate()
returns the information about currently selected item like so:
echo defx#get_candidate()
"{'word': 'native-base-theme/', 'is_directory': v:true, 'action__path': '/foo/bar.txt', 'level': 0, 'is_opened_tree': v:false}
Seems like you can use action__path
to know where you are as following:
let l:path = expand('%:p:h')
if has_key(defx#get_candidate(), 'action__path')
let l:path = fnamemodify(defx#get_candidate()['action__path'], ':p:h')
endif
If defx is not opened, it uses the parent path of the currently editing file instead, so you can quickly search sibling files without opening up defx.
vim config
So, I've update my vim config like so:
" use floating
let s:denite_win_width_percent = 0.8
let s:denite_win_height_percent = 0.7
let s:denite_default_options = {
\ 'split': 'floating',
\ 'winwidth': float2nr(&columns * s:denite_win_width_percent),
\ 'wincol': float2nr((&columns - (&columns * s:denite_win_width_percent)) / 2),
\ 'winheight': float2nr(&lines * s:denite_win_height_percent),
\ 'winrow': float2nr((&lines - (&lines * s:denite_win_height_percent)) / 2),
\ 'highlight_filter_background': 'DeniteFilter',
\ 'prompt': 'λ ',
\ 'start_filter': v:true,
\ }
let s:denite_option_array = []
for [key, value] in items(s:denite_default_options)
call add(s:denite_option_array, '-'.key.'='.value)
endfor
call denite#custom#option('default', s:denite_default_options)
" Ag command on grep source
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', [])
" grep
command! -nargs=? Dgrep call s:Dgrep(<f-args>)
function s:Dgrep(...)
if a:0 > 0
execute(':Denite -buffer-name=grep-buffer-denite grep -path='.a:1)
else
let l:path = expand('%:p:h')
if has_key(defx#get_candidate(), 'action__path')
let l:path = fnamemodify(defx#get_candidate()['action__path'], ':p:h')
endif
execute(':Denite -buffer-name=grep-buffer-denite -no-empty '.join(s:denite_option_array, ' ').' grep -path='.l:path)
endif
endfunction
" show Denite grep results
command! Dresume execute(':Denite -resume -buffer-name=grep-buffer-denite '.join(s:denite_option_array, ' ').'')
nnoremap <silent> ;r :<C-u>Dgrep<CR>
Works like a charm!