xref: /vim-8.2.3635/runtime/autoload/zip.vim (revision 044b68f4)
1" zip.vim: Handles browsing zipfiles
2"            AUTOLOAD PORTION
3" Date:		Sep 29, 2006
4" Version:	12
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     = "v12"
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
40
41" ----------------
42"  Functions: {{{1
43" ----------------
44
45" ---------------------------------------------------------------------
46" zip#Browse: {{{2
47fun! zip#Browse(zipfile)
48"  call Dfunc("zip#Browse(zipfile<".a:zipfile.">)")
49  let repkeep= &report
50  set report=10
51
52  " sanity checks
53  if !executable("unzip")
54   redraw!
55   echohl Error | echo "***error*** (zip#Browse) unzip not available on your system"
56"   call inputsave()|call input("Press <cr> to continue")|call inputrestore()
57   let &report= repkeep
58"   call Dret("zip#Browse")
59   return
60  endif
61  if !filereadable(a:zipfile)
62   if a:zipfile !~# '^\a\+://'
63    " if its an url, don't complain, let url-handlers such as vim do its thing
64    redraw!
65    echohl Error | echo "***error*** (zip#Browse) File not readable<".a:zipfile.">" | echohl None
66"    call inputsave()|call input("Press <cr> to continue")|call inputrestore()
67   endif
68   let &report= repkeep
69"   call Dret("zip#Browse : file<".a:zipfile."> not readable")
70   return
71  endif
72"  call Decho("passed sanity checks")
73  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
93"  call Decho("exe silent r! unzip -l ".s:QuoteFileDir(a:zipfile))
94  exe "silent r! unzip -l ".s:QuoteFileDir(a:zipfile)
95  if v:shell_error != 0
96   redraw!
97   echohl WarningMsg | echo "***warning*** (zip#Browse) ".a:zipfile." is not a zip file" | echohl None
98"   call inputsave()|call input("Press <cr> to continue")|call inputrestore()
99   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
108"  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
113  $d
114  if namecol > 0
115   exe 'silent 4,$s/^.*\%'.namecol.'c//'
116  endif
117
118  setlocal noma nomod ro
119  noremap <silent> <buffer> <cr> :call <SID>ZipBrowseSelect()<cr>
120
121  let &report= repkeep
122"  call Dret("zip#Browse")
123endfun
124
125" ---------------------------------------------------------------------
126" ZipBrowseSelect: {{{2
127fun! s:ZipBrowseSelect()
128"  call Dfunc("ZipBrowseSelect() zipfile<".w:zipfile."> curfile<".expand("%").">")
129  let repkeep= &report
130  set report=10
131  let fname= getline(".")
132
133  " sanity check
134  if fname =~ '^"'
135   let &report= repkeep
136"   call Dret("ZipBrowseSelect")
137   return
138  endif
139  if fname =~ '/$'
140   redraw!
141   echohl Error | echo "***error*** (zip#Browse) Please specify a file, not a directory" | echohl None
142"   call inputsave()|call input("Press <cr> to continue")|call inputrestore()
143   let &report= repkeep
144"   call Dret("ZipBrowseSelect")
145   return
146  endif
147
148"  call Decho("fname<".fname.">")
149
150  " get zipfile to the new-window
151  let zipfile = w:zipfile
152  let curfile= expand("%")
153"  call Decho("zipfile<".zipfile.">")
154"  call Decho("curfile<".curfile.">")
155
156  new
157  wincmd _
158  let s:zipfile_{winnr()}= curfile
159"  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)
161  filetype detect
162
163  let &report= repkeep
164"  call Dret("ZipBrowseSelect : s:zipfile_".winnr()."<".s:zipfile_{winnr()}.">")
165endfun
166
167" ---------------------------------------------------------------------
168" zip#Read: {{{2
169fun! zip#Read(fname,mode)
170"  call Dfunc("zip#Read(fname<".a:fname.">,mode=".a:mode.")")
171  let repkeep= &report
172  set report=10
173
174  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','')
180
181   " TODO Needs to predicated to using InfoZIP's unzip on Windows
182   let fname = substitute(fname, '[', '[[]', 'g')
183  endif
184"  call Decho("zipfile<".zipfile.">")
185"  call Decho("fname  <".fname.">")
186
187"  call Decho("exe r! unzip -p ".s:QuoteFileDir(zipfile)." ".s:QuoteFileDir(fname))
188  exe "silent r! unzip -p ".s:QuoteFileDir(zipfile)." ".s:QuoteFileDir(fname)
189
190  " cleanup
191  0d
192  set nomod
193
194  let &report= repkeep
195"  call Dret("zip#Read")
196endfun
197
198" ---------------------------------------------------------------------
199" zip#Write: {{{2
200fun! zip#Write(fname)
201"  call Dfunc("zip#Write(fname<".a:fname.">) zipfile_".winnr()."<".s:zipfile_{winnr()}.">")
202  let repkeep= &report
203  set report=10
204
205  " sanity checks
206  if !executable("zip")
207   redraw!
208   echohl Error | echo "***error*** (zip#Write) sorry, your system doesn't appear to have the zip pgm" | echohl None
209"   call inputsave()|call input("Press <cr> to continue")|call inputrestore()
210   let &report= repkeep
211"   call Dret("zip#Write")
212   return
213  endif
214  if !exists("*mkdir")
215   redraw!
216   echohl Error | echo "***error*** (zip#Write) sorry, mkdir() doesn't work on your system" | echohl None
217"   call inputsave()|call input("Press <cr> to continue")|call inputrestore()
218   let &report= repkeep
219"   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
233  if s:ChgDir(tmpdir,s:ERROR,"(zip#Write) cannot cd to temporary directory")
234   let &report= repkeep
235"   call Dret("zip#Write")
236   return
237  endif
238"  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
248  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.">")
257
258  if fname =~ '/'
259   let dirpath = substitute(fname,'/[^/]\+$','','e')
260   if executable("cygpath")
261    let dirpath = substitute(system("cygpath ".dirpath),'\n','','e')
262   endif
263"   call Decho("mkdir(dirpath<".dirpath.">,p)")
264   call mkdir(dirpath,"p")
265  endif
266  if zipfile !~ '/'
267   let zipfile= curdir.'/'.zipfile
268  endif
269"  call Decho("zipfile<".zipfile."> fname<".fname.">")
270
271  exe "w! ".escape(fname,s:zipfile_escape)
272  if executable("cygpath")
273   let zipfile = substitute(system("cygpath ".zipfile),'\n','','e')
274  endif
275
276  " 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))
283  if v:shell_error != 0
284   redraw!
285   echohl Error | echo "***error*** (zip#Write) sorry, unable to update ".zipfile." with ".fname | echohl None
286"   call inputsave()|call input("Press <cr> to continue")|call inputrestore()
287
288  elseif s:zipfile_{winnr()} =~ '^\a\+://'
289   " support writing zipfiles across a network
290   let netzipfile= s:zipfile_{winnr()}
291"   call Decho("handle writing <".zipfile."> across network as <".netzipfile.">")
292   1split|enew
293   let binkeep= &binary
294   let eikeep = &ei
295   set binary ei=all
296   exe "e! ".zipfile
297   call netrw#NetWrite(netzipfile)
298   let &ei     = eikeep
299   let &binary = binkeep
300   q!
301   unlet s:zipfile_{winnr()}
302  endif
303
304  " cleanup and restore current directory
305  cd ..
306  call s:Rmdir("_ZIPVIM_")
307  call s:ChgDir(curdir,s:WARNING,"(zip#Write) unable to return to ".curdir."!")
308  call s:Rmdir(tmpdir)
309  setlocal nomod
310
311  let &report= repkeep
312"  call Dret("zip#Write")
313endfun
314
315" ---------------------------------------------------------------------
316" 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" ---------------------------------------------------------------------
355" Rmdir: {{{2
356fun! s:Rmdir(fname)
357"  call Dfunc("Rmdir(fname<".a:fname.">)")
358  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))
362  endif
363"  call Dret("Rmdir")
364endfun
365
366" ------------------------------------------------------------------------
367" Modelines And Restoration: {{{1
368let &cpo= s:keepcpo
369unlet s:keepcpo
370"  vim:ts=8 fdm=marker
371