2

I have an "optional" plugin that depends on python (pack/habamax/opt/myplugin)

in my settings I have the following:

if has('python') || has('python3')
    do some setup
    packadd myplugin
endif

This thing fails if there is no myplugin though.

Is there a way I can add to an if statement to check if myplugin exists? if packexists('myplugin')?

I can probably have a try catch to suppress errors but the thing is that there might be elseif:

" if there is package myplugin and all dependencies
if has('python') || has('python3')
    do some setup
    packadd myplugin
else
"use another plugin without dependencies
    do some setup
    packadd anotherplugin
endif

@Matt,

enter image description here

UPDATE

Thanks for the help.

I end up using silent! packadd ...:

" try to load myplugin first
if has('python') || has('python3')
    do some setup
    silent! packadd myplugin
endif

"use another plugin without dependencies
if !exists("g:myplugin_loaded")
    do some setup
    packadd anotherplugin
endif

19
  • If no one comes up with a proper solution, you can easily workaround the else requirement by setting a flag if packadd is successful, and loading your other plugin in an if block that checks if the flag is set.
    – Rich
    Nov 22, 2019 at 14:56
  • As it's an "optional" plugin, what do you mean by "exists": exists in path or was already loaded?
    – Matt
    Nov 22, 2019 at 14:56
  • @Matt exists in path, not loaded. I want to load it if dependencies are satisfied
    – Maxim Kim
    Nov 22, 2019 at 14:59
  • @Rich so try catch in that case?
    – Maxim Kim
    Nov 22, 2019 at 14:59
  • 1
    packadd does not throw an exception. So you have to packadd and then additionally check if there's loaded_myplugin flag, or exists('smth'), or whatever else.
    – Matt
    Nov 22, 2019 at 15:03

3 Answers 3

2

You could just

silent! packadd <plugin>
1
  • Thx, this really suppress the error. So with that I can also check if package has been really loaded with g:loaded... variables
    – Maxim Kim
    Nov 22, 2019 at 15:26
2

You can use :h exists() to test if a variable, a command or a function provided by the plugin is defined. If it is defined then it means the plugin is available:

exists({expr})  The result is a Number, which is |TRUE| if {expr} is
        defined, zero otherwise.

        The {expr} argument is a string, which contains one of these:
            &option-name    Vim option (only checks if it exists,
                    not if it really works)
            [...]
            *funcname   built-in function (see |functions|)
                    or user defined function (see
                    |user-functions|). Also works for a
                    variable that is a Funcref.
            [...]
            :cmdname    Ex command: built-in command, user
                    command or command modifier |:command|.
                    Returns:
                    1  for match with start of a command
                    2  full match with a command
                    3  matches several user commands
                    To check for a supported command
                    always check the return value to be 2.

So the idea is to check for something defined by the plugin. For example if you want to test that GitGutter is installed you can check for the g:loaded_gitgutter variable it defines like this:

if (exists('g:loaded_gitgutter'))
    nnoremap <C-L> :nohlsearch\|GitGutter<CR><C-L>
endif

Note that most of the plugins should defined a variable of the form g:loaded_pluginname as @Rich pointed out in the comments.

9
  • Command doesn't exist -- myplugin is in opt and not loaded unless I try to packadd it. Or am I missing something?
    – Maxim Kim
    Nov 22, 2019 at 15:00
  • 1
    g:loaded_gitgutter is probably a less brittle thing to check. Most plugins have a similar variable, as it's recommended in the "how to write a plugin" docs.
    – Rich
    Nov 22, 2019 at 15:01
  • @MaximKim The idea is to grab something defined by your plugin, so maybe it has a g:loaded_XXX variable or something like this, if you can share the name of the plugin we can check that. @ Rich definitely a better way to do it indeed.
    – statox
    Nov 22, 2019 at 15:11
  • @statox that is LeaderF plugin
    – Maxim Kim
    Nov 22, 2019 at 15:21
  • @Rich do all g variables exist even if I didn't add a package from opt with packadd?
    – Maxim Kim
    Nov 22, 2019 at 15:22
2

You can also use a try/catch block and a local variable to control whether you managed to load it successfully.

let has_myplugin = 0
" if there is package myplugin and all dependencies
if has('python') || has('python3')
    do some setup
    try
        packadd myplugin
        let has_myplugin = 1
    catch /^Vim\%((\a\+)\)\=:E919:/
        " Directory not found in packpath.
        " Fallback to the ! has_myplugin case.
    endtry
endif

if ! has_myplugin
    " use another plugin without dependencies
    do some setup
    packadd anotherplugin
endif

Also consider that you might want to use packadd! if you're doing it from your vimrc file. From :help :packadd:

When the optional ! is added no plugin files or ftdetect scripts are loaded, only the matching directories are added to runtimepath. This is useful in your .vimrc. The plugins will then be loaded during initialization, see load-plugins.

(See also: :help :packloadall.)

4
  • Thx, try catch came first to my mind but I wasn't sure about it
    – Maxim Kim
    Nov 22, 2019 at 15:59
  • 2
    Eek, a naked catch! You might want to catch command not found or some specific error
    – D. Ben Knoble
    Nov 22, 2019 at 16:01
  • @D.BenKnoble Yeah good point! Fixed now. Possibly too specific, but maybe that's good? Would probably need to test that it works as expected.
    – filbranden
    Nov 22, 2019 at 17:05
  • 1
    Nice! (Filler text)
    – D. Ben Knoble
    Nov 22, 2019 at 17:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.