1" zip.vim: Handles browsing zipfiles 2" AUTOLOAD PORTION 3" Date: Apr 12, 2010 4" Version: 23 5" Maintainer: Charles E Campbell, Jr <NdrOchip@ScampbellPfamily.AbizM-NOSPAM> 6" License: Vim License (see vim's :help license) 7" Copyright: Copyright (C) 2005-2008 Charles E. Campbell, Jr. {{{1 8" Permission is hereby granted to use and distribute this code, 9" with or without modifications, provided that this copyright 10" notice is copied with it. Like anything else that's free, 11" zip.vim and zipPlugin.vim are provided *as is* and comes with 12" no warranty of any kind, either expressed or implied. By using 13" this plugin, you agree that in no event will the copyright 14" holder be liable for any damages resulting from the use 15" of this software. 16 17" --------------------------------------------------------------------- 18" Load Once: {{{1 19if &cp || exists("g:loaded_zip") 20 finish 21endif 22let g:loaded_zip= "v23" 23if v:version < 702 24 echohl WarningMsg 25 echo "***warning*** this version of zip needs vim 7.2" 26 echohl Normal 27 finish 28endif 29let s:keepcpo= &cpo 30set cpo&vim 31 32let s:zipfile_escape = ' ?&;\' 33let s:ERROR = 2 34let s:WARNING = 1 35let s:NOTE = 0 36 37" --------------------------------------------------------------------- 38" Global Values: {{{1 39if !exists("g:zip_shq") 40 if &shq != "" 41 let g:zip_shq= &shq 42 elseif has("unix") 43 let g:zip_shq= "'" 44 else 45 let g:zip_shq= '"' 46 endif 47endif 48if !exists("g:zip_zipcmd") 49 let g:zip_zipcmd= "zip" 50endif 51if !exists("g:zip_unzipcmd") 52 let g:zip_unzipcmd= "unzip" 53endif 54 55" ---------------- 56" Functions: {{{1 57" ---------------- 58 59" --------------------------------------------------------------------- 60" zip#Browse: {{{2 61fun! zip#Browse(zipfile) 62" call Dfunc("zip#Browse(zipfile<".a:zipfile.">)") 63 let repkeep= &report 64 set report=10 65 66 " sanity checks 67 if !exists("*fnameescape") 68 if &verbose > 1 69 echoerr "the zip plugin is not available (your vim doens't support fnameescape())" 70 endif 71 return 72 endif 73 if !executable(g:zip_unzipcmd) 74 redraw! 75 echohl Error | echo "***error*** (zip#Browse) unzip not available on your system" 76" call inputsave()|call input("Press <cr> to continue")|call inputrestore() 77 let &report= repkeep 78" call Dret("zip#Browse") 79 return 80 endif 81 if !filereadable(a:zipfile) 82 if a:zipfile !~# '^\a\+://' 83 " if its an url, don't complain, let url-handlers such as vim do its thing 84 redraw! 85 echohl Error | echo "***error*** (zip#Browse) File not readable<".a:zipfile.">" | echohl None 86" call inputsave()|call input("Press <cr> to continue")|call inputrestore() 87 endif 88 let &report= repkeep 89" call Dret("zip#Browse : file<".a:zipfile."> not readable") 90 return 91 endif 92" call Decho("passed sanity checks") 93 if &ma != 1 94 set ma 95 endif 96 let b:zipfile= a:zipfile 97 98 setlocal noswapfile 99 setlocal buftype=nofile 100 setlocal bufhidden=hide 101 setlocal nobuflisted 102 setlocal nowrap 103 set ft=tar 104 105 " give header 106 let lastline= line("$") 107 call setline(lastline+1,'" zip.vim version '.g:loaded_zip) 108 call setline(lastline+2,'" Browsing zipfile '.a:zipfile) 109 call setline(lastline+3,'" Select a file with cursor and press ENTER') 110 $put ='' 111 0d 112 $ 113 114" call Decho("exe silent r! ".g:zip_unzipcmd." -l -- ".s:Escape(a:zipfile,1)) 115 exe "silent r! ".g:zip_unzipcmd." -l -- ".s:Escape(a:zipfile,1) 116 if v:shell_error != 0 117 redraw! 118 echohl WarningMsg | echo "***warning*** (zip#Browse) ".fnameescape(a:zipfile)." is not a zip file" | echohl None 119" call inputsave()|call input("Press <cr> to continue")|call inputrestore() 120 silent %d 121 let eikeep= &ei 122 set ei=BufReadCmd,FileReadCmd 123 exe "r ".fnameescape(a:zipfile) 124 let &ei= eikeep 125 1d 126" call Dret("zip#Browse") 127 return 128 endif 129" call Decho("line 6: ".getline(6)) 130 let namecol= stridx(getline(6),'Name') + 1 131" call Decho("namecol=".namecol) 132 4,$g/^\s*----/d 133 4,$g/^\s*\a/d 134 $d 135 if namecol > 0 136 exe 'silent 4,$s/^.*\%'.namecol.'c//' 137 endif 138 139 setlocal noma nomod ro 140 noremap <silent> <buffer> <cr> :call <SID>ZipBrowseSelect()<cr> 141 142 let &report= repkeep 143" call Dret("zip#Browse") 144endfun 145 146" --------------------------------------------------------------------- 147" ZipBrowseSelect: {{{2 148fun! s:ZipBrowseSelect() 149" call Dfunc("ZipBrowseSelect() zipfile<".b:zipfile."> curfile<".expand("%").">") 150 let repkeep= &report 151 set report=10 152 let fname= getline(".") 153 154 " sanity check 155 if fname =~ '^"' 156 let &report= repkeep 157" call Dret("ZipBrowseSelect") 158 return 159 endif 160 if fname =~ '/$' 161 redraw! 162 echohl Error | echo "***error*** (zip#Browse) Please specify a file, not a directory" | echohl None 163" call inputsave()|call input("Press <cr> to continue")|call inputrestore() 164 let &report= repkeep 165" call Dret("ZipBrowseSelect") 166 return 167 endif 168 169" call Decho("fname<".fname.">") 170 171 " get zipfile to the new-window 172 let zipfile = b:zipfile 173 let curfile= expand("%") 174" call Decho("zipfile<".zipfile.">") 175" call Decho("curfile<".curfile.">") 176 177 new 178 if !exists("g:zip_nomax") || g:zip_nomax == 0 179 wincmd _ 180 endif 181 let s:zipfile_{winnr()}= curfile 182" call Decho("exe e ".fnameescape("zipfile:".zipfile.'::'.fname)) 183 exe "e ".fnameescape("zipfile:".zipfile.'::'.fname) 184 filetype detect 185 186 let &report= repkeep 187" call Dret("ZipBrowseSelect : s:zipfile_".winnr()."<".s:zipfile_{winnr()}.">") 188endfun 189 190" --------------------------------------------------------------------- 191" zip#Read: {{{2 192fun! zip#Read(fname,mode) 193" call Dfunc("zip#Read(fname<".a:fname.">,mode=".a:mode.")") 194 let repkeep= &report 195 set report=10 196 197 if has("unix") 198 let zipfile = substitute(a:fname,'zipfile:\(.\{-}\)::[^\\].*$','\1','') 199 let fname = substitute(a:fname,'zipfile:.\{-}::\([^\\].*\)$','\1','') 200 else 201 let zipfile = substitute(a:fname,'^.\{-}zipfile:\(.\{-}\)::[^\\].*$','\1','') 202 let fname = substitute(a:fname,'^.\{-}zipfile:.\{-}::\([^\\].*\)$','\1','') 203 let fname = substitute(fname, '[', '[[]', 'g') 204 endif 205" call Decho("zipfile<".zipfile.">") 206" call Decho("fname <".fname.">") 207 208" call Decho("exe r! ".g:zip_unzipcmd." -p -- ".s:Escape(zipfile,1)." ".s:Escape(fname,1)) 209 exe "silent r! ".g:zip_unzipcmd." -p -- ".s:Escape(zipfile,1)." ".s:Escape(fname,1) 210 211 " cleanup 212 0d 213 set nomod 214 215 let &report= repkeep 216" call Dret("zip#Read") 217endfun 218 219" --------------------------------------------------------------------- 220" zip#Write: {{{2 221fun! zip#Write(fname) 222" call Dfunc("zip#Write(fname<".a:fname.">) zipfile_".winnr()."<".s:zipfile_{winnr()}.">") 223 let repkeep= &report 224 set report=10 225 226 " sanity checks 227 if !executable(g:zip_zipcmd) 228 redraw! 229 echohl Error | echo "***error*** (zip#Write) sorry, your system doesn't appear to have the zip pgm" | echohl None 230" call inputsave()|call input("Press <cr> to continue")|call inputrestore() 231 let &report= repkeep 232" call Dret("zip#Write") 233 return 234 endif 235 if !exists("*mkdir") 236 redraw! 237 echohl Error | echo "***error*** (zip#Write) sorry, mkdir() doesn't work on your system" | echohl None 238" call inputsave()|call input("Press <cr> to continue")|call inputrestore() 239 let &report= repkeep 240" call Dret("zip#Write") 241 return 242 endif 243 244 let curdir= getcwd() 245 let tmpdir= tempname() 246" call Decho("orig tempname<".tmpdir.">") 247 if tmpdir =~ '\.' 248 let tmpdir= substitute(tmpdir,'\.[^.]*$','','e') 249 endif 250" call Decho("tmpdir<".tmpdir.">") 251 call mkdir(tmpdir,"p") 252 253 " attempt to change to the indicated directory 254 if s:ChgDir(tmpdir,s:ERROR,"(zip#Write) cannot cd to temporary directory") 255 let &report= repkeep 256" call Dret("zip#Write") 257 return 258 endif 259" call Decho("current directory now: ".getcwd()) 260 261 " place temporary files under .../_ZIPVIM_/ 262 if isdirectory("_ZIPVIM_") 263 call s:Rmdir("_ZIPVIM_") 264 endif 265 call mkdir("_ZIPVIM_") 266 cd _ZIPVIM_ 267" call Decho("current directory now: ".getcwd()) 268 269 if has("unix") 270 let zipfile = substitute(a:fname,'zipfile:\(.\{-}\)::[^\\].*$','\1','') 271 let fname = substitute(a:fname,'zipfile:.\{-}::\([^\\].*\)$','\1','') 272 else 273 let zipfile = substitute(a:fname,'^.\{-}zipfile:\(.\{-}\)::[^\\].*$','\1','') 274 let fname = substitute(a:fname,'^.\{-}zipfile:.\{-}::\([^\\].*\)$','\1','') 275 endif 276" call Decho("zipfile<".zipfile.">") 277" call Decho("fname <".fname.">") 278 279 if fname =~ '/' 280 let dirpath = substitute(fname,'/[^/]\+$','','e') 281 if executable("cygpath") 282 let dirpath = substitute(system("cygpath ".s:Escape(dirpath,0)),'\n','','e') 283 endif 284" call Decho("mkdir(dirpath<".dirpath.">,p)") 285 call mkdir(dirpath,"p") 286 endif 287 if zipfile !~ '/' 288 let zipfile= curdir.'/'.zipfile 289 endif 290" call Decho("zipfile<".zipfile."> fname<".fname.">") 291 292 exe "w! ".fnameescape(fname) 293 if executable("cygpath") 294 let zipfile = substitute(system("cygpath ".s:Escape(zipfile,0)),'\n','','e') 295 endif 296 297 if (has("win32") || has("win95") || has("win64") || has("win16")) && &shell !~? 'sh$' 298 let fname = substitute(fname, '[', '[[]', 'g') 299 endif 300 301" call Decho(g:zip_zipcmd." -u ".s:Escape(fnamemodify(zipfile,":p"),0)." ".s:Escape(fname,0)) 302 call system(g:zip_zipcmd." -u ".s:Escape(fnamemodify(zipfile,":p"),0)." ".s:Escape(fname,0)) 303 if v:shell_error != 0 304 redraw! 305 echohl Error | echo "***error*** (zip#Write) sorry, unable to update ".zipfile." with ".fname | echohl None 306" call inputsave()|call input("Press <cr> to continue")|call inputrestore() 307 308 elseif s:zipfile_{winnr()} =~ '^\a\+://' 309 " support writing zipfiles across a network 310 let netzipfile= s:zipfile_{winnr()} 311" call Decho("handle writing <".zipfile."> across network as <".netzipfile.">") 312 1split|enew 313 let binkeep= &binary 314 let eikeep = &ei 315 set binary ei=all 316 exe "e! ".fnameescape(zipfile) 317 call netrw#NetWrite(netzipfile) 318 let &ei = eikeep 319 let &binary = binkeep 320 q! 321 unlet s:zipfile_{winnr()} 322 endif 323 324 " cleanup and restore current directory 325 cd .. 326 call s:Rmdir("_ZIPVIM_") 327 call s:ChgDir(curdir,s:WARNING,"(zip#Write) unable to return to ".curdir."!") 328 call s:Rmdir(tmpdir) 329 setlocal nomod 330 331 let &report= repkeep 332" call Dret("zip#Write") 333endfun 334 335" --------------------------------------------------------------------- 336" s:Escape: {{{2 337fun! s:Escape(fname,isfilt) 338" call Dfunc("QuoteFileDir(fname<".a:fname."> isfilt=".a:isfilt.")") 339 if exists("*shellescape") 340 if a:isfilt 341 let qnameq= shellescape(a:fname,1) 342 else 343 let qnameq= shellescape(a:fname) 344 endif 345 else 346 let qnameq= g:zip_shq.escape(a:fname,g:zip_shq).g:zip_shq 347 endif 348" call Dret("QuoteFileDir <".qnameq.">") 349 return qnameq 350endfun 351 352" --------------------------------------------------------------------- 353" ChgDir: {{{2 354fun! s:ChgDir(newdir,errlvl,errmsg) 355" call Dfunc("ChgDir(newdir<".a:newdir."> errlvl=".a:errlvl." errmsg<".a:errmsg.">)") 356 357 try 358 exe "cd ".fnameescape(a:newdir) 359 catch /^Vim\%((\a\+)\)\=:E344/ 360 redraw! 361 if a:errlvl == s:NOTE 362 echo "***note*** ".a:errmsg 363 elseif a:errlvl == s:WARNING 364 echohl WarningMsg | echo "***warning*** ".a:errmsg | echohl NONE 365 elseif a:errlvl == s:ERROR 366 echohl Error | echo "***error*** ".a:errmsg | echohl NONE 367 endif 368" call inputsave()|call input("Press <cr> to continue")|call inputrestore() 369" call Dret("ChgDir 1") 370 return 1 371 endtry 372 373" call Dret("ChgDir 0") 374 return 0 375endfun 376 377" --------------------------------------------------------------------- 378" s:Rmdir: {{{2 379fun! s:Rmdir(fname) 380" call Dfunc("Rmdir(fname<".a:fname.">)") 381 if (has("win32") || has("win95") || has("win64") || has("win16")) && &shell !~? 'sh$' 382 call system("rmdir /S/Q ".s:Escape(a:fname,0)) 383 else 384 call system("/bin/rm -rf ".s:Escape(a:fname,0)) 385 endif 386" call Dret("Rmdir") 387endfun 388 389" ------------------------------------------------------------------------ 390" Modelines And Restoration: {{{1 391let &cpo= s:keepcpo 392unlet s:keepcpo 393" vim:ts=8 fdm=marker 394