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