From c1ae1c8f07cfdfa126075be838fd9a0ed0b302d0 Mon Sep 17 00:00:00 2001 From: Junegunn Choi Date: Thu, 20 Aug 2015 03:19:48 +0900 Subject: [PATCH] More advanced options for fzf#complete --- README.md | 17 ++++++++++++----- plugin/fzf.vim | 19 +++++++++++++++++-- 2 files changed, 29 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 16cd9ee..1bdfb04 100644 --- a/README.md +++ b/README.md @@ -71,18 +71,25 @@ inoremap fzf#complete('cat /usr/share/dict/words') ``` 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 -`reducer` function instead of `sink` or `sink*`. +of options is pretty much identical to that for `fzf#run` only with the +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 -" Reducer function transforms the output of fzf into a single string value -function! FirstLineInUpperCase(lines) +function! s:first_line_in_uppercase(lines) return toupper(a:lines[0]) endfunction inoremap fzf#complete({ \ 'source': 'cat /usr/share/dict/words', - \ 'reducer': function('FirstLineInUpperCase'), + \ 'reducer': function('first_line_in_uppercase'), \ 'options': '--no-multi --reverse --margin 15%,0', \ 'left': 20}) ``` diff --git a/plugin/fzf.vim b/plugin/fzf.vim index 6842117..6ba8d5a 100644 --- a/plugin/fzf.vim +++ b/plugin/fzf.vim @@ -436,10 +436,21 @@ function! s:complete_insert(lines) endif 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(...) if a:0 == 0 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*') echoerr 'sink not allowed' return '' @@ -455,8 +466,12 @@ function! fzf#complete(...) let s:eol = col('.') == eol let &ve = ve + let prefix = s:pluck(s:opts, 'prefix', '\k*$') 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("\(-fzf-complete-trigger)") return '' endfunction