xref: /vim-8.2.3635/runtime/autoload/tar.vim (revision a0122dcd)
1" tar.vim: Handles browsing tarfiles
2"            AUTOLOAD PORTION
3" Date:		Jan 07, 2020
4" Version:	32
5" Maintainer:	Charles E Campbell <[email protected]>
6" License:	Vim License  (see vim's :help license)
7"
8"	Contains many ideas from Michael Toren's <tar.vim>
9"
10" Copyright:    Copyright (C) 2005-2017 Charles E. Campbell {{{1
11"               Permission is hereby granted to use and distribute this code,
12"               with or without modifications, provided that this copyright
13"               notice is copied with it. Like anything else that's free,
14"               tar.vim and tarPlugin.vim are provided *as is* and comes
15"               with no warranty of any kind, either expressed or implied.
16"               By using this plugin, you agree that in no event will the
17"               copyright holder be liable for any damages resulting from
18"               the use of this software.
19"     call inputsave()|call input("Press <cr> to continue")|call inputrestore()
20" ---------------------------------------------------------------------
21" Load Once: {{{1
22if &cp || exists("g:loaded_tar")
23 finish
24endif
25let g:loaded_tar= "v32"
26if v:version < 702
27 echohl WarningMsg
28 echo "***warning*** this version of tar needs vim 7.2"
29 echohl Normal
30 finish
31endif
32let s:keepcpo= &cpo
33set cpo&vim
34"DechoTabOn
35"call Decho("loading autoload/tar.vim")
36
37" ---------------------------------------------------------------------
38"  Default Settings: {{{1
39if !exists("g:tar_browseoptions")
40 let g:tar_browseoptions= "Ptf"
41endif
42if !exists("g:tar_readoptions")
43 let g:tar_readoptions= "OPxf"
44endif
45if !exists("g:tar_cmd")
46 let g:tar_cmd= "tar"
47endif
48if !exists("g:tar_writeoptions")
49 let g:tar_writeoptions= "uf"
50endif
51if !exists("g:tar_delfile")
52 let g:tar_delfile="--delete -f"
53endif
54if !exists("g:netrw_cygwin")
55 if has("win32") || has("win95") || has("win64") || has("win16")
56  if &shell =~ '\%(\<bash\>\|\<zsh\>\)\%(\.exe\)\=$'
57   let g:netrw_cygwin= 1
58  else
59   let g:netrw_cygwin= 0
60  endif
61 else
62  let g:netrw_cygwin= 0
63 endif
64endif
65if !exists("g:tar_copycmd")
66 if !exists("g:netrw_localcopycmd")
67  if has("win32") || has("win95") || has("win64") || has("win16")
68   if g:netrw_cygwin
69    let g:netrw_localcopycmd= "cp"
70   else
71    let g:netrw_localcopycmd= "copy"
72   endif
73  elseif has("unix") || has("macunix")
74   let g:netrw_localcopycmd= "cp"
75  else
76   let g:netrw_localcopycmd= ""
77  endif
78 endif
79 let g:tar_copycmd= g:netrw_localcopycmd
80endif
81if !exists("g:tar_extractcmd")
82 let g:tar_extractcmd= "tar -xf"
83endif
84
85" set up shell quoting character
86if !exists("g:tar_shq")
87 if exists("+shq") && exists("&shq") && &shq != ""
88  let g:tar_shq= &shq
89 elseif has("win32") || has("win95") || has("win64") || has("win16")
90  if exists("g:netrw_cygwin") && g:netrw_cygwin
91   let g:tar_shq= "'"
92  else
93   let g:tar_shq= '"'
94  endif
95 else
96  let g:tar_shq= "'"
97 endif
98" call Decho("g:tar_shq<".g:tar_shq.">")
99endif
100
101" ----------------
102"  Functions: {{{1
103" ----------------
104
105" ---------------------------------------------------------------------
106" tar#Browse: {{{2
107fun! tar#Browse(tarfile)
108"  call Dfunc("tar#Browse(tarfile<".a:tarfile.">)")
109  let repkeep= &report
110  set report=10
111
112  " sanity checks
113  if !executable(g:tar_cmd)
114   redraw!
115"   call Decho('***error*** (tar#Browse) "'.g:tar_cmd.'" not available on your system')
116   echohl Error | echo '***error*** (tar#Browse) "'.g:tar_cmd.'" not available on your system'
117   let &report= repkeep
118"   call Dret("tar#Browse")
119   return
120  endif
121  if !filereadable(a:tarfile)
122"   call Decho('a:tarfile<'.a:tarfile.'> not filereadable')
123   if a:tarfile !~# '^\a\+://'
124    " if it's an url, don't complain, let url-handlers such as vim do its thing
125    redraw!
126"    call Decho("***error*** (tar#Browse) File not readable<".a:tarfile.">")
127    echohl Error | echo "***error*** (tar#Browse) File not readable<".a:tarfile.">" | echohl None
128   endif
129   let &report= repkeep
130"   call Dret("tar#Browse : file<".a:tarfile."> not readable")
131   return
132  endif
133  if &ma != 1
134   set ma
135  endif
136  let b:tarfile= a:tarfile
137
138  setlocal noswapfile
139  setlocal buftype=nofile
140  setlocal bufhidden=hide
141  setlocal nobuflisted
142  setlocal nowrap
143  set ft=tar
144
145  " give header
146"  call Decho("printing header")
147  let lastline= line("$")
148  call setline(lastline+1,'" tar.vim version '.g:loaded_tar)
149  call setline(lastline+2,'" Browsing tarfile '.a:tarfile)
150  call setline(lastline+3,'" Select a file with cursor and press ENTER')
151  keepj $put =''
152  keepj sil! 0d
153  keepj $
154
155  let tarfile= a:tarfile
156  if has("win32unix") && executable("cygpath")
157   " assuming cygwin
158   let tarfile=substitute(system("cygpath -u ".shellescape(tarfile,0)),'\n$','','e')
159  endif
160  let curlast= line("$")
161
162  if tarfile =~# '\.\(gz\)$'
163"   call Decho("1: exe silent r! gzip -d -c -- ".shellescape(tarfile,1)." | ".g:tar_cmd." -".g:tar_browseoptions." - ")
164   exe "sil! r! gzip -d -c -- ".shellescape(tarfile,1)." | ".g:tar_cmd." -".g:tar_browseoptions." - "
165
166  elseif tarfile =~# '\.\(tgz\)$' || tarfile =~# '\.\(tbz\)$' || tarfile =~# '\.\(txz\)$' || tarfile =~# '\.\(tzs\)$'
167   if has("unix") && executable("file")
168    let filekind= system("file ".shellescape(tarfile,1)) =~ "bzip2"
169   else
170    let filekind= ""
171   endif
172
173   if filekind =~ "bzip2"
174    exe "sil! r! bzip2 -d -c -- ".shellescape(tarfile,1)." | ".g:tar_cmd." -".g:tar_browseoptions." - "
175   elseif filekind =~ "XZ"
176    exe "sil! r! xz -d -c -- ".shellescape(tarfile,1)." | ".g:tar_cmd." -".g:tar_browseoptions." - "
177   elseif filekind =~ "Zstandard"
178    exe "sil! r! zstd --decompress --stdout -- ".shellescape(tarfile,1)." | ".g:tar_cmd." -".g:tar_browseoptions." - "
179   else
180    exe "sil! r! gzip -d -c -- ".shellescape(tarfile,1)." | ".g:tar_cmd." -".g:tar_browseoptions." - "
181   endif
182
183  elseif tarfile =~# '\.lrp'
184"   call Decho("2: exe silent r! cat -- ".shellescape(tarfile,1)."|gzip -d -c -|".g:tar_cmd." -".g:tar_browseoptions." - ")
185   exe "sil! r! cat -- ".shellescape(tarfile,1)."|gzip -d -c -|".g:tar_cmd." -".g:tar_browseoptions." - "
186  elseif tarfile =~# '\.\(bz2\|tbz\|tb2\)$'
187"   call Decho("3: exe silent r! bzip2 -d -c -- ".shellescape(tarfile,1)." | ".g:tar_cmd." -".g:tar_browseoptions." - ")
188   exe "sil! r! bzip2 -d -c -- ".shellescape(tarfile,1)." | ".g:tar_cmd." -".g:tar_browseoptions." - "
189  elseif tarfile =~# '\.\(lzma\|tlz\)$'
190"   call Decho("3: exe silent r! lzma -d -c -- ".shellescape(tarfile,1)." | ".g:tar_cmd." -".g:tar_browseoptions." - ")
191   exe "sil! r! lzma -d -c -- ".shellescape(tarfile,1)." | ".g:tar_cmd." -".g:tar_browseoptions." - "
192  elseif tarfile =~# '\.\(xz\|txz\)$'
193"   call Decho("3: exe silent r! xz --decompress --stdout -- ".shellescape(tarfile,1)." | ".g:tar_cmd." -".g:tar_browseoptions." - ")
194   exe "sil! r! xz --decompress --stdout -- ".shellescape(tarfile,1)." | ".g:tar_cmd." -".g:tar_browseoptions." - "
195  elseif tarfile =~# '\.\(zst\|tzs\)$'
196   exe "sil! r! zstd --decompress --stdout -- ".shellescape(tarfile,1)." | ".g:tar_cmd." -".g:tar_browseoptions." - "
197  else
198   if tarfile =~ '^\s*-'
199    " A file name starting with a dash is taken as an option.  Prepend ./ to avoid that.
200    let tarfile = substitute(tarfile, '-', './-', '')
201   endif
202"   call Decho("4: exe silent r! ".g:tar_cmd." -".g:tar_browseoptions." ".shellescape(tarfile,0))
203   exe "sil! r! ".g:tar_cmd." -".g:tar_browseoptions." ".shellescape(tarfile,1)
204  endif
205  if v:shell_error != 0
206   redraw!
207   echohl WarningMsg | echo "***warning*** (tar#Browse) please check your g:tar_browseoptions<".g:tar_browseoptions.">"
208"   call Dret("tar#Browse : a:tarfile<".a:tarfile.">")
209   return
210  endif
211  if line("$") == curlast || ( line("$") == (curlast + 1) && getline("$") =~# '\c\%(warning\|error\|inappropriate\|unrecognized\)')
212   redraw!
213   echohl WarningMsg | echo "***warning*** (tar#Browse) ".a:tarfile." doesn't appear to be a tar file" | echohl None
214   keepj sil! %d
215   let eikeep= &ei
216   set ei=BufReadCmd,FileReadCmd
217   exe "r ".fnameescape(a:tarfile)
218   let &ei= eikeep
219   keepj sil! 1d
220"   call Dret("tar#Browse : a:tarfile<".a:tarfile.">")
221   return
222  endif
223
224  " set up maps supported for tar
225  setlocal noma nomod ro
226  noremap <silent> <buffer>	<cr>		:call <SID>TarBrowseSelect()<cr>
227  noremap <silent> <buffer>	x	 	:call tar#Extract()<cr>
228  if &mouse != ""
229   noremap <silent> <buffer>	<leftmouse>	<leftmouse>:call <SID>TarBrowseSelect()<cr>
230  endif
231
232  let &report= repkeep
233"  call Dret("tar#Browse : b:tarfile<".b:tarfile.">")
234endfun
235
236" ---------------------------------------------------------------------
237" TarBrowseSelect: {{{2
238fun! s:TarBrowseSelect()
239"  call Dfunc("TarBrowseSelect() b:tarfile<".b:tarfile."> curfile<".expand("%").">")
240  let repkeep= &report
241  set report=10
242  let fname= getline(".")
243"  call Decho("fname<".fname.">")
244
245  if !exists("g:tar_secure") && fname =~ '^\s*-\|\s\+-'
246   redraw!
247   echohl WarningMsg | echo '***warning*** (tar#BrowseSelect) rejecting tarfile member<'.fname.'> because of embedded "-"'
248"   call Dret('tar#BrowseSelect : rejecting tarfile member<'.fname.'> because of embedded "-"')
249   return
250  endif
251
252  " sanity check
253  if fname =~ '^"'
254   let &report= repkeep
255"   call Dret("TarBrowseSelect")
256   return
257  endif
258
259  " about to make a new window, need to use b:tarfile
260  let tarfile= b:tarfile
261  let curfile= expand("%")
262  if has("win32unix") && executable("cygpath")
263   " assuming cygwin
264   let tarfile=substitute(system("cygpath -u ".shellescape(tarfile,0)),'\n$','','e')
265  endif
266
267  " open a new window (tar#Read will read a file into it)
268  noswapfile new
269  if !exists("g:tar_nomax") || g:tar_nomax == 0
270   wincmd _
271  endif
272  let s:tblfile_{winnr()}= curfile
273  call tar#Read("tarfile:".tarfile.'::'.fname,1)
274  filetype detect
275  set nomod
276  exe 'com! -buffer -nargs=? -complete=file TarDiff	:call tar#Diff(<q-args>,"'.fnameescape(fname).'")'
277
278  let &report= repkeep
279"  call Dret("TarBrowseSelect : s:tblfile_".winnr()."<".s:tblfile_{winnr()}.">")
280endfun
281
282" ---------------------------------------------------------------------
283" tar#Read: {{{2
284fun! tar#Read(fname,mode)
285"  call Dfunc("tar#Read(fname<".a:fname.">,mode=".a:mode.")")
286  let repkeep= &report
287  set report=10
288  let tarfile = substitute(a:fname,'tarfile:\(.\{-}\)::.*$','\1','')
289  let fname   = substitute(a:fname,'tarfile:.\{-}::\(.*\)$','\1','')
290  if has("win32unix") && executable("cygpath")
291   " assuming cygwin
292   let tarfile=substitute(system("cygpath -u ".shellescape(tarfile,0)),'\n$','','e')
293  endif
294"  call Decho("tarfile<".tarfile.">")
295"  call Decho("fname<".fname.">")
296
297  if  fname =~ '\.bz2$' && executable("bzcat")
298   let decmp= "|bzcat"
299   let doro = 1
300  elseif      fname =~ '\.t\=gz$'  && executable("zcat")
301   let decmp= "|zcat"
302   let doro = 1
303  elseif  fname =~ '\.lzma$' && executable("lzcat")
304   let decmp= "|lzcat"
305   let doro = 1
306  elseif  fname =~ '\.xz$' && executable("xzcat")
307   let decmp= "|xzcat"
308   let doro = 1
309  elseif  fname =~ '\.zst$' && executable("zstdcat")
310   let decmp= "|zstdcat"
311   let doro = 1
312  else
313   let decmp=""
314   let doro = 0
315   if fname =~ '\.bz2$\|\.gz$\|\.lzma$\|\.xz$\|\.zip$\|\.Z$'
316    setlocal bin
317   endif
318  endif
319
320  if exists("g:tar_secure")
321   let tar_secure= " -- "
322  else
323   let tar_secure= " "
324  endif
325
326  if tarfile =~# '\.bz2$'
327   exe "sil! r! bzip2 -d -c -- ".shellescape(tarfile,1)."| ".g:tar_cmd." -".g:tar_readoptions." - ".tar_secure.shellescape(fname,1).decmp
328  elseif tarfile =~# '\.\(gz\)$'
329   exe "sil! r! gzip -d -c -- ".shellescape(tarfile,1)."| ".g:tar_cmd." -".g:tar_readoptions." - ".tar_secure.shellescape(fname,1).decmp
330
331  elseif tarfile =~# '\(\.tgz\|\.tbz\|\.txz\)'
332   if has("unix") && executable("file")
333    let filekind= system("file ".shellescape(tarfile,1))
334   else
335    let filekind= ""
336   endif
337   if filekind =~ "bzip2"
338    exe "sil! r! bzip2 -d -c -- ".shellescape(tarfile,1)."| ".g:tar_cmd." -".g:tar_readoptions." - ".tar_secure.shellescape(fname,1).decmp
339   elseif filekind =~ "XZ"
340    exe "sil! r! xz -d -c -- ".shellescape(tarfile,1)."| ".g:tar_cmd." -".g:tar_readoptions." - ".tar_secure.shellescape(fname,1).decmp
341   elseif filekind =~ "Zstandard"
342    exe "sil! r! zstd --decompress --stdout -- ".shellescape(tarfile,1)."| ".g:tar_cmd." -".g:tar_readoptions." - ".tar_secure.shellescape(fname,1).decmp
343   else
344    exe "sil! r! gzip -d -c -- ".shellescape(tarfile,1)."| ".g:tar_cmd." -".g:tar_readoptions." - ".tar_secure.shellescape(fname,1).decmp
345   endif
346
347  elseif tarfile =~# '\.lrp$'
348   exe "sil! r! cat -- ".shellescape(tarfile,1)." | gzip -d -c - | ".g:tar_cmd." -".g:tar_readoptions." - ".tar_secure.shellescape(fname,1).decmp
349  elseif tarfile =~# '\.lzma$'
350   exe "sil! r! lzma -d -c -- ".shellescape(tarfile,1)."| ".g:tar_cmd." -".g:tar_readoptions." - ".tar_secure.shellescape(fname,1).decmp
351  elseif tarfile =~# '\.\(xz\|txz\)$'
352   exe "sil! r! xz --decompress --stdout -- ".shellescape(tarfile,1)." | ".g:tar_cmd." -".g:tar_readoptions." - ".tar_secure.shellescape(fname,1).decmp
353  else
354   if tarfile =~ '^\s*-'
355    " A file name starting with a dash is taken as an option.  Prepend ./ to avoid that.
356    let tarfile = substitute(tarfile, '-', './-', '')
357   endif
358"   call Decho("8: exe silent r! ".g:tar_cmd." -".g:tar_readoptions.tar_secure.shellescape(tarfile,1)." ".shellescape(fname,1).decmp)
359   exe "silent r! ".g:tar_cmd." -".g:tar_readoptions.shellescape(tarfile,1)." ".tar_secure.shellescape(fname,1).decmp
360  endif
361
362  if doro
363   " because the reverse process of compressing changed files back into the tarball is not currently supported
364   setlocal ro
365  endif
366
367  let b:tarfile= a:fname
368  exe "file tarfile::".fnameescape(fname)
369
370  " cleanup
371  keepj sil! 0d
372  set nomod
373
374  let &report= repkeep
375"  call Dret("tar#Read : b:tarfile<".b:tarfile.">")
376endfun
377
378" ---------------------------------------------------------------------
379" tar#Write: {{{2
380fun! tar#Write(fname)
381"  call Dfunc("tar#Write(fname<".a:fname.">) b:tarfile<".b:tarfile."> tblfile_".winnr()."<".s:tblfile_{winnr()}.">")
382  let repkeep= &report
383  set report=10
384
385  if !exists("g:tar_secure") && a:fname =~ '^\s*-\|\s\+-'
386   redraw!
387   echohl WarningMsg | echo '***warning*** (tar#Write) rejecting tarfile member<'.a:fname.'> because of embedded "-"'
388"   call Dret('tar#Write : rejecting tarfile member<'.fname.'> because of embedded "-"')
389   return
390  endif
391
392  " sanity checks
393  if !executable(g:tar_cmd)
394   redraw!
395"   call Decho('***error*** (tar#Browse) "'.g:tar_cmd.'" not available on your system')
396   let &report= repkeep
397"   call Dret("tar#Write")
398   return
399  endif
400  if !exists("*mkdir")
401   redraw!
402"   call Decho("***error*** (tar#Write) sorry, mkdir() doesn't work on your system")
403   echohl Error | echo "***error*** (tar#Write) sorry, mkdir() doesn't work on your system" | echohl None
404   let &report= repkeep
405"   call Dret("tar#Write")
406   return
407  endif
408
409  let curdir= getcwd()
410  let tmpdir= tempname()
411"  call Decho("orig tempname<".tmpdir.">")
412  if tmpdir =~ '\.'
413   let tmpdir= substitute(tmpdir,'\.[^.]*$','','e')
414  endif
415"  call Decho("tmpdir<".tmpdir.">")
416  call mkdir(tmpdir,"p")
417
418  " attempt to change to the indicated directory
419  try
420   exe "cd ".fnameescape(tmpdir)
421  catch /^Vim\%((\a\+)\)\=:E344/
422   redraw!
423"   call Decho("***error*** (tar#Write) cannot cd to temporary directory")
424   echohl Error | echo "***error*** (tar#Write) cannot cd to temporary directory" | Echohl None
425   let &report= repkeep
426"   call Dret("tar#Write")
427   return
428  endtry
429"  call Decho("current directory now: ".getcwd())
430
431  " place temporary files under .../_ZIPVIM_/
432  if isdirectory("_ZIPVIM_")
433   call s:Rmdir("_ZIPVIM_")
434  endif
435  call mkdir("_ZIPVIM_")
436  cd _ZIPVIM_
437"  call Decho("current directory now: ".getcwd())
438
439  let tarfile = substitute(b:tarfile,'tarfile:\(.\{-}\)::.*$','\1','')
440  let fname   = substitute(b:tarfile,'tarfile:.\{-}::\(.*\)$','\1','')
441
442  " handle compressed archives
443  if tarfile =~# '\.bz2'
444   call system("bzip2 -d -- ".shellescape(tarfile,0))
445   let tarfile = substitute(tarfile,'\.bz2','','e')
446   let compress= "bzip2 -- ".shellescape(tarfile,0)
447"   call Decho("compress<".compress.">")
448  elseif tarfile =~# '\.gz'
449   call system("gzip -d -- ".shellescape(tarfile,0))
450   let tarfile = substitute(tarfile,'\.gz','','e')
451   let compress= "gzip -- ".shellescape(tarfile,0)
452"   call Decho("compress<".compress.">")
453  elseif tarfile =~# '\.tgz'
454   call system("gzip -d -- ".shellescape(tarfile,0))
455   let tarfile = substitute(tarfile,'\.tgz','.tar','e')
456   let compress= "gzip -- ".shellescape(tarfile,0)
457   let tgz     = 1
458"   call Decho("compress<".compress.">")
459  elseif tarfile =~# '\.xz'
460   call system("xz -d -- ".shellescape(tarfile,0))
461   let tarfile = substitute(tarfile,'\.xz','','e')
462   let compress= "xz -- ".shellescape(tarfile,0)
463"   call Decho("compress<".compress.">")
464  elseif tarfile =~# '\.zst'
465   call system("zstd --decompress -- ".shellescape(tarfile,0))
466   let tarfile = substitute(tarfile,'\.zst','','e')
467   let compress= "zstd -- ".shellescape(tarfile,0)
468  elseif tarfile =~# '\.lzma'
469   call system("lzma -d -- ".shellescape(tarfile,0))
470   let tarfile = substitute(tarfile,'\.lzma','','e')
471   let compress= "lzma -- ".shellescape(tarfile,0)
472"   call Decho("compress<".compress.">")
473  endif
474"  call Decho("tarfile<".tarfile.">")
475
476  if v:shell_error != 0
477   redraw!
478"   call Decho("***error*** (tar#Write) sorry, unable to update ".tarfile." with ".fname)
479   echohl Error | echo "***error*** (tar#Write) sorry, unable to update ".tarfile." with ".fname | echohl None
480  else
481
482"   call Decho("tarfile<".tarfile."> fname<".fname.">")
483
484   if fname =~ '/'
485    let dirpath = substitute(fname,'/[^/]\+$','','e')
486    if has("win32unix") && executable("cygpath")
487     let dirpath = substitute(system("cygpath ".shellescape(dirpath, 0)),'\n','','e')
488    endif
489    call mkdir(dirpath,"p")
490   endif
491   if tarfile !~ '/'
492    let tarfile= curdir.'/'.tarfile
493   endif
494   if tarfile =~ '^\s*-'
495    " A file name starting with a dash may be taken as an option.  Prepend ./ to avoid that.
496    let tarfile = substitute(tarfile, '-', './-', '')
497   endif
498"   call Decho("tarfile<".tarfile."> fname<".fname.">")
499
500   if exists("g:tar_secure")
501    let tar_secure= " -- "
502   else
503    let tar_secure= " "
504   endif
505   exe "w! ".fnameescape(fname)
506   if has("win32unix") && executable("cygpath")
507    let tarfile = substitute(system("cygpath ".shellescape(tarfile,0)),'\n','','e')
508   endif
509
510   " delete old file from tarfile
511"   call Decho("system(".g:tar_cmd." ".g:tar_delfile." ".shellescape(tarfile,0)." -- ".shellescape(fname,0).")")
512   call system(g:tar_cmd." ".g:tar_delfile." ".shellescape(tarfile,0).tar_secure.shellescape(fname,0))
513   if v:shell_error != 0
514    redraw!
515"    call Decho("***error*** (tar#Write) sorry, unable to update ".fnameescape(tarfile)." with ".fnameescape(fname))
516    echohl Error | echo "***error*** (tar#Write) sorry, unable to update ".fnameescape(tarfile)." with ".fnameescape(fname) | echohl None
517   else
518
519    " update tarfile with new file
520"    call Decho(g:tar_cmd." -".g:tar_writeoptions." ".shellescape(tarfile,0).tar_secure.shellescape(fname,0))
521    call system(g:tar_cmd." -".g:tar_writeoptions." ".shellescape(tarfile,0).tar_secure.shellescape(fname,0))
522    if v:shell_error != 0
523     redraw!
524"     call Decho("***error*** (tar#Write) sorry, unable to update ".fnameescape(tarfile)." with ".fnameescape(fname))
525     echohl Error | echo "***error*** (tar#Write) sorry, unable to update ".fnameescape(tarfile)." with ".fnameescape(fname) | echohl None
526    elseif exists("compress")
527"     call Decho("call system(".compress.")")
528     call system(compress)
529     if exists("tgz")
530"      call Decho("rename(".tarfile.".gz,".substitute(tarfile,'\.tar$','.tgz','e').")")
531      call rename(tarfile.".gz",substitute(tarfile,'\.tar$','.tgz','e'))
532     endif
533    endif
534   endif
535
536   " support writing tarfiles across a network
537   if s:tblfile_{winnr()} =~ '^\a\+://'
538"    call Decho("handle writing <".tarfile."> across network to <".s:tblfile_{winnr()}.">")
539    let tblfile= s:tblfile_{winnr()}
540    1split|noswapfile enew
541    let binkeep= &l:binary
542    let eikeep = &ei
543    set binary ei=all
544    exe "noswapfile e! ".fnameescape(tarfile)
545    call netrw#NetWrite(tblfile)
546    let &ei       = eikeep
547    let &l:binary = binkeep
548    q!
549    unlet s:tblfile_{winnr()}
550   endif
551  endif
552
553  " cleanup and restore current directory
554  cd ..
555  call s:Rmdir("_ZIPVIM_")
556  exe "cd ".fnameescape(curdir)
557  setlocal nomod
558
559  let &report= repkeep
560"  call Dret("tar#Write")
561endfun
562
563" ---------------------------------------------------------------------
564" tar#Diff: {{{2
565fun! tar#Diff(userfname,fname)
566"  call Dfunc("tar#Diff(userfname<".a:userfname."> fname<".a:fname.")")
567  let fname= a:fname
568  if a:userfname != ""
569   let fname= a:userfname
570  endif
571  if filereadable(fname)
572   " sets current file (from tarball) for diff'ing
573   " splits window vertically
574   " opens original file, sets it for diff'ing
575   " sets up b:tardiff_otherbuf variables so each buffer knows about the other (for closing purposes)
576   diffthis
577   wincmd v
578   exe "noswapfile e ".fnameescape(fname)
579   diffthis
580  else
581   redraw!
582   echo "***warning*** unable to read file<".fname.">"
583  endif
584"  call Dret("tar#Diff")
585endfun
586
587" ---------------------------------------------------------------------
588" tar#Extract: extract a file from a (possibly compressed) tar archive {{{2
589fun! tar#Extract()
590"  call Dfunc("tar#Extract()")
591
592  let repkeep= &report
593  set report=10
594  let fname= getline(".")
595"  call Decho("fname<".fname.">")
596
597  if !exists("g:tar_secure") && fname =~ '^\s*-\|\s\+-'
598   redraw!
599   echohl WarningMsg | echo '***warning*** (tar#BrowseSelect) rejecting tarfile member<'.fname.'> because of embedded "-"'
600"   call Dret('tar#BrowseSelect : rejecting tarfile member<'.fname.'> because of embedded "-"')
601   return
602  endif
603
604  " sanity check
605  if fname =~ '^"'
606   let &report= repkeep
607"   call Dret("TarBrowseSelect")
608   return
609  endif
610
611  let tarball = expand("%")
612"  call Decho("tarball<".tarball.">")
613  let tarbase = substitute(tarball,'\..*$','','')
614"  call Decho("tarbase<".tarbase.">")
615
616  let extractcmd= netrw#WinPath(g:tar_extractcmd)
617  if filereadable(tarbase.".tar")
618"   call Decho("system(".extractcmd." ".shellescape(tarbase).".tar ".shellescape(fname).")")
619   call system(extractcmd." ".shellescape(tarbase).".tar ".shellescape(fname))
620   if v:shell_error != 0
621    echohl Error | echo "***error*** ".extractcmd." ".tarbase.".tar ".fname.": failed!" | echohl NONE
622"    call Decho("***error*** ".extractcmd." ".tarbase.".tar ".fname.": failed!")
623   else
624    echo "***note*** successfully extracted ".fname
625   endif
626
627  elseif filereadable(tarbase.".tgz")
628   let extractcmd= substitute(extractcmd,"-","-z","")
629"   call Decho("system(".extractcmd." ".shellescape(tarbase).".tgz ".shellescape(fname).")")
630   call system(extractcmd." ".shellescape(tarbase).".tgz ".shellescape(fname))
631   if v:shell_error != 0
632    echohl Error | echo "***error*** ".extractcmd." ".tarbase.".tgz ".fname.": failed!" | echohl NONE
633"    call Decho("***error*** ".extractcmd."t ".tarbase.".tgz ".fname.": failed!")
634   else
635    echo "***note*** successfully extracted ".fname
636   endif
637
638  elseif filereadable(tarbase.".tar.gz")
639   let extractcmd= substitute(extractcmd,"-","-z","")
640"   call Decho("system(".extractcmd." ".shellescape(tarbase).".tar.gz ".shellescape(fname).")")
641   call system(extractcmd." ".shellescape(tarbase).".tar.gz ".shellescape(fname))
642   if v:shell_error != 0
643    echohl Error | echo "***error*** ".extractcmd." ".tarbase.".tar.gz ".fname.": failed!" | echohl NONE
644"    call Decho("***error*** ".extractcmd." ".tarbase.".tar.gz ".fname.": failed!")
645   else
646    echo "***note*** successfully extracted ".fname
647   endif
648
649  elseif filereadable(tarbase.".tbz")
650   let extractcmd= substitute(extractcmd,"-","-j","")
651"   call Decho("system(".extractcmd." ".shellescape(tarbase).".tbz ".shellescape(fname).")")
652   call system(extractcmd." ".shellescape(tarbase).".tbz ".shellescape(fname))
653   if v:shell_error != 0
654    echohl Error | echo "***error*** ".extractcmd."j ".tarbase.".tbz ".fname.": failed!" | echohl NONE
655"    call Decho("***error*** ".extractcmd."j ".tarbase.".tbz ".fname.": failed!")
656   else
657    echo "***note*** successfully extracted ".fname
658   endif
659
660  elseif filereadable(tarbase.".tar.bz2")
661   let extractcmd= substitute(extractcmd,"-","-j","")
662"   call Decho("system(".extractcmd." ".shellescape(tarbase).".tar.bz2 ".shellescape(fname).")")
663   call system(extractcmd." ".shellescape(tarbase).".tar.bz2 ".shellescape(fname))
664   if v:shell_error != 0
665    echohl Error | echo "***error*** ".extractcmd."j ".tarbase.".tar.bz2 ".fname.": failed!" | echohl NONE
666"    call Decho("***error*** ".extractcmd."j ".tarbase.".tar.bz2 ".fname.": failed!")
667   else
668    echo "***note*** successfully extracted ".fname
669   endif
670
671  elseif filereadable(tarbase.".txz")
672   let extractcmd= substitute(extractcmd,"-","-J","")
673"   call Decho("system(".extractcmd." ".shellescape(tarbase).".txz ".shellescape(fname).")")
674   call system(extractcmd." ".shellescape(tarbase).".txz ".shellescape(fname))
675   if v:shell_error != 0
676    echohl Error | echo "***error*** ".extractcmd." ".tarbase.".txz ".fname.": failed!" | echohl NONE
677"    call Decho("***error*** ".extractcmd." ".tarbase.".txz ".fname.": failed!")
678   else
679    echo "***note*** successfully extracted ".fname
680   endif
681
682  elseif filereadable(tarbase.".tar.xz")
683   let extractcmd= substitute(extractcmd,"-","-J","")
684"   call Decho("system(".extractcmd." ".shellescape(tarbase).".tar.xz ".shellescape(fname).")")
685   call system(extractcmd." ".shellescape(tarbase).".tar.xz ".shellescape(fname))
686   if v:shell_error != 0
687    echohl Error | echo "***error*** ".extractcmd." ".tarbase.".tar.xz ".fname.": failed!" | echohl NONE
688"    call Decho("***error*** ".extractcmd." ".tarbase.".tar.xz ".fname.": failed!")
689   else
690    echo "***note*** successfully extracted ".fname
691   endif
692
693  elseif filereadable(tarbase.".tzs")
694   let extractcmd= substitute(extractcmd,"-","--zstd","")
695"   call Decho("system(".extractcmd." ".shellescape(tarbase).".tzs ".shellescape(fname).")")
696   call system(extractcmd." ".shellescape(tarbase).".txz ".shellescape(fname))
697   if v:shell_error != 0
698    echohl Error | echo "***error*** ".extractcmd." ".tarbase.".tzs ".fname.": failed!" | echohl NONE
699"    call Decho("***error*** ".extractcmd." ".tarbase.".tzs ".fname.": failed!")
700   else
701    echo "***note*** successfully extracted ".fname
702   endif
703
704  elseif filereadable(tarbase.".tar.zst")
705   let extractcmd= substitute(extractcmd,"-","--zstd","")
706"   call Decho("system(".extractcmd." ".shellescape(tarbase).".tar.zst ".shellescape(fname).")")
707   call system(extractcmd." ".shellescape(tarbase).".tar.xz ".shellescape(fname))
708   if v:shell_error != 0
709    echohl Error | echo "***error*** ".extractcmd." ".tarbase.".tar.zst ".fname.": failed!" | echohl NONE
710"    call Decho("***error*** ".extractcmd." ".tarbase.".tar.zst ".fname.": failed!")
711   else
712    echo "***note*** successfully extracted ".fname
713   endif
714  endif
715
716  " restore option
717  let &report= repkeep
718
719"  call Dret("tar#Extract")
720endfun
721
722" ---------------------------------------------------------------------
723" s:Rmdir: {{{2
724fun! s:Rmdir(fname)
725"  call Dfunc("Rmdir(fname<".a:fname.">)")
726  if has("unix")
727   call system("/bin/rm -rf -- ".shellescape(a:fname,0))
728  elseif has("win32") || has("win95") || has("win64") || has("win16")
729   if &shell =~? "sh$"
730    call system("/bin/rm -rf -- ".shellescape(a:fname,0))
731   else
732    call system("del /S ".shellescape(a:fname,0))
733   endif
734  endif
735"  call Dret("Rmdir")
736endfun
737
738" ---------------------------------------------------------------------
739" tar#Vimuntar: installs a tarball in the user's .vim / vimfiles directory {{{2
740fun! tar#Vimuntar(...)
741"  call Dfunc("tar#Vimuntar() a:0=".a:0." a:1<".(exists("a:1")? a:1 : "-n/a-").">")
742  let tarball = expand("%")
743"  call Decho("tarball<".tarball.">")
744  let tarbase = substitute(tarball,'\..*$','','')
745"  call Decho("tarbase<".tarbase.">")
746  let tarhome = expand("%:p")
747  if has("win32") || has("win95") || has("win64") || has("win16")
748   let tarhome= substitute(tarhome,'\\','/','g')
749  endif
750  let tarhome= substitute(tarhome,'/[^/]*$','','')
751"  call Decho("tarhome<".tarhome.">")
752  let tartail = expand("%:t")
753"  call Decho("tartail<".tartail.">")
754  let curdir  = getcwd()
755"  call Decho("curdir <".curdir.">")
756  " set up vimhome
757  if a:0 > 0 && a:1 != ""
758   let vimhome= a:1
759  else
760   let vimhome= vimball#VimballHome()
761  endif
762"  call Decho("vimhome<".vimhome.">")
763
764"  call Decho("curdir<".curdir."> vimhome<".vimhome.">")
765  if simplify(curdir) != simplify(vimhome)
766   " copy (possibly compressed) tarball to .vim/vimfiles
767"   call Decho(netrw#WinPath(g:tar_copycmd)." ".shellescape(tartail)." ".shellescape(vimhome))
768   call system(netrw#WinPath(g:tar_copycmd)." ".shellescape(tartail)." ".shellescape(vimhome))
769"   call Decho("exe cd ".fnameescape(vimhome))
770   exe "cd ".fnameescape(vimhome)
771  endif
772"  call Decho("getcwd<".getcwd().">")
773
774  " if necessary, decompress the tarball; then, extract it
775  if tartail =~ '\.tgz'
776   if executable("gunzip")
777    silent exe "!gunzip ".shellescape(tartail)
778   elseif executable("gzip")
779    silent exe "!gzip -d ".shellescape(tartail)
780   else
781    echoerr "unable to decompress<".tartail."> on this sytem"
782    if simplify(curdir) != simplify(tarhome)
783     " remove decompressed tarball, restore directory
784"     call Decho("delete(".tartail.".tar)")
785     call delete(tartail.".tar")
786"     call Decho("exe cd ".fnameescape(curdir))
787     exe "cd ".fnameescape(curdir)
788    endif
789"    call Dret("tar#Vimuntar")
790    return
791   endif
792  else
793   call vimball#Decompress(tartail,0)
794  endif
795  let extractcmd= netrw#WinPath(g:tar_extractcmd)
796"  call Decho("system(".extractcmd." ".shellescape(tarbase.".tar").")")
797  call system(extractcmd." ".shellescape(tarbase.".tar"))
798
799  " set up help
800  if filereadable("doc/".tarbase.".txt")
801"   call Decho("exe helptags ".getcwd()."/doc")
802   exe "helptags ".getcwd()."/doc"
803  endif
804
805  if simplify(tarhome) != simplify(vimhome)
806   " remove decompressed tarball, restore directory
807   call delete(vimhome."/".tarbase.".tar")
808   exe "cd ".fnameescape(curdir)
809  endif
810
811"  call Dret("tar#Vimuntar")
812endfun
813
814" =====================================================================
815" Modelines And Restoration: {{{1
816let &cpo= s:keepcpo
817unlet s:keepcpo
818" vim:ts=8 fdm=marker
819