xref: /vim-8.2.3635/runtime/autoload/zip.vim (revision ff034194)
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