Skip to content

Instantly share code, notes, and snippets.

@Konfekt
Last active March 28, 2025 18:14
Show Gist options
  • Save Konfekt/46475d2329bf2a3347a79316ce216d16 to your computer and use it in GitHub Desktop.
Save Konfekt/46475d2329bf2a3347a79316ce216d16 to your computer and use it in GitHub Desktop.
preview file under cursor in Vim using ctags as fallback
" Adapted from https://github.com/drmikehenry/vimfiles/blob/e5c369dadde340ead7438b0c4937c3f470acf524/vimrc#L3239
"
" With --extra=+f in ~/.ctags respectively --extras=+f in
" ~/.config/ctags/default.ctags, filenames are tags, too, so
" the following mappings will work when a file isn't in the path.
"
" For automatic (C)tags generation, see either
" https://tbaggery.com or https://bolt80.com/gutentags/
nnoremap <silent> gf :<c-u>call <sid>gf("gf")<cr>
nnoremap <silent> <c-w>f :<c-u>call <sid>gf("\<lt>c-w>f")<cr>
nnoremap <silent> <c-w>gf :<c-u>call <sid>gf("\<lt>c-w>gf")<cr>
nmap <silent> <C-w><C-f> <C-w>f
nnoremap <silent> gF :<c-u>call <sid>gf("gF")<cr>
nnoremap <silent> <c-w>F :<c-u>call <sid>gf("\<lt>c-w>F")<cr>
nnoremap <silent> <c-w>gF :<c-u>call <sid>gf("\<lt>c-w>gF")<cr>
function! s:gf(map)
try
if a:map ==# 'gf'
let fname = expand('<cfile>')
if match(&includeexpr, 'v:fname') >= 0
exe 'let fname = '..substitute(&includeexpr, 'v:fname', 'fname', 'g')
endif
let fname = findfile(fname, &path)
if filereadable(fname)
exe 'pedit' fname
else
wincmd F
setlocal previewwindow
endif
else
exe 'normal!' a:map
endif
catch /^Vim\%((\a\+)\)\=:E447/
try
let tag = expand('<cfile>:t')
if a:map ==# "gf"
exe 'ptjump' tag
elseif a:map ==# "gF"
exe 'tjump' tag
elseif a:map ==# "\<c-w>f" || a:map ==# "\<c-w>F"
exe 'stjump' tag
elseif a:map ==# "\<c-w>gf" || a:map ==# "\<c-w>gF"
exe 'tab stjump' tag
endif
catch /^Vim\%((\a\+)\)\=:E\%(426\|433\)/
echomsg 'Error: neither path nor tag for this file name found!'
endtry
endtry
endfunction
" (forcefully) close preview window and jump back
nnoremap <silent><expr> g[ ':<c-u>silent! pclose<cr>:silent! '..v:count1..'pop<cr>'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment