Plugin config functions

45 views
Skip to first unread message

Paul Jolly

unread,
May 30, 2019, 1:06:31 PM5/30/19
to vim...@googlegroups.com
Hi all,

As a follow up to a recent thread ("Plugins exposing events to other
plugins": https://groups.google.com/d/msg/vim_dev/uiw6gHft-0g/i8qdfT8YBQAJ)
I'd like to ask whether there is an existing pattern of configuration
functions that plugin developers follow?

Some background.

I'm not really a fan of global config variables in .vimrc files, e.g.:

let g:govim_quickfix_auto_diagnotics_disable=1

especially when it comes to channel-based plugins, because they (the
channel-based plugins) end up having to make a roundtrip call to check
a global variable value; if this is on a "hot" path it becomes
expensive. But also because it's too easy to mis-type/set an invalid
value.

So I'd like to explore a pattern by which the end user calls a config
function from their .vimrc or whenever they want to change a config
value. This will have the benefit of pushing the config value to the
channel-based plugin, but also allowing tighter validation at the time
of the value being set.

The main problem (aside from my complete lack of real understanding of
the .vimrc load sequence) is that plugins have not loaded at the time
.vimrc is processed, and hence it's not possible to call a
plugin-defined config function directly... so we'd need to handle this
somehow.

Does anyone have any thoughts on/experience of the above?

Thanks in advance,


Paul

Gary Johnson

unread,
May 30, 2019, 1:46:12 PM5/30/19
to vim...@googlegroups.com
On 2019-05-30, Paul Jolly wrote:

> So I'd like to explore a pattern by which the end user calls a config
> function from their .vimrc or whenever they want to change a config
> value. This will have the benefit of pushing the config value to the
> channel-based plugin, but also allowing tighter validation at the time
> of the value being set.
>
> The main problem (aside from my complete lack of real understanding of
> the .vimrc load sequence) is that plugins have not loaded at the time
> .vimrc is processed, and hence it's not possible to call a
> plugin-defined config function directly... so we'd need to handle this
> somehow.
>
> Does anyone have any thoughts on/experience of the above?

If you really want to load a plugin so that its functions are
accessible from your vimrc, then put a :source or :runtime command
in your vimrc before you call those functions, e.g.,

:runtime! my_early_plugin.vim
:MyEarlyPluginCommand arg1 arg2

Note that :runtime searches your 'runtimepath' for the specified
file, so in the example above, you would put my_early_plugin.vim in
your ~/.vim directory, not in your ~/.vim/plugin directory.

Regards,
Gary

Andy Massimino

unread,
May 30, 2019, 2:07:01 PM5/30/19
to vim...@googlegroups.com
On 5/30/19 1:06 PM, Paul Jolly wrote:

> Hi all,
>
> As a follow up to a recent thread ("Plugins exposing events to other
> plugins":
> https://groups.google.com/d/msg/vim_dev/uiw6gHft-0g/i8qdfT8YBQAJ)
> I'd like to ask whether there is an existing pattern of configuration
> functions that plugin developers follow?
>
> Some background.
>
> I'm not really a fan of global config variables in .vimrc files, e.g.:
>
> let g:govim_quickfix_auto_diagnotics_disable=1
>
> especially when it comes to channel-based plugins, because they (the
> channel-based plugins) end up having to make a roundtrip call to check
> a global variable value; if this is on a "hot" path it becomes
> expensive. But also because it's too easy to mis-type/set an invalid
> value.
>
> So I'd like to explore a pattern by which the end user calls a config
> function from their .vimrc or whenever they want to change a config
> value. This will have the benefit of pushing the config value to the
> channel-based plugin, but also allowing tighter validation at the time
> of the value being set.
>
> The main problem (aside from my complete lack of real understanding of
> the .vimrc load sequence) is that plugins have not loaded at the time
> .vimrc is processed, and hence it's not possible to call a
> plugin-defined config function directly... so we'd need to handle this
> somehow.
>
> Does anyone have any thoughts on/experience of the above?
>
> Thanks in advance,
>
>
> Paul
>
I don't really see the difference between configuring via global
variable or by calling a function in your vimrc.  Your plugin doesn't
need to check vim's global variable every time you use a feature, just
check it once during plugin initialization and set some internal
variable (supposing your plugin is written in go/python/etc).  There is
no expectation to the user that modifying `g:govim_whatever` will take
immediate effect after the plugin has already started (if you want you
can provide a :GovimReload or similar).  You can also do validation just
once when you are saving the values.

Another option is to use a separate .json or .ini file for configuration
so you don't have to worry about vimrc/plugin sourcing order.  But this
is less idiomatic than putting settings in a single g: dictionary.

To address the direct question, a standard is to use autoloaded
functions, `call myplugin#configure()`.  This merely requires the plugin
to be in the runtimepath which is handled by :Plug or packadd!   A
seperate standard is to use User autocmd which requests the user call
some myplugin#configure() function- if the autocmd is fired the plugin
is definitely loaded and ready to get options set.


Paul Jolly

unread,
Jun 3, 2019, 4:33:01 AM6/3/19
to vim...@googlegroups.com
Thanks for the detailed response.

> I don't really see the difference between configuring via global
> variable or by calling a function in your vimrc. Your plugin doesn't
> need to check vim's global variable every time you use a feature, just
> check it once during plugin initialization and set some internal
> variable (supposing your plugin is written in go/python/etc). There is
> no expectation to the user that modifying `g:govim_whatever` will take
> immediate effect after the plugin has already started (if you want you
> can provide a :GovimReload or similar). You can also do validation just
> once when you are saving the values.

Understood, thanks.

The point about the user's expectation on changing the config value at
runtime is key; I'd like to provide an approach that will work either
in vimrc (i.e. pre-init) or at runtime (i.e. post init).

> Another option is to use a separate .json or .ini file for configuration
> so you don't have to worry about vimrc/plugin sourcing order. But this
> is less idiomatic than putting settings in a single g: dictionary.

Agreed, I'd like to avoid this.

> To address the direct question, a standard is to use autoloaded
> functions, `call myplugin#configure()`. This merely requires the plugin
> to be in the runtimepath which is handled by :Plug or packadd! A
> seperate standard is to use User autocmd which requests the user call
> some myplugin#configure() function- if the autocmd is fired the plugin
> is definitely loaded and ready to get options set.

autoload appears to be exactly what I'm after, thank you. I'll give
this approach a try.

Thanks again.

Paul Jolly

unread,
Jun 13, 2019, 11:22:17 AM6/13/19
to vim...@googlegroups.com
FYI - I implemented this for govim and it's working rather well:

https://github.com/myitcv/govim/blob/5a5f92f0433c07b2aa48a81e7285590f06eb12e7/autoload/govim/config.vim

With the one exception of when govim is loaded as a Vim8 package,
because (and this is a detail I only just came across) packages are
loaded _after_ the .vimrc.

A workaround for this is to do a packloadall at the end of the .vimrc,
followed by calls to the config functions.

Is there perhaps a cleaner solution?

Thanks in advance.

Bram Moolenaar

unread,
Jun 13, 2019, 2:40:38 PM6/13/19
to vim...@googlegroups.com, Paul Jolly

Paul Jolly wrote:

> FYI - I implemented this for govim and it's working rather well:
>
> https://github.com/myitcv/govim/blob/5a5f92f0433c07b2aa48a81e7285590f06eb12e7/autoload/govim/config.vim
>
> With the one exception of when govim is loaded as a Vim8 package,
> because (and this is a detail I only just came across) packages are
> loaded _after_ the .vimrc.
>
> A workaround for this is to do a packloadall at the end of the .vimrc,
> followed by calls to the config functions.
>
> Is there perhaps a cleaner solution?

If someone wants to use the config functions, it should be
straightforward to first to "packadd govim". That also keeps it
together with the settings, thus I would think it is a good solution.
Even better than using some plugin manager where loading the plugin and
doing the settings would be in separate places.

--
hundred-and-one symptoms of being an internet addict:
168. You have your own domain name.

/// Bram Moolenaar -- Br...@Moolenaar.net -- http://www.Moolenaar.net \\\
/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\ an exciting new programming language -- http://www.Zimbu.org ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///
Reply all
Reply to author
Forward
0 new messages