@ -1,17 +1,48 @@
" ---------------------------------------------------------------------------
" Try to clone all new bundles given (or all bundles in g:vundle#bundles by
" default) to g:vundle#bundle_dir. If a:bang is 1 it will also update all
" plugins (git pull).
"
" bang -- 1 or 0
" ... -- any number of bundle specifications (separate arguments)
" ---------------------------------------------------------------------------
func ! vundle #installer #new ( bang , ...) abort
func ! vundle #installer #new ( bang , ...) abort
let bundles = ( a :1 = = '' ) ?
\ g :bundles :
\ map ( copy ( a :000 ) , 'vundle#config#bundle(v:val, {})' )
" No specific plugins are specified. Operate on all plugins.
if a :0 = = 0
let bundles = g :vundle #bundles
" Specific plugins are specified for update. Update them.
elseif ( a :bang )
let bundles = filter ( copy ( g :vundle #bundles ) , 'index(a:000, v:val.name) > -1' )
" Specific plugins are specified for installation. Install them.
else
let bundles = map ( copy ( a :000 ) , 'vundle#config#bundle(v:val, {})' )
endif
if empty ( bundles )
echoerr 'No bundles were selected for operation'
return
endif
let names = vundle #scripts #bundle_names ( map ( copy ( bundles ) , 'v:val.name_spec' ) )
let names = vundle #scripts #bundle_names ( map ( copy ( bundles ) , 'v:val.name_spec' ) )
call vundle #scripts #view ( 'Installer' , ['" Installing bundles to ' .expand ( g :bundle_dir , 1 ) ], names + ['Helptags' ])
call vundle #scripts #view ( 'Installer' , ['" Installing plugin s to ' .expand ( g :vundle #bundle_dir , 1 ) ], names + ['Helptags' ])
" This calls 'add' as a normal mode command. This is a buffer local mapping
" defined in vundle#scripts#view(). The mapping will call a buffer local
" command InstallPlugin which in turn will call vundle#installer#run() with
" vundle#installer#install().
call s :process ( a :bang , ( a :bang ? 'add!' : 'add' ) )
call s :process ( a :bang , ( a :bang ? 'add!' : 'add' ) )
call vundle #config #require ( bundles )
call vundle #config #require ( bundles )
endf
endf
" ---------------------------------------------------------------------------
" Iterate over all lines in a Vundle window and execute the given command for
" every line. Used by the installation and cleaning functions.
"
" bang -- not used (FIXME)
" cmd -- the (normal mode) command to execute for every line as a string
" ---------------------------------------------------------------------------
func ! s :process ( bang , cmd )
func ! s :process ( bang , cmd )
let msg = ''
let msg = ''
@ -25,12 +56,12 @@ func! s:process(bang, cmd)
exec ':norm ' .a :cmd
exec ':norm ' .a :cmd
if 'error' = = g :vundle_ last_status
if 'error' = = s :last_status
let msg = 'With errors; press l to view log'
let msg = 'With errors; press l to view log'
endif
endif
if 'updated' = = g :vundle_ last_status && empty ( msg )
let msg = 'Bundle s updated; press u to view changelog'
if 'updated' = = s :last_status && empty ( msg )
let msg = 'Plugin s updated; press u to view changelog'
endif
endif
" goto next one
" goto next one
@ -43,6 +74,16 @@ func! s:process(bang, cmd)
echo 'Done! ' .msg
echo 'Done! ' .msg
endf
endf
" ---------------------------------------------------------------------------
" Call another function in the different Vundle windows.
"
" func_name -- the function to call
" name -- the bundle name to call func_name for (string)
" ... -- the argument to be used when calling func_name (only the first
" optional argument will be used)
" return -- the status returned by the call to func_name
" ---------------------------------------------------------------------------
func ! vundle #installer #run ( func_name , name , ...) abort
func ! vundle #installer #run ( func_name , name , ...) abort
let n = a :name
let n = a :name
@ -67,6 +108,8 @@ func! vundle#installer#run(func_name, name, ...) abort
echo n .' deleted'
echo n .' deleted'
elseif 'helptags' = = status
elseif 'helptags' = = status
echo n .' regenerated'
echo n .' regenerated'
elseif 'pinned' = = status
echo n .' pinned'
elseif 'error' = = status
elseif 'error' = = status
echohl Error
echohl Error
echo 'Error processing ' .n
echo 'Error processing ' .n
@ -76,12 +119,19 @@ func! vundle#installer#run(func_name, name, ...) abort
throw 'whoops, unknown status:' .status
throw 'whoops, unknown status:' .status
endif
endif
let g :vundle_ last_status = status
let s :last_status = status
return status
return status
endf
endf
func ! s :sign ( status )
" ---------------------------------------------------------------------------
" Put a sign on the current line, indicating the status of the installation
" step.
"
" status -- string describing the status
" ---------------------------------------------------------------------------
func ! s :sign ( status )
if ( ! has ( 'signs' ) )
if ( ! has ( 'signs' ) )
return
return
endif
endif
@ -89,6 +139,14 @@ func! s:sign(status)
exe ":sign place " .line ( '.' ) ." line=" .line ( '.' ) ." name=Vu_" . a :status ." buffer=" . bufnr ( "%" )
exe ":sign place " .line ( '.' ) ." line=" .line ( '.' ) ." name=Vu_" . a :status ." buffer=" . bufnr ( "%" )
endf
endf
" ---------------------------------------------------------------------------
" Install a plugin, then add it to the runtimepath and source it.
"
" bang -- 1 or 0, passed directly to vundle#installer#install()
" name -- the name of a bundle (string)
" return -- the return value from vundle#installer#install()
" ---------------------------------------------------------------------------
func ! vundle #installer #install_and_require ( bang , name ) abort
func ! vundle #installer #install_and_require ( bang , name ) abort
let result = vundle #installer #install ( a :bang , a :name )
let result = vundle #installer #install ( a :bang , a :name )
let b = vundle #config #bundle ( a :name , {})
let b = vundle #config #bundle ( a :name , {})
@ -97,22 +155,51 @@ func! vundle#installer#install_and_require(bang, name) abort
return result
return result
endf
endf
" ---------------------------------------------------------------------------
" Install or update a bundle given by its name.
"
" bang -- 1 or 0, passed directly to s:sync()
" name -- the name of a bundle (string)
" return -- the return value from s:sync()
" ---------------------------------------------------------------------------
func ! vundle #installer #install ( bang , name ) abort
func ! vundle #installer #install ( bang , name ) abort
if ! isdirectory ( g :bundle_dir ) | call mkdir ( g :bundle_dir , 'p' ) | endif
if ! isdirectory ( g :vundle #bundle_dir ) | call mkdir ( g :vundle #bundle_dir , 'p' ) | endif
let b = vundle #config #init_bundle ( a :name , {})
let n = substitute ( a :name , "['" .'"]\+' , '' , 'g' )
let matched = filter ( copy ( g :vundle #bundles ) , 'v:val.name_spec == n' )
if len ( matched ) > 0
let b = matched [0 ]
else
let b = vundle #config #init_bundle ( a :name , {})
endif
return s :sync ( a :bang , b )
return s :sync ( a :bang , b )
endf
endf
" ---------------------------------------------------------------------------
" Call :helptags for all bundles in g:vundle#bundles.
"
" return -- 'error' if an error occurred, else return 'helptags'
" ---------------------------------------------------------------------------
func ! vundle #installer #docs ( ) abort
func ! vundle #installer #docs ( ) abort
let error_count = vundle #installer #helptags ( g :bundles )
let error_count = vundle #installer #helptags ( g :vundle #bundles )
if error_count > 0
if error_count > 0
return 'error'
return 'error'
endif
endif
return 'helptags'
return 'helptags'
endf
endf
" ---------------------------------------------------------------------------
" Call :helptags for a list of bundles.
"
" bundles -- a list of bundle dictionaries for which :helptags should be
" called.
" return -- the number of directories where :helptags failed
" ---------------------------------------------------------------------------
func ! vundle #installer #helptags ( bundles ) abort
func ! vundle #installer #helptags ( bundles ) abort
let bundle_dirs = map ( copy ( a :bundles ) , 'v:val.rtpath' )
let bundle_dirs = map ( copy ( a :bundles ) , 'v:val.rtpath' )
let help_dirs = filter ( bundle_dirs , 's:has_doc(v:val)' )
let help_dirs = filter ( bundle_dirs , 's:has_doc(v:val)' )
@ -123,31 +210,45 @@ func! vundle#installer#helptags(bundles) abort
let statuses = map ( copy ( help_dirs ) , 's:helptags(v:val)' )
let statuses = map ( copy ( help_dirs ) , 's:helptags(v:val)' )
let errors = filter ( statuses , 'v:val == 0' )
let errors = filter ( statuses , 'v:val == 0' )
call s :log ( 'Helptags: ' .len ( help_dirs ) .' bundle s processed' )
call s :log ( 'Helptags: ' .len ( help_dirs ) .' plugin s processed' )
return len ( errors )
return len ( errors )
endf
endf
" ---------------------------------------------------------------------------
" List all installed plugins.
" Corresponding documentation: vundle-plugins-list
"
" bang -- not used
" ---------------------------------------------------------------------------
func ! vundle #installer #list ( bang ) abort
func ! vundle #installer #list ( bang ) abort
let bundles = vundle #scripts #bundle_names ( map ( copy ( g :bundles ) , 'v:val.name_spec' ) )
call vundle #scripts #view ( 'list' , ['" My Bundles' ], bundles )
let bundles = vundle #scripts #bundle_names ( map ( copy ( g :vundle #bundles ) , 'v:val.name_spec' ) )
call vundle #scripts #view ( 'list' , ['" My Plugin s' ], bundles )
redraw
redraw
echo len ( g :bundles ) .' bundles configured'
echo len ( g :vundle #bundles ) .' plugin s configured'
endf
endf
" ---------------------------------------------------------------------------
" List and remove all directories in the bundle directory which are not
" activated (added to the bundle list).
"
" bang -- 0 if the user should be asked to confirm every deletion, 1 if they
" should be removed unconditionally
" ---------------------------------------------------------------------------
func ! vundle #installer #clean ( bang ) abort
func ! vundle #installer #clean ( bang ) abort
let bundle_dirs = map ( copy ( g :bundles ) , 'v:val.path()' )
let bundle_dirs = map ( copy ( g :vundle #bundles ) , 'v:val.path()' )
let all_dirs = ( v :version > 702 | | ( v :version = = 702 && has ( "patch51" ) ) )
let all_dirs = ( v :version > 702 | | ( v :version = = 702 && has ( "patch51" ) ) )
\ ? split ( globpath ( g :bundle_dir , '*' , 1 ) , "\n" )
\ : split ( globpath ( g :bundle_dir , '*' ) , "\n" )
\ ? split ( globpath ( g :vundle #bundle_dir , '*' , 1 ) , "\n" )
\ : split ( globpath ( g :vundle #bundle_dir , '*' ) , "\n" )
let x_dirs = filter ( all_dirs , '0 > index(bundle_dirs, v:val)' )
let x_dirs = filter ( all_dirs , '0 > index(bundle_dirs, v:val)' )
if empty ( x_dirs )
if empty ( x_dirs )
let headers = ['" All clean!' ]
let headers = ['" All clean!' ]
let names = []
let names = []
else
else
let headers = ['" Removing bundle s:' ]
let headers = ['" Removing Plugin s:' ]
let names = vundle #scripts #bundle_names ( map ( copy ( x_dirs ) , 'fnamemodify(v:val, ":t")' ) )
let names = vundle #scripts #bundle_names ( map ( copy ( x_dirs ) , 'fnamemodify(v:val, ":t")' ) )
end
end
@ -167,6 +268,14 @@ func! vundle#installer#clean(bang) abort
endf
endf
" ---------------------------------------------------------------------------
" Delete to directory for a plugin.
"
" bang -- not used
" dir_name -- the bundle directory to be deleted (as a string)
" return -- 'error' if an error occurred, 'deleted' if the plugin folder was
" successfully deleted
" ---------------------------------------------------------------------------
func ! vundle #installer #delete ( bang , dir_name ) abort
func ! vundle #installer #delete ( bang , dir_name ) abort
let cmd = ( ( has ( 'win32' ) | | has ( 'win64' ) ) && empty ( matchstr ( &shell , 'sh' ) ) ) ?
let cmd = ( ( has ( 'win32' ) | | has ( 'win64' ) ) && empty ( matchstr ( &shell , 'sh' ) ) ) ?
@ -174,14 +283,14 @@ func! vundle#installer#delete(bang, dir_name) abort
\ 'rm -rf'
\ 'rm -rf'
let bundle = vundle #config #init_bundle ( a :dir_name , {})
let bundle = vundle #config #init_bundle ( a :dir_name , {})
let cmd .= ' ' .vundle #compat #shellescape ( bundle .path ( ) )
let cmd .= ' ' .vundle #installer #shellesc ( bundle .path ( ) )
let out = s :system ( cmd )
let out = s :system ( cmd )
call s :log ( '' )
call s :log ( '' )
call s :log ( 'Bundle ' .a :dir_name )
call s :log ( '$ ' .cmd )
call s :log ( '> ' .out )
call s :log ( 'Plugin ' .a :dir_name )
call s :log ( cmd , '$ ' )
call s :log ( out , '> ' )
if 0 ! = v :shell_error
if 0 ! = v :shell_error
return 'error'
return 'error'
@ -190,6 +299,13 @@ func! vundle#installer#delete(bang, dir_name) abort
endif
endif
endf
endf
" ---------------------------------------------------------------------------
" Check if a bundled plugin has any documentation.
"
" rtp -- a path (string) where the plugin is installed
" return -- 1 if some documentation was found, 0 otherwise
" ---------------------------------------------------------------------------
func ! s :has_doc ( rtp ) abort
func ! s :has_doc ( rtp ) abort
return isdirectory ( a :rtp .'/doc' )
return isdirectory ( a :rtp .'/doc' )
\ && ( ! filereadable ( a :rtp .'/doc/tags' ) | | filewritable ( a :rtp .'/doc/tags' ) )
\ && ( ! filereadable ( a :rtp .'/doc/tags' ) | | filewritable ( a :rtp .'/doc/tags' ) )
@ -198,11 +314,19 @@ func! s:has_doc(rtp) abort
\ : ! ( empty ( glob ( a :rtp .'/doc/*.txt' ) ) && empty ( glob ( a :rtp .'/doc/*.??x' ) ) )
\ : ! ( empty ( glob ( a :rtp .'/doc/*.txt' ) ) && empty ( glob ( a :rtp .'/doc/*.??x' ) ) )
endf
endf
" ---------------------------------------------------------------------------
" Update the helptags for a plugin.
"
" rtp -- the path to the plugin's root directory (string)
" return -- 1 if :helptags succeeded, 0 otherwise
" ---------------------------------------------------------------------------
func ! s :helptags ( rtp ) abort
func ! s :helptags ( rtp ) abort
let doc_path = a :rtp .'/doc/'
" it is important to keep trailing slash here
let doc_path = resolve ( a :rtp . '/doc/' )
call s :log ( ':helptags ' .doc_path )
call s :log ( ':helptags ' .doc_path )
try
try
execute 'helptags ' . resolve ( doc_path )
execute 'helptags ' . doc_path
catch
catch
call s :log ( "> Error running :helptags " .doc_path )
call s :log ( "> Error running :helptags " .doc_path )
return 0
return 0
@ -210,27 +334,123 @@ func! s:helptags(rtp) abort
return 1
return 1
endf
endf
func ! s :sync ( bang , bundle ) abort
" ---------------------------------------------------------------------------
" Get the URL for the remote called 'origin' on the repository that
" corresponds to a given bundle.
"
" bundle -- a bundle object to check the repository for
" return -- the URL for the origin remote (string)
" ---------------------------------------------------------------------------
func ! s :get_current_origin_url ( bundle ) abort
let cmd = 'cd ' .vundle #installer #shellesc ( a :bundle .path ( ) ) .' && git config --get remote.origin.url'
let cmd = vundle #installer #shellesc_cd ( cmd )
let out = s :strip ( s :system ( cmd ) )
return out
endf
" ---------------------------------------------------------------------------
" Get a short sha of the HEAD of the repository for a given bundle
"
" bundle -- a bundle object
" return -- A 15 character log sha for the current HEAD
" ---------------------------------------------------------------------------
func ! s :get_current_sha ( bundle )
let cmd = 'cd ' .vundle #installer #shellesc ( a :bundle .path ( ) ) .' && git rev-parse HEAD'
let cmd = vundle #installer #shellesc_cd ( cmd )
let out = s :system ( cmd ) [0 :15 ]
return out
endf
" ---------------------------------------------------------------------------
" Create the appropriate sync command to run according to the current state of
" the local repository (clone, pull, reset, etc).
"
" In the case of a pull (update), also return the current sha, so that we can
" later check that there has been an upgrade.
"
" bang -- 0 if only new plugins should be installed, 1 if existing plugins
" should be updated
" bundle -- a bundle object to create the sync command for
" return -- A list containing the command to run and the sha for the current
" HEAD
" ---------------------------------------------------------------------------
func ! s :make_sync_command ( bang , bundle ) abort
let git_dir = expand ( a :bundle .path ( ) .'/.git/' , 1 )
let git_dir = expand ( a :bundle .path ( ) .'/.git/' , 1 )
if isdirectory ( git_dir ) | | filereadable ( expand ( a :bundle .path ( ) .'/.git' , 1 ) )
if isdirectory ( git_dir ) | | filereadable ( expand ( a :bundle .path ( ) .'/.git' , 1 ) )
if ! ( a :bang ) | return 'todate' | endif
let cmd = 'cd ' .vundle #compat #shellescape ( a :bundle .path ( ) ) .' && git pull && git submodule update --init --recursive'
let cmd = g :shellesc_cd ( cmd )
let current_origin_url = s :get_current_origin_url ( a :bundle )
if current_origin_url ! = a :bundle .uri
call s :log ( 'Plugin URI change detected for Plugin ' . a :bundle .name )
call s :log ( '> Plugin ' . a :bundle .name . ' old URI: ' . current_origin_url )
call s :log ( '> Plugin ' . a :bundle .name . ' new URI: ' . a :bundle .uri )
" Directory names match but the origin remotes are not the same
let cmd_parts = [
\ 'cd ' .vundle #installer #shellesc ( a :bundle .path ( ) ) ,
\ 'git remote set-url origin ' . vundle #installer #shellesc ( a :bundle .uri ) ,
\ 'git fetch' ,
\ 'git reset --hard origin/HEAD' ,
\ 'git submodule update --init --recursive' ,
\ ]
let cmd = join ( cmd_parts , ' && ' )
let cmd = vundle #installer #shellesc_cd ( cmd )
let initial_sha = ''
return [cmd , initial_sha ]
endif
if ! ( a :bang )
" The repo exists, and no !, so leave as it is.
return ['' , '' ]
endif
let cmd_parts = [
\ 'cd ' .vundle #installer #shellesc ( a :bundle .path ( ) ) ,
\ 'git pull' ,
\ 'git submodule update --init --recursive' ,
\ ]
let cmd = join ( cmd_parts , ' && ' )
let cmd = vundle #installer #shellesc_cd ( cmd )
let get_current_sha = 'cd ' .vundle #compat #shellescape ( a :bundle .path ( ) ) .' && git rev-parse HEAD'
let get_current_sha = g :shellesc_cd ( get_current_sha )
let initial_sha = s :system ( get_current_sha ) [0 :15 ]
let initial_sha = s :get_current_sha ( a :bundle )
else
else
let cmd = 'git clone --recursive ' .vundle #compat #shellescape ( a :bundle .uri ) .' ' .vundle #compat #shellescape ( a :bundle .path ( ) )
let cmd = 'git clone --recursive ' .vundle #installer #shellesc ( a :bundle .uri ) .' ' .vundle #installer #shellesc ( a :bundle .path ( ) )
let initial_sha = ''
let initial_sha = ''
endif
endif
return [cmd , initial_sha ]
endf
" ---------------------------------------------------------------------------
" Install or update a given bundle object with git.
"
" bang -- 0 if only new plugins should be installed, 1 if existing plugins
" should be updated
" bundle -- a bundle object (dictionary)
" return -- a string indicating the status of the bundle installation:
" - todate : Nothing was updated or the repository was up to date
" - new : The plugin was newly installed
" - updated : Some changes where pulled via git
" - error : An error occurred in the shell command
" - pinned : The bundle is marked as pinned
" ---------------------------------------------------------------------------
func ! s :sync ( bang , bundle ) abort
" Do not sync if this bundle is pinned
if a :bundle .is_pinned ( )
return 'pinned'
endif
let [ cmd , initial_sha ] = s :make_sync_command ( a :bang , a :bundle )
if empty ( cmd )
return 'todate'
endif
let out = s :system ( cmd )
let out = s :system ( cmd )
call s :log ( '' )
call s :log ( '' )
call s :log ( 'Bundle ' .a :bundle .name_spec )
call s :log ( '$ ' .cmd )
call s :log ( '> ' .out )
call s :log ( 'Plugin ' .a :bundle .name_spec )
call s :log ( cmd , '$ ' )
call s :log ( out , '> ' )
if 0 ! = v :shell_error
if 0 ! = v :shell_error
return 'error'
return 'error'
@ -240,41 +460,88 @@ func! s:sync(bang, bundle) abort
return 'new'
return 'new'
endif
endif
let updated_sha = s :system ( get_current_sha ) [0 :15 ]
let updated_sha = s :get_current_sha ( a :bundle )
if initial_sha = = updated_sha
if initial_sha = = updated_sha
return 'todate'
return 'todate'
endif
endif
call add ( g :updated_bundles , [initial_sha , updated_sha , a :bundle ])
call add ( g :vundle #updated_bundles , [initial_sha , updated_sha , a :bundle ])
return 'updated'
return 'updated'
endf
endf
func ! g :shellesc ( cmd ) abort
" ---------------------------------------------------------------------------
" Escape special characters in a string to be able to use it as a shell
" command with system().
"
" cmd -- the string holding the shell command
" return -- a string with the relevant characters escaped
" ---------------------------------------------------------------------------
func ! vundle #installer #shellesc ( cmd ) abort
if ( ( has ( 'win32' ) | | has ( 'win64' ) ) && empty ( matchstr ( &shell , 'sh' ) ) )
if ( ( has ( 'win32' ) | | has ( 'win64' ) ) && empty ( matchstr ( &shell , 'sh' ) ) )
if &shellxquote ! = '(' " workaround for patch #445
return '"' .a :cmd .'"' " enclose in quotes so && joined cmds work
endif
return '"' . substitute ( a :cmd , '"' , '\\"' , 'g' ) . '"'
endif
endif
return a :cmd
return vundle #compat #shellescape ( a :cmd )
endf
endf
func ! g :shellesc_cd ( cmd ) abort
" ---------------------------------------------------------------------------
" Fix a cd shell command to be used on Windows.
"
" cmd -- the command to be fixed (string)
" return -- the fixed command (string)
" ---------------------------------------------------------------------------
func ! vundle #installer #shellesc_cd ( cmd ) abort
if ( ( has ( 'win32' ) | | has ( 'win64' ) ) && empty ( matchstr ( &shell , 'sh' ) ) )
if ( ( has ( 'win32' ) | | has ( 'win64' ) ) && empty ( matchstr ( &shell , 'sh' ) ) )
let cmd = substitute ( a :cmd , '^cd ' , 'cd /d ' , '' ) " add /d switch to change drives
let cmd = substitute ( a :cmd , '^cd ' , 'cd /d ' , '' ) " add /d switch to change drives
let cmd = g :shellesc ( cmd )
return cmd
return cmd
else
else
return a :cmd
return a :cmd
endif
endif
endf
endf
" ---------------------------------------------------------------------------
" Make a system call. This can be used to change the way system calls
" are made during developing, without searching the whole code base for
" actual system() calls.
"
" cmd -- the command passed to system() (string)
" return -- the return value from system()
" ---------------------------------------------------------------------------
func ! s :system ( cmd ) abort
func ! s :system ( cmd ) abort
return system ( a :cmd )
return system ( a :cmd )
endf
endf
func ! s :log ( str ) abort
let fmt = '%y%m%d %H:%M:%S'
call add ( g :vundle_log , '[' .strftime ( fmt ) .'] ' .a :str )
" ---------------------------------------------------------------------------
" Add a log message to Vundle's internal logging variable.
"
" str -- the log message (string)
" prefix -- optional prefix for multi-line entries (string)
" return -- a:str
" ---------------------------------------------------------------------------
func ! s :log ( str , ...) abort
let prefix = a :0 > 0 ? a :1 : ''
let fmt = '%Y-%m-%d %H:%M:%S'
let lines = split ( a :str , '\n' , 1 )
let time = strftime ( fmt )
for line in lines
call add ( g :vundle #log , '[' . time .'] ' . prefix . line )
endfor
return a :str
return a :str
endf
endf
" ---------------------------------------------------------------------------
" Remove leading and trailing whitespace from a string
"
" str -- The string to rid of trailing and leading spaces
" return -- A string stripped of side spaces
" ---------------------------------------------------------------------------
func ! s :strip ( str )
return substitute ( a :str , '\%^\_s*\(.\{-}\)\_s*\%$' , '\1' , '' )
endf
" vim: set expandtab sts=2 ts=2 sw=2 tw=78 norl: