Hello Vim developers,

some days ago, there was a short discussion on #vim, that one cannot
easily prevent plugins from loading. A distribution could install some
scripts/plugins in the system-wide vimfiles directory, but the user
could not defend against such a "pollution". Each plugin uses a
different guard, so it's tedious to find out which one keeps a script
from loading.

I thought a bit about this problem and came up with the following
solution: Gatekeeper. Gatekeeper keeps track of which plugins the user
wants to load, which plugins the users dislikes and which he doesn't
care about. So it is easy to disable specific plugins.

On the other hand gatekeeper also provides an opt-in way of handling
plugins, where no plugin is loaded unless the user explicitly allows the
plugin to be loaded.

>From the script's perspective using gatekeeper is quite simple. It is a
single function call, which is used in the plugin guard header, which
prevents the script from being sourced multiple times. In fact,
gatekeeper even simplifies this header, since the normally used guard
variable is hidden away.

Further versions could even consider certain versions of a script, or
inter-plugin dependencies.

Positive things I see:
 * Gatekeeper is easy to use.
 * In fact it may even simplify the header guard.
 * It provides full control over plugins.
 * It may be used to check for dependencies. (for the future)

Negative things:
 * It must be supported by the plugin. (For a distribution this can be
   easily accomplished with a simple patch.)

So I'd like to drop this on the list with a request for comments. Any
comments on the idea are appreciated.

Sincerely
Meikel

