1" vimball : construct a file containing both paths and files 2" Author: Charles E. Campbell, Jr. 3" Date: Apr 26, 2006 4" Version: 9 5" GetLatestVimScripts: 1502 1 :AutoInstall: vimball.vim 6" Copyright: (c) 2004-2006 by Charles E. Campbell, Jr. 7" The VIM LICENSE applies to Vimball.vim, and Vimball.txt 8" (see |copyright|) except use "Vimball" instead of "Vim". 9" No warranty, express or implied. 10" *** *** Use At-Your-Own-Risk! *** *** 11 12" --------------------------------------------------------------------- 13" Load Once: {{{1 14if &cp || exists("g:loaded_vimball") 15 finish 16endif 17let s:keepcpo = &cpo 18let g:loaded_vimball = "v9" 19set cpo&vim 20 21" ===================================================================== 22" Functions: {{{1 23 24" --------------------------------------------------------------------- 25" MkVimball: creates a vimball given a list of paths to files {{{2 26" Vimball Format: 27" path 28" filesize 29" [file] 30" path 31" filesize 32" [file] 33fun! vimball#MkVimball(line1,line2,writelevel,vimballname) range 34" call Dfunc("MkVimball(line1=".a:line1." line2=".a:line2." writelevel=".a:writelevel." vimballname<".a:vimballname.">") 35 let vbname= substitute(a:vimballname,'\.[^.]*$','','e').'.vba' 36 if !a:writelevel && filereadable(vbname) 37 echohl Error | echoerr "(MkVimball) file<".vbname."> exists; use ! to insist" | echohl None 38" call Dret("MkVimball : file<".vbname."> already exists; use ! to insist") 39 return 40 endif 41 42 " user option bypass 43 let eikeep = &ei 44 let acdkeep = &acd 45 set ei=all noacd 46 47 " go to vim plugin home 48 for home in split(&rtp,',') + [''] 49 if isdirectory(home) | break | endif 50 endfor 51 if home == "" 52 let home= substitute(&rtp,',.*$','','') 53 endif 54 if (has("win32") || has("win95") || has("win64") || has("win16")) 55 let home= substitute(home,'/','\\','ge') 56 endif 57" call Decho("home<".home.">") 58 59 " save current directory 60 let curdir = getcwd() 61 call s:ChgDir(home) 62 63 " record current tab, initialize while loop index 64 let curtabnr = tabpagenr() 65 let linenr = a:line1 66" call Decho("curtabnr=".curtabnr) 67 68 while linenr <= a:line2 69 let svfile = getline(linenr) 70" call Decho("svfile<".svfile.">") 71 72 if !filereadable(svfile) 73 echohl Error | echo "unable to read file<".svfile.">" | echohl None 74 call s:ChgDir(curdir) 75 let &ei = eikeep 76 let &acd = acdkeep 77" call Dret("MkVimball") 78 return 79 endif 80 81 " create/switch to mkvimball tab 82 if !exists("vbtabnr") 83 tabnew 84 silent! file Vimball 85 let vbtabnr= tabpagenr() 86 else 87 exe "tabn ".vbtabnr 88 endif 89 90 let lastline= line("$") + 1 91 if lastline == 2 && getline("$") == "" 92 call setline(1,'" Vimball Archiver by Charles E. Campbell, Jr., Ph.D.') 93 call setline(2,'UseVimball') 94 call setline(3,'finish') 95 let lastline= 4 96 endif 97 call setline(lastline ,svfile) 98 call setline(lastline+1,0) 99 100 " write the file from the tab 101 let svfilepath= s:Path(svfile,'') 102" call Decho("exe $r ".svfilepath) 103 exe "$r ".svfilepath 104 105 call setline(lastline+1,line("$") - lastline - 1) 106" call Decho("lastline=".lastline." line$=".line("$")) 107 108 " restore to normal tab 109 exe "tabn ".curtabnr 110 let linenr= linenr + 1 111 endwhile 112 113 " write the vimball 114 exe "tabn ".vbtabnr 115 call s:ChgDir(curdir) 116 if a:writelevel 117 let vbnamepath= s:Path(vbname,'') 118" call Decho("exe w! ".vbnamepath) 119 exe "w! ".vbnamepath 120 else 121 let vbnamepath= s:Path(vbname,'') 122" call Decho("exe w ".vbnamepath) 123 exe "w ".vbnamepath 124 endif 125" call Decho("Vimball<".vbname."> created") 126 echo "Vimball<".vbname."> created" 127 128 " remove the evidence 129 setlocal nomod bh=wipe 130 exe "tabn ".curtabnr 131 exe "tabc ".vbtabnr 132 133 " restore options 134 let &ei = eikeep 135 let &acd = acdkeep 136 137" call Dret("MkVimball") 138endfun 139 140" --------------------------------------------------------------------- 141" Vimball: {{{2 142fun! vimball#Vimball(really) 143" call Dfunc("Vimball(really=".a:really.")") 144 145 if getline(1) !~ '^" Vimball Archiver by Charles E. Campbell, Jr., Ph.D.$' 146 echoerr "(Vimball) The current file does not appear to be a Vimball!" 147" call Dret("Vimball") 148 return 149 endif 150 151 " initialize 152 let acdkeep = &acd 153 let fenkeep = &fen 154 let regakeep = @a 155 let eikeep = &ei 156 let vekeep = &ve 157 let makeep = getpos("'a") 158 let curtabnr = tabpagenr() 159 set ei=all ve=all nofen noacd 160 161 " set up vimball tab 162 tabnew 163 silent! file Vimball 164 let vbtabnr= tabpagenr() 165 let didhelp= "" 166 167 " go to vim plugin home 168 for home in split(&rtp,',') + [''] 169 if isdirectory(home) | break | endif 170 endfor 171 if home == "" 172 let home= substitute(&rtp,',.*$','','') 173 endif 174 if (has("win32") || has("win95") || has("win64") || has("win16")) 175 let home= substitute(home,'/','\\','ge') 176 endif 177" call Decho("home<".home.">") 178 179 " save current directory 180 let curdir = getcwd() 181 call s:ChgDir(home) 182 183 let linenr = 4 184 let filecnt = 0 185 186 " give title to listing of (extracted) files from Vimball Archive 187 if a:really 188 echohl Title | echomsg "Vimball Archive" | echohl None 189 else 190 echohl Title | echomsg "Vimball Archive Listing" | echohl None 191 endif 192 193 " apportion vimball contents to various files 194" call Decho("exe tabn ".curtabnr) 195 exe "tabn ".curtabnr 196" call Decho("linenr=".linenr." line$=".line("$")) 197 while 1 < linenr && linenr < line("$") 198 let fname = getline(linenr) 199 let fsize = getline(linenr+1) 200 let filecnt = filecnt + 1 201 if a:really 202 echomsg "extracted <".fname.">: ".fsize." lines" 203 else 204 echomsg "would extract <".fname.">: ".fsize." lines" 205 endif 206" call Decho("using L#".linenr.": will extract file<".fname.">") 207" call Decho("using L#".(linenr+1).": fsize=".fsize) 208 209 " make directories if they don't exist yet 210" call Decho("making directories if they don't exist yet") 211 let fnamebuf= fname 212 while fnamebuf =~ '/' 213 let dirname = home."/".substitute(fnamebuf,'/.*$','','e') 214 let fnamebuf = substitute(fnamebuf,'^.\{-}/\(.*\)$','\1','e') 215 if !isdirectory(dirname) 216" call Decho("making <".dirname.">") 217 call mkdir(dirname) 218 endif 219 endwhile 220 call s:ChgDir(home) 221 222 " grab specified qty of lines and place into "a" buffer 223 " (skip over path/filename and qty-lines) 224 let linenr = linenr + 2 225 let lastline = linenr + fsize - 1 226" call Decho("exe ".linenr.",".lastline."yank a") 227 exe "silent ".linenr.",".lastline."yank a" 228 229 " copy "a" buffer into tab 230" call Decho('copy "a buffer into tab#'.vbtabnr) 231 exe "tabn ".vbtabnr 232 silent! %d 233 silent put a 234 1 235 silent d 236 237 " write tab to file 238 if a:really 239 let fnamepath= s:Path(home."/".fname,'') 240" call Decho("exe w! ".fnamepath) 241 exe "silent w! ".fnamepath 242 echo "wrote ".fnamepath 243 endif 244 245 " return to tab with vimball 246" call Decho("exe tabn ".curtabnr) 247 exe "tabn ".curtabnr 248 249 " set up help if its a doc/*.txt file 250" call Decho("didhelp<".didhelp."> fname<".fname.">") 251 if a:really && didhelp == "" && fname =~ 'doc/[^/]\+\.txt$' 252 let didhelp= substitute(fname,'^\(.*\<doc\)[/\\][^.]*\.txt$','\1','e') 253" call Decho("didhelp<".didhelp.">") 254 endif 255 256 " update for next file 257" let oldlinenr = linenr " Decho 258 let linenr = linenr + fsize 259" call Decho("update linenr= [linenr=".oldlinenr."] + [fsize=".fsize."] = ".linenr) 260 endwhile 261 262 " set up help 263" call Decho("about to set up help: didhelp<".didhelp.">") 264 if didhelp != "" 265 let htpath= escape(substitute(s:Path(home."/".didhelp,'"'),'"','','ge'),' ') 266" call Decho("exe helptags ".htpath) 267 exe "helptags ".htpath 268 echo "did helptags" 269 endif 270 271 " make sure a "Press ENTER..." prompt appears to keep the messages showing! 272 while filecnt <= &ch 273 echomsg " " 274 let filecnt= filecnt + 1 275 endwhile 276 277 " restore events, delete tab and buffer 278 exe "tabn ".vbtabnr 279 setlocal nomod bh=wipe 280 exe "tabn ".curtabnr 281 exe "tabc ".vbtabnr 282 let &ei = eikeep 283 let @a = regakeep 284 let &fen = fenkeep 285 let &acd = acdkeep 286 if makeep[0] != 0 287 " restore mark a 288" call Decho("restore mark-a: makeep=".string(makeep)) 289 call setpos("'a",makeep) 290 ka 291 endif 292 call s:ChgDir(curdir) 293 294" call Dret("Vimball") 295endfun 296 297" --------------------------------------------------------------------- 298" vimball#Decompress: attempts to automatically decompress vimballs {{{2 299fun! vimball#Decompress(fname) 300" call Dfunc("Decompress(fname<".a:fname.">)") 301 302 " decompression: 303 if expand("%") =~ '.*\.gz' && executable("gunzip") 304 exe "!gunzip ".a:fname 305 let fname= substitute(a:fname,'\.gz$','','') 306 exe "e ".escape(fname,' \') 307 call vimball#ShowMesg("Source this file to extract it! (:so %)") 308 elseif expand("%") =~ '.*\.bz2' && executable("bunzip2") 309 exe "!bunzip2 ".a:fname 310 let fname= substitute(a:fname,'\.bz2$','','') 311 exe "e ".escape(fname,' \') 312 call vimball#ShowMesg("Source this file to extract it! (:so %)") 313 elseif expand("%") =~ '.*\.zip' && executable("unzip") 314 exe "!unzip ".a:fname 315 let fname= substitute(a:fname,'\.zip$','','') 316 exe "e ".escape(fname,' \') 317 call vimball#ShowMesg("Source this file to extract it! (:so %)") 318 endif 319 320" call Dret("Decompress") 321endfun 322 323" --------------------------------------------------------------------- 324" ChgDir: change directory (in spite of Windoze) {{{2 325fun! s:ChgDir(newdir) 326" call Dfunc("ChgDir(newdir<".a:newdir.">)") 327 if (has("win32") || has("win95") || has("win64") || has("win16")) 328 exe 'silent cd '.escape(substitute(a:newdir,'/','\\','g'),' ') 329 else 330 exe 'silent cd '.escape(a:newdir,' ') 331 endif 332" call Dret("ChgDir") 333endfun 334 335" --------------------------------------------------------------------- 336" Path: {{{2 337fun! s:Path(cmd,quote) 338" call Dfunc("Path(cmd<".a:cmd."> quote<".a:quote.">)") 339 if (has("win32") || has("win95") || has("win64") || has("win16")) 340 let cmdpath= a:quote.substitute(a:cmd,'/','\\','ge').a:quote 341 else 342 let cmdpath= a:quote.a:cmd.a:quote 343 endif 344 if a:quote == "" 345 let cmdpath= escape(cmdpath,' ') 346 endif 347" call Dret("Path <".cmdpath.">") 348 return cmdpath 349endfun 350 351" --------------------------------------------------------------------- 352" vimball#ShowMesg: {{{2 353fun! vimball#ShowMesg(msg) 354" call Dfunc("vimball#ShowMesg(msg<".a:msg.">)") 355 let ich= 1 356 echohl WarningMsg | echo a:msg | echohl None 357 while ich < &ch 358 echo " " 359 let ich= ich + 1 360 endwhile 361" call Dret("vimball#ShowMesg") 362endfun 363 364" --------------------------------------------------------------------- 365let &cpo= s:keepcpo 366unlet s:keepcpo 367" ===================================================================== 368" Modelines: {{{1 369" vim: fdm=marker 370