Get variable value
make -p -f/dev/null 2>/dev/null | grep -Po 'var\s*=\s*\K.+'
Complete in vim
I use :h complete() in this case, you need to tell it where complete starts and give it a list of candidates.
Assume your current line looks like this:
........$(var)/mid0/mid1/mid2/base
^---cursor position in insert mode
The idea is to get var
, mid=/mid0/mid1/mid2/
and base
, send var
to :h system() to expand it, combine the expanded value with mid and base, send it to :h glob() , remove leading expanded var + mid
from every item in glob result, and that's our final complete candidates:
inoremap <c-b> <c-r>=<sid>complete_make_var_path()<cr>
function! s:complete_make_var_path()
" search $(..) backward, do nothing if not found
let dolllar_pos = searchpos('\v\$\([^)]+\)', 'bn', line('.'))
if dolllar_pos == [0, 0]
return ''
endif
" get prefix from $ to current column -1
let dir_base = getline('.')[ dolllar_pos[1] - 1 : col('.') - 2 ]
" separate $(var)/mid0/mid1/mid2/base into var, mid, base
let [var, mid, base] = matchlist(dir_base, '\v\$\(([^)]+)\)(.*/)?(.*)')[1:3]
" expand var, erase trailing newline
let evar = system('make -p -f/dev/null 2>/dev/null | grep -Po ''' . var . '\s*=\s*\K.+''' )
if empty(evar)
return ''
endif
let evar = evar[ 0 : len(evar) - 2 ]
" glob candidates, remove leading evar+prefix
let candidates = map(glob(evar . mid . base . '*', 0, 1), {i,v -> v[ len(evar . mid) : ]})
call complete(col('.') - len(base), candidates)
return ''
endfunction