preservim / tagbar

Vim plugin that displays tags in a window, ordered by scope
https://preservim.github.io/tagbar
Other
6.13k stars 487 forks source link

Setting g:tagbar_scopestrs has no effect #720

Closed Strahinja closed 3 years ago

Strahinja commented 3 years ago

I'm trying to set up Tagbar to show symbols instead of tag scopes using an extended snippet from the Tagbar documentation, having this in my ~/.config/nvim/init.vim:

let g:tagbar_scopestrs = {
    \    'class': "\uf0e8",
    \    'const': "\uf8ff",
    \    'constant': "\uf8ff",
    \    'enum': "\uf702",
    \    'field': "\uf30b",
    \    'func': "\uf794",
    \    'function': "\uf794",
    \    'functions': "\uf794",
    \    'getter': "\ufab6",
    \    'implementation': "\uf776",
    \    'interface': "\uf7fe",
    \    'map': "\ufb44",
    \    'member': "\uf02b",
    \    'method': "\uf6a6",
    \    'setter': "\uf7a9",
    \    'variable': "\uf71b",
    \    'variables': "\uf71b",
    \ }

but it seems it has no effect. I'm still getting the scopes displayed as strings: Tagbar scopes.

I'm using the latest Tagbar (using vim-plug and latest tagbar commit b63e8cb83f08165d15474ea1291c51f6661f1f7e), and the latest neovim on Artix Linux (NVIM v0.4.4).

raven42 commented 3 years ago

There are a number of things to note with the g:tagbar_scopestrs setting.

First it is mutually exclusive with the g:tagbar_show_data_type setting. If the show_data_type value is set, then the scopestrs is not used. It does not look like you have that enabled though, so I don't think that is it for your use case.

Second, the scopestrs only operates on the ctags kinds that are listed in the kind2scope definition for that particular kind. In the example you gave, it doesn't look like the variables or functions types are defined in the kind2scope. Instead all functions are being grouped together.

Thirdly, I'm wondering if you are expecting the correct display. The scopestrs setting doesn't change the parent name functions or variables in your example, but it changes the scope info that is printed after a given tag when it is a scoped kind.

See an example from a c file with a custom g:tagbar_type_c definition to add functions to the kind2scope. I'll include the base definition with no tagbar options first, and then the scopestrs definition.

C code example

#include <stdio.h>

typedef struct {
    int     s1_var1;
    int     s1_var2;
} s1_t;

typedef struct s2_s {
    int     s2_var1;
    int     s2_var2;
} s2_t;

int function1(int c) {
    return (0);
}

int main(int arvc, char *argv[]) {
    return (0);
}

Base tagbar definition for c file

image

Custom g:tagbar_type_c to add functions to the kind2scope / scope2kind

let g:tagbar_type_c = {
      \ 'ctagstype' : 'c',
      \ 'kinds'     : [
         \ 'h:header files:1:0',
         \ 'd:macros:1:0',
         \ 'p:prototypes:1:0',
         \ 'g:enums:0:1',
         \ 'e:enumerators:0:0',
         \ 't:typedefs:0:0',
         \ 's:structs:0:1',
         \ 'm:members:1:0',
         \ 'v:variables:0:0',
         \ 'f:functions:0:1:{:}'
      \ ],
      \ 'sro'           : '::',
      \ 'kind2scope'    : {
         \ 'g' : 'enum',
         \ 's' : 'struct',
         \ 'f' : 'functions',
      \ },
      \ 'scope2kind'    : {
         \ 'enum'   : 'g',
         \ 'struct' : 's',
         \ 'functions' : 'f',
      \ }
   \ }

image

Custom g:tagbar_type_c with g:tagbar_scope_strs to change the scope str value for functions

let g:tagbar_type_c = {
      \ 'ctagstype' : 'c',
      \ 'kinds'     : [
         \ 'h:header files:1:0',
         \ 'd:macros:1:0',
         \ 'p:prototypes:1:0',
         \ 'g:enums:0:1',
         \ 'e:enumerators:0:0',
         \ 't:typedefs:0:0',
         \ 's:structs:0:1',
         \ 'm:members:1:0',
         \ 'v:variables:0:0',
         \ 'f:functions:0:1:{:}'
      \ ],
      \ 'sro'           : '::',
      \ 'kind2scope'    : {
         \ 'g' : 'enum',
         \ 's' : 'struct',
         \ 'f' : 'functions',
      \ },
      \ 'scope2kind'    : {
         \ 'enum'   : 'g',
         \ 'struct' : 's',
         \ 'functions' : 'f',
      \ }
   \ }

let g:tagbar_scopestrs = {
   \    'functions': "BLAH",
   \ }

image

Kind header definition

Now if I'm understanding what you are looking for correctly, I am thinking you are trying to change the kind headers so for example, all functions would show up under a different header. If this is what you are looking for, then you still need to define a custom g:tagbar_type_<lang> for your language, but instead of adding the kind2scope / scope2kind I mentioned above, you can change the long name value for a given kind. Here is an example using the same c file but a different g:tagbar_type_c definition. In this instance, I changed the f ctags kind to have a long label of BLAH.

let g:tagbar_type_c = {
      \ 'ctagstype' : 'c',
      \ 'kinds'     : [
         \ 'h:header files:1:0',
         \ 'd:macros:1:0',
         \ 'p:prototypes:1:0',
         \ 'g:enums:0:1',
         \ 'e:enumerators:0:0',
         \ 't:typedefs:0:0',
         \ 's:structs:0:1',
         \ 'm:members:1:0',
         \ 'v:variables:0:0',
         \ 'f:BLAH:0:1:{:}'
      \ ],
      \ 'sro'           : '::',
      \ 'kind2scope'    : {
         \ 'g' : 'enum',
         \ 's' : 'struct',
      \ },
      \ 'scope2kind'    : {
         \ 'enum'   : 'g',
         \ 'struct' : 's',
      \ }
   \ }

image

Strahinja commented 3 years ago

I apologize, it seems the ctags terminology wasn't clear to me in this case. I think a couple of minimal examples next to this option in the help would greatly benefit clearing this up for future readers, and especially taking note of the interaction with the g:tagbar_show_data_type setting. Thanks for the clarification, I'll close this now.