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