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:
@@ -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
|
||||
|
||||
@@ -14,6 +14,7 @@ function! tagbar#prototypes#basetag#new(name) abort
|
||||
let newobj.fields = {}
|
||||
let newobj.fields.line = 0
|
||||
let newobj.fields.column = 0
|
||||
let newobj.fields.end = 0
|
||||
let newobj.prototype = ''
|
||||
let newobj.data_type = ''
|
||||
let newobj.path = ''
|
||||
|
||||
Reference in New Issue
Block a user