1
0
mirror of https://github.com/gryf/tagbar.git synced 2025-12-18 03:50:26 +01:00

Scoped kinds (#696)

* Add support for scope
Closes #508, #516

Add --fields=e (end) to the ctags field types to look for the end of the scope.
Update the `s:GetNearbyTag()` routine to use this scope to look for the correct tag.

* Update comment to call out exuberant ctags not supporting the -e option

* Update autoload/tagbar.vim

Co-authored-by: Caleb Maclennan <caleb@alerque.com>

* Optimize nearesttag search, add option for scoped-stl search method

Co-authored-by: Caleb Maclennan <caleb@alerque.com>
This commit is contained in:
raven42
2020-11-02 15:15:55 -06:00
committed by GitHub
parent 601b5c0073
commit 55b8ffa85c
3 changed files with 108 additions and 53 deletions

View File

@@ -1342,7 +1342,7 @@ function! s:ExecuteCtagsOnFile(fname, realfname, typeinfo) abort
\ '-',
\ '--format=2',
\ '--excmd=pattern',
\ '--fields=nksSaft',
\ '--fields=nksSafet',
\ '--sort=no',
\ '--append=no'
\ ]
@@ -1463,7 +1463,7 @@ function! s:ParseTagline(part1, part2, typeinfo, fileinfo) abort
let fielddict[key] = 'yes'
endif
if len(val) > 0
if key ==# 'line' || key ==# 'column'
if key ==# 'line' || key ==# 'column' || key ==# 'end'
let fielddict[key] = str2nr(val)
else
let fielddict[key] = val
@@ -1525,6 +1525,22 @@ function! s:ProcessTag(name, filename, pattern, fields, is_split, typeinfo, file
let taginfo.fields.line = 0
endif
" Make sure our 'end' is valid
if taginfo.fields.end < taginfo.fields.line
if a:typeinfo.getKind(taginfo.fields.kind).stl
" the config indicates this is a scoped kind due to 'stl', but we
" don't have scope vars, assume scope goes to end of file. This
" can also be the case for exhuberant ctags which doesn't support
" the --fields=e option.
" When we call the GetNearbyTag(), it will look up for the nearest
" tag, so if we have multiples that have scope to the end of the
" file it will still only grab the first one above the current line
let taginfo.fields.end = line('$')
else
let taginfo.fields.end = taginfo.fields.line
endif
endif
if !has_key(taginfo.fields, 'kind')
call tagbar#debug#log(
\ "Warning: No 'kind' field found for tag " . a:name[0] . '!')
@@ -2153,9 +2169,9 @@ function! s:HighlightTag(openfolds, ...) abort
let force = a:0 > 0 ? a:1 : 0
if a:0 > 1
let tag = s:GetNearbyTag('highlight', 0, a:2)
let tag = s:GetNearbyTag('nearest-stl', 0, a:2)
else
let tag = s:GetNearbyTag('highlight', 0)
let tag = s:GetNearbyTag('nearest-stl', 0)
endif
if !empty(tag)
let tagline = tag.tline
@@ -2615,7 +2631,7 @@ function! s:OpenParents(...) abort
if a:0 == 1
let tag = a:1
else
let tag = s:GetNearbyTag('parent', 0)
let tag = s:GetNearbyTag('nearest', 0)
endif
if !empty(tag)
@@ -3058,19 +3074,17 @@ function! s:GetNearbyTag(request, forcecurrent, ...) abort
for line in range(curline, 1, -1)
if has_key(fileinfo.fline, line)
let curtag = fileinfo.fline[line]
if a:request ==# 'highlight' && typeinfo.getKind(curtag.fields.kind).stl
if a:request ==# 'nearest-stl'
\ && typeinfo.getKind(curtag.fields.kind).stl || line == curline
let tag = curtag
break
endif
if a:request ==# 'highlight' && line == curline
elseif a:request ==# 'scoped-stl'
\ && typeinfo.getKind(curtag.fields.kind).stl
\ && curtag.fields.line <= curline
\ && curline <= curtag.fields.end
let tag = curtag
break
endif
if a:request ==# 'statusline' && typeinfo.getKind(curtag.fields.kind).stl
let tag = curtag
break
endif
if a:request ==# 'parent'
elseif a:request ==# 'nearest'
let tag = curtag
break
endif
@@ -3586,31 +3600,6 @@ endfunction
" Autoload functions {{{1
" Wrappers {{{2
function! tagbar#GetTagNearLine(lnum, ...) abort
if a:0 > 0
let fmt = a:1
let longsig = a:2 =~# 's'
let fullpath = a:2 =~# 'f'
let prototype = a:2 =~# 'p'
else
let fmt = '%s'
let longsig = 0
let fullpath = 0
let prototype = 0
endif
let taginfo = s:GetNearbyTag('statusline', 1, a:lnum)
if empty(taginfo)
return ''
endif
if prototype
return taginfo.getPrototype(1)
else
return printf(fmt, taginfo.str(longsig, fullpath))
endif
endfunction
function! tagbar#ToggleWindow(...) abort
let flags = a:0 > 0 ? a:1 : ''
@@ -3719,28 +3708,67 @@ function! tagbar#autoopen(...) abort
call tagbar#debug#log('tagbar#autoopen finished without finding valid file')
endfunction
" tagbar#GetTagNearLine() {{{2
function! tagbar#GetTagNearLine(lnum, ...) abort
if a:0 >= 2
let fmt = a:1
let longsig = a:2 =~# 's'
let fullpath = a:2 =~# 'f'
let prototype = a:2 =~# 'p'
if a:0 >= 3
let search_method = a:3
else
let search_method = 'nearest-stl'
endif
else
let fmt = '%s'
let longsig = 0
let fullpath = 0
let prototype = 0
let search_method = 'nearest-stl'
endif
let taginfo = s:GetNearbyTag(search_method, 1, a:lnum)
if empty(taginfo)
return ''
endif
if prototype
return taginfo.getPrototype(1)
else
return printf(fmt, taginfo.str(longsig, fullpath))
endif
endfunction
" tagbar#currenttag() {{{2
function! tagbar#currenttag(fmt, default, ...) abort
" Indicate that the statusline functionality is being used. This prevents
" the CloseWindow() function from removing the autocommands.
let s:statusline_in_use = 1
if a:0 > 0
if a:0 >= 1
" also test for non-zero value for backwards compatibility
let longsig = a:1 =~# 's' || (type(a:1) == type(0) && a:1 != 0)
let fullpath = a:1 =~# 'f'
let prototype = a:1 =~# 'p'
if a:0 >= 2
let search_method = a:2
else
let search_method = 'nearest-stl'
endif
else
let longsig = 0
let fullpath = 0
let prototype = 0
let search_method = 'nearest-stl'
endif
if !s:Init(1)
return a:default
endif
let tag = s:GetNearbyTag('statusline', 1)
let tag = s:GetNearbyTag(search_method, 1)
if !empty(tag)
if prototype
@@ -3812,7 +3840,7 @@ function! tagbar#currenttagtype(fmt, default) abort
" the CloseWindow() function from removing the autocommands.
let s:statusline_in_use = 1
let kind = ''
let tag = s:GetNearbyTag('statusline', 1)
let tag = s:GetNearbyTag('scoped-stl', 1)
if empty(tag)
return a:default