blob: 2a15deeafe1b35015b9526f17a740e617435a94e [file] [log] [blame]
Bram Moolenaar60a795a2005-09-16 21:55:43 +00001" zip.vim: Handles browsing zipfiles
2" AUTOLOAD PORTION
Bram Moolenaar9964e462007-05-05 17:54:07 +00003" Date: Sep 29, 2006
4" Version: 12
5" Maintainer: Charles E Campbell, Jr <NdrOchip@ScampbellPfamily.AbizM-NOSPAM>
6" License: Vim License (see vim's :help license)
Bram Moolenaar60a795a2005-09-16 21:55:43 +00007" 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" ---------------------------------------------------------------------
Bram Moolenaar9964e462007-05-05 17:54:07 +000018" Load Once: {{{1
Bram Moolenaar60a795a2005-09-16 21:55:43 +000019let s:keepcpo= &cpo
20set cpo&vim
Bram Moolenaar9964e462007-05-05 17:54:07 +000021if &cp || exists("g:loaded_zip") || v:version < 700
Bram Moolenaar60a795a2005-09-16 21:55:43 +000022 finish
23endif
24
Bram Moolenaar9964e462007-05-05 17:54:07 +000025let g:loaded_zip = "v12"
Bram Moolenaardb552d602006-03-23 22:59:57 +000026let s:zipfile_escape = ' ?&;\'
Bram Moolenaar9964e462007-05-05 17:54:07 +000027let 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
Bram Moolenaar60a795a2005-09-16 21:55:43 +000040
41" ----------------
42" Functions: {{{1
43" ----------------
44
45" ---------------------------------------------------------------------
46" zip#Browse: {{{2
47fun! zip#Browse(zipfile)
48" call Dfunc("zip#Browse(zipfile<".a:zipfile.">)")
Bram Moolenaar36c31f72005-11-28 23:01:53 +000049 let repkeep= &report
50 set report=10
Bram Moolenaar60a795a2005-09-16 21:55:43 +000051
52 " sanity checks
53 if !executable("unzip")
Bram Moolenaar9964e462007-05-05 17:54:07 +000054 redraw!
Bram Moolenaar60a795a2005-09-16 21:55:43 +000055 echohl Error | echo "***error*** (zip#Browse) unzip not available on your system"
Bram Moolenaar9964e462007-05-05 17:54:07 +000056" call inputsave()|call input("Press <cr> to continue")|call inputrestore()
Bram Moolenaar36c31f72005-11-28 23:01:53 +000057 let &report= repkeep
Bram Moolenaar60a795a2005-09-16 21:55:43 +000058" call Dret("zip#Browse")
59 return
60 endif
61 if !filereadable(a:zipfile)
Bram Moolenaara5792f52005-11-23 21:25:05 +000062 if a:zipfile !~# '^\a\+://'
63 " if its an url, don't complain, let url-handlers such as vim do its thing
Bram Moolenaar9964e462007-05-05 17:54:07 +000064 redraw!
Bram Moolenaara5792f52005-11-23 21:25:05 +000065 echohl Error | echo "***error*** (zip#Browse) File not readable<".a:zipfile.">" | echohl None
Bram Moolenaar9964e462007-05-05 17:54:07 +000066" call inputsave()|call input("Press <cr> to continue")|call inputrestore()
Bram Moolenaara5792f52005-11-23 21:25:05 +000067 endif
Bram Moolenaar36c31f72005-11-28 23:01:53 +000068 let &report= repkeep
Bram Moolenaara5792f52005-11-23 21:25:05 +000069" call Dret("zip#Browse : file<".a:zipfile."> not readable")
Bram Moolenaar60a795a2005-09-16 21:55:43 +000070 return
71 endif
Bram Moolenaardb552d602006-03-23 22:59:57 +000072" call Decho("passed sanity checks")
Bram Moolenaar60a795a2005-09-16 21:55:43 +000073 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
Bram Moolenaar9964e462007-05-05 17:54:07 +000093" call Decho("exe silent r! unzip -l ".s:QuoteFileDir(a:zipfile))
94 exe "silent r! unzip -l ".s:QuoteFileDir(a:zipfile)
Bram Moolenaard68071d2006-05-02 22:08:30 +000095 if v:shell_error != 0
Bram Moolenaar9964e462007-05-05 17:54:07 +000096 redraw!
Bram Moolenaard68071d2006-05-02 22:08:30 +000097 echohl WarningMsg | echo "***warning*** (zip#Browse) ".a:zipfile." is not a zip file" | echohl None
Bram Moolenaar9964e462007-05-05 17:54:07 +000098" call inputsave()|call input("Press <cr> to continue")|call inputrestore()
Bram Moolenaard68071d2006-05-02 22:08:30 +000099 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
Bram Moolenaar910f66f2006-04-05 20:41:53 +0000108" 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
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000113 $d
Bram Moolenaar4c3f5362006-04-11 21:38:50 +0000114 if namecol > 0
115 exe 'silent 4,$s/^.*\%'.namecol.'c//'
116 endif
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000117
118 setlocal noma nomod ro
119 noremap <silent> <buffer> <cr> :call <SID>ZipBrowseSelect()<cr>
120
Bram Moolenaar36c31f72005-11-28 23:01:53 +0000121 let &report= repkeep
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000122" call Dret("zip#Browse")
123endfun
124
125" ---------------------------------------------------------------------
126" ZipBrowseSelect: {{{2
127fun! s:ZipBrowseSelect()
Bram Moolenaara5792f52005-11-23 21:25:05 +0000128" call Dfunc("ZipBrowseSelect() zipfile<".w:zipfile."> curfile<".expand("%").">")
Bram Moolenaar36c31f72005-11-28 23:01:53 +0000129 let repkeep= &report
130 set report=10
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000131 let fname= getline(".")
132
133 " sanity check
134 if fname =~ '^"'
Bram Moolenaar36c31f72005-11-28 23:01:53 +0000135 let &report= repkeep
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000136" call Dret("ZipBrowseSelect")
137 return
138 endif
139 if fname =~ '/$'
Bram Moolenaar9964e462007-05-05 17:54:07 +0000140 redraw!
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000141 echohl Error | echo "***error*** (zip#Browse) Please specify a file, not a directory" | echohl None
Bram Moolenaar9964e462007-05-05 17:54:07 +0000142" call inputsave()|call input("Press <cr> to continue")|call inputrestore()
Bram Moolenaar36c31f72005-11-28 23:01:53 +0000143 let &report= repkeep
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000144" call Dret("ZipBrowseSelect")
145 return
146 endif
147
148" call Decho("fname<".fname.">")
149
150 " get zipfile to the new-window
Bram Moolenaar9964e462007-05-05 17:54:07 +0000151 let zipfile = w:zipfile
Bram Moolenaar910f66f2006-04-05 20:41:53 +0000152 let curfile= expand("%")
Bram Moolenaardb552d602006-03-23 22:59:57 +0000153" call Decho("zipfile<".zipfile.">")
154" call Decho("curfile<".curfile.">")
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000155
156 new
157 wincmd _
Bram Moolenaara5792f52005-11-23 21:25:05 +0000158 let s:zipfile_{winnr()}= curfile
Bram Moolenaard68071d2006-05-02 22:08:30 +0000159" 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)
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000161 filetype detect
162
Bram Moolenaar36c31f72005-11-28 23:01:53 +0000163 let &report= repkeep
Bram Moolenaara5792f52005-11-23 21:25:05 +0000164" call Dret("ZipBrowseSelect : s:zipfile_".winnr()."<".s:zipfile_{winnr()}.">")
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000165endfun
166
167" ---------------------------------------------------------------------
168" zip#Read: {{{2
169fun! zip#Read(fname,mode)
170" call Dfunc("zip#Read(fname<".a:fname.">,mode=".a:mode.")")
Bram Moolenaar36c31f72005-11-28 23:01:53 +0000171 let repkeep= &report
172 set report=10
173
Bram Moolenaard68071d2006-05-02 22:08:30 +0000174 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','')
Bram Moolenaar9964e462007-05-05 17:54:07 +0000180
181 " TODO Needs to predicated to using InfoZIP's unzip on Windows
182 let fname = substitute(fname, '[', '[[]', 'g')
Bram Moolenaard68071d2006-05-02 22:08:30 +0000183 endif
184" call Decho("zipfile<".zipfile.">")
185" call Decho("fname <".fname.">")
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000186
Bram Moolenaar9964e462007-05-05 17:54:07 +0000187" call Decho("exe r! unzip -p ".s:QuoteFileDir(zipfile)." ".s:QuoteFileDir(fname))
188 exe "silent r! unzip -p ".s:QuoteFileDir(zipfile)." ".s:QuoteFileDir(fname)
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000189
190 " cleanup
191 0d
192 set nomod
193
Bram Moolenaar36c31f72005-11-28 23:01:53 +0000194 let &report= repkeep
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000195" call Dret("zip#Read")
196endfun
197
198" ---------------------------------------------------------------------
199" zip#Write: {{{2
200fun! zip#Write(fname)
Bram Moolenaar910f66f2006-04-05 20:41:53 +0000201" call Dfunc("zip#Write(fname<".a:fname.">) zipfile_".winnr()."<".s:zipfile_{winnr()}.">")
Bram Moolenaar36c31f72005-11-28 23:01:53 +0000202 let repkeep= &report
203 set report=10
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000204
205 " sanity checks
206 if !executable("zip")
Bram Moolenaar9964e462007-05-05 17:54:07 +0000207 redraw!
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000208 echohl Error | echo "***error*** (zip#Write) sorry, your system doesn't appear to have the zip pgm" | echohl None
Bram Moolenaar9964e462007-05-05 17:54:07 +0000209" call inputsave()|call input("Press <cr> to continue")|call inputrestore()
Bram Moolenaar36c31f72005-11-28 23:01:53 +0000210 let &report= repkeep
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000211" call Dret("zip#Write")
212 return
213 endif
214 if !exists("*mkdir")
Bram Moolenaar9964e462007-05-05 17:54:07 +0000215 redraw!
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000216 echohl Error | echo "***error*** (zip#Write) sorry, mkdir() doesn't work on your system" | echohl None
Bram Moolenaar9964e462007-05-05 17:54:07 +0000217" call inputsave()|call input("Press <cr> to continue")|call inputrestore()
Bram Moolenaar36c31f72005-11-28 23:01:53 +0000218 let &report= repkeep
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000219" 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
Bram Moolenaar9964e462007-05-05 17:54:07 +0000233 if s:ChgDir(tmpdir,s:ERROR,"(zip#Write) cannot cd to temporary directory")
Bram Moolenaar36c31f72005-11-28 23:01:53 +0000234 let &report= repkeep
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000235" call Dret("zip#Write")
236 return
Bram Moolenaar9964e462007-05-05 17:54:07 +0000237 endif
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000238" 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
Bram Moolenaard68071d2006-05-02 22:08:30 +0000248 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.">")
Bram Moolenaarc7486e02005-12-29 22:48:26 +0000257
258 if fname =~ '/'
259 let dirpath = substitute(fname,'/[^/]\+$','','e')
260 if executable("cygpath")
261 let dirpath = substitute(system("cygpath ".dirpath),'\n','','e')
262 endif
Bram Moolenaar910f66f2006-04-05 20:41:53 +0000263" call Decho("mkdir(dirpath<".dirpath.">,p)")
Bram Moolenaarc7486e02005-12-29 22:48:26 +0000264 call mkdir(dirpath,"p")
265 endif
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000266 if zipfile !~ '/'
267 let zipfile= curdir.'/'.zipfile
268 endif
269" call Decho("zipfile<".zipfile."> fname<".fname.">")
270
Bram Moolenaar910f66f2006-04-05 20:41:53 +0000271 exe "w! ".escape(fname,s:zipfile_escape)
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000272 if executable("cygpath")
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000273 let zipfile = substitute(system("cygpath ".zipfile),'\n','','e')
274 endif
275
Bram Moolenaar9964e462007-05-05 17:54:07 +0000276 " 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))
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000283 if v:shell_error != 0
Bram Moolenaar9964e462007-05-05 17:54:07 +0000284 redraw!
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000285 echohl Error | echo "***error*** (zip#Write) sorry, unable to update ".zipfile." with ".fname | echohl None
Bram Moolenaar9964e462007-05-05 17:54:07 +0000286" call inputsave()|call input("Press <cr> to continue")|call inputrestore()
Bram Moolenaara5792f52005-11-23 21:25:05 +0000287
288 elseif s:zipfile_{winnr()} =~ '^\a\+://'
289 " support writing zipfiles across a network
290 let netzipfile= s:zipfile_{winnr()}
Bram Moolenaar9964e462007-05-05 17:54:07 +0000291" call Decho("handle writing <".zipfile."> across network as <".netzipfile.">")
Bram Moolenaara5792f52005-11-23 21:25:05 +0000292 1split|enew
293 let binkeep= &binary
294 let eikeep = &ei
295 set binary ei=all
Bram Moolenaar9964e462007-05-05 17:54:07 +0000296 exe "e! ".zipfile
Bram Moolenaara5792f52005-11-23 21:25:05 +0000297 call netrw#NetWrite(netzipfile)
298 let &ei = eikeep
299 let &binary = binkeep
300 q!
301 unlet s:zipfile_{winnr()}
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000302 endif
303
304 " cleanup and restore current directory
305 cd ..
306 call s:Rmdir("_ZIPVIM_")
Bram Moolenaar9964e462007-05-05 17:54:07 +0000307 call s:ChgDir(curdir,s:WARNING,"(zip#Write) unable to return to ".curdir."!")
308 call s:Rmdir(tmpdir)
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000309 setlocal nomod
310
Bram Moolenaar36c31f72005-11-28 23:01:53 +0000311 let &report= repkeep
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000312" call Dret("zip#Write")
313endfun
314
315" ---------------------------------------------------------------------
Bram Moolenaar9964e462007-05-05 17:54:07 +0000316" 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" ---------------------------------------------------------------------
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000355" Rmdir: {{{2
356fun! s:Rmdir(fname)
357" call Dfunc("Rmdir(fname<".a:fname.">)")
Bram Moolenaar9964e462007-05-05 17:54:07 +0000358 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))
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000362 endif
363" call Dret("Rmdir")
364endfun
365
366" ------------------------------------------------------------------------
367" Modelines And Restoration: {{{1
368let &cpo= s:keepcpo
369unlet s:keepcpo
Bram Moolenaar9964e462007-05-05 17:54:07 +0000370" vim:ts=8 fdm=marker