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