From bc48b8b84bced1ac35d01f50b2e2ce2c8030631d Mon Sep 17 00:00:00 2001 From: raven42 Date: Mon, 26 Oct 2020 10:19:14 -0500 Subject: [PATCH] Scoped Highlighting (#683) * Scoped highlighting fix Attempt to change the scoped highlighting of the tagbar window. This will now look only for 'stl' tag types when looking for the nearby tag when looking to highlight. It does however take into account if the cursor is on the same line as the tag and highlights it then as well. * Add additional documentation * Add documentation for tagbar#printfileinfo() debug routine --- autoload/tagbar.vim | 62 ++++++++++++++++++++----- autoload/tagbar/prototypes/fileinfo.vim | 3 ++ doc/tagbar.txt | 26 ++++++++++- 3 files changed, 79 insertions(+), 12 deletions(-) diff --git a/autoload/tagbar.vim b/autoload/tagbar.vim index 0e699e4..4f7b890 100644 --- a/autoload/tagbar.vim +++ b/autoload/tagbar.vim @@ -1767,9 +1767,7 @@ function! s:create_pseudotag(name, parent, kind, typeinfo, fileinfo) abort \ pseudotag.path . a:typeinfo.sro . pseudotag.name endif let pseudotag.depth = len(split(pseudotag.path, '\V' . escape(a:typeinfo.sro, '\'))) - let pseudotag.parent = a:parent - let pseudotag.fileinfo = a:fileinfo let pseudotag.typeinfo = a:typeinfo @@ -1985,7 +1983,6 @@ function! s:PrintKinds(typeinfo, fileinfo) abort let curline = len(output) + offset let tag.tline = curline let a:fileinfo.tline[curline] = tag - let tag.depth = 1 endfor endif @@ -2136,9 +2133,9 @@ function! s:HighlightTag(openfolds, ...) abort let force = a:0 > 0 ? a:1 : 0 if a:0 > 1 - let tag = s:GetNearbyTag(1, 0, a:2) + let tag = s:GetNearbyTag('highlight', 0, a:2) else - let tag = s:GetNearbyTag(1, 0) + let tag = s:GetNearbyTag('highlight', 0) endif if !empty(tag) let tagline = tag.tline @@ -2576,7 +2573,7 @@ function! s:OpenParents(...) abort if a:0 == 1 let tag = a:1 else - let tag = s:GetNearbyTag(1, 0) + let tag = s:GetNearbyTag('parent', 0) endif if !empty(tag) @@ -2993,7 +2990,7 @@ endfunction " s:GetNearbyTag() {{{2 " Get the tag info for a file near the cursor in the current file -function! s:GetNearbyTag(all, forcecurrent, ...) abort +function! s:GetNearbyTag(request, forcecurrent, ...) abort if s:nearby_disabled return {} endif @@ -3019,7 +3016,19 @@ function! s:GetNearbyTag(all, forcecurrent, ...) abort for line in range(curline, 1, -1) if has_key(fileinfo.fline, line) let curtag = fileinfo.fline[line] - if a:all || typeinfo.getKind(curtag.fields.kind).stl + if a:request ==# 'highlight' && typeinfo.getKind(curtag.fields.kind).stl + let tag = curtag + break + endif + if a:request ==# 'highlight' && line == curline + let tag = curtag + break + endif + if a:request ==# 'statusline' && typeinfo.getKind(curtag.fields.kind).stl + let tag = curtag + break + endif + if a:request ==# 'parent' let tag = curtag break endif @@ -3548,7 +3557,7 @@ function! tagbar#GetTagNearLine(lnum, ...) abort let prototype = 0 endif - let taginfo = s:GetNearbyTag(0, 1, a:lnum) + let taginfo = s:GetNearbyTag('statusline', 1, a:lnum) if empty(taginfo) return '' @@ -3689,7 +3698,7 @@ function! tagbar#currenttag(fmt, default, ...) abort return a:default endif - let tag = s:GetNearbyTag(0, 1) + let tag = s:GetNearbyTag('statusline', 1) if !empty(tag) if prototype @@ -3761,7 +3770,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(0, 1) + let tag = s:GetNearbyTag('statusline', 1) if empty(tag) return a:default @@ -3782,5 +3791,36 @@ function! tagbar#currenttagtype(fmt, default) abort return printf(a:fmt, singular) endfunction +" tagbar#printfileinfo() {{{2 +function! tagbar#printfileinfo() abort + if !tagbar#debug#enabled() + echo 'Tagbar debug is disabled - unable to print fileinfo to tagbar log' + return + endif + + let fileinfo = tagbar#state#get_current_file(0) + if empty(fileinfo) + call tagbar#debug#log('File contains no tag entries') + return + endif + let typeinfo = fileinfo.typeinfo + + call tagbar#debug#log('Printing fileinfo [' . fileinfo.fpath . ' lines:' . fileinfo.lnum) + for line in range(1, fileinfo.lnum) + if has_key(fileinfo.fline, line) + let tag = fileinfo.fline[line] + call tagbar#debug#log(' ' + \ . ' line:' . line + \ . ' kind:' . tag.fields.kind + \ . ' depth:' . tag.depth + \ . ' [' . tag.strfmt() . ']' + \ ) + endif + endfor + call tagbar#debug#log('All tags printed') + + echo 'Tagbar fileinfo printed to debug logfile' +endfunction + " Modeline {{{1 " vim: ts=8 sw=4 sts=4 et foldenable foldmethod=marker foldcolumn=1 diff --git a/autoload/tagbar/prototypes/fileinfo.vim b/autoload/tagbar/prototypes/fileinfo.vim index 934ae1a..fe2ae86 100644 --- a/autoload/tagbar/prototypes/fileinfo.vim +++ b/autoload/tagbar/prototypes/fileinfo.vim @@ -12,6 +12,9 @@ function! tagbar#prototypes#fileinfo#new(fname, ftype, typeinfo) abort " Get file size let newobj.fsize = getfsize(a:fname) + " Get the number of lines in the file + let newobj.lnum = line('$') + " The vim file type let newobj.ftype = a:ftype diff --git a/doc/tagbar.txt b/doc/tagbar.txt index 84b1dec..31dc9b0 100644 --- a/doc/tagbar.txt +++ b/doc/tagbar.txt @@ -348,6 +348,11 @@ FUNCTIONS *tagbar-functions* value. This also clears the internal flags to the file will be re-examined again. +tagbar#printfileinfo() + This function is used in conjunction with |TagbarDebug| and will print all + the known tags into the tagbar debug logfile. This is useful for looking + at the internal tag information that tagbar tracks. + ------------------------------------------------------------------------------ KEY MAPPINGS *tagbar-keys* @@ -1199,7 +1204,26 @@ kinds: A list of the "language kinds" that should be listed in Tagbar, "f:functions:1" < would list all the function definitions in a file under the header "functions", fold them, and implicitly show them in the statusline - if tagbar#currenttag() is used. + if tagbar#currenttag() is used. The {stl} field is also used to + determine tag that are considered for scoped highlighting in the + tagbar window. By default, whenever the cursor is on a line + containing a known tag, then that tag will be highlighted in the + tagbar window. However if the cursor is not on a line containing a + tag, then only tags of a type that has {stl} set to 1 will be + highlighted. For example, in C the "macro" type has an {stl} value + of 0. So if there is a macro defined within the scope of a + function such as this: +> + int function1(int arg) { + #define BUF_LENGTH 10 + char buffer[BUF_LENGTH + 1]; + snprintf(buffer, BUF_LENGTH, "some string"); + } +< + Then when the cursor is on the #define line, then that macro will + be highlighted in the tagbar window. However if the cursor was on + the snprintf() line, then the tag for function1() would be + highlighted. sro: The scope resolution operator. For example, in C++ it is "::" and in Java it is ".". If in doubt run ctags as shown below and check the output.