vxlib_plugin.txt        Installable plugins       Last Change: January 2010

==============================================================================
INSTALLABLE PLUGINS                                            vxlib-plugin

   The Anatomy of a plugin               vxlib-plugin-example
   How to Enable plugins in .vimrc       vxlib-plugin-enable
   Plugin Code Generator                 vxlib-plugin-generator

Utilities that help a developer create plugins that can be enabled or disabled
by setting a flag in a global dictionary.

The startup configuration of every plugin can be put into a single file in the
plugin directory. The rest of the plugin code is autoloaded when it is
actually used for the first time.

The Anatomy of a plugin                                vxlib-plugin-example
-----------------------

Example plugin (Hello "user"):
>
      " file: ~/.vim/autoload/test/hello.vim
   00 if vxlib#plugin#StopLoading("#au#test#hello")
         finish
      endif

   01 " Initialization - on autoload
      let s:TimesCalled = 0
      call vxlib#plugin#CheckSetting("g:TestHelloExtra", " ,have fun.")

   02 function! test#hello#Hello()
         echo "Hello " . g:TestHelloUser . g:TestHelloExtra
         let s:TimesCalled += 1
         echo "Hello calls: " . s:TimesCalled
         echo "Buffer switches: " . g:VxPluginVar.test_hello_switchcount
      endfunc
   09
   10 " Plugin initialization
      finish

   11 " <VIMPLUGIN id="test#hello" require="python&&gui_running">
   12    call s:CheckSetting("g:TestHelloUser", "Dear Friend")
   13    let g:VxPluginVar.test_hello_switchcount = 0
   14    function! s:test_hello_AddSwitchCount()
            let g:VxPluginVar.test_hello_switchcount += 1
         endfunc
   15    autocmd BufEnter * call s:test_hello_AddSwitchCount()
   16    command SayHello  call test#hello#Hello()
   17    " <STARTUP>
           " eg. commands to parse vimrc variables
         " </STARTUP>
   19 " </VIMPLUGIN>
<
00 Module Loading Guard
>
   if vxlib#plugin#StopLoading("#au#test#hello")
      finish
   endif
<
   The module will be loaded only if it is not marked as already loaded. The
   parameter of the above function is the current file ID. For convenience the
   IDs of the modules in the autoload directory start with "#au#".

   The list of loaded modules and plugins can be displayed with:
>
   :VxStatus
   or
   :call vxlib#plugin#List()
<
01 Moule Initialization

   This part is executed when the code is auto-loaded (see autoload). This
   part should define variables local to the module and global variables that
   are not needed until the module is autoloaded.

02 Public Funcitons
>
   function! test#hello#Hello()
<
   These functions will be exported from the module and will cause the module
   to be auto-loaded on first call.

10 Plugin Interface

   This is where the auto-loadable module ends and the plugin begins. (This
   part could also be placed in another file).

11 Plugin Definition Block start
>
   " <VIMPLUGIN id="test#hello" require="python&&gui_running">
<
   Every plugin must have a unique ID. In this case the autoload prefix is
   used. The code in this block (12-19) SHOULD NOT reference any function or
   variable defined in the module code (01-09), otherwise the module will be
   autoloaded at startup or during a vim event, which is what we are trying to
   avoid. It is usually safe to put "internal" calls to command definitions
   (16).

   A plugin may require certain Vim features to be enabled. The features can
   be described with an expression using feature names and the following
   operators: &&, ||, (), !. If the features are not present when the plugin
   is being loaded, the loding won't continue and the plugin will be marked as
   "features-missing". The missing features can be displayed with:
>
   :VxStatus
<
   The Plugin Code Generator (vxlib-plugin-generator) processes the code
   inside the VIMPLUGIN block and generates the final plugin code.

12 User settings for the plugin code

   Here the global variables that are needed by other code in 12-19 are
   defined here. The code generated by the Plugin Code Generator contains the
   function s:CheckSetting() that will set the variable to the default value if
   it doesn't exist.

