3

I have the following configuration for OCaml development which works fine:

" --------------- OCaml -----------------------------
" Merlin
let g:opamshare = substitute(system('opam config var share'),'\n$','','''')
execute 'set rtp+=' . g:opamshare . '/merlin/vim'
" ocp-indent
execute 'set rtp^=' . g:opamshare . '/ocp-indent/vim'
" enable deoplete
let g:deoplete#enable_at_startup = 1

Given that I use differents languages, I want to just use this configuration with OCaml files so I tried to create a function and to call it if the FileType is ocaml:

augroup OCaml_Environment
  autocmd!
  autocmd FileType ocaml :call OCamlEnvSetup()
augroup END

function! OCamlEnvSetup()
  let g:opamshare = substitute(system('opam config var share'),'\n$','','''')
  execute 'set rtp+=' . g:opamshare . '/merlin/vim'
  " ocp-indent
  execute 'set rtp^=' . g:opamshare . '/ocp-indent/vim'
  " enable deoplete
  let g:deoplete#enable_at_startup = 1
endfunction

But now I can not access to commands defined in merlin/vim for example. What am I doing wrong?

Edit

Based on the answers I modified my function:

augroup OCaml_Environment
    autocmd!
    autocmd FileType ocaml :call OCamlEnvSetup()
augroup END


function! OCamlEnvSetup()    
   let g:opamshare = substitute(system('opam config var share'),'\n$','','''')
   execute 'set rtp+=' . g:opamshare . '/merlin/vim'
   execute 'runtime ' . g:opamshare . '/merlin/vim'
   " ocp-indent
   execute 'set rtp^=' . g:opamshare . '/ocp-indent/vim'
   execute 'runtime ' . g:opamshare . '/ocp-indent/vim'
endfunction

let g:deoplete#enable_at_startup = 1

With this I have the following error:

[deoplete] Merlin not found, make sure ocamlmerlin is in your path and merlin's vim plugin is installed.

After that I tried to use a filetype-plugin too, creating the file ~/.config/nvim/ftplugin/ocaml.vim with the following content:

let g:opamshare = substitute(system('opam config var share'),'\n$','','''')
execute 'set rtp+=' . g:opamshare . '/merlin/vim'
execute 'runtime ' . g:opamshare . '/merlin/vim/plugin/**/*.vim'
" ocp-indent
execute 'set rtp^=' . g:opamshare . '/ocp-indent/vim'
execute 'runtime ' . g:opamshare . '/ocp-indent/vim/plugin/**/*.vim'

But now it looks like the configuration is not loaded, because for example, I can not use the :MerlinTypeOf that is available with merlin.vim.

3
  • Use the filetype plugin system: see e.g. my answer here
    – D. Ben Knoble
    Oct 28, 2018 at 16:01
  • Thinking on it additionally, it may be because of when vim loads things from runtimepath. That is, you may need to runtime <filename> after changing the rtp to get it to work
    – D. Ben Knoble
    Oct 28, 2018 at 16:02
  • I created a file ~/.config/nvim/ftplugin/ocaml.vim with the initial configuration but it does not work. I also used the initial configuration adding runtime g:opamshare . '/merlin/vim' but it doesn't help neither.
    – cedlemo
    Oct 28, 2018 at 20:50

2 Answers 2

3

Have a look at :help startup. If you set up 'runtimepath' in your ~/.vimrc, Vim will later load the plugins found there (:help load-plugins).

Now if you do the 'runtimepath' setup later, Vim is ready to source any autoload functions from there, but the plugin configuration itself (that would make use of the autoload functions), has never been loaded! Therefore, you need to explicitly :runtime any plugins and filetype detections yourself. In the comments, you've indicated that you've tried that via runtime g:opamshare . '/merlin/vim':

  • Vim's evaluation rules are different than most programming languages. You need to use :execute in order to evaluate a variable (or expression); otherwise, it's taken literally; i.e. Vim uses the variable name itself as the argument.
  • :runtime needs a list of files / file glob, and you want to get all plugin files (i.e. from the plugin subdirectory).
:execute 'runtime' g:opamshare . '/merlin/vim/plugin/**/*.vim'

Wait, there are also filetype plugins

Please note that your approach is only recommended for general plugins that you however only want to use in the context of a certain filetype. For plugins that truly are specific to a filetype, there's :help filetype-plugins built into Vim, and that is far more elegant that the approach described here.

4
  • I changed my configuration (both in init.vim or in the filetype plugin) with the hints you gave me, but without success unfortunately, I edited my question so that you can see the modifications I did.
    – cedlemo
    Nov 3, 2018 at 8:38
  • 1
    In OCamlEnvSetup(), you still miss the .../plugin/**/*.vim. And you can't simply switch between filetype and normal plugin. A plugin is written either as one or the other. Your filetype stuff would continuously augment the runtimepath, with every Ocaml file you edit. Nov 3, 2018 at 9:43
  • Oups, you are right for I forgot .../plugin/**/*.vim, but it does not make it work.
    – cedlemo
    Nov 3, 2018 at 15:52
  • 1
    Well, unless you feel able to troubleshoot this further on your own (with :scriptnames and :set verbose), I'd really recommend to look into the plugin alternatives I've put into a separate answer, or just stick with loading the plugin all the time (which shouldn't be so bad if the plugin is well-written - you never mentioned your motivation for all of this). Nov 3, 2018 at 19:59
1

As you apparently struggle with setting this up yourself, an alternative may be delegating the implementation to a plugin:

  • vim-plug is a fully-featured plugin manager (that offers much more than just runtimepath manipulation); it explicitly supports On-demand loading for faster startup time
  • enabler.vim is a more dedicated plugin to load plugins/bundles as needed

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.