Keep a tab inside a BTags pattern from cutting the address

ctags leaves a tab as it found it, so splitting the source line on tabs left
'/^' for a tab-indented definition, which matched whatever line came next, and
'/^static int g = 1;' for a tab later on, which only happened to match. Write
the tab as '\t', which matches the same text and keeps the address one field.

:BTags with 'ctags --excmd=pattern' now reaches every tag in a tab-indented
file, where the address was a fragment before.
This commit is contained in:
Junegunn Choi
2026-09-28 05:01:20 +09:00
parent 3e34f1dc6d
commit b268241f4a
+10 -1
View File
@@ -1653,6 +1653,14 @@ endfunction
" ------------------------------------------------------------------
" BTags
" ------------------------------------------------------------------
" ctags leaves a tab inside a pattern as it found it, and splitting the line on
" tabs would cut the address short, leaving a fragment that matches some other
" line. '\t' matches the same text and keeps the field the line's third
function! s:tabs_in_address(line)
return substitute(a:line, '^\%([^\t]*\t\)\{2}\zs.\{-}\ze\%(;"\t\|$\)',
\ '\=substitute(submatch(0), "\t", ''\\t'', "g")', '')
endfunction
function! s:btags_source(tag_cmds)
if !filereadable(expand('%'))
throw 'Save the file first'
@@ -1669,7 +1677,8 @@ function! s:btags_source(tag_cmds)
elseif empty(lines)
throw 'No tags found'
endif
return map(s:align_lists(map(lines, 'split(v:val, "\t")')), 'join(v:val, "\t")')
return map(s:align_lists(map(map(lines, 's:tabs_in_address(v:val)'),
\ 'split(v:val, "\t")')), 'join(v:val, "\t")')
endfunction
" Position to return to with CTRL-T. Captured before fzf opens, because the