diff --git a/autoload/fzf/vim.vim b/autoload/fzf/vim.vim index 098a448..e205959 100755 --- a/autoload/fzf/vim.vim +++ b/autoload/fzf/vim.vim @@ -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