blob: 5875be0d93c4bde80898fc77cff003ae5dd07155 [file] [log] [blame]
Bram Moolenaar60a795a2005-09-16 21:55:43 +00001" zip.vim: Handles browsing zipfiles
2" AUTOLOAD PORTION
Bram Moolenaarccc18222007-05-10 18:25:20 +00003" Date: May 08, 2007
4" Version: 14
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 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 Moolenaarccc18222007-05-10 18:25:20 +000025let g:loaded_zip = "v14"
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 Moolenaarccc18222007-05-10 18:25:20 +000040if !exists("g:zip_zipcmd")
41 let g:zip_zipcmd= "zip"
42endif
43if !exists("g:zip_unzipcmd")
44 let g:zip_unzipcmd= "unzip"
45endif
Bram Moolenaar60a795a2005-09-16 21:55:43 +000046
47" ----------------
48" Functions: {{{1
49" ----------------
50
51" ---------------------------------------------------------------------
52" zip#Browse: {{{2
53fun! zip#Browse(zipfile)
54" call Dfunc("zip#Browse(zipfile<".a:zipfile.">)")
Bram Moolenaar36c31f72005-11-28 23:01:53 +000055 let repkeep= &report
56 set report=10
Bram Moolenaar60a795a2005-09-16 21:55:43 +000057
58 " sanity checks
Bram Moolenaarccc18222007-05-10 18:25:20 +000059 if !executable(g:zip_unzipcmd)
Bram Moolenaar9964e462007-05-05 17:54:07 +000060 redraw!
Bram Moolenaar60a795a2005-09-16 21:55:43 +000061 echohl Error | echo "***error*** (zip#Browse) unzip not available on your system"
Bram Moolenaar9964e462007-05-05 17:54:07 +000062" call inputsave()|call input("Press <cr> to continue")|call inputrestore()
Bram Moolenaar36c31f72005-11-28 23:01:53 +000063 let &report= repkeep
Bram Moolenaar60a795a2005-09-16 21:55:43 +000064" call Dret("zip#Browse")
65 return
66 endif
67 if !filereadable(a:zipfile)
Bram Moolenaara5792f52005-11-23 21:25:05 +000068 if a:zipfile !~# '^\a\+://'
69 " if its an url, don't complain, let url-handlers such as vim do its thing
Bram Moolenaar9964e462007-05-05 17:54:07 +000070 redraw!
Bram Moolenaara5792f52005-11-23 21:25:05 +000071 echohl Error | echo "***error*** (zip#Browse) File not readable<".a:zipfile.">" | echohl None
Bram Moolenaar9964e462007-05-05 17:54:07 +000072" call inputsave()|call input("Press <cr> to continue")|call inputrestore()
Bram Moolenaara5792f52005-11-23 21:25:05 +000073 endif
Bram Moolenaar36c31f72005-11-28 23:01:53 +000074 let &report= repkeep
Bram Moolenaara5792f52005-11-23 21:25:05 +000075" call Dret("zip#Browse : file<".a:zipfile."> not readable")
Bram Moolenaar60a795a2005-09-16 21:55:43 +000076 return
77 endif
Bram Moolenaardb552d602006-03-23 22:59:57 +000078" call Decho("passed sanity checks")
Bram Moolenaar60a795a2005-09-16 21:55:43 +000079 if &ma != 1
80 set ma
81 endif
Bram Moolenaarccc18222007-05-10 18:25:20 +000082 let b:zipfile= a:zipfile
Bram Moolenaar60a795a2005-09-16 21:55:43 +000083
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
Bram Moolenaarccc18222007-05-10 18:25:20 +000099" 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)
Bram Moolenaard68071d2006-05-02 22:08:30 +0000101 if v:shell_error != 0
Bram Moolenaar9964e462007-05-05 17:54:07 +0000102 redraw!
Bram Moolenaard68071d2006-05-02 22:08:30 +0000103 echohl WarningMsg | echo "***warning*** (zip#Browse) ".a:zipfile." is not a zip file" | echohl None
Bram Moolenaar9964e462007-05-05 17:54:07 +0000104" call inputsave()|call input("Press <cr> to continue")|call inputrestore()
Bram Moolenaard68071d2006-05-02 22:08:30 +0000105 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
Bram Moolenaar910f66f2006-04-05 20:41:53 +0000114" 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
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000119 $d
Bram Moolenaar4c3f5362006-04-11 21:38:50 +0000120 if namecol > 0
121 exe 'silent 4,$s/^.*\%'.namecol.'c//'
122 endif
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000123
124 setlocal noma nomod ro
125 noremap <silent> <buffer> <cr> :call <SID>ZipBrowseSelect()<cr>
126
Bram Moolenaar36c31f72005-11-28 23:01:53 +0000127 let &report= repkeep
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000128" call Dret("zip#Browse")
129endfun
130
131" ---------------------------------------------------------------------
132" ZipBrowseSelect: {{{2
133fun! s:ZipBrowseSelect()
Bram Moolenaarccc18222007-05-10 18:25:20 +0000134" call Dfunc("ZipBrowseSelect() zipfile<".b:zipfile."> curfile<".expand("%").">")
Bram Moolenaar36c31f72005-11-28 23:01:53 +0000135 let repkeep= &report
136 set report=10
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000137 let fname= getline(".")
138
139 " sanity check
140 if fname =~ '^"'
Bram Moolenaar36c31f72005-11-28 23:01:53 +0000141 let &report= repkeep
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000142" call Dret("ZipBrowseSelect")
143 return
144 endif
145 if fname =~ '/$'
Bram Moolenaar9964e462007-05-05 17:54:07 +0000146 redraw!
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000147 echohl Error | echo "***error*** (zip#Browse) Please specify a file, not a directory" | echohl None
Bram Moolenaar9964e462007-05-05 17:54:07 +0000148" call inputsave()|call input("Press <cr> to continue")|call inputrestore()
Bram Moolenaar36c31f72005-11-28 23:01:53 +0000149 let &report= repkeep
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000150" call Dret("ZipBrowseSelect")
151 return
152 endif
153
154" call Decho("fname<".fname.">")
155
156 " get zipfile to the new-window
Bram Moolenaarccc18222007-05-10 18:25:20 +0000157 let zipfile = b:zipfile
Bram Moolenaar910f66f2006-04-05 20:41:53 +0000158 let curfile= expand("%")
Bram Moolenaardb552d602006-03-23 22:59:57 +0000159" call Decho("zipfile<".zipfile.">")
160" call Decho("curfile<".curfile.">")
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000161
162 new
163 wincmd _
Bram Moolenaara5792f52005-11-23 21:25:05 +0000164 let s:zipfile_{winnr()}= curfile
Bram Moolenaard68071d2006-05-02 22:08:30 +0000165" 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)
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000167 filetype detect
168
Bram Moolenaar36c31f72005-11-28 23:01:53 +0000169 let &report= repkeep
Bram Moolenaara5792f52005-11-23 21:25:05 +0000170" call Dret("ZipBrowseSelect : s:zipfile_".winnr()."<".s:zipfile_{winnr()}.">")
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000171endfun
172
173" ---------------------------------------------------------------------
174" zip#Read: {{{2
175fun! zip#Read(fname,mode)
176" call Dfunc("zip#Read(fname<".a:fname.">,mode=".a:mode.")")
Bram Moolenaar36c31f72005-11-28 23:01:53 +0000177 let repkeep= &report
178 set report=10
179
Bram Moolenaard68071d2006-05-02 22:08:30 +0000180 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','')
Bram Moolenaar9964e462007-05-05 17:54:07 +0000186 let fname = substitute(fname, '[', '[[]', 'g')
Bram Moolenaard68071d2006-05-02 22:08:30 +0000187 endif
188" call Decho("zipfile<".zipfile.">")
189" call Decho("fname <".fname.">")
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000190
Bram Moolenaarccc18222007-05-10 18:25:20 +0000191" 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)
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000193
194 " cleanup
195 0d
196 set nomod
197
Bram Moolenaar36c31f72005-11-28 23:01:53 +0000198 let &report= repkeep
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000199" call Dret("zip#Read")
200endfun
201
202" ---------------------------------------------------------------------
203" zip#Write: {{{2
204fun! zip#Write(fname)
Bram Moolenaar910f66f2006-04-05 20:41:53 +0000205" call Dfunc("zip#Write(fname<".a:fname.">) zipfile_".winnr()."<".s:zipfile_{winnr()}.">")
Bram Moolenaar36c31f72005-11-28 23:01:53 +0000206 let repkeep= &report
207 set report=10
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000208
209 " sanity checks
Bram Moolenaarccc18222007-05-10 18:25:20 +0000210 if !executable(g:zip_zipcmd)
Bram Moolenaar9964e462007-05-05 17:54:07 +0000211 redraw!
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000212 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 +0000213" call inputsave()|call input("Press <cr> to continue")|call inputrestore()
Bram Moolenaar36c31f72005-11-28 23:01:53 +0000214 let &report= repkeep
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000215" call Dret("zip#Write")
216 return
217 endif
218 if !exists("*mkdir")
Bram Moolenaar9964e462007-05-05 17:54:07 +0000219 redraw!
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000220 echohl Error | echo "***error*** (zip#Write) sorry, mkdir() doesn't work on your system" | echohl None
Bram Moolenaar9964e462007-05-05 17:54:07 +0000221" call inputsave()|call input("Press <cr> to continue")|call inputrestore()
Bram Moolenaar36c31f72005-11-28 23:01:53 +0000222 let &report= repkeep
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000223" 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
Bram Moolenaar9964e462007-05-05 17:54:07 +0000237 if s:ChgDir(tmpdir,s:ERROR,"(zip#Write) cannot cd to temporary directory")
Bram Moolenaar36c31f72005-11-28 23:01:53 +0000238 let &report= repkeep
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000239" call Dret("zip#Write")
240 return
Bram Moolenaar9964e462007-05-05 17:54:07 +0000241 endif
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000242" 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
Bram Moolenaard68071d2006-05-02 22:08:30 +0000252 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.">")
Bram Moolenaarc7486e02005-12-29 22:48:26 +0000261
262 if fname =~ '/'
263 let dirpath = substitute(fname,'/[^/]\+$','','e')
264 if executable("cygpath")
265 let dirpath = substitute(system("cygpath ".dirpath),'\n','','e')
266 endif
Bram Moolenaar910f66f2006-04-05 20:41:53 +0000267" call Decho("mkdir(dirpath<".dirpath.">,p)")
Bram Moolenaarc7486e02005-12-29 22:48:26 +0000268 call mkdir(dirpath,"p")
269 endif
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000270 if zipfile !~ '/'
271 let zipfile= curdir.'/'.zipfile
272 endif
273" call Decho("zipfile<".zipfile."> fname<".fname.">")
274
Bram Moolenaar910f66f2006-04-05 20:41:53 +0000275 exe "w! ".escape(fname,s:zipfile_escape)
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000276 if executable("cygpath")
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000277 let zipfile = substitute(system("cygpath ".zipfile),'\n','','e')
278 endif
279
Bram Moolenaar9964e462007-05-05 17:54:07 +0000280 if (has("win32") || has("win95") || has("win64") || has("win16")) && &shell !~? 'sh$'
281 let fname = substitute(fname, '[', '[[]', 'g')
282 endif
283
Bram Moolenaarccc18222007-05-10 18:25:20 +0000284" 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))
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000286 if v:shell_error != 0
Bram Moolenaar9964e462007-05-05 17:54:07 +0000287 redraw!
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000288 echohl Error | echo "***error*** (zip#Write) sorry, unable to update ".zipfile." with ".fname | echohl None
Bram Moolenaar9964e462007-05-05 17:54:07 +0000289" call inputsave()|call input("Press <cr> to continue")|call inputrestore()
Bram Moolenaara5792f52005-11-23 21:25:05 +0000290
291 elseif s:zipfile_{winnr()} =~ '^\a\+://'
292 " support writing zipfiles across a network
293 let netzipfile= s:zipfile_{winnr()}
Bram Moolenaar9964e462007-05-05 17:54:07 +0000294" call Decho("handle writing <".zipfile."> across network as <".netzipfile.">")
Bram Moolenaara5792f52005-11-23 21:25:05 +0000295 1split|enew
296 let binkeep= &binary
297 let eikeep = &ei
298 set binary ei=all
Bram Moolenaar9964e462007-05-05 17:54:07 +0000299 exe "e! ".zipfile
Bram Moolenaara5792f52005-11-23 21:25:05 +0000300 call netrw#NetWrite(netzipfile)
301 let &ei = eikeep
302 let &binary = binkeep
303 q!
304 unlet s:zipfile_{winnr()}
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000305 endif
306
307 " cleanup and restore current directory
308 cd ..
309 call s:Rmdir("_ZIPVIM_")
Bram Moolenaar9964e462007-05-05 17:54:07 +0000310 call s:ChgDir(curdir,s:WARNING,"(zip#Write) unable to return to ".curdir."!")
311 call s:Rmdir(tmpdir)
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000312 setlocal nomod
313
Bram Moolenaar36c31f72005-11-28 23:01:53 +0000314 let &report= repkeep
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000315" call Dret("zip#Write")
316endfun
317
318" ---------------------------------------------------------------------
Bram Moolenaar9964e462007-05-05 17:54:07 +0000319" 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" ---------------------------------------------------------------------
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000358" Rmdir: {{{2
359fun! s:Rmdir(fname)
360" call Dfunc("Rmdir(fname<".a:fname.">)")
Bram Moolenaar9964e462007-05-05 17:54:07 +0000361 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))
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000365 endif
366" call Dret("Rmdir")
367endfun
368
369" ------------------------------------------------------------------------
370" Modelines And Restoration: {{{1
371let &cpo= s:keepcpo
372unlet s:keepcpo
Bram Moolenaarccc18222007-05-10 18:25:20 +0000373" vim:ts=8 fdm=marker