Restore the behavior of custom actions on Ag/Rg/Tags/Commits

Fix #1505
This commit is contained in:
Junegunn Choi
2023-09-16 19:36:06 +09:00
parent 937f430ce3
commit fe362d413a

View File

@@ -351,14 +351,32 @@ function! s:execute_silent(cmd)
silent keepjumps keepalt execute a:cmd silent keepjumps keepalt execute a:cmd
endfunction endfunction
function! s:action_for(key) " [key, [filename, [stay_on_edit: 0]]]
function! s:action_for(key, ...)
let Cmd = get(get(g:, 'fzf_action', s:default_action), a:key, '') let Cmd = get(get(g:, 'fzf_action', s:default_action), a:key, '')
let cmd = type(Cmd) == s:TYPE.string ? Cmd : '' let cmd = type(Cmd) == s:TYPE.string ? Cmd : ''
" See If the command is the default action that opens the selected file in
" the current window. i.e. :edit
let edit = stridx('edit', cmd) == 0 " empty, e, ed, ..
" If no extra argument is given, we just execute the command and ignore
" errors. e.g. E471: Argument required: tab drop
if !a:0
if !edit
normal! m' normal! m'
if len(cmd) silent! call s:execute_silent(cmd)
call s:execute_silent(cmd) endif
else
" For the default edit action, we don't execute the action if the
" selected file is already opened in the current window, or we are
" instructed to stay on the current buffer.
let stay = edit && (a:0 > 1 && a:2 || fnamemodify(a:1, ':p') ==# expand('%:p'))
if !stay
normal! m'
call s:execute_silent((len(cmd) ? cmd : 'edit').' '.s:escape(a:1))
endif
endif endif
return cmd
endfunction endfunction
function! s:open(target) function! s:open(target)
@@ -824,7 +842,7 @@ function! s:ag_handler(name, lines)
return return
endif endif
call s:action_for(a:lines[0]) call s:action_for(a:lines[0], list[0].filename, len(list) > 1)
if s:fill_quickfix(a:name, list) if s:fill_quickfix(a:name, list)
return return
endif endif
@@ -832,7 +850,6 @@ function! s:ag_handler(name, lines)
" Single item selected " Single item selected
let first = list[0] let first = list[0]
try try
call s:open(first.filename)
execute first.lnum execute first.lnum
if has_key(first, 'col') if has_key(first, 'col')
call cursor(0, first.col) call cursor(0, first.col)
@@ -1001,18 +1018,29 @@ function! s:tags_sink(lines)
if len(a:lines) < 2 if len(a:lines) < 2
return return
endif endif
" Remember the current position
let buf = bufnr()
let view = winsaveview()
let qfl = [] let qfl = []
call s:action_for(a:lines[0]) let [key; list] = a:lines
try try
let [magic, &magic, wrapscan, &wrapscan, acd, &acd] = [&magic, 0, &wrapscan, 1, &acd, 0] let [magic, &magic, wrapscan, &wrapscan, acd, &acd] = [&magic, 0, &wrapscan, 1, &acd, 0]
for line in a:lines[1:] for line in list
try try
let parts = split(line, '\t\zs') let parts = split(line, '\t\zs')
let excmd = matchstr(join(parts[2:-2], '')[:-2], '^.\{-}\ze;\?"\t') let excmd = matchstr(join(parts[2:-2], '')[:-2], '^.\{-}\ze;\?"\t')
let base = fnamemodify(parts[-1], ':h') let base = fnamemodify(parts[-1], ':h')
let relpath = parts[1][:-2] let relpath = parts[1][:-2]
let abspath = relpath =~ (s:is_win ? '^[A-Z]:\' : '^/') ? relpath : join([base, relpath], '/') let abspath = relpath =~ (s:is_win ? '^[A-Z]:\' : '^/') ? relpath : join([base, relpath], '/')
if len(list) == 1
call s:action_for(key, expand(abspath, 1))
else
call s:open(expand(abspath, 1)) call s:open(expand(abspath, 1))
endif
call s:execute_silent(excmd) call s:execute_silent(excmd)
call add(qfl, {'filename': expand('%'), 'lnum': line('.'), 'text': getline('.')}) call add(qfl, {'filename': expand('%'), 'lnum': line('.'), 'text': getline('.')})
catch /^Vim:Interrupt$/ catch /^Vim:Interrupt$/
@@ -1026,12 +1054,18 @@ function! s:tags_sink(lines)
endtry endtry
if len(qfl) > 1 if len(qfl) > 1
" Go back to the original position " Go back to the original position. Because 'listproc' will use 'cfirst'
normal! g`' " to go to the first item in the list.
" Because 'listproc' will use 'cfirst' to go to the first item in the list call s:execute_silent('b '.buf)
call winrestview(view)
" However, if a non-default action is triggered, we need to open the first
" entry using the action, to be as backward compatible as possible.
call s:action_for(key, qfl[0].filename, 1)
call s:fill_quickfix('tags', qfl) call s:fill_quickfix('tags', qfl)
else else
normal! zvzz normal! ^zvzz
endif endif
endfunction endfunction
@@ -1383,7 +1417,9 @@ function! s:commits_sink(lines)
end end
let diff = a:lines[0] == 'ctrl-d' let diff = a:lines[0] == 'ctrl-d'
let cmd = s:action_for(a:lines[0]) let Cmd = get(get(g:, 'fzf_action', s:default_action), a:lines[0], '')
let cmd = type(Cmd) == s:TYPE.string ? Cmd : ''
let buf = bufnr('') let buf = bufnr('')
for idx in range(1, len(a:lines) - 1) for idx in range(1, len(a:lines) - 1)
let sha = matchstr(a:lines[idx], pat) let sha = matchstr(a:lines[idx], pat)