diff options
author | Junegunn Choi <junegunn.c@gmail.com> | 2016-07-26 02:35:40 +0900 |
---|---|---|
committer | Junegunn Choi <junegunn.c@gmail.com> | 2016-07-26 02:37:12 +0900 |
commit | f787f7e65108938fda981abb71f4fdfb08fd9f31 (patch) | |
tree | 85131066923318cb13ff4b40c61bbaf46a805307 /plugin | |
parent | a7c9c08371d27b550f3896ab554f6490871a7a0a (diff) |
[vim] Add fzf#wrap helper function
Close #627
Diffstat (limited to 'plugin')
-rw-r--r-- | plugin/fzf.vim | 147 |
1 files changed, 100 insertions, 47 deletions
diff --git a/plugin/fzf.vim b/plugin/fzf.vim index 668af7d5..53cb4cba 100644 --- a/plugin/fzf.vim +++ b/plugin/fzf.vim @@ -22,6 +22,7 @@ " WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. let s:default_layout = { 'down': '~40%' } +let s:layout_keys = ['window', 'up', 'down', 'left', 'right'] let s:fzf_go = expand('<sfile>:h:h').'/bin/fzf' let s:install = expand('<sfile>:h:h').'/install' let s:installed = 0 @@ -104,6 +105,101 @@ function! s:warn(msg) echohl None endfunction +function! s:has_any(dict, keys) + for key in a:keys + if has_key(a:dict, key) + return 1 + endif + endfor + return 0 +endfunction + +function! s:open(cmd, target) + if stridx('edit', a:cmd) == 0 && fnamemodify(a:target, ':p') ==# expand('%:p') + return + endif + execute a:cmd s:escape(a:target) +endfunction + +function! s:common_sink(action, lines) abort + if len(a:lines) < 2 + return + endif + let key = remove(a:lines, 0) + let cmd = get(a:action, key, 'e') + if len(a:lines) > 1 + augroup fzf_swap + autocmd SwapExists * let v:swapchoice='o' + \| call s:warn('fzf: E325: swap file exists: '.expand('<afile>')) + augroup END + endif + try + let empty = empty(expand('%')) && line('$') == 1 && empty(getline(1)) && !&modified + let autochdir = &autochdir + set noautochdir + for item in a:lines + if empty + execute 'e' s:escape(item) + let empty = 0 + else + call s:open(cmd, item) + endif + if exists('#BufEnter') && isdirectory(item) + doautocmd BufEnter + endif + endfor + finally + let &autochdir = autochdir + silent! autocmd! fzf_swap + endtry +endfunction + +" name string, [opts dict, [fullscreen boolean]] +function! fzf#wrap(name, ...) + if type(a:name) != type('') + throw 'invalid name type: string expected' + endif + let opts = copy(get(a:000, 0, {})) + let bang = get(a:000, 1, 0) + + " Layout: g:fzf_layout (and deprecated g:fzf_height) + if bang + for key in s:layout_keys + if has_key(opts, key) + call remove(opts, key) + endif + endfor + elseif !s:has_any(opts, s:layout_keys) + if !exists('g:fzf_layout') && exists('g:fzf_height') + let opts.down = g:fzf_height + else + let opts = extend(opts, get(g:, 'fzf_layout', s:default_layout)) + endif + endif + + " History: g:fzf_history_dir + let opts.options = get(opts, 'options', '') + if len(get(g:, 'fzf_history_dir', '')) + let dir = expand(g:fzf_history_dir) + if !isdirectory(dir) + call mkdir(dir, 'p') + endif + let opts.options = join(['--history', s:escape(dir.'/'.a:name), opts.options]) + endif + + " Action: g:fzf_action + if !s:has_any(opts, ['sink', 'sink*']) + let opts._action = get(g:, 'fzf_action', s:default_action) + let opts.options .= ' --expect='.join(keys(opts._action), ',') + function! opts.sink(lines) abort + return s:common_sink(self._action, a:lines) + endfunction + let opts['sink*'] = remove(opts, 'sink') + endif + + return opts +endfunction + function! fzf#run(...) abort try let oshell = &shell @@ -137,7 +233,7 @@ try call writefile(source, temps.input) let prefix = 'cat '.s:shellesc(temps.input).'|' else - throw 'Invalid source type' + throw 'invalid source type' endif else let prefix = '' @@ -435,60 +531,17 @@ function! s:callback(dict, lines) abort endfunction let s:default_action = { - \ 'ctrl-m': 'e', \ 'ctrl-t': 'tab split', \ 'ctrl-x': 'split', \ 'ctrl-v': 'vsplit' } -function! s:cmd_callback(lines) abort - if empty(a:lines) - return - endif - let key = remove(a:lines, 0) - let cmd = get(s:action, key, 'e') - if len(a:lines) > 1 - augroup fzf_swap - autocmd SwapExists * let v:swapchoice='o' - \| call s:warn('fzf: E325: swap file exists: '.expand('<afile>')) - augroup END - endif - try - let empty = empty(expand('%')) && line('$') == 1 && empty(getline(1)) && !&modified - let autochdir = &autochdir - set noautochdir - for item in a:lines - if empty - execute 'e' s:escape(item) - let empty = 0 - else - execute cmd s:escape(item) - endif - if exists('#BufEnter') && isdirectory(item) - doautocmd BufEnter - endif - endfor - finally - let &autochdir = autochdir - silent! autocmd! fzf_swap - endtry -endfunction - function! s:cmd(bang, ...) abort - let s:action = get(g:, 'fzf_action', s:default_action) - let args = extend(['--expect='.join(keys(s:action), ',')], a:000) + let args = copy(a:000) let opts = {} - if len(args) > 0 && isdirectory(expand(args[-1])) + if len(args) && isdirectory(expand(args[-1])) let opts.dir = substitute(remove(args, -1), '\\\(["'']\)', '\1', 'g') endif - if !a:bang - " For backward compatibility - if !exists('g:fzf_layout') && exists('g:fzf_height') - let opts.down = g:fzf_height - else - let opts = extend(opts, get(g:, 'fzf_layout', s:default_layout)) - endif - endif - call fzf#run(extend({'options': join(args), 'sink*': function('<sid>cmd_callback')}, opts)) + call fzf#run(fzf#wrap('FZF', extend({'options': join(args)}, opts), a:bang)) endfunction command! -nargs=* -complete=dir -bang FZF call s:cmd(<bang>0, <f-args>) |