tagbar icon indicating copy to clipboard operation
tagbar copied to clipboard

tagbar window highlighting broken when unknown tag kind is found

Open raven42 opened this issue 3 years ago • 1 comments

This is a side effect of #676. When the ctags output contains a new kind not defined in types/uctags.vim, then when the cursor moves through the main file window, the highlighting doesn't work once the cursor moves below one of the unknown kinds. I suspect this has something to do with the GetNearbyTag() routine, but I'm not sure how best to fix it. This will be an issue if any known supported filetypes have an appropriate definition, but if ctags outputs a new type not previously supported for that filetype.

I have tried the following, but that doesn't seem to work. Documenting this here to track this issue.

diff --git a/autoload/tagbar.vim b/autoload/tagbar.vim
index 9f619e6..c7f0ce2 100644
--- a/autoload/tagbar.vim
+++ b/autoload/tagbar.vim
@@ -3017,7 +3017,7 @@ 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 has_key(typeinfo.kinddict, curtag.fields.kind) && a:all || typeinfo.getKind(curtag.fields.kind).stl
                 let tag = curtag
                 break
             endif

raven42 avatar Oct 20 '20 13:10 raven42

figured out a little more about this issue... want to document it here.

This occurs because for some file types, irregardless of the --<filetype>-kinds specified on the command line, ctags might still output additional kinds.

Take the following perl file:

   1  package package::obj;
   2  
   3  use Moose;
   4  
   5  use Class::Load qw(load_class);
   6  
   7  =method something
   8  Calls something for object
   9  
  10      $obj->something();
  11  
  12  =cut
  13  sub something {
  14      my $self = shift;
  15  }

In this instance, ctags will have two tags for something, one of them being a method, and the other being a subroutine

something	test.pl	/^sub something {$/;"	s	line:13
something	test.pl	/^sub something {$/;"	m	line:13	class:package::obj

In the initial issue #672, the error was that tagbar wasn't aware of the m kind for methods. However it still created a tag entry for it. In this file above, there will be a tag in tagbar defined for something as a method, and a second tag for something defined as a subroutine. These existed in the same dictionary in tagbar under the same key.

Side note: I have no idea why ctags is identifying the line number as the same on both the subroutine and method tags.

So now for the highlighting issue. Lets say we have the cursor at line 14. When the lookup is done to highlight, tagbar first does a s:GetNearbyTag() to find the nearest tag. It finds the correct something tag for the subroutine kind. But then later when rendering the content, tagbar is going through the list of tags looking for something while not taking into account the kind. This results in tagbar finding the something tag entry for the method kind, and since that was previously an unknown kind, it wasn't rendered and so tagbar thought it had nothing to highlight since that particular tag wasn't visible.

So this situation is unique to when ctags might output two different kinds, and when the file being examined contains two entries with the same name but are two different kinds. There are a couple possible fixes for this. First is tagbar could ignore the unknown tag types and not create internal tags if it doesn't know the kind. The second option I see would be to make the tag key a combination of the tag.name and tag.kind. Both of these options would avoid duplication of the tag list.

raven42 avatar Nov 13 '20 16:11 raven42