mirror of
https://github.com/junegunn/fzf.vim.git
synced 2026-08-31 11:56:56 +08:00
Show a buffer-local entry in the buffer the run started on
BLines, BTags and a lowercase mark carry a position but no buffer, so they landed wherever the window had got to. The window can leave that buffer while fzf is open, including through another run's show key, and BLines then applied its line number to the wrong buffer, clamped to its length. The callback carries the buffer alongside the window and returns to it first, or does nothing if it is gone.
This commit is contained in:
+16
-11
@@ -651,7 +651,7 @@ endfunction
|
||||
" window is current, so the entry goes to the window fzf was started from.
|
||||
" Scopes the options s:goto_entry needs, which every early return has to
|
||||
" restore, hence the split.
|
||||
function! s:show_entry(winid, dir, kind, entry) abort
|
||||
function! s:show_entry(winid, bufnr, dir, kind, entry) abort
|
||||
if empty(a:entry)
|
||||
return
|
||||
endif
|
||||
@@ -664,7 +664,7 @@ function! s:show_entry(winid, dir, kind, entry) abort
|
||||
let [&magic, &wrapscan] = [0, 1]
|
||||
endif
|
||||
try
|
||||
call s:goto_entry(a:winid, a:dir, a:kind, a:entry)
|
||||
call s:goto_entry(a:winid, a:bufnr, a:dir, a:kind, a:entry)
|
||||
finally
|
||||
let [&magic, &wrapscan, &acd] = [magic, wrapscan, acd]
|
||||
endtry
|
||||
@@ -672,7 +672,7 @@ endfunction
|
||||
|
||||
" Parses the entry the way that command's sink does and moves the window to
|
||||
" it. Runs with the options s:show_entry set.
|
||||
function! s:goto_entry(winid, dir, kind, entry) abort
|
||||
function! s:goto_entry(winid, bufnr, dir, kind, entry) abort
|
||||
let entry = a:entry
|
||||
if a:kind ==# 'gitstatus'
|
||||
" ' M path', '?? path', or a rename reported as 'old -> new'
|
||||
@@ -693,12 +693,14 @@ function! s:goto_entry(winid, dir, kind, entry) abort
|
||||
let cmds = ['keepalt keepjumps hide buffer '.str2nr(chunks[0]),
|
||||
\ 'keepjumps '.str2nr(chunks[2]), 'normal! ^zvzz']
|
||||
elseif a:kind ==# 'blines'
|
||||
" line number, text, in the buffer the run started from
|
||||
" line number, text, in the buffer the run started from, which the window
|
||||
" can have left while fzf was open
|
||||
let lnum = str2nr(split(entry, "\t", 1)[0])
|
||||
if lnum <= 0
|
||||
if lnum <= 0 || !bufexists(a:bufnr)
|
||||
return
|
||||
endif
|
||||
let cmds = ['keepjumps '.lnum, 'normal! ^zvzz']
|
||||
let cmds = ['keepalt keepjumps hide buffer '.a:bufnr,
|
||||
\ 'keepjumps '.lnum, 'normal! ^zvzz']
|
||||
elseif a:kind ==# 'tags'
|
||||
let parts = split(entry, '\t\zs')
|
||||
if len(parts) < 3
|
||||
@@ -716,16 +718,19 @@ function! s:goto_entry(winid, dir, kind, entry) abort
|
||||
\ 'keepjumps '.excmd, 'normal! ^zvzz']
|
||||
elseif a:kind ==# 'btags'
|
||||
let parts = split(entry, "\t")
|
||||
if len(parts) < 3
|
||||
if len(parts) < 3 || !bufexists(a:bufnr)
|
||||
return
|
||||
endif
|
||||
let cmds = ['keepjumps '.parts[2], 'normal! zvzz']
|
||||
let cmds = ['keepalt keepjumps hide buffer '.a:bufnr,
|
||||
\ 'keepjumps '.parts[2], 'normal! zvzz']
|
||||
elseif a:kind ==# 'marks'
|
||||
" A lowercase mark is local to the buffer the run started on
|
||||
let mark = matchstr(entry, '^\s*\zs\S')
|
||||
if empty(mark)
|
||||
if empty(mark) || !bufexists(a:bufnr)
|
||||
return
|
||||
endif
|
||||
let cmds = ['keepalt keepjumps hide normal! `'.mark.'zvzz']
|
||||
let cmds = ['keepalt keepjumps hide buffer '.a:bufnr,
|
||||
\ 'keepalt keepjumps hide normal! `'.mark.'zvzz']
|
||||
elseif a:kind ==# 'changes'
|
||||
" buffer, offset, line, column, text
|
||||
let parts = split(entry)
|
||||
@@ -867,7 +872,7 @@ function! s:add_hints(spec, bang) abort
|
||||
if !empty(kind) && !empty(key) && s:can_show(a:spec, a:bang, key, claimed)
|
||||
let dir = get(a:spec, 'dir', '')
|
||||
let fifo = fzf#vim#ipc#start(function('s:show_entry',
|
||||
\ [win_getid(), empty(dir) ? getcwd() : dir, kind]))
|
||||
\ [win_getid(), bufnr(''), empty(dir) ? getcwd() : dir, kind]))
|
||||
if !empty(fifo)
|
||||
" Wrap an 'exit' the spec already carries. call() drops the dict of a
|
||||
" dict function, so the wrapped ones are partials
|
||||
|
||||
Reference in New Issue
Block a user