preservim / tagbar

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

[question, feature request] how to check that the tagbar plugin is loaded? #774

Closed XSven closed 3 years ago

XSven commented 3 years ago

Seeminly there exists no such global boolean variable like g:loaded_tagbar or g:loaded_tagbarPlugin or g:loaded_tagbar_plugin to check that the tagbar plugin is loaded. What alternative exists? If no proper alternative exists, could one of the previous variables be implemented and documented?

raven42 commented 3 years ago

You are correct that there is no global variable currently. Can I ask what your intended purpose is? There are ways to check for it that don't require any changes, but it would depend on your use case.

XSven commented 3 years ago

I would like to add this

" Tagbar perl configuration
if exists('g:loaded_tagbar_plugin')
  let g:tagbar_type_perl = {
    \ 'kinds' : [
      \ 'c:constants:0:0',
      \ 'f:formats:0:0',
      \ 'l:labels:0:1',
      \ 'p:packages:1:0',
      \ 's:subroutines:0:1',
      \ 'd:subroutineDeclaration:0:0',
      \ 'M:modules:0:0',
    \ ],
    \ 'deffile' : '~/.vim/ctags/perl.ctags',
  \ }
endif

to my ~/.vim/ftplugin/perl.vim file.

raven42 commented 3 years ago

I'm not sure that will work as expected. Once tagbar is loaded into memory, defining a different g:tagbar_type_perl will not be effective. It will have already loaded the default perl profile.

I would recommend checking the vim runtime path to look for tagbar similar to this:

let g:have_tagbar = &runtimepath =~# 'tagbar' ? 1 : 0

if g:have_tagbar
    " Setup tagbar parameters here
endif
XSven commented 3 years ago

I dont' get your first sentence about effectiveness: I have read :h tagbar-extend and I thought it is possible to overwrite g:tagbar_type_perl. I need this because its default

let g:tagbar_type_perl = {
      \ 'kinds' : [
          \ 'p:packages:1:0',
          \ 'c:constants:0:0',
          \ 'a:attributes:0:0',
          \ 'f:formats:0:0',
          \ 'l:labels',
          \ 's:subroutines',
          \ 'm:methods',
      \ ],
  \ }

does not fit to what universal-ctags offers

  ctags --list-kinds-full=perl
  #LETTER NAME                  ENABLED REFONLY NROLES MASTER DESCRIPTION
  M       module                no      yes     2      NONE   modules
  c       constant              yes     no      0      NONE   constants
  d       subroutineDeclaration no      no      0      NONE   subroutine declarations
  f       format                yes     no      0      NONE   formats
  l       label                 yes     no      0      NONE   labels
  p       package               yes     no      0      NONE   packages
  s       subroutine            yes     no      0      NONE   subroutines

By the way your suggestion works but it is ugly. I would recommend to introduce a g:loaded_... style of variable. I think this approach is common for plugin implementations.

raven42 commented 3 years ago

The issue is when the tagbar plugin loads, that is when any user defined g:tagbar_type_xxx definitions are loaded and built into a mapping for the files. Adding or changing g:tagbar_type_xxx after the plugin has loaded will have no effect as the initialization is already complete.

For this to work correctly, you have to define g:tagbar_type_xxx before tagbar is loaded. That is the only way it will know about the different language settings. The current code and way tagbar was setup, it doesn't support changing a language tag definition at runtime. Only when tagbar first loads into memory does it check for any custom g:tagbar_type_xxx type definitions and load them up. So that is what I meant by it wouldn't be effective. What you are needing is a way to see if tagbar is available to load so you can define your custom definition as described in the tagbar-extend as you are indicating, and then after you have your definition set, then allow the plugin to load.

I know of the approach you speak of with other plugins, and I use some of those variables myself. I'm not against doing it, but for your desired use-case it will not work. Actually looking at the code I did find there is the following:

let g:loaded_tagbar = 1

This is located in tagbar/autoload/tagbar.vim and should be set once tagbar is loaded. You could certainly try it out, but as I stated previously, once tagbar is loaded, defining or changing g:tagbar_type_perl will have no effect.

Now down to the root issue. You are correct that it does look like the default perl definition in tagbar is out of date. I'm not sure when this changed, but I think the best approach would be to correct the default perl definition in tagbar instead of forcing someone like yourself to define some custom settings. I don't really work with perl myself, but would you be able to try out a patch to see if it works? This should correct the definition for everyone.

diff --git a/autoload/tagbar/types/uctags.vim b/autoload/tagbar/types/uctags.vim
index 87be168..5fd4a28 100644
--- a/autoload/tagbar/types/uctags.vim
+++ b/autoload/tagbar/types/uctags.vim
@@ -797,11 +797,11 @@ function! tagbar#types#uctags#init(supported_types) abort
     let type_perl.kinds     = [
         \ {'short' : 'p', 'long' : 'packages',    'fold' : 1, 'stl' : 0},
         \ {'short' : 'c', 'long' : 'constants',   'fold' : 0, 'stl' : 0},
-        \ {'short' : 'a', 'long' : 'attributes',  'fold' : 0, 'stl' : 0},
+        \ {'short' : 'M', 'long' : 'modules',     'fold' : 0, 'stl' : 0},
         \ {'short' : 'f', 'long' : 'formats',     'fold' : 0, 'stl' : 0},
         \ {'short' : 'l', 'long' : 'labels',      'fold' : 0, 'stl' : 1},
         \ {'short' : 's', 'long' : 'subroutines', 'fold' : 0, 'stl' : 1},
-        \ {'short' : 'm', 'long' : 'methods',     'fold' : 0, 'stl' : 1}
+        \ {'short' : 'd', 'long' : 'subroutineDeclarations',     'fold' : 0, 'stl' : 0}
     \ ]
     let types.perl = type_perl
     " Perl 6 {{{1
XSven commented 3 years ago

I can confirm that your change of the perl default kinds works. At least the d kind. I could not figure out yet what the kind M refers to. Yes it says modules and I have some perl experience:-(

I have also understood your explanation about g:tagbar_type_xxx. Fortunately when I have opened a perl file the tagbar was never present (loaded) automatically. Therefore the plugin was not loaded and g:loaded_tagbar was undefined (did not exist) but g:have_tagbar was true and the g:tagbar_type_perl overwrite in my perl.vim did work.

XSven commented 3 years ago

One more comment. This debug output

2021-06-23 07:49:50.071215: ctags_args (is a list): ['--extras=+F', '-f', '-', '--format=2', '--excmd=pattern', '--fields=nksSafet', '--sort=no', '--append=no', '-V', '--options=~/.vim/ctags/perl.ctags', '--language-force=perl', '--perl-kinds=pcMflds']

shows that a g:tagbar_ctags_options setting (--options) comes before --perl-kinds. With this order it is not possible to turn of kinds like for example p configuring --kinds-perl=-p in ~/.vim/ctags/perl.ctags. I don't know if this order is on purpose?!

raven42 commented 3 years ago

Ok glad the fix is working. I am not sure about the M option either for modules. Perhaps someone more familiar with perl than me will be able to help.

I'll merge in the fix for the perl modules.

Regarding the other argument ordering issue, I don't think that was done specifically to prevent that type of thing. I think it more likely that use-case was simply not thought of when the options were added. If you want to open a separate issue to track that, I can play around with seeing if the order can be changed.