blob: b35a411d729ac831e6c93ec40e3abe29138eeec3 [file] [log] [blame]
Bram Moolenaar60a795a2005-09-16 21:55:43 +00001" zip.vim: Handles browsing zipfiles
2" AUTOLOAD PORTION
Bram Moolenaarc236c162008-07-13 17:41:49 +00003" Date: Jul 12, 2008
4" Version: 21 (modified by Bram)
Bram Moolenaar9964e462007-05-05 17:54:07 +00005" Maintainer: Charles E Campbell, Jr <NdrOchip@ScampbellPfamily.AbizM-NOSPAM>
6" License: Vim License (see vim's :help license)
Bram Moolenaar446cb832008-06-24 21:56:24 +00007" Copyright: Copyright (C) 2005-2008 Charles E. Campbell, Jr. {{{1
Bram Moolenaar60a795a2005-09-16 21:55:43 +00008" 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,
Bram Moolenaar446cb832008-06-24 21:56:24 +000011" 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
Bram Moolenaar60a795a2005-09-16 21:55:43 +000014" 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 Moolenaarc236c162008-07-13 17:41:49 +000025let g:loaded_zip = "v21+b"
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")
Bram Moolenaar446cb832008-06-24 21:56:24 +000034 if &shq != ""
35 let g:zip_shq= &shq
36 elseif has("unix")
Bram Moolenaar9964e462007-05-05 17:54:07 +000037 let g:zip_shq= "'"
38 else
39 let g:zip_shq= '"'
40 endif
41endif
Bram Moolenaarccc18222007-05-10 18:25:20 +000042if !exists("g:zip_zipcmd")
43 let g:zip_zipcmd= "zip"
44endif
45if !exists("g:zip_unzipcmd")
46 let g:zip_unzipcmd= "unzip"
47endif
Bram Moolenaar60a795a2005-09-16 21:55:43 +000048
49" ----------------
50" Functions: {{{1
51" ----------------
52
53" ---------------------------------------------------------------------
54" zip#Browse: {{{2
55fun! zip#Browse(zipfile)
56" call Dfunc("zip#Browse(zipfile<".a:zipfile.">)")
Bram Moolenaar36c31f72005-11-28 23:01:53 +000057 let repkeep= &report
58 set report=10
Bram Moolenaar60a795a2005-09-16 21:55:43 +000059
60 " sanity checks
Bram Moolenaarccc18222007-05-10 18:25:20 +000061 if !executable(g:zip_unzipcmd)
Bram Moolenaar9964e462007-05-05 17:54:07 +000062 redraw!
Bram Moolenaar60a795a2005-09-16 21:55:43 +000063 echohl Error | echo "***error*** (zip#Browse) unzip not available on your system"
Bram Moolenaar9964e462007-05-05 17:54:07 +000064" call inputsave()|call input("Press <cr> to continue")|call inputrestore()
Bram Moolenaar36c31f72005-11-28 23:01:53 +000065 let &report= repkeep
Bram Moolenaar60a795a2005-09-16 21:55:43 +000066" call Dret("zip#Browse")
67 return
68 endif
69 if !filereadable(a:zipfile)
Bram Moolenaara5792f52005-11-23 21:25:05 +000070 if a:zipfile !~# '^\a\+://'
71 " if its an url, don't complain, let url-handlers such as vim do its thing
Bram Moolenaar9964e462007-05-05 17:54:07 +000072 redraw!
Bram Moolenaara5792f52005-11-23 21:25:05 +000073 echohl Error | echo "***error*** (zip#Browse) File not readable<".a:zipfile.">" | echohl None
Bram Moolenaar9964e462007-05-05 17:54:07 +000074" call inputsave()|call input("Press <cr> to continue")|call inputrestore()
Bram Moolenaara5792f52005-11-23 21:25:05 +000075 endif
Bram Moolenaar36c31f72005-11-28 23:01:53 +000076 let &report= repkeep
Bram Moolenaara5792f52005-11-23 21:25:05 +000077" call Dret("zip#Browse : file<".a:zipfile."> not readable")
Bram Moolenaar60a795a2005-09-16 21:55:43 +000078 return
79 endif
Bram Moolenaardb552d602006-03-23 22:59:57 +000080" call Decho("passed sanity checks")
Bram Moolenaar60a795a2005-09-16 21:55:43 +000081 if &ma != 1
82 set ma
83 endif
Bram Moolenaarccc18222007-05-10 18:25:20 +000084 let b:zipfile= a:zipfile
Bram Moolenaar60a795a2005-09-16 21:55:43 +000085
86 setlocal noswapfile
87 setlocal buftype=nofile
88 setlocal bufhidden=hide
89 setlocal nobuflisted
90 setlocal nowrap
91 set ft=tar
92
93 " give header
Bram Moolenaarc236c162008-07-13 17:41:49 +000094 let lastline= line("$")
95 call setline(lastline+1,'" zip.vim version '.g:loaded_zip)
96 call setline(lastline+2,'" Browsing zipfile '.a:zipfile)
97 call setline(lastline+3,'" Select a file with cursor and press ENTER')
Bram Moolenaar60a795a2005-09-16 21:55:43 +000098 $put =''
99 0d
100 $
101
Bram Moolenaarc236c162008-07-13 17:41:49 +0000102" call Decho("exe silent r! ".g:zip_unzipcmd." -l ".s:Escape(a:zipfile,1))
103 exe "silent r! ".g:zip_unzipcmd." -l ".s:Escape(a:zipfile,1)
Bram Moolenaard68071d2006-05-02 22:08:30 +0000104 if v:shell_error != 0
Bram Moolenaar9964e462007-05-05 17:54:07 +0000105 redraw!
Bram Moolenaarc236c162008-07-13 17:41:49 +0000106 echohl WarningMsg | echo "***warning*** (zip#Browse) ".fnameescape(a:zipfile)." is not a zip file" | echohl None
Bram Moolenaar9964e462007-05-05 17:54:07 +0000107" call inputsave()|call input("Press <cr> to continue")|call inputrestore()
Bram Moolenaard68071d2006-05-02 22:08:30 +0000108 silent %d
109 let eikeep= &ei
110 set ei=BufReadCmd,FileReadCmd
Bram Moolenaarc236c162008-07-13 17:41:49 +0000111 exe "r ".fnameescape(a:zipfile)
Bram Moolenaard68071d2006-05-02 22:08:30 +0000112 let &ei= eikeep
113 1d
114" call Dret("zip#Browse")
115 return
116 endif
Bram Moolenaar910f66f2006-04-05 20:41:53 +0000117" call Decho("line 6: ".getline(6))
118 let namecol= stridx(getline(6),'Name') + 1
119" call Decho("namecol=".namecol)
120 4,$g/^\s*----/d
121 4,$g/^\s*\a/d
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000122 $d
Bram Moolenaar4c3f5362006-04-11 21:38:50 +0000123 if namecol > 0
124 exe 'silent 4,$s/^.*\%'.namecol.'c//'
125 endif
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000126
127 setlocal noma nomod ro
128 noremap <silent> <buffer> <cr> :call <SID>ZipBrowseSelect()<cr>
129
Bram Moolenaar36c31f72005-11-28 23:01:53 +0000130 let &report= repkeep
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000131" call Dret("zip#Browse")
132endfun
133
134" ---------------------------------------------------------------------
135" ZipBrowseSelect: {{{2
136fun! s:ZipBrowseSelect()
Bram Moolenaarccc18222007-05-10 18:25:20 +0000137" call Dfunc("ZipBrowseSelect() zipfile<".b:zipfile."> curfile<".expand("%").">")
Bram Moolenaar36c31f72005-11-28 23:01:53 +0000138 let repkeep= &report
139 set report=10
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000140 let fname= getline(".")
141
142 " sanity check
143 if fname =~ '^"'
Bram Moolenaar36c31f72005-11-28 23:01:53 +0000144 let &report= repkeep
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000145" call Dret("ZipBrowseSelect")
146 return
147 endif
148 if fname =~ '/$'
Bram Moolenaar9964e462007-05-05 17:54:07 +0000149 redraw!
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000150 echohl Error | echo "***error*** (zip#Browse) Please specify a file, not a directory" | echohl None
Bram Moolenaar9964e462007-05-05 17:54:07 +0000151" call inputsave()|call input("Press <cr> to continue")|call inputrestore()
Bram Moolenaar36c31f72005-11-28 23:01:53 +0000152 let &report= repkeep
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000153" call Dret("ZipBrowseSelect")
154 return
155 endif
156
157" call Decho("fname<".fname.">")
158
159 " get zipfile to the new-window
Bram Moolenaarccc18222007-05-10 18:25:20 +0000160 let zipfile = b:zipfile
Bram Moolenaar910f66f2006-04-05 20:41:53 +0000161 let curfile= expand("%")
Bram Moolenaardb552d602006-03-23 22:59:57 +0000162" call Decho("zipfile<".zipfile.">")
163" call Decho("curfile<".curfile.">")
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000164
165 new
Bram Moolenaar446cb832008-06-24 21:56:24 +0000166 if !exists("g:zip_nomax") || g:zip_nomax == 0
167 wincmd _
168 endif
Bram Moolenaara5792f52005-11-23 21:25:05 +0000169 let s:zipfile_{winnr()}= curfile
Bram Moolenaarc236c162008-07-13 17:41:49 +0000170" call Decho("exe e ".fnameescape("zipfile:".zipfile.'::'.fname))
171 exe "e ".fnameescape("zipfile:".zipfile.'::'.fname)
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000172 filetype detect
173
Bram Moolenaar36c31f72005-11-28 23:01:53 +0000174 let &report= repkeep
Bram Moolenaara5792f52005-11-23 21:25:05 +0000175" call Dret("ZipBrowseSelect : s:zipfile_".winnr()."<".s:zipfile_{winnr()}.">")
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000176endfun
177
178" ---------------------------------------------------------------------
179" zip#Read: {{{2
180fun! zip#Read(fname,mode)
181" call Dfunc("zip#Read(fname<".a:fname.">,mode=".a:mode.")")
Bram Moolenaar36c31f72005-11-28 23:01:53 +0000182 let repkeep= &report
183 set report=10
184
Bram Moolenaard68071d2006-05-02 22:08:30 +0000185 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','')
Bram Moolenaar9964e462007-05-05 17:54:07 +0000191 let fname = substitute(fname, '[', '[[]', 'g')
Bram Moolenaard68071d2006-05-02 22:08:30 +0000192 endif
193" call Decho("zipfile<".zipfile.">")
194" call Decho("fname <".fname.">")
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000195
Bram Moolenaarc236c162008-07-13 17:41:49 +0000196" call Decho("exe r! ".g:zip_unzipcmd." -p ".s:Escape(zipfile,1)." ".s:Escape(fname,1))
197 exe "silent r! ".g:zip_unzipcmd." -p ".s:Escape(zipfile,1)." ".s:Escape(fname,1)
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000198
199 " cleanup
200 0d
201 set nomod
202
Bram Moolenaar36c31f72005-11-28 23:01:53 +0000203 let &report= repkeep
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000204" call Dret("zip#Read")
205endfun
206
207" ---------------------------------------------------------------------
208" zip#Write: {{{2
209fun! zip#Write(fname)
Bram Moolenaar910f66f2006-04-05 20:41:53 +0000210" call Dfunc("zip#Write(fname<".a:fname.">) zipfile_".winnr()."<".s:zipfile_{winnr()}.">")
Bram Moolenaar36c31f72005-11-28 23:01:53 +0000211 let repkeep= &report
212 set report=10
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000213
214 " sanity checks
Bram Moolenaarccc18222007-05-10 18:25:20 +0000215 if !executable(g:zip_zipcmd)
Bram Moolenaar9964e462007-05-05 17:54:07 +0000216 redraw!
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000217 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 +0000218" call inputsave()|call input("Press <cr> to continue")|call inputrestore()
Bram Moolenaar36c31f72005-11-28 23:01:53 +0000219 let &report= repkeep
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000220" call Dret("zip#Write")
221 return
222 endif
223 if !exists("*mkdir")
Bram Moolenaar9964e462007-05-05 17:54:07 +0000224 redraw!
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000225 echohl Error | echo "***error*** (zip#Write) sorry, mkdir() doesn't work on your system" | echohl None
Bram Moolenaar9964e462007-05-05 17:54:07 +0000226" call inputsave()|call input("Press <cr> to continue")|call inputrestore()
Bram Moolenaar36c31f72005-11-28 23:01:53 +0000227 let &report= repkeep
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000228" call Dret("zip#Write")
229 return
230 endif
231
232 let curdir= getcwd()
233 let tmpdir= tempname()
234" call Decho("orig tempname<".tmpdir.">")
235 if tmpdir =~ '\.'
236 let tmpdir= substitute(tmpdir,'\.[^.]*$','','e')
237 endif
238" call Decho("tmpdir<".tmpdir.">")
239 call mkdir(tmpdir,"p")
240
241 " attempt to change to the indicated directory
Bram Moolenaar9964e462007-05-05 17:54:07 +0000242 if s:ChgDir(tmpdir,s:ERROR,"(zip#Write) cannot cd to temporary directory")
Bram Moolenaar36c31f72005-11-28 23:01:53 +0000243 let &report= repkeep
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000244" call Dret("zip#Write")
245 return
Bram Moolenaar9964e462007-05-05 17:54:07 +0000246 endif
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000247" call Decho("current directory now: ".getcwd())
248
249 " place temporary files under .../_ZIPVIM_/
250 if isdirectory("_ZIPVIM_")
251 call s:Rmdir("_ZIPVIM_")
252 endif
253 call mkdir("_ZIPVIM_")
254 cd _ZIPVIM_
255" call Decho("current directory now: ".getcwd())
256
Bram Moolenaard68071d2006-05-02 22:08:30 +0000257 if has("unix")
258 let zipfile = substitute(a:fname,'zipfile:\(.\{-}\)::[^\\].*$','\1','')
259 let fname = substitute(a:fname,'zipfile:.\{-}::\([^\\].*\)$','\1','')
260 else
261 let zipfile = substitute(a:fname,'^.\{-}zipfile:\(.\{-}\)::[^\\].*$','\1','')
262 let fname = substitute(a:fname,'^.\{-}zipfile:.\{-}::\([^\\].*\)$','\1','')
263 endif
264" call Decho("zipfile<".zipfile.">")
265" call Decho("fname <".fname.">")
Bram Moolenaarc7486e02005-12-29 22:48:26 +0000266
267 if fname =~ '/'
268 let dirpath = substitute(fname,'/[^/]\+$','','e')
269 if executable("cygpath")
Bram Moolenaarc236c162008-07-13 17:41:49 +0000270 let dirpath = substitute(system("cygpath ".s:Escape(dirpath,0)),'\n','','e')
Bram Moolenaarc7486e02005-12-29 22:48:26 +0000271 endif
Bram Moolenaar910f66f2006-04-05 20:41:53 +0000272" call Decho("mkdir(dirpath<".dirpath.">,p)")
Bram Moolenaarc7486e02005-12-29 22:48:26 +0000273 call mkdir(dirpath,"p")
274 endif
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000275 if zipfile !~ '/'
276 let zipfile= curdir.'/'.zipfile
277 endif
278" call Decho("zipfile<".zipfile."> fname<".fname.">")
279
Bram Moolenaarc236c162008-07-13 17:41:49 +0000280 exe "w! ".fnameescape(fname)
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000281 if executable("cygpath")
Bram Moolenaarc236c162008-07-13 17:41:49 +0000282 let zipfile = substitute(system("cygpath ".s:Escape(zipfile,0)),'\n','','e')
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000283 endif
284
Bram Moolenaar9964e462007-05-05 17:54:07 +0000285 if (has("win32") || has("win95") || has("win64") || has("win16")) && &shell !~? 'sh$'
286 let fname = substitute(fname, '[', '[[]', 'g')
287 endif
288
Bram Moolenaarc236c162008-07-13 17:41:49 +0000289" call Decho(g:zip_zipcmd." -u ".s:Escape(zipfile,0)." ".s:Escape(fname,0))
290 call system(g:zip_zipcmd." -u ".s:Escape(zipfile,0)." ".s:Escape(fname,0))
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000291 if v:shell_error != 0
Bram Moolenaar9964e462007-05-05 17:54:07 +0000292 redraw!
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000293 echohl Error | echo "***error*** (zip#Write) sorry, unable to update ".zipfile." with ".fname | echohl None
Bram Moolenaar9964e462007-05-05 17:54:07 +0000294" call inputsave()|call input("Press <cr> to continue")|call inputrestore()
Bram Moolenaara5792f52005-11-23 21:25:05 +0000295
296 elseif s:zipfile_{winnr()} =~ '^\a\+://'
297 " support writing zipfiles across a network
298 let netzipfile= s:zipfile_{winnr()}
Bram Moolenaar9964e462007-05-05 17:54:07 +0000299" call Decho("handle writing <".zipfile."> across network as <".netzipfile.">")
Bram Moolenaara5792f52005-11-23 21:25:05 +0000300 1split|enew
301 let binkeep= &binary
302 let eikeep = &ei
303 set binary ei=all
Bram Moolenaarc236c162008-07-13 17:41:49 +0000304 exe "e! ".fnameescape(zipfile)
Bram Moolenaara5792f52005-11-23 21:25:05 +0000305 call netrw#NetWrite(netzipfile)
306 let &ei = eikeep
307 let &binary = binkeep
308 q!
309 unlet s:zipfile_{winnr()}
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000310 endif
311
312 " cleanup and restore current directory
313 cd ..
314 call s:Rmdir("_ZIPVIM_")
Bram Moolenaar9964e462007-05-05 17:54:07 +0000315 call s:ChgDir(curdir,s:WARNING,"(zip#Write) unable to return to ".curdir."!")
316 call s:Rmdir(tmpdir)
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000317 setlocal nomod
318
Bram Moolenaar36c31f72005-11-28 23:01:53 +0000319 let &report= repkeep
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000320" call Dret("zip#Write")
321endfun
322
323" ---------------------------------------------------------------------
Bram Moolenaarc236c162008-07-13 17:41:49 +0000324" s:Escape: {{{2
325fun! s:Escape(fname,isfilt)
326" call Dfunc("QuoteFileDir(fname<".a:fname."> isfilt=".a:isfilt.")")
327 if exists("*shellescape")
328 if a:isfilt
329 let qnameq= shellescape(a:fname,1)
330 else
331 let qnameq= shellescape(a:fname)
332 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +0000333 else
334 let qnameq= g:zip_shq.escape(a:fname,g:zip_shq).g:zip_shq
335 endif
336" call Dret("QuoteFileDir <".qnameq.">")
337 return qnameq
Bram Moolenaar9964e462007-05-05 17:54:07 +0000338endfun
339
340" ---------------------------------------------------------------------
341" ChgDir: {{{2
342fun! s:ChgDir(newdir,errlvl,errmsg)
343" call Dfunc("ChgDir(newdir<".a:newdir."> errlvl=".a:errlvl." errmsg<".a:errmsg.">)")
344
Bram Moolenaar9964e462007-05-05 17:54:07 +0000345
346 try
Bram Moolenaarc236c162008-07-13 17:41:49 +0000347 exe "cd ".fnameescape(newdir)
Bram Moolenaar9964e462007-05-05 17:54:07 +0000348 catch /^Vim\%((\a\+)\)\=:E344/
349 redraw!
350 if a:errlvl == s:NOTE
351 echo "***note*** ".a:errmsg
352 elseif a:errlvl == s:WARNING
353 echohl WarningMsg | echo "***warning*** ".a:errmsg | echohl NONE
354 elseif a:errlvl == s:ERROR
355 echohl Error | echo "***error*** ".a:errmsg | echohl NONE
356 endif
357" call inputsave()|call input("Press <cr> to continue")|call inputrestore()
358" call Dret("ChgDir 1")
359 return 1
360 endtry
361
362" call Dret("ChgDir 0")
363 return 0
364endfun
365
366" ---------------------------------------------------------------------
Bram Moolenaarc236c162008-07-13 17:41:49 +0000367" s:Rmdir: {{{2
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000368fun! s:Rmdir(fname)
369" call Dfunc("Rmdir(fname<".a:fname.">)")
Bram Moolenaar9964e462007-05-05 17:54:07 +0000370 if (has("win32") || has("win95") || has("win64") || has("win16")) && &shell !~? 'sh$'
Bram Moolenaarc236c162008-07-13 17:41:49 +0000371 call system("rmdir /S/Q ".s:Escape(a:fname,0))
Bram Moolenaar9964e462007-05-05 17:54:07 +0000372 else
Bram Moolenaarc236c162008-07-13 17:41:49 +0000373 call system("/bin/rm -rf ".s:Escape(a:fname,0))
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000374 endif
375" call Dret("Rmdir")
376endfun
377
378" ------------------------------------------------------------------------
379" Modelines And Restoration: {{{1
380let &cpo= s:keepcpo
381unlet s:keepcpo
Bram Moolenaarccc18222007-05-10 18:25:20 +0000382" vim:ts=8 fdm=marker