| 425 | 1 " pathogen.vim - path option manipulation | 
|  | 2 " Maintainer:   Tim Pope <http://tpo.pe/> | 
|  | 3 " Version:      2.0 | 
|  | 4 | 
|  | 5 " Install in ~/.vim/autoload (or ~\vimfiles\autoload). | 
|  | 6 " | 
|  | 7 " For management of individually installed plugins in ~/.vim/bundle (or | 
|  | 8 " ~\vimfiles\bundle), adding `call pathogen#infect()` to the top of your | 
|  | 9 " .vimrc is the only other setup necessary. | 
|  | 10 " | 
|  | 11 " The API is documented inline below.  For maximum ease of reading, | 
|  | 12 " :set foldmethod=marker | 
|  | 13 | 
|  | 14 if exists("g:loaded_pathogen") || &cp | 
|  | 15   finish | 
|  | 16 endif | 
|  | 17 let g:loaded_pathogen = 1 | 
|  | 18 | 
|  | 19 " Point of entry for basic default usage.  Give a directory name to invoke | 
|  | 20 " pathogen#runtime_append_all_bundles() (defaults to "bundle"), or a full path | 
|  | 21 " to invoke pathogen#runtime_prepend_subdirectories().  Afterwards, | 
|  | 22 " pathogen#cycle_filetype() is invoked. | 
|  | 23 function! pathogen#infect(...) abort " {{{1 | 
|  | 24   let source_path = a:0 ? a:1 : 'bundle' | 
|  | 25   if source_path =~# '[\\/]' | 
|  | 26     call pathogen#runtime_prepend_subdirectories(source_path) | 
|  | 27   else | 
|  | 28     call pathogen#runtime_append_all_bundles(source_path) | 
|  | 29   endif | 
|  | 30   call pathogen#cycle_filetype() | 
|  | 31 endfunction " }}}1 | 
|  | 32 | 
|  | 33 " Split a path into a list. | 
|  | 34 function! pathogen#split(path) abort " {{{1 | 
|  | 35   if type(a:path) == type([]) | return a:path | endif | 
|  | 36   let split = split(a:path,'\\\@<!\%(\\\\\)*\zs,') | 
|  | 37   return map(split,'substitute(v:val,''\\\([\\,]\)'',''\1'',"g")') | 
|  | 38 endfunction " }}}1 | 
|  | 39 | 
|  | 40 " Convert a list to a path. | 
|  | 41 function! pathogen#join(...) abort " {{{1 | 
|  | 42   if type(a:1) == type(1) && a:1 | 
|  | 43     let i = 1 | 
|  | 44     let space = ' ' | 
|  | 45   else | 
|  | 46     let i = 0 | 
|  | 47     let space = '' | 
|  | 48   endif | 
|  | 49   let path = "" | 
|  | 50   while i < a:0 | 
|  | 51     if type(a:000[i]) == type([]) | 
|  | 52       let list = a:000[i] | 
|  | 53       let j = 0 | 
|  | 54       while j < len(list) | 
|  | 55         let escaped = substitute(list[j],'[,'.space.']\|\\[\,'.space.']\@=','\\&','g') | 
|  | 56         let path .= ',' . escaped | 
|  | 57         let j += 1 | 
|  | 58       endwhile | 
|  | 59     else | 
|  | 60       let path .= "," . a:000[i] | 
|  | 61     endif | 
|  | 62     let i += 1 | 
|  | 63   endwhile | 
|  | 64   return substitute(path,'^,','','') | 
|  | 65 endfunction " }}}1 | 
|  | 66 | 
|  | 67 " Convert a list to a path with escaped spaces for 'path', 'tag', etc. | 
|  | 68 function! pathogen#legacyjoin(...) abort " {{{1 | 
|  | 69   return call('pathogen#join',[1] + a:000) | 
|  | 70 endfunction " }}}1 | 
|  | 71 | 
|  | 72 " Remove duplicates from a list. | 
|  | 73 function! pathogen#uniq(list) abort " {{{1 | 
|  | 74   let i = 0 | 
|  | 75   let seen = {} | 
|  | 76   while i < len(a:list) | 
|  | 77     if (a:list[i] ==# '' && exists('empty')) || has_key(seen,a:list[i]) | 
|  | 78       call remove(a:list,i) | 
|  | 79     elseif a:list[i] ==# '' | 
|  | 80       let i += 1 | 
|  | 81       let empty = 1 | 
|  | 82     else | 
|  | 83       let seen[a:list[i]] = 1 | 
|  | 84       let i += 1 | 
|  | 85     endif | 
|  | 86   endwhile | 
|  | 87   return a:list | 
|  | 88 endfunction " }}}1 | 
|  | 89 | 
|  | 90 " \ on Windows unless shellslash is set, / everywhere else. | 
|  | 91 function! pathogen#separator() abort " {{{1 | 
|  | 92   return !exists("+shellslash") || &shellslash ? '/' : '\' | 
|  | 93 endfunction " }}}1 | 
|  | 94 | 
|  | 95 " Convenience wrapper around glob() which returns a list. | 
|  | 96 function! pathogen#glob(pattern) abort " {{{1 | 
|  | 97   let files = split(glob(a:pattern),"\n") | 
|  | 98   return map(files,'substitute(v:val,"[".pathogen#separator()."/]$","","")') | 
|  | 99 endfunction "}}}1 | 
|  | 100 | 
|  | 101 " Like pathogen#glob(), only limit the results to directories. | 
|  | 102 function! pathogen#glob_directories(pattern) abort " {{{1 | 
|  | 103   return filter(pathogen#glob(a:pattern),'isdirectory(v:val)') | 
|  | 104 endfunction "}}}1 | 
|  | 105 | 
|  | 106 " Turn filetype detection off and back on again if it was already enabled. | 
|  | 107 function! pathogen#cycle_filetype() " {{{1 | 
|  | 108   if exists('g:did_load_filetypes') | 
|  | 109     filetype off | 
|  | 110     filetype on | 
|  | 111   endif | 
|  | 112 endfunction " }}}1 | 
|  | 113 | 
|  | 114 " Checks if a bundle is 'disabled'. A bundle is considered 'disabled' if | 
|  | 115 " its 'basename()' is included in g:pathogen_disabled[]' or ends in a tilde. | 
|  | 116 function! pathogen#is_disabled(path) " {{{1 | 
|  | 117   if a:path =~# '\~$' | 
|  | 118     return 1 | 
|  | 119   elseif !exists("g:pathogen_disabled") | 
|  | 120     return 0 | 
|  | 121   endif | 
|  | 122   let sep = pathogen#separator() | 
|  | 123   return index(g:pathogen_disabled, strpart(a:path, strridx(a:path, sep)+1)) != -1 | 
|  | 124 endfunction "}}}1 | 
|  | 125 | 
|  | 126 " Prepend all subdirectories of path to the rtp, and append all 'after' | 
|  | 127 " directories in those subdirectories. | 
|  | 128 function! pathogen#runtime_prepend_subdirectories(path) " {{{1 | 
|  | 129   let sep    = pathogen#separator() | 
|  | 130   let before = filter(pathogen#glob_directories(a:path.sep."*"), '!pathogen#is_disabled(v:val)') | 
|  | 131   let after  = filter(pathogen#glob_directories(a:path.sep."*".sep."after"), '!pathogen#is_disabled(v:val[0:-7])') | 
|  | 132   let rtp = pathogen#split(&rtp) | 
|  | 133   let path = expand(a:path) | 
|  | 134   call filter(rtp,'v:val[0:strlen(path)-1] !=# path') | 
|  | 135   let &rtp = pathogen#join(pathogen#uniq(before + rtp + after)) | 
|  | 136   return &rtp | 
|  | 137 endfunction " }}}1 | 
|  | 138 | 
|  | 139 " For each directory in rtp, check for a subdirectory named dir.  If it | 
|  | 140 " exists, add all subdirectories of that subdirectory to the rtp, immediately | 
|  | 141 " after the original directory.  If no argument is given, 'bundle' is used. | 
|  | 142 " Repeated calls with the same arguments are ignored. | 
|  | 143 function! pathogen#runtime_append_all_bundles(...) " {{{1 | 
|  | 144   let sep = pathogen#separator() | 
|  | 145   let name = a:0 ? a:1 : 'bundle' | 
|  | 146   if "\n".s:done_bundles =~# "\\M\n".name."\n" | 
|  | 147     return "" | 
|  | 148   endif | 
|  | 149   let s:done_bundles .= name . "\n" | 
|  | 150   let list = [] | 
|  | 151   for dir in pathogen#split(&rtp) | 
|  | 152     if dir =~# '\<after$' | 
|  | 153       let list +=  filter(pathogen#glob_directories(substitute(dir,'after$',name,'').sep.'*[^~]'.sep.'after'), '!pathogen#is_disabled(v:val[0:-7])') + [dir] | 
|  | 154     else | 
|  | 155       let list +=  [dir] + filter(pathogen#glob_directories(dir.sep.name.sep.'*[^~]'), '!pathogen#is_disabled(v:val)') | 
|  | 156     endif | 
|  | 157   endfor | 
|  | 158   let &rtp = pathogen#join(pathogen#uniq(list)) | 
|  | 159   return 1 | 
|  | 160 endfunction | 
|  | 161 | 
|  | 162 let s:done_bundles = '' | 
|  | 163 " }}}1 | 
|  | 164 | 
|  | 165 " Invoke :helptags on all non-$VIM doc directories in runtimepath. | 
|  | 166 function! pathogen#helptags() " {{{1 | 
|  | 167   let sep = pathogen#separator() | 
|  | 168   for dir in pathogen#split(&rtp) | 
|  | 169     if (dir.sep)[0 : strlen($VIMRUNTIME)] !=# $VIMRUNTIME.sep && filewritable(dir.sep.'doc') == 2 && !empty(filter(split(glob(dir.sep.'doc'.sep.'*'),"\n>"),'!isdirectory(v:val)')) && (!filereadable(dir.sep.'doc'.sep.'tags') || filewritable(dir.sep.'doc'.sep.'tags')) | 
|  | 170       helptags `=dir.'/doc'` | 
|  | 171     endif | 
|  | 172   endfor | 
|  | 173 endfunction " }}}1 | 
|  | 174 | 
|  | 175 command! -bar Helptags :call pathogen#helptags() | 
|  | 176 | 
|  | 177 " Like findfile(), but hardcoded to use the runtimepath. | 
|  | 178 function! pathogen#runtime_findfile(file,count) "{{{1 | 
|  | 179   let rtp = pathogen#join(1,pathogen#split(&rtp)) | 
|  | 180   let file = findfile(a:file,rtp,a:count) | 
|  | 181   if file ==# '' | 
|  | 182     return '' | 
|  | 183   else | 
|  | 184     return fnamemodify(file,':p') | 
|  | 185   endif | 
|  | 186 endfunction " }}}1 | 
|  | 187 | 
|  | 188 " Backport of fnameescape(). | 
|  | 189 function! pathogen#fnameescape(string) " {{{1 | 
|  | 190   if exists('*fnameescape') | 
|  | 191     return fnameescape(a:string) | 
|  | 192   elseif a:string ==# '-' | 
|  | 193     return '\-' | 
|  | 194   else | 
|  | 195     return substitute(escape(a:string," \t\n*?[{`$\\%#'\"|!<"),'^[+>]','\\&','') | 
|  | 196   endif | 
|  | 197 endfunction " }}}1 | 
|  | 198 | 
|  | 199 if exists(':Vedit') | 
|  | 200   finish | 
|  | 201 endif | 
|  | 202 | 
|  | 203 function! s:find(count,cmd,file,lcd) " {{{1 | 
|  | 204   let rtp = pathogen#join(1,pathogen#split(&runtimepath)) | 
|  | 205   let file = pathogen#runtime_findfile(a:file,a:count) | 
|  | 206   if file ==# '' | 
|  | 207     return "echoerr 'E345: Can''t find file \"".a:file."\" in runtimepath'" | 
|  | 208   elseif a:lcd | 
|  | 209     let path = file[0:-strlen(a:file)-2] | 
|  | 210     execute 'lcd `=path`' | 
|  | 211     return a:cmd.' '.pathogen#fnameescape(a:file) | 
|  | 212   else | 
|  | 213     return a:cmd.' '.pathogen#fnameescape(file) | 
|  | 214   endif | 
|  | 215 endfunction " }}}1 | 
|  | 216 | 
|  | 217 function! s:Findcomplete(A,L,P) " {{{1 | 
|  | 218   let sep = pathogen#separator() | 
|  | 219   let cheats = { | 
|  | 220         \'a': 'autoload', | 
|  | 221         \'d': 'doc', | 
|  | 222         \'f': 'ftplugin', | 
|  | 223         \'i': 'indent', | 
|  | 224         \'p': 'plugin', | 
|  | 225         \'s': 'syntax'} | 
|  | 226   if a:A =~# '^\w[\\/]' && has_key(cheats,a:A[0]) | 
|  | 227     let request = cheats[a:A[0]].a:A[1:-1] | 
|  | 228   else | 
|  | 229     let request = a:A | 
|  | 230   endif | 
|  | 231   let pattern = substitute(request,'/\|\'.sep,'*'.sep,'g').'*' | 
|  | 232   let found = {} | 
|  | 233   for path in pathogen#split(&runtimepath) | 
|  | 234     let path = expand(path, ':p') | 
|  | 235     let matches = split(glob(path.sep.pattern),"\n") | 
|  | 236     call map(matches,'isdirectory(v:val) ? v:val.sep : v:val') | 
|  | 237     call map(matches,'expand(v:val, ":p")[strlen(path)+1:-1]') | 
|  | 238     for match in matches | 
|  | 239       let found[match] = 1 | 
|  | 240     endfor | 
|  | 241   endfor | 
|  | 242   return sort(keys(found)) | 
|  | 243 endfunction " }}}1 | 
|  | 244 | 
|  | 245 command! -bar -bang -range=1 -nargs=1 -complete=customlist,s:Findcomplete Ve       :execute s:find(<count>,'edit<bang>',<q-args>,0) | 
|  | 246 command! -bar -bang -range=1 -nargs=1 -complete=customlist,s:Findcomplete Vedit    :execute s:find(<count>,'edit<bang>',<q-args>,0) | 
|  | 247 command! -bar -bang -range=1 -nargs=1 -complete=customlist,s:Findcomplete Vopen    :execute s:find(<count>,'edit<bang>',<q-args>,1) | 
|  | 248 command! -bar -bang -range=1 -nargs=1 -complete=customlist,s:Findcomplete Vsplit   :execute s:find(<count>,'split',<q-args>,<bang>1) | 
|  | 249 command! -bar -bang -range=1 -nargs=1 -complete=customlist,s:Findcomplete Vvsplit  :execute s:find(<count>,'vsplit',<q-args>,<bang>1) | 
|  | 250 command! -bar -bang -range=1 -nargs=1 -complete=customlist,s:Findcomplete Vtabedit :execute s:find(<count>,'tabedit',<q-args>,<bang>1) | 
|  | 251 command! -bar -bang -range=1 -nargs=1 -complete=customlist,s:Findcomplete Vpedit   :execute s:find(<count>,'pedit',<q-args>,<bang>1) | 
|  | 252 command! -bar -bang -range=1 -nargs=1 -complete=customlist,s:Findcomplete Vread    :execute s:find(<count>,'read',<q-args>,<bang>1) | 
|  | 253 | 
|  | 254 " vim:set et sw=2: |