1" zip.vim: Handles browsing zipfiles 2" AUTOLOAD PORTION 3" Date: Apr 17, 2013 4" Version: 26 5" Maintainer: Charles E Campbell <[email protected]> 6" License: Vim License (see vim's :help license) 7" Copyright: Copyright (C) 2005-2012 Charles E. Campbell {{{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= "v26" 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 call append(0, ['" zip.vim version '.g:loaded_zip, 107 \ '" Browsing zipfile '.a:zipfile, 108 \ '" Select a file with cursor and press ENTER']) 109 keepj $ 110 111" call Decho("exe silent r! ".g:zip_unzipcmd." -l -- ".s:Escape(a:zipfile,1)) 112 exe "keepj sil! r! ".g:zip_unzipcmd." -Z -1 -- ".s:Escape(a:zipfile,1) 113 if v:shell_error != 0 114 redraw! 115 echohl WarningMsg | echo "***warning*** (zip#Browse) ".fnameescape(a:zipfile)." is not a zip file" | echohl None 116" call inputsave()|call input("Press <cr> to continue")|call inputrestore() 117 keepj sil! %d 118 let eikeep= &ei 119 set ei=BufReadCmd,FileReadCmd 120 exe "keepj r ".fnameescape(a:zipfile) 121 let &ei= eikeep 122 keepj 1d 123" call Dret("zip#Browse") 124 return 125 endif 126 127 setlocal noma nomod ro 128 noremap <silent> <buffer> <cr> :call <SID>ZipBrowseSelect()<cr> 129 130 let &report= repkeep 131" call Dret("zip#Browse") 132endfun 133 134" --------------------------------------------------------------------- 135" ZipBrowseSelect: {{{2 136fun! s:ZipBrowseSelect() 137" call Dfunc("ZipBrowseSelect() zipfile<".b:zipfile."> curfile<".expand("%").">") 138 let repkeep= &report 139 set report=10 140 let fname= getline(".") 141 142 " sanity check 143 if fname =~ '^"' 144 let &report= repkeep 145" call Dret("ZipBrowseSelect") 146 return 147 endif 148 if fname =~ '/$' 149 redraw! 150 echohl Error | echo "***error*** (zip#Browse) Please specify a file, not a directory" | echohl None 151" call inputsave()|call input("Press <cr> to continue")|call inputrestore() 152 let &report= repkeep 153" call Dret("ZipBrowseSelect") 154 return 155 endif 156 157" call Decho("fname<".fname.">") 158 159 " get zipfile to the new-window 160 let zipfile = b:zipfile 161 let curfile= expand("%") 162" call Decho("zipfile<".zipfile.">") 163" call Decho("curfile<".curfile.">") 164 165 new 166 if !exists("g:zip_nomax") || g:zip_nomax == 0 167 wincmd _ 168 endif 169 let s:zipfile_{winnr()}= curfile 170" call Decho("exe e ".fnameescape("zipfile:".zipfile.'::'.fname)) 171 exe "e ".fnameescape("zipfile:".zipfile.'::'.fname) 172 filetype detect 173 174 let &report= repkeep 175" call Dret("ZipBrowseSelect : s:zipfile_".winnr()."<".s:zipfile_{winnr()}.">") 176endfun 177 178" --------------------------------------------------------------------- 179" zip#Read: {{{2 180fun! zip#Read(fname,mode) 181" call Dfunc("zip#Read(fname<".a:fname.">,mode=".a:mode.")") 182 let repkeep= &report 183 set report=10 184 185 if has("unix") 186 let zipfile = substitute(a:fname,'zipfile:\(.\{-}\)::[^\\].*$','\1','') 187 let fname = substitute(a:fname,'zipfile:.\{-}::\([^\\].*\)$','\1','') 188 else 189 let zipfile = substitute(a:fname,'^.\{-}zipfile:\(.\{-}\)::[^\\].*$','\1','') 190 let fname = substitute(a:fname,'^.\{-}zipfile:.\{-}::\([^\\].*\)$','\1','') 191 let fname = substitute(fname, '[', '[[]', 'g') 192 endif 193" call Decho("zipfile<".zipfile.">") 194" call Decho("fname <".fname.">") 195 196 " the following code does much the same thing as 197 " exe "keepj sil! r! ".g:zip_unzipcmd." -p -- ".s:Escape(zipfile,1)." ".s:Escape(fnameescape(fname),1) 198 " but allows zipfile:... entries in quickfix lists 199 let temp = tempname() 200 let fn = expand('%:p') 201 exe "sil! !".g:zip_unzipcmd." -p -- ".s:Escape(zipfile,1)." ".s:Escape(fnameescape(fname),1).' > '.temp 202" call Decho("exe sil! !".g:zip_unzipcmd." -p -- ".s:Escape(zipfile,1)." ".s:Escape(fnameescape(fname),1).' > '.temp) 203 sil exe 'keepalt file '.temp 204 sil keepj e! 205 sil exe 'keepalt file '.fnameescape(fn) 206 call delete(temp) 207 208 filetype detect 209 210 " cleanup 211 keepj 0d 212 set nomod 213 214 let &report= repkeep 215" call Dret("zip#Read") 216endfun 217 218" --------------------------------------------------------------------- 219" zip#Write: {{{2 220fun! zip#Write(fname) 221" call Dfunc("zip#Write(fname<".a:fname.">) zipfile_".winnr()."<".s:zipfile_{winnr()}.">") 222 let repkeep= &report 223 set report=10 224 225 " sanity checks 226 if !executable(g:zip_zipcmd) 227 redraw! 228 echohl Error | echo "***error*** (zip#Write) sorry, your system doesn't appear to have the zip pgm" | echohl None 229" call inputsave()|call input("Press <cr> to continue")|call inputrestore() 230 let &report= repkeep 231" call Dret("zip#Write") 232 return 233 endif 234 if !exists("*mkdir") 235 redraw! 236 echohl Error | echo "***error*** (zip#Write) sorry, mkdir() doesn't work on your system" | echohl None 237" call inputsave()|call input("Press <cr> to continue")|call inputrestore() 238 let &report= repkeep 239" call Dret("zip#Write") 240 return 241 endif 242 243 let curdir= getcwd() 244 let tmpdir= tempname() 245" call Decho("orig tempname<".tmpdir.">") 246 if tmpdir =~ '\.' 247 let tmpdir= substitute(tmpdir,'\.[^.]*$','','e') 248 endif 249" call Decho("tmpdir<".tmpdir.">") 250 call mkdir(tmpdir,"p") 251 252 " attempt to change to the indicated directory 253 if s:ChgDir(tmpdir,s:ERROR,"(zip#Write) cannot cd to temporary directory") 254 let &report= repkeep 255" call Dret("zip#Write") 256 return 257 endif 258" call Decho("current directory now: ".getcwd()) 259 260 " place temporary files under .../_ZIPVIM_/ 261 if isdirectory("_ZIPVIM_") 262 call s:Rmdir("_ZIPVIM_") 263 endif 264 call mkdir("_ZIPVIM_") 265 cd _ZIPVIM_ 266" call Decho("current directory now: ".getcwd()) 267 268 if has("unix") 269 let zipfile = substitute(a:fname,'zipfile:\(.\{-}\)::[^\\].*$','\1','') 270 let fname = substitute(a:fname,'zipfile:.\{-}::\([^\\].*\)$','\1','') 271 else 272 let zipfile = substitute(a:fname,'^.\{-}zipfile:\(.\{-}\)::[^\\].*$','\1','') 273 let fname = substitute(a:fname,'^.\{-}zipfile:.\{-}::\([^\\].*\)$','\1','') 274 endif 275" call Decho("zipfile<".zipfile.">") 276" call Decho("fname <".fname.">") 277 278 if fname =~ '/' 279 let dirpath = substitute(fname,'/[^/]\+$','','e') 280 if has("win32unix") && executable("cygpath") 281 let dirpath = substitute(system("cygpath ".s:Escape(dirpath,0)),'\n','','e') 282 endif 283" call Decho("mkdir(dirpath<".dirpath.">,p)") 284 call mkdir(dirpath,"p") 285 endif 286 if zipfile !~ '/' 287 let zipfile= curdir.'/'.zipfile 288 endif 289" call Decho("zipfile<".zipfile."> fname<".fname.">") 290 291 exe "w! ".fnameescape(fname) 292 if has("win32unix") && executable("cygpath") 293 let zipfile = substitute(system("cygpath ".s:Escape(zipfile,0)),'\n','','e') 294 endif 295 296 if (has("win32") || has("win95") || has("win64") || has("win16")) && &shell !~? 'sh$' 297 let fname = substitute(fname, '[', '[[]', 'g') 298 endif 299 300" call Decho(g:zip_zipcmd." -u ".s:Escape(fnamemodify(zipfile,":p"),0)." ".s:Escape(fname,0)) 301 call system(g:zip_zipcmd." -u ".s:Escape(fnamemodify(zipfile,":p"),0)." ".s:Escape(fname,0)) 302 if v:shell_error != 0 303 redraw! 304 echohl Error | echo "***error*** (zip#Write) sorry, unable to update ".zipfile." with ".fname | echohl None 305" call inputsave()|call input("Press <cr> to continue")|call inputrestore() 306 307 elseif s:zipfile_{winnr()} =~ '^\a\+://' 308 " support writing zipfiles across a network 309 let netzipfile= s:zipfile_{winnr()} 310" call Decho("handle writing <".zipfile."> across network as <".netzipfile.">") 311 1split|enew 312 let binkeep= &binary 313 let eikeep = &ei 314 set binary ei=all 315 exe "e! ".fnameescape(zipfile) 316 call netrw#NetWrite(netzipfile) 317 let &ei = eikeep 318 let &binary = binkeep 319 q! 320 unlet s:zipfile_{winnr()} 321 endif 322 323 " cleanup and restore current directory 324 cd .. 325 call s:Rmdir("_ZIPVIM_") 326 call s:ChgDir(curdir,s:WARNING,"(zip#Write) unable to return to ".curdir."!") 327 call s:Rmdir(tmpdir) 328 setlocal nomod 329 330 let &report= repkeep 331" call Dret("zip#Write") 332endfun 333 334" --------------------------------------------------------------------- 335" s:Escape: {{{2 336fun! s:Escape(fname,isfilt) 337" call Dfunc("QuoteFileDir(fname<".a:fname."> isfilt=".a:isfilt.")") 338 if exists("*shellescape") 339 if a:isfilt 340 let qnameq= shellescape(a:fname,1) 341 else 342 let qnameq= shellescape(a:fname) 343 endif 344 else 345 let qnameq= g:zip_shq.escape(a:fname,g:zip_shq).g:zip_shq 346 endif 347" call Dret("QuoteFileDir <".qnameq.">") 348 return qnameq 349endfun 350 351" --------------------------------------------------------------------- 352" ChgDir: {{{2 353fun! s:ChgDir(newdir,errlvl,errmsg) 354" call Dfunc("ChgDir(newdir<".a:newdir."> errlvl=".a:errlvl." errmsg<".a:errmsg.">)") 355 356 try 357 exe "cd ".fnameescape(a:newdir) 358 catch /^Vim\%((\a\+)\)\=:E344/ 359 redraw! 360 if a:errlvl == s:NOTE 361 echo "***note*** ".a:errmsg 362 elseif a:errlvl == s:WARNING 363 echohl WarningMsg | echo "***warning*** ".a:errmsg | echohl NONE 364 elseif a:errlvl == s:ERROR 365 echohl Error | echo "***error*** ".a:errmsg | echohl NONE 366 endif 367" call inputsave()|call input("Press <cr> to continue")|call inputrestore() 368" call Dret("ChgDir 1") 369 return 1 370 endtry 371 372" call Dret("ChgDir 0") 373 return 0 374endfun 375 376" --------------------------------------------------------------------- 377" s:Rmdir: {{{2 378fun! s:Rmdir(fname) 379" call Dfunc("Rmdir(fname<".a:fname.">)") 380 if (has("win32") || has("win95") || has("win64") || has("win16")) && &shell !~? 'sh$' 381 call system("rmdir /S/Q ".s:Escape(a:fname,0)) 382 else 383 call system("/bin/rm -rf ".s:Escape(a:fname,0)) 384 endif 385" call Dret("Rmdir") 386endfun 387 388" ------------------------------------------------------------------------ 389" Modelines And Restoration: {{{1 390let &cpo= s:keepcpo 391unlet s:keepcpo 392" vim:ts=8 fdm=marker 393