[Tags] Support multiple tags files

We also apply --nth 1..2 by default to limit the search scope.

Close #106
Related #5, #329
This commit is contained in:
Junegunn Choi 2017-03-10 17:04:52 +09:00
parent e4f79f6e98
commit 06a8b870c0
No known key found for this signature in database
GPG key ID: 254BC280FEF9C627
2 changed files with 37 additions and 19 deletions

View file

@ -29,8 +29,10 @@ set cpo&vim
" ------------------------------------------------------------------
let s:layout_keys = ['window', 'up', 'down', 'left', 'right']
let s:which_bin = executable('ruby') ? '/bin/preview.rb' : '/bin/preview.sh'
let s:bin = { 'preview': expand('<sfile>:h:h:h') . s:which_bin }
let s:bin_dir = expand('<sfile>:h:h:h').'/bin/'
let s:bin = {
\ 'preview': s:bin_dir.executable('ruby') ? 'preview.rb' : 'preview.sh',
\ 'tags': s:bin_dir.'tags.pl' }
let s:TYPE = {'dict': type({}), 'funcref': type(function('call')), 'string': type('')}
" [[options to wrap], preview window expression, [toggle-preview keys...]]
@ -728,8 +730,11 @@ function! s:tags_sink(lines)
for line in a:lines[1:]
try
let parts = split(line, '\t\zs')
let excmd = matchstr(join(parts[2:], ''), '^.*\ze;"\t')
call s:open(cmd, parts[1][:-2])
let excmd = matchstr(join(parts[2:-2], '')[:-2], '^.*\ze;"\t')
let base = fnamemodify(parts[-1], ':h')
let relpath = parts[1][:-2]
let abspath = relpath =~ '^/' ? relpath : join([base, relpath], '/')
call s:open(cmd, abspath)
execute excmd
call add(qfl, {'filename': expand('%'), 'lnum': line('.'), 'text': getline('.')})
catch /^Vim:Interrupt$/
@ -769,22 +774,20 @@ function! fzf#vim#tags(query, ...)
endif
endif
let tagfile = tagfiles()[0]
" We don't want to apply --ansi option when tags file is large as it makes
" processing much slower.
let tagsize = getfsize(tagfile)
if tagsize > 1024 * 1024 * 20
let proc = 'grep -av ''^\!'' '
let copt = tagsize > 1024 * 1024 * 200 ? '--algo=v1 ' : ''
else
let proc = 'perl -ne ''unless (/^\!/) { s/^(.*?)\t(.*?)\t/'.s:yellow('\1', 'Function').'\t'.s:blue('\2', 'String').'\t/; print }'' '
let copt = '--ansi '
let tagfiles = tagfiles()
let v2_limit = 1024 * 1024 * 200
for tagfile in tagfiles
let v2_limit -= getfsize(tagfile)
if v2_limit < 0
break
endif
endfor
let opts = v2_limit < 0 ? '--algo=v1 ' : ''
return s:fzf('tags', {
\ 'source': proc.shellescape(fnamemodify(tagfile, ':t')),
\ 'source': shellescape(s:bin.tags).' '.join(map(tagfiles, 'shellescape(fnamemodify(v:val, ":p"))')),
\ 'sink*': s:function('s:tags_sink'),
\ 'dir': fnamemodify(tagfile, ':h'),
\ 'options': copt.'-m --tiebreak=begin --prompt "Tags> "'.s:q(a:query)}, a:000)
\ 'options': opts.'--nth 1..2 --with-nth ..-2 -m --tiebreak=begin --prompt "Tags> "'.s:q(a:query)}, a:000)
endfunction
" ------------------------------------------------------------------

15
bin/tags.pl Executable file
View file

@ -0,0 +1,15 @@
#!/usr/bin/env perl
use strict;
foreach my $file (@ARGV) {
open my $lines, $file;
while (<$lines>) {
unless (/^\!/) {
s/^[^\t]*/sprintf("%-24s", $&)/e;
s/$/\t$file/;
print;
}
}
close $lines;
}