More advanced options for fzf#complete

This commit is contained in:
Junegunn Choi 2015-08-20 03:19:48 +09:00
parent 5282e5c427
commit c1ae1c8f07
2 changed files with 29 additions and 7 deletions

View file

@ -71,18 +71,25 @@ inoremap <expr> <c-x><c-k> fzf#complete('cat /usr/share/dict/words')
``` ```
For advanced uses, you can pass an options dictionary to the function. The set For advanced uses, you can pass an options dictionary to the function. The set
of options is almost identical to that for `fzf#run`, except that it takes of options is pretty much identical to that for `fzf#run` only with the
`reducer` function instead of `sink` or `sink*`. following exceptions:
- `reducer` (funcref)
- Reducer transforms the output lines of fzf into a single string value
- `prefix` (string; default: `\k*$`)
- Regular expression pattern to extract the completion prefix
- Both `source` and `options` can be given as funcrefs that take the
completion prefix as the argument and return the final value
- `sink` or `sink*` are not allowed
```vim ```vim
" Reducer function transforms the output of fzf into a single string value function! s:first_line_in_uppercase(lines)
function! FirstLineInUpperCase(lines)
return toupper(a:lines[0]) return toupper(a:lines[0])
endfunction endfunction
inoremap <expr> <c-x><c-k> fzf#complete({ inoremap <expr> <c-x><c-k> fzf#complete({
\ 'source': 'cat /usr/share/dict/words', \ 'source': 'cat /usr/share/dict/words',
\ 'reducer': function('FirstLineInUpperCase'), \ 'reducer': function('<sid>first_line_in_uppercase'),
\ 'options': '--no-multi --reverse --margin 15%,0', \ 'options': '--no-multi --reverse --margin 15%,0',
\ 'left': 20}) \ 'left': 20})
``` ```

View file

@ -436,10 +436,21 @@ function! s:complete_insert(lines)
endif endif
endfunction endfunction
let s:TYPE = {'dict': type({}), 'funcref': type(function('call'))}
function! s:eval(dict, key, arg)
if has_key(a:dict, a:key) && type(a:dict[a:key]) == s:TYPE.funcref
let ret = copy(a:dict)
let ret[a:key] = call(a:dict[a:key], [a:arg])
return ret
endif
return a:dict
endfunction
function! fzf#complete(...) function! fzf#complete(...)
if a:0 == 0 if a:0 == 0
let s:opts = copy(get(g:, 'fzf_window', s:default_window)) let s:opts = copy(get(g:, 'fzf_window', s:default_window))
elseif type(a:1) == type({}) elseif type(a:1) == s:TYPE.dict
if has_key(a:1, 'sink') || has_key(a:1, 'sink*') if has_key(a:1, 'sink') || has_key(a:1, 'sink*')
echoerr 'sink not allowed' echoerr 'sink not allowed'
return '' return ''
@ -455,8 +466,12 @@ function! fzf#complete(...)
let s:eol = col('.') == eol let s:eol = col('.') == eol
let &ve = ve let &ve = ve
let prefix = s:pluck(s:opts, 'prefix', '\k*$')
let s:query = col('.') == 1 ? '' : let s:query = col('.') == 1 ? '' :
\ matchstr(getline('.')[0 : col('.')-2], '\k*$') \ matchstr(getline('.')[0 : col('.')-2], prefix)
let s:opts = s:eval(s:opts, 'source', s:query)
let s:opts = s:eval(s:opts, 'options', s:query)
call feedkeys("\<Plug>(-fzf-complete-trigger)") call feedkeys("\<Plug>(-fzf-complete-trigger)")
return '' return ''
endfunction endfunction