13 Internal plugin variables
>
   let g:VxPluginVar.test_hello_switchcount = 0
<
   If the code 12-19 needs to manage some variables that are also used by the
   module code 01-09, these variables can be stored in the g:VxPluginVar
   dictionary to reduce global namespace pollution. The varialble names should
   be unique so they are prefixed with the module name (test_hello_).
   Example: list of recently open files is managed in plugin code (12-19), but
   displayed in module code (01-09).

14 Functions local to the plugin
>
   function! s:test_hello_AddSwitchCount()
<
   The function names should be unique so they are prefixed with the module
   name (test_hello_).

15 Autocommands
>
   autocmd BufEnter * call s:test_hello_AddSwitchCount()
<
   The autocommand calls a plugin-local function and it doesn't autoload the
   main module.

16 Commands
>
   command SayHello  call test#hello#Hello()
<
   Commands are usually executed by the user so it is safe to call the main
   module in them.

17 Startup commands
>
   <STARTUP>
      ex-commands
   </STARTUP>
<
   This commands will execute the first time one of the events BufWinEnter or
   VimEnter is triggered. The commands will be wrapped by a function that will
   be executed when an event is triggered. The function will be deleted on
   completion.

   This block is useful if some kind of processing of the vimrc content is
   needed (sth. like: load the most recent file from file history).

   The Plugin Code Generator will generate the following code for the above
   block:
>
      function! s:G_<plugin_id>_auto_startup
         ex-commands
         autocmd! G_<plugin_id>_auto_onetime
      endfunc
      augroup G_<plugin_id>_auto_onetime
         autocmd!
         autocmd BufWinEnter,VimEnter *
            \ call s:G_<plugin_id>_auto_startup()
            \ | delfunc G_<plugin_id>_auto_startup
      augroup END
<
   WARNING: The startup code will be generated whenever the STARTUP tag is
   present even if the block doesn't contain any commands. If the startup code
   isn't needed, the startup block should not be present.


How to Enable plugins in .vimrc                       vxlib-plugin-enable
-------------------------------

Some plugins store their options in global dictionaries that are not
initialized until the plugin is read. This only happens after .vimrc is
processed so a custom command for setting options is necessary. The command is
called 'VxLet' and is created with
>
    call vxlib#plugin#Init()
<
                                                      vxlet
The command VxLet takes 3 parameters: the name of the global dictionary
(without g:), the key under which an option is stored in the dictionary and
a Vim expression that represents the new value for the option.

Initially all the plugins are enabled by default. To disable an undesired
plugin you can write
>
    VxLet VxPlugin test#hello 0
<
The global variable g:VxPlugin is created when the function plugin#Init() is
called so plugins can also be disabled like this:
>
    let g:VxPlugin["test#hello"] = 0
<
If you want to use only specific plugins, you can disable all the plugins
by default using
>
    let g:VxPluginEnabledDefault = 0
<
and then for each plugin that you want to use
>
    VxLet VxPlugin test#hello 1
<

Plugin Code Generator                                 vxlib-plugin-generator
---------------------

The Plugin Code Generator is an standalone python script that parses .vim
files specified in the command line and searches for the tag "VIMPLUGIN". It
extracts the code and generates plugin activation code for each VIMPLUGIN
block. The generated code is written to standard output.

Example:
>
   cd ~/.vim/autoload
   python vxlib/plugin.py . > ../plugin/_vimuiex_au_.vim
<
The code generated for a plugin will look like this:
>
   if vxlib#plugin#ContinueLoading("test#hello")
    if ! (has("python")&&has("gui_running"))
     call s:SetLoaded("test#helo", -2)
     let g:VxPluginMissFeatures["test#helo"] = "python&&gui_running: " .
        \ s:StrHas("gui_running,python")
    else
      " code 12-19
    endif
   endif
<


## vim:tw=78:noet:wrap:ts=8:ft=help:norl: