mirror of
https://github.com/Llewellynvdm/fzf.git
synced 2025-01-10 18:24:39 +00:00
[vim] Neovim compatibility (#137)
Use terminal emulator of Neovim to open fzf
This commit is contained in:
parent
68503d32df
commit
622e69ff54
@ -317,11 +317,16 @@ of the selected items.
|
|||||||
| `source` | list | Vim list as input to fzf |
|
| `source` | list | Vim list as input to fzf |
|
||||||
| `sink` | string | Vim command to handle the selected item (e.g. `e`, `tabe`) |
|
| `sink` | string | Vim command to handle the selected item (e.g. `e`, `tabe`) |
|
||||||
| `sink` | funcref | Reference to function to process each selected item |
|
| `sink` | funcref | Reference to function to process each selected item |
|
||||||
|
| `sink*` | funcref | Similar to `sink`, but takes the list of output lines at once |
|
||||||
| `options` | string | Options to fzf |
|
| `options` | string | Options to fzf |
|
||||||
| `dir` | string | Working directory |
|
| `dir` | string | Working directory |
|
||||||
| `up`/`down`/`left`/`right` | number/string | Use tmux pane with the given size (e.g. `20`, `50%`) |
|
| `up`/`down`/`left`/`right` | number/string | Use tmux pane with the given size (e.g. `20`, `50%`) |
|
||||||
|
| `window` (*Neovim only*) | string | Command to open fzf window (e.g. `vertical aboveleft 30new`) |
|
||||||
| `launcher` | string | External terminal emulator to start fzf with (Only used in GVim) |
|
| `launcher` | string | External terminal emulator to start fzf with (Only used in GVim) |
|
||||||
|
|
||||||
|
*However on Neovim `fzf#run` is asynchronous and does not return values so you
|
||||||
|
should use `sink` or `sink+` to process the output from fzf.*
|
||||||
|
|
||||||
##### Examples
|
##### Examples
|
||||||
|
|
||||||
If `sink` option is not given, `fzf#run` will simply return the list.
|
If `sink` option is not given, `fzf#run` will simply return the list.
|
||||||
|
116
plugin/fzf.vim
116
plugin/fzf.vim
@ -122,12 +122,14 @@ function! fzf#run(...) abort
|
|||||||
else
|
else
|
||||||
let prefix = ''
|
let prefix = ''
|
||||||
endif
|
endif
|
||||||
let split = s:tmux_enabled() && s:tmux_splittable(dict)
|
let tmux = !has('nvim') && s:tmux_enabled() && s:splittable(dict)
|
||||||
let command = prefix.(split ? s:fzf_tmux(dict) : fzf_exec).' '.optstr.' > '.temps.result
|
let command = prefix.(tmux ? s:fzf_tmux(dict) : fzf_exec).' '.optstr.' > '.temps.result
|
||||||
|
|
||||||
try
|
try
|
||||||
if split
|
if tmux
|
||||||
return s:execute_tmux(dict, command, temps)
|
return s:execute_tmux(dict, command, temps)
|
||||||
|
elseif has('nvim')
|
||||||
|
return s:execute_term(dict, command, temps)
|
||||||
else
|
else
|
||||||
return s:execute(dict, command, temps)
|
return s:execute(dict, command, temps)
|
||||||
endif
|
endif
|
||||||
@ -150,19 +152,24 @@ function! s:fzf_tmux(dict)
|
|||||||
for o in ['up', 'down', 'left', 'right']
|
for o in ['up', 'down', 'left', 'right']
|
||||||
if s:present(a:dict, o)
|
if s:present(a:dict, o)
|
||||||
let size = '-'.o[0].(a:dict[o] == 1 ? '' : a:dict[o])
|
let size = '-'.o[0].(a:dict[o] == 1 ? '' : a:dict[o])
|
||||||
|
break
|
||||||
endif
|
endif
|
||||||
endfor
|
endfor
|
||||||
return printf('LINES=%d COLUMNS=%d %s %s %s --',
|
return printf('LINES=%d COLUMNS=%d %s %s %s --',
|
||||||
\ &lines, &columns, s:fzf_tmux, size, (has_key(a:dict, 'source') ? '' : '-'))
|
\ &lines, &columns, s:fzf_tmux, size, (has_key(a:dict, 'source') ? '' : '-'))
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:tmux_splittable(dict)
|
function! s:splittable(dict)
|
||||||
return s:present(a:dict, 'up', 'down', 'left', 'right')
|
return s:present(a:dict, 'up', 'down', 'left', 'right')
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:pushd(dict)
|
function! s:pushd(dict)
|
||||||
if s:present(a:dict, 'dir')
|
if s:present(a:dict, 'dir')
|
||||||
let a:dict.prev_dir = getcwd()
|
let cwd = getcwd()
|
||||||
|
if get(a:dict, 'prev_dir', '') ==# cwd
|
||||||
|
return 1
|
||||||
|
endif
|
||||||
|
let a:dict.prev_dir = cwd
|
||||||
execute 'chdir '.s:escape(a:dict.dir)
|
execute 'chdir '.s:escape(a:dict.dir)
|
||||||
let a:dict.dir = getcwd()
|
let a:dict.dir = getcwd()
|
||||||
return 1
|
return 1
|
||||||
@ -210,6 +217,60 @@ function! s:execute_tmux(dict, command, temps)
|
|||||||
return s:callback(a:dict, a:temps)
|
return s:callback(a:dict, a:temps)
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
function! s:calc_size(max, val)
|
||||||
|
if a:val =~ '%$'
|
||||||
|
return a:max * str2nr(a:val[:-2]) / 100
|
||||||
|
else
|
||||||
|
return min([a:max, a:val])
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:split(dict)
|
||||||
|
let directions = {
|
||||||
|
\ 'up': ['topleft', &lines],
|
||||||
|
\ 'down': ['botright', &lines],
|
||||||
|
\ 'left': ['vertical topleft', &columns],
|
||||||
|
\ 'right': ['vertical botright', &columns] }
|
||||||
|
try
|
||||||
|
for [dir, pair] in items(directions)
|
||||||
|
let val = get(a:dict, dir, '')
|
||||||
|
if !empty(val)
|
||||||
|
let [cmd, max] = pair
|
||||||
|
execute cmd s:calc_size(max, val).'new'
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
if s:present(a:dict, 'window')
|
||||||
|
execute a:dict.window
|
||||||
|
else
|
||||||
|
tabnew
|
||||||
|
endif
|
||||||
|
finally
|
||||||
|
setlocal winfixwidth winfixheight
|
||||||
|
endtry
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:execute_term(dict, command, temps)
|
||||||
|
call s:pushd(a:dict)
|
||||||
|
call s:split(a:dict)
|
||||||
|
|
||||||
|
let fzf = { 'buf': bufnr('%'), 'dict': a:dict, 'temps': a:temps }
|
||||||
|
function! fzf.on_exit(id, code)
|
||||||
|
execute 'bd!' self.buf
|
||||||
|
call s:pushd(self.dict)
|
||||||
|
try
|
||||||
|
call s:callback(self.dict, self.temps)
|
||||||
|
finally
|
||||||
|
call s:popd(self.dict)
|
||||||
|
endtry
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
call termopen(a:command, fzf)
|
||||||
|
file [FZF]
|
||||||
|
startinsert
|
||||||
|
return []
|
||||||
|
endfunction
|
||||||
|
|
||||||
function! s:callback(dict, temps)
|
function! s:callback(dict, temps)
|
||||||
if !filereadable(a:temps.result)
|
if !filereadable(a:temps.result)
|
||||||
let lines = []
|
let lines = []
|
||||||
@ -224,6 +285,9 @@ function! s:callback(dict, temps)
|
|||||||
endif
|
endif
|
||||||
endfor
|
endfor
|
||||||
endif
|
endif
|
||||||
|
if has_key(a:dict, 'sink*')
|
||||||
|
call a:dict['sink*'](lines)
|
||||||
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
for tf in values(a:temps)
|
for tf in values(a:temps)
|
||||||
@ -233,6 +297,26 @@ function! s:callback(dict, temps)
|
|||||||
return lines
|
return lines
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
function! s:cmd_callback(lines) abort
|
||||||
|
if empty(a:lines)
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
let key = remove(a:lines, 0)
|
||||||
|
if key == 'ctrl-t' | let cmd = 'tabedit'
|
||||||
|
elseif key == 'ctrl-x' | let cmd = 'split'
|
||||||
|
elseif key == 'ctrl-v' | let cmd = 'vsplit'
|
||||||
|
else | let cmd = 'e'
|
||||||
|
endif
|
||||||
|
call s:pushd(s:opts)
|
||||||
|
try
|
||||||
|
for item in a:lines
|
||||||
|
execute cmd s:escape(item)
|
||||||
|
endfor
|
||||||
|
finally
|
||||||
|
call s:popd(s:opts)
|
||||||
|
endtry
|
||||||
|
endfunction
|
||||||
|
|
||||||
function! s:cmd(bang, ...) abort
|
function! s:cmd(bang, ...) abort
|
||||||
let args = copy(a:000)
|
let args = copy(a:000)
|
||||||
if !s:legacy
|
if !s:legacy
|
||||||
@ -247,26 +331,10 @@ function! s:cmd(bang, ...) abort
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
if s:legacy
|
if s:legacy
|
||||||
call fzf#run(extend({ 'sink': 'e', 'options': join(args) }, opts))
|
call fzf#run(extend({ 'options': join(args), 'sink': 'e' }, opts))
|
||||||
else
|
else
|
||||||
let output = fzf#run(extend({ 'options': join(args) }, opts))
|
let s:opts = opts
|
||||||
if empty(output)
|
call fzf#run(extend({ 'options': join(args), 'sink*': function('<sid>cmd_callback') }, opts))
|
||||||
return
|
|
||||||
endif
|
|
||||||
let key = remove(output, 0)
|
|
||||||
if key == 'ctrl-t' | let cmd = 'tabedit'
|
|
||||||
elseif key == 'ctrl-x' | let cmd = 'split'
|
|
||||||
elseif key == 'ctrl-v' | let cmd = 'vsplit'
|
|
||||||
else | let cmd = 'e'
|
|
||||||
endif
|
|
||||||
try
|
|
||||||
call s:pushd(opts)
|
|
||||||
for item in output
|
|
||||||
execute cmd s:escape(item)
|
|
||||||
endfor
|
|
||||||
finally
|
|
||||||
call s:popd(opts)
|
|
||||||
endtry
|
|
||||||
endif
|
endif
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user