-- 
  |\      _,,,---,,_
  /,`.-'`'    -.  ;-;;,_
 |,4-  ) )-,_..;\ (  `'-'
'---(_/--'  `-'\_)  fL                     http://ec.kotka.de

--~--~---------~--~----~------------~-------~--~----~
You received this message from the "vim_dev" maillist.
For more information, visit http://www.vim.org/maillist.php
-~----------~----~----~----~------~----~------~--~---

" Vimball Archiver by Charles E. Campbell, Jr., Ph.D.
UseVimball
finish
autoload/gatekeeper.vim [[[1
112
"##### HEADER [ {{{ ]
" Plugin:       Gatekeeper
" Version:      0.1
" Author:       Meikel Brandmeyer <[EMAIL PROTECTED]>
" Created:      Mon Apr 21 20:13:05 2008
" Last Change:  Mon Apr 21 2008
"
" License:
" Copyright (c) 2008 Meikel Brandmeyer, Frankfurt am Main
" 
" All rights reserved.
" 
" Permission is hereby granted, free of charge, to any person obtaining a copy
" of this software and associated documentation files (the "Software"), to deal
" in the Software without restriction, including without limitation the rights
" to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
" copies of the Software, and to permit persons to whom the Software is
" furnished to do so, subject to the following conditions:
" 
" The above copyright notice and this permission notice shall be included in
" all copies or substantial portions of the Software.
" 
" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
" IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
" FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
" AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
" LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
" OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
" THE SOFTWARE.
"
" Description:
" Gatekeeper provides an infrastructure for scripts to handle dependencies
" and loading of scripts. The user may easily disable certain scripts or
" choose an opt-in mode, where each script must be explicitely enabled.
" Missing or disabled dependencies give either an error or are simply enabled
" if the corresponding switch is set by the user.
"##### [ }}} ]

"##### PROLOG [ {{{ ]
if exists("g:GatekeeperLoaded") 
        finish
endif
let g:GatekeeperLoaded = 1

let s:saved_cpo = &cpo
set cpo&vim
"##### [ }}} ]

"##### VARIABLES [ {{{ ]
"### VARIABLE gatekeeper#OptOut, gatekeeper#OptIn [ {{{ ]
" Description:
" Gatekeeper works in two modes: opt-in or opt-out.
"
" opt-out is the traditional mode which is used by most plugins. In case the
" user doesn't want the script to be loaded, he has to manually fiddle around
" with one of the many ways to stop the script from being sourced.
"
" opt-in is newly introduced by Gatekeeper and works the other way around. No
" plugin is loaded unless specified by the user. In this way it is easy to
" disable scripts.
"
if !exists("gatekeeper#OptOut")
        let gatekeeper#OptOut = 1
endif
if !exists("gatekeeper#OptIn")
        let gatekeeper#OptIn = 0
endif
"### [ }}} ]
"##### [ }}} ]

"##### FUNCTIONS [ {{{ ]
"### FUNCTION gatekeeper#Guard [ {{{ ]
" Description:
" This is the heart of the system. This function is used in the header guard,
" which controls whether the script is sourced or not. Is a script disabled
" this function indicates so back to the script which should 'finish'.
"
function gatekeeper#Guard(plugin)
        " If the user didn't set a choice for the plugin, check for the
        " standard behaviour. If it's OptIn we stop here (script is not
        " explicitely enabled). If the choice exists, we check whether it
        " was disabled. If so we stop also.
        if !exists("g:gatekeeper#" . a:plugin)
                if (g:gatekeeper#OptIn == 1 || g:gatekeeper#OptOut == 0)
                        return 0
                endif
        else
                if !eval("g:gatekeeper#" . a:plugin)
                        return 0
                endif
        endif

        " If we reach here, either the plugin is enabled or OptOut is our
        " mode of operation.
        "
        " Now we simply check whether the plugin is already loaded. If so
        " we stop, otherwise we set the guard and give green light for
        " further processing.
        if exists("g:" . a:plugin . "Loaded")
                return 0
        endif
        execute "let g:" . a:plugin . "Loaded = 1"

        return 1
endfunction
"### [ }}} ]
"##### [ }}} ]

"##### EPILOG [ {{{ ]
let &cpo = s:saved_cpo
unlet s:saved_cpo
"##### [ }}} ]
doc/gatekeeper.txt      [[[1
105

                            Gatekeeper

                                            *gatekeeper*

Gatekeeper is a system which let's the user decide whether a plugin should be
loaded or not. By simply switching the usual opt-out to an opt-in mode, gives
full control over which plugins/scripts are loaded.

Of course the scripts have to support Gatekeeper, but this is actually very
easy. Since at the head of each plugin should be a guard, which checks whether
the plugin is already loaded, the only thing we have to do is to adjust the
guard to use the |gatekeeper#Guard| function instead of checking itself for
the guard variable. This even simplifies the guard header!

For the user is no change necessary. Without changing any setting one gets the
same behaviour one is used to. But on the other hand one gets the full control
of gatekeeper.

==============================================================================
CONTENTS

 1. OptOut                                  |gatekeeper#OptOut|
 2. OptIn                                   |gatekeeper#OptIn|
 3. Guard                                   |gatekeeper#Guard|
 4. Todo                                    |gatekeeper#Todo|
 5. License                                 |gatekeeper#License|
==============================================================================

 1. OptOut                                  *gatekeeper#OptOut*

let gatekeeper#OptOut = 1

In opt-out mode, Gatekeeper behaves like the traditional script. Every script
is loaded unless the user specifies otherwise. This is also the default if the
user just uses Gatekeeper without modifying any setting. So it is 100%
backward compatible.

==============================================================================

 2. OptIn                                   *gatekeeper#OptIn*

let gatekeeper#OptIn = 1
or equivalent: let gatekeeper#OptOut = 0

In opt-in mode, no script or plugin is sourced unless excplicitely wanted by
the user. This is useful if you want complete control, over which plugins are
loaded and which are skipped.

==============================================================================

 3. Guard                                   *gatekeeper#Guard*

if (!gatekeeper#Guard("MyPlugin"))
        finish
endif

This is the heart of the whole system. It checks whether the given plugin is
enabled, disabled or already loaded. According to this information it gives
feedback to calling script whether it should |:finish| loading or whether it
should go on.

To explicitely enable a plugin set the corresponding Gatekeeper variable. >

        let gatekeeper#MyPlugin = 1
<
Similarly one can disable a script by setting the value to zero. >

        let gatekeeper#MyPlugin = 0
<
==============================================================================

 4. Todo                                    *gatekeeper-Todo*

 * different versions of a script ?
 * depedency handling ?

==============================================================================

 5. License                                 *gatekeeper-License*

Copyright (c) 2008 Meikel Brandmeyer, Frankfurt am Main

All rights reserved.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

==============================================================================
vim: ft=help:norl:ts=8:tw=78
t/001_gatekeeper_optout.t       [[[1
12
call vimtap#Plan(4)

let gatekeeper#PluginB = 1
let gatekeeper#PluginC = 0
let g:PluginDLoaded = 1

call vimtap#Ok(gatekeeper#Guard("PluginA"), "opt-out")
call vimtap#Ok(gatekeeper#Guard("PluginB"), "opt-out and enabled plugin")
call vimtap#Ok(!gatekeeper#Guard("PluginC"), "opt-out and disabled plugin")
call vimtap#Ok(!gatekeeper#Guard("PluginC"), "opt-out and loaded plugin")

" vim:ft=vim:
t/001_gatekeeper_no_optout.t    [[[1
14
call vimtap#Plan(4)

let gatekeeper#OptOut = 0

let gatekeeper#PluginB = 1
let gatekeeper#PluginC = 0
let g:PluginDLoaded = 1

call vimtap#Ok(!gatekeeper#Guard("PluginA"), "no opt-out")
call vimtap#Ok(gatekeeper#Guard("PluginB"), "no opt-out and enabled plugin")
call vimtap#Ok(!gatekeeper#Guard("PluginC"), "no opt-out and disabled plugin")
call vimtap#Ok(!gatekeeper#Guard("PluginD"), "no opt-out and loaded plugin")

" vim:ft=vim:
t/001_gatekeeper_optin.t        [[[1
14
call vimtap#Plan(4)

let gatekeeper#OptIn = 1

let gatekeeper#PluginB = 1
let gatekeeper#PluginC = 0
let g:PluginDLoaded = 1

call vimtap#Ok(!gatekeeper#Guard("PluginA"), "opt-in")
call vimtap#Ok(gatekeeper#Guard("PluginB"), "opt-in and enabled plugin")
call vimtap#Ok(!gatekeeper#Guard("PluginC"), "opt-in and disabled plugin")
call vimtap#Ok(!gatekeeper#Guard("PluginD"), "opt-in and loaded plugin")

" vim:ft=vim:

Raspunde prin e-mail lui