4

When I run this command in ex mode it works without a problem:

:call deoplete#custom#source('ultisnips', 'rank', 1000)

However, when I put it in my vimrc I get an error:

Error detected while processing /Users/me/config/nvim/plugins/deoplete.vim:
line   14:
E117: Unknown function: deoplete#custom#source

I have the deoplete plugin installed via a git submodule and deoplete works in vim. I just can't use call with any of its commands. Am using Neovim 0.3.3. I feel perhaps my init is being sourced before the plugin has finished loading but I am not sure how to go about sorting this out.

3
  • 1
    Where is the plugin located? If it’s in packpath, in wont be loaded until after your vimrc is loaded.
    – D. Ben Knoble
    Feb 22, 2019 at 14:42
  • They are in site/pack/me/start/** - is there somewhere else they should be ?
    – thornomad
    Feb 22, 2019 at 18:56
  • Thats the right spot. I’ll add an answer addressing packages.
    – D. Ben Knoble
    Feb 22, 2019 at 19:33

2 Answers 2

1

According to the OP, the plugin directory is located inside the 'packpath', which means the plugin is not available until after the vimrc is processed:

When Vim starts up, after processing your .vimrc, it scans all directories in
'packpath' for plugins under the "pack/*/start" directory.  First all those
directories are added to 'runtimepath'.  Then all the plugins are loaded.
See |packload-two-steps| for how these two steps can be useful.

[...]

Note that the files under "pack/foo/opt" are not loaded automatically, only the
ones under "pack/foo/start".  See |pack-add| below for how the "opt" directory
is used.
Loading packages automatically will not happen if loading plugins is disabled,
see |load-plugins|.
To load packages earlier, so that 'runtimepath' gets updated: >
    :packloadall
This also works when loading plugins is disabled.  The automatic loading will
only happen once.

(:help packages)

While the help system mentions using :packloadall to load packages earlier, I offer an alternative suggestion: the after directory. By the time after files load, packages have been loaded. In my own Dotfiles, I keep a directory ~/.vim/after/plugin/config/1 with short files to customize my plugins.

As an example, my config for ale is in ~/.vim/after/plugin/config/ale.vim:

if ! exists(':ALEInfo')
  finish
endif

let g:ale_set_signs = 0

let g:ale_linters = {
      \ 'python': 'all',
      \ 'java': [],
      \ }

The trick is generally to find a reliable way of testing for the presence of the plugin: when they define commands or "skip" variables (e.g. g:loaded_{name}), we can test those. Autoload'ed functions (file#name) are harder because they don't exist until they are used.

In your case, I'd use g:loaded_deoplete in a file like ~/.vim/after/plugin/config/deoplete.vim (use the equivalent for neovim):

if ! exists('g:loaded_deoplete')
  finish
endif

" your custom code here
call deoplete#custom#source('ultisnips', 'rank', 1000)

  1. The name plugin does not mean plugin as a set of code from GitHub or elsewhere, but rather a plugin script (cf. :help plugin). The name config is not significant except that it helps me organize my after/plugin directory: all the configuration lies there. Note that all subdirectories of a plugin directory are searched for scripts.
1
  • 1
    Thanks for that detailed response - I think the after\plugin folder seems a more canonical way to do things and now that I've moved everything around I like it much better. I guess it would make sense to move all my plugin related business in there, come to think of it!
    – thornomad
    Feb 22, 2019 at 22:02
2

You could try using the VimEnter autocmd:

augroup DeopleteOptions
   au!
   autocmd VimEnter * 
   \ if exists('*deoplete#custom#source') | 
   \     call deoplete#custom#source('ultisnips', 'rank', 1000) |
   \ endif
augroup END

The if avoids errors if you are running somewhere you don't have all your plugins installed.

4
  • Thanks for such a detailed response! The if statement trips it up though for me ... if I remove it and just call: autocmd VimEnter * call deoplete#custom#source('ultisnips', 'rank', 1000) it works ... I tried to play around with variations but can't figure out what is wrong with that if statement.
    – thornomad
    Feb 21, 2019 at 21:58
  • 1
    @thornomad glad I could help! Have you tried to uninstall the plugin (or at least rename the autoload folder)? It is supposed to make no difference if you have the deoplete plugin installed. But if you copy your vimrc to a server to do some quick work without installing your plugins then you would keep receiving annoying errors every time you open neovim.
    – mMontu
    Feb 22, 2019 at 10:57
  • The if wont work because autoloaded functions arent defined until first-called.
    – D. Ben Knoble
    Feb 22, 2019 at 19:33
  • Thanks @D.BenKnoble, you are right. OP could try if &rtp =~ 'plugin-name, as suggested here.
    – mMontu
    Feb 25, 2019 at 14:38

Your Answer

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

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