xref: /vim-8.2.3635/runtime/autoload/zip.vim (revision 3577c6fa)
1" zip.vim: Handles browsing zipfiles
2"            AUTOLOAD PORTION
3" Date:		May 08, 2007
4" Version:	14
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     = "v14"
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
40if !exists("g:zip_zipcmd")
41 let g:zip_zipcmd= "zip"
42endif
43if !exists("g:zip_unzipcmd")
44 let g:zip_unzipcmd= "unzip"
45endif
46
47" ----------------
48"  Functions: {{{1
49" ----------------
50
51" ---------------------------------------------------------------------
52" zip#Browse: {{{2
53fun! zip#Browse(zipfile)
54"  call Dfunc("zip#Browse(zipfile<".a:zipfile.">)")
55  let repkeep= &report
56  set report=10
57
58  " sanity checks
59  if !executable(g:zip_unzipcmd)
60   redraw!
61   echohl Error | echo "***error*** (zip#Browse) unzip not available on your system"
62"   call inputsave()|call input("Press <cr> to continue")|call inputrestore()
63   let &report= repkeep
64"   call Dret("zip#Browse")
65   return
66  endif
67  if !filereadable(a:zipfile)
68   if a:zipfile !~# '^\a\+://'
69    " if its an url, don't complain, let url-handlers such as vim do its thing
70    redraw!
71    echohl Error | echo "***error*** (zip#Browse) File not readable<".a:zipfile.">" | echohl None
72"    call inputsave()|call input("Press <cr> to continue")|call inputrestore()
73   endif
74   let &report= repkeep
75"   call Dret("zip#Browse : file<".a:zipfile."> not readable")
76   return
77  endif
78"  call Decho("passed sanity checks")
79  if &ma != 1
80   set ma
81  endif
82  let b:zipfile= a:zipfile
83
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
99"  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)
101  if v:shell_error != 0
102   redraw!
103   echohl WarningMsg | echo "***warning*** (zip#Browse) ".a:zipfile." is not a zip file" | echohl None
104"   call inputsave()|call input("Press <cr> to continue")|call inputrestore()
105   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
114"  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
119  $d
120  if namecol > 0
121   exe 'silent 4,$s/^.*\%'.namecol.'c//'
122  endif
123
124  setlocal noma nomod ro
125  noremap <silent> <buffer> <cr> :call <SID>ZipBrowseSelect()<cr>
126
127  let &report= repkeep
128"  call Dret("zip#Browse")
129endfun
130
131" ---------------------------------------------------------------------
132" ZipBrowseSelect: {{{2
133fun! s:ZipBrowseSelect()
134"  call Dfunc("ZipBrowseSelect() zipfile<".b:zipfile."> curfile<".expand("%").">")
135  let repkeep= &report
136  set report=10
137  let fname= getline(".")
138
139  " sanity check
140  if fname =~ '^"'
141   let &report= repkeep
142"   call Dret("ZipBrowseSelect")
143   return
144  endif
145  if fname =~ '/$'
146   redraw!
147   echohl Error | echo "***error*** (zip#Browse) Please specify a file, not a directory" | echohl None
148"   call inputsave()|call input("Press <cr> to continue")|call inputrestore()
149   let &report= repkeep
150"   call Dret("ZipBrowseSelect")
151   return
152  endif
153
154"  call Decho("fname<".fname.">")
155
156  " get zipfile to the new-window
157  let zipfile = b:zipfile
158  let curfile= expand("%")
159"  call Decho("zipfile<".zipfile.">")
160"  call Decho("curfile<".curfile.">")
161
162  new
163  wincmd _
164  let s:zipfile_{winnr()}= curfile
165"  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)
167  filetype detect
168
169  let &report= repkeep
170"  call Dret("ZipBrowseSelect : s:zipfile_".winnr()."<".s:zipfile_{winnr()}.">")
171endfun
172
173" ---------------------------------------------------------------------
174" zip#Read: {{{2
175fun! zip#Read(fname,mode)
176"  call Dfunc("zip#Read(fname<".a:fname.">,mode=".a:mode.")")
177  let repkeep= &report
178  set report=10
179
180  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','')
186   let fname = substitute(fname, '[', '[[]', 'g')
187  endif
188"  call Decho("zipfile<".zipfile.">")
189"  call Decho("fname  <".fname.">")
190
191"  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)
193
194  " cleanup
195  0d
196  set nomod
197
198  let &report= repkeep
199"  call Dret("zip#Read")
200endfun
201
202" ---------------------------------------------------------------------
203" zip#Write: {{{2
204fun! zip#Write(fname)
205"  call Dfunc("zip#Write(fname<".a:fname.">) zipfile_".winnr()."<".s:zipfile_{winnr()}.">")
206  let repkeep= &report
207  set report=10
208
209  " sanity checks
210  if !executable(g:zip_zipcmd)
211   redraw!
212   echohl Error | echo "***error*** (zip#Write) sorry, your system doesn't appear to have the zip pgm" | echohl None
213"   call inputsave()|call input("Press <cr> to continue")|call inputrestore()
214   let &report= repkeep
215"   call Dret("zip#Write")
216   return
217  endif
218  if !exists("*mkdir")
219   redraw!
220   echohl Error | echo "***error*** (zip#Write) sorry, mkdir() doesn't work on your system" | echohl None
221"   call inputsave()|call input("Press <cr> to continue")|call inputrestore()
222   let &report= repkeep
223"   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
237  if s:ChgDir(tmpdir,s:ERROR,"(zip#Write) cannot cd to temporary directory")
238   let &report= repkeep
239"   call Dret("zip#Write")
240   return
241  endif
242"  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
252  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.">")
261
262  if fname =~ '/'
263   let dirpath = substitute(fname,'/[^/]\+$','','e')
264   if executable("cygpath")
265    let dirpath = substitute(system("cygpath ".dirpath),'\n','','e')
266   endif
267"   call Decho("mkdir(dirpath<".dirpath.">,p)")
268   call mkdir(dirpath,"p")
269  endif
270  if zipfile !~ '/'
271   let zipfile= curdir.'/'.zipfile
272  endif
273"  call Decho("zipfile<".zipfile."> fname<".fname.">")
274
275  exe "w! ".escape(fname,s:zipfile_escape)
276  if executable("cygpath")
277   let zipfile = substitute(system("cygpath ".zipfile),'\n','','e')
278  endif
279
280  if (has("win32") || has("win95") || has("win64") || has("win16")) && &shell !~? 'sh$'
281    let fname = substitute(fname, '[', '[[]', 'g')
282  endif
283
284"  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))
286  if v:shell_error != 0
287   redraw!
288   echohl Error | echo "***error*** (zip#Write) sorry, unable to update ".zipfile." with ".fname | echohl None
289"   call inputsave()|call input("Press <cr> to continue")|call inputrestore()
290
291  elseif s:zipfile_{winnr()} =~ '^\a\+://'
292   " support writing zipfiles across a network
293   let netzipfile= s:zipfile_{winnr()}
294"   call Decho("handle writing <".zipfile."> across network as <".netzipfile.">")
295   1split|enew
296   let binkeep= &binary
297   let eikeep = &ei
298   set binary ei=all
299   exe "e! ".zipfile
300   call netrw#NetWrite(netzipfile)
301   let &ei     = eikeep
302   let &binary = binkeep
303   q!
304   unlet s:zipfile_{winnr()}
305  endif
306
307  " cleanup and restore current directory
308  cd ..
309  call s:Rmdir("_ZIPVIM_")
310  call s:ChgDir(curdir,s:WARNING,"(zip#Write) unable to return to ".curdir."!")
311  call s:Rmdir(tmpdir)
312  setlocal nomod
313
314  let &report= repkeep
315"  call Dret("zip#Write")
316endfun
317
318" ---------------------------------------------------------------------
319" 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" ---------------------------------------------------------------------
358" Rmdir: {{{2
359fun! s:Rmdir(fname)
360"  call Dfunc("Rmdir(fname<".a:fname.">)")
361  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))
365  endif
366"  call Dret("Rmdir")
367endfun
368
369" ------------------------------------------------------------------------
370" Modelines And Restoration: {{{1
371let &cpo= s:keepcpo
372unlet s:keepcpo
373" vim:ts=8 fdm=marker
374