blob: 499036ef9cdca9469851c3a3c968de94e7889b61 [file] [log] [blame]
Corpulent Robinb69cd522025-02-06 21:10:49 +01001" tar.vim: Handles browsing tarfiles - AUTOLOAD PORTION
Christian Brabandt8ac975d2025-03-01 17:13:40 +01002" Date: Mar 01, 2025
Christian Brabandt67abf152023-11-14 17:15:17 +01003" Version: 32b (with modifications from the Vim Project)
Christian Brabandtf9ca1392024-02-19 20:37:11 +01004" Maintainer: This runtime file is looking for a new maintainer.
5" Former Maintainer: Charles E Campbell
Bram Moolenaar29634562020-01-09 21:46:04 +01006" License: Vim License (see vim's :help license)
Jim Zhou56957ed2025-02-28 18:06:14 +01007" Last Change:
8" 2024 Jan 08 by Vim Project: fix a few problems (#138331, #12637, #8109)
9" 2024 Feb 19 by Vim Project: announce adoption
10" 2024 Nov 11 by Vim Project: support permissions (#7379)
11" 2025 Feb 06 by Vim Project: add support for lz4 (#16591)
12" 2025 Feb 28 by Vim Project: add support for bzip3 (#16755)
Christian Brabandt8ac975d2025-03-01 17:13:40 +010013" 2025 Mar 01 by Vim Project: fix syntax error in tar#Read()
Christian Brabandt334a13b2025-03-02 19:33:51 +010014" 2025 Mar 02 by Vim Project: escape the filename before using :read
Christian Brabandta2507382025-03-02 22:23:28 +010015" 2025 Mar 02 by Vim Project: determine the compression using readblob()
16" instead of shelling out to file(1)
Christian Brabandt470317f2025-04-16 17:13:28 +020017" 2025 Apr 16 by Vim Project: decouple from netrw by adding s:WinPath()
Bram Moolenaar87e25fd2005-07-27 21:13:01 +000018"
Bram Moolenaara5792f52005-11-23 21:25:05 +000019" Contains many ideas from Michael Toren's <tar.vim>
Bram Moolenaar87e25fd2005-07-27 21:13:01 +000020"
Bram Moolenaar29634562020-01-09 21:46:04 +010021" Copyright: Copyright (C) 2005-2017 Charles E. Campbell {{{1
Bram Moolenaara5792f52005-11-23 21:25:05 +000022" Permission is hereby granted to use and distribute this code,
23" with or without modifications, provided that this copyright
24" notice is copied with it. Like anything else that's free,
Bram Moolenaar8c8de832008-06-24 22:58:06 +000025" tar.vim and tarPlugin.vim are provided *as is* and comes
26" with no warranty of any kind, either expressed or implied.
27" By using this plugin, you agree that in no event will the
28" copyright holder be liable for any damages resulting from
29" the use of this software.
Bram Moolenaarab194812005-09-14 21:40:12 +000030" ---------------------------------------------------------------------
Bram Moolenaarc81e5e72007-05-05 18:24:42 +000031" Load Once: {{{1
Bram Moolenaar5c736222010-01-06 20:54:52 +010032if &cp || exists("g:loaded_tar")
Bram Moolenaara5792f52005-11-23 21:25:05 +000033 finish
34endif
Lennart00129a8442024-11-11 22:39:30 +010035let g:loaded_tar= "v32b"
Bram Moolenaar5c736222010-01-06 20:54:52 +010036if v:version < 702
37 echohl WarningMsg
38 echo "***warning*** this version of tar needs vim 7.2"
39 echohl Normal
40 finish
Bram Moolenaar8c8de832008-06-24 22:58:06 +000041endif
Bram Moolenaar5c736222010-01-06 20:54:52 +010042let s:keepcpo= &cpo
43set cpo&vim
Bram Moolenaar87e25fd2005-07-27 21:13:01 +000044
Bram Moolenaara5792f52005-11-23 21:25:05 +000045" ---------------------------------------------------------------------
46" Default Settings: {{{1
47if !exists("g:tar_browseoptions")
48 let g:tar_browseoptions= "Ptf"
49endif
50if !exists("g:tar_readoptions")
Lennart00129a8442024-11-11 22:39:30 +010051 let g:tar_readoptions= "pPxf"
Bram Moolenaara5792f52005-11-23 21:25:05 +000052endif
Bram Moolenaar910f66f2006-04-05 20:41:53 +000053if !exists("g:tar_cmd")
54 let g:tar_cmd= "tar"
55endif
Bram Moolenaara5792f52005-11-23 21:25:05 +000056if !exists("g:tar_writeoptions")
57 let g:tar_writeoptions= "uf"
58endif
Bram Moolenaar29634562020-01-09 21:46:04 +010059if !exists("g:tar_delfile")
60 let g:tar_delfile="--delete -f"
61endif
Bram Moolenaar251e1912011-06-19 05:09:16 +020062if !exists("g:netrw_cygwin")
63 if has("win32") || has("win95") || has("win64") || has("win16")
64 if &shell =~ '\%(\<bash\>\|\<zsh\>\)\%(\.exe\)\=$'
65 let g:netrw_cygwin= 1
66 else
67 let g:netrw_cygwin= 0
68 endif
69 else
70 let g:netrw_cygwin= 0
71 endif
72endif
Bram Moolenaar5c736222010-01-06 20:54:52 +010073if !exists("g:tar_copycmd")
74 if !exists("g:netrw_localcopycmd")
75 if has("win32") || has("win95") || has("win64") || has("win16")
76 if g:netrw_cygwin
77 let g:netrw_localcopycmd= "cp"
78 else
79 let g:netrw_localcopycmd= "copy"
80 endif
81 elseif has("unix") || has("macunix")
82 let g:netrw_localcopycmd= "cp"
83 else
84 let g:netrw_localcopycmd= ""
85 endif
86 endif
87 let g:tar_copycmd= g:netrw_localcopycmd
88endif
Bram Moolenaar5c736222010-01-06 20:54:52 +010089if !exists("g:tar_extractcmd")
Lennart00129a8442024-11-11 22:39:30 +010090 let g:tar_extractcmd= "tar -pxf"
Bram Moolenaar5c736222010-01-06 20:54:52 +010091endif
Bram Moolenaar87e25fd2005-07-27 21:13:01 +000092
Bram Moolenaar8c8de832008-06-24 22:58:06 +000093" set up shell quoting character
94if !exists("g:tar_shq")
Bram Moolenaarff034192013-04-24 18:51:19 +020095 if exists("+shq") && exists("&shq") && &shq != ""
Bram Moolenaar8c8de832008-06-24 22:58:06 +000096 let g:tar_shq= &shq
97 elseif has("win32") || has("win95") || has("win64") || has("win16")
98 if exists("g:netrw_cygwin") && g:netrw_cygwin
99 let g:tar_shq= "'"
100 else
101 let g:tar_shq= '"'
102 endif
103 else
104 let g:tar_shq= "'"
105 endif
Bram Moolenaar8c8de832008-06-24 22:58:06 +0000106endif
107
Bram Moolenaara5792f52005-11-23 21:25:05 +0000108" ----------------
109" Functions: {{{1
110" ----------------
Bram Moolenaar87e25fd2005-07-27 21:13:01 +0000111
Bram Moolenaara5792f52005-11-23 21:25:05 +0000112" ---------------------------------------------------------------------
113" tar#Browse: {{{2
114fun! tar#Browse(tarfile)
Bram Moolenaarbba577a2005-11-28 23:05:55 +0000115 let repkeep= &report
116 set report=10
Bram Moolenaar87e25fd2005-07-27 21:13:01 +0000117
Bram Moolenaara5792f52005-11-23 21:25:05 +0000118 " sanity checks
Bram Moolenaar910f66f2006-04-05 20:41:53 +0000119 if !executable(g:tar_cmd)
Bram Moolenaarc81e5e72007-05-05 18:24:42 +0000120 redraw!
Bram Moolenaar910f66f2006-04-05 20:41:53 +0000121 echohl Error | echo '***error*** (tar#Browse) "'.g:tar_cmd.'" not available on your system'
Bram Moolenaarbba577a2005-11-28 23:05:55 +0000122 let &report= repkeep
Bram Moolenaara5792f52005-11-23 21:25:05 +0000123 return
124 endif
125 if !filereadable(a:tarfile)
126 if a:tarfile !~# '^\a\+://'
Bram Moolenaar8024f932020-01-14 19:29:13 +0100127 " if it's an url, don't complain, let url-handlers such as vim do its thing
Bram Moolenaarc81e5e72007-05-05 18:24:42 +0000128 redraw!
Bram Moolenaara5792f52005-11-23 21:25:05 +0000129 echohl Error | echo "***error*** (tar#Browse) File not readable<".a:tarfile.">" | echohl None
Bram Moolenaara5792f52005-11-23 21:25:05 +0000130 endif
Bram Moolenaarbba577a2005-11-28 23:05:55 +0000131 let &report= repkeep
Bram Moolenaara5792f52005-11-23 21:25:05 +0000132 return
133 endif
134 if &ma != 1
135 set ma
136 endif
Bram Moolenaar7fc0c062010-08-10 21:43:35 +0200137 let b:tarfile= a:tarfile
Bram Moolenaar87e25fd2005-07-27 21:13:01 +0000138
Bram Moolenaara5792f52005-11-23 21:25:05 +0000139 setlocal noswapfile
140 setlocal buftype=nofile
141 setlocal bufhidden=hide
142 setlocal nobuflisted
143 setlocal nowrap
144 set ft=tar
Bram Moolenaar87e25fd2005-07-27 21:13:01 +0000145
Bram Moolenaara5792f52005-11-23 21:25:05 +0000146 " give header
Bram Moolenaar8c8de832008-06-24 22:58:06 +0000147 let lastline= line("$")
148 call setline(lastline+1,'" tar.vim version '.g:loaded_tar)
149 call setline(lastline+2,'" Browsing tarfile '.a:tarfile)
Christian Brabandt470317f2025-04-16 17:13:28 +0200150 call setline(lastline+3,'" Select a file with cursor and press ENTER, "x" to extract a file')
Bram Moolenaar251e1912011-06-19 05:09:16 +0200151 keepj $put =''
Bram Moolenaar6be7f872012-01-20 21:08:56 +0100152 keepj sil! 0d
Bram Moolenaar251e1912011-06-19 05:09:16 +0200153 keepj $
Bram Moolenaar87e25fd2005-07-27 21:13:01 +0000154
Bram Moolenaar910f66f2006-04-05 20:41:53 +0000155 let tarfile= a:tarfile
Bram Moolenaarff034192013-04-24 18:51:19 +0200156 if has("win32unix") && executable("cygpath")
Bram Moolenaar910f66f2006-04-05 20:41:53 +0000157 " assuming cygwin
Bram Moolenaar5c736222010-01-06 20:54:52 +0100158 let tarfile=substitute(system("cygpath -u ".shellescape(tarfile,0)),'\n$','','e')
Bram Moolenaara5792f52005-11-23 21:25:05 +0000159 endif
Bram Moolenaard68071d2006-05-02 22:08:30 +0000160 let curlast= line("$")
Bram Moolenaar29634562020-01-09 21:46:04 +0100161
162 if tarfile =~# '\.\(gz\)$'
Bram Moolenaar29634562020-01-09 21:46:04 +0100163 exe "sil! r! gzip -d -c -- ".shellescape(tarfile,1)." | ".g:tar_cmd." -".g:tar_browseoptions." - "
164
Corpulent Robinb69cd522025-02-06 21:10:49 +0100165 elseif tarfile =~# '\.\(tgz\)$' || tarfile =~# '\.\(tbz\)$' || tarfile =~# '\.\(txz\)$' ||
166 \ tarfile =~# '\.\(tzst\)$' || tarfile =~# '\.\(tlz4\)$'
Christian Brabandta2507382025-03-02 22:23:28 +0100167 let header= s:Header(tarfile)
Bram Moolenaar29634562020-01-09 21:46:04 +0100168
Christian Brabandta2507382025-03-02 22:23:28 +0100169 if header =~? 'bzip2'
Bram Moolenaar29634562020-01-09 21:46:04 +0100170 exe "sil! r! bzip2 -d -c -- ".shellescape(tarfile,1)." | ".g:tar_cmd." -".g:tar_browseoptions." - "
Christian Brabandta2507382025-03-02 22:23:28 +0100171 elseif header =~? 'bzip3'
Jim Zhou56957ed2025-02-28 18:06:14 +0100172 exe "sil! r! bzip3 -d -c -- ".shellescape(tarfile,1)." | ".g:tar_cmd." -".g:tar_browseoptions." - "
Christian Brabandta2507382025-03-02 22:23:28 +0100173 elseif header =~? 'xz'
Bram Moolenaar29634562020-01-09 21:46:04 +0100174 exe "sil! r! xz -d -c -- ".shellescape(tarfile,1)." | ".g:tar_cmd." -".g:tar_browseoptions." - "
Christian Brabandta2507382025-03-02 22:23:28 +0100175 elseif header =~? 'zstd'
Bram Moolenaar23515b42020-11-29 14:36:24 +0100176 exe "sil! r! zstd --decompress --stdout -- ".shellescape(tarfile,1)." | ".g:tar_cmd." -".g:tar_browseoptions." - "
Christian Brabandta2507382025-03-02 22:23:28 +0100177 elseif header =~? 'lz4'
Corpulent Robinb69cd522025-02-06 21:10:49 +0100178 exe "sil! r! lz4 --decompress --stdout -- ".shellescape(tarfile,1)." | ".g:tar_cmd." -".g:tar_browseoptions." - "
Christian Brabandta2507382025-03-02 22:23:28 +0100179 elseif header =~? 'gzip'
Bram Moolenaar29634562020-01-09 21:46:04 +0100180 exe "sil! r! gzip -d -c -- ".shellescape(tarfile,1)." | ".g:tar_cmd." -".g:tar_browseoptions." - "
181 endif
182
Bram Moolenaar8c8de832008-06-24 22:58:06 +0000183 elseif tarfile =~# '\.lrp'
Bram Moolenaard4a1aab2018-09-08 15:10:34 +0200184 exe "sil! r! cat -- ".shellescape(tarfile,1)."|gzip -d -c -|".g:tar_cmd." -".g:tar_browseoptions." - "
Bram Moolenaar6be7f872012-01-20 21:08:56 +0100185 elseif tarfile =~# '\.\(bz2\|tbz\|tb2\)$'
Bram Moolenaar251e1912011-06-19 05:09:16 +0200186 exe "sil! r! bzip2 -d -c -- ".shellescape(tarfile,1)." | ".g:tar_cmd." -".g:tar_browseoptions." - "
Jim Zhou56957ed2025-02-28 18:06:14 +0100187 elseif tarfile =~# '\.\(bz3\|tb3\)$'
188 exe "sil! r! bzip3 -d -c -- ".shellescape(tarfile,1)." | ".g:tar_cmd." -".g:tar_browseoptions." - "
Bram Moolenaar6be7f872012-01-20 21:08:56 +0100189 elseif tarfile =~# '\.\(lzma\|tlz\)$'
Bram Moolenaar251e1912011-06-19 05:09:16 +0200190 exe "sil! r! lzma -d -c -- ".shellescape(tarfile,1)." | ".g:tar_cmd." -".g:tar_browseoptions." - "
Bram Moolenaar477db062010-07-28 18:17:41 +0200191 elseif tarfile =~# '\.\(xz\|txz\)$'
Bram Moolenaar251e1912011-06-19 05:09:16 +0200192 exe "sil! r! xz --decompress --stdout -- ".shellescape(tarfile,1)." | ".g:tar_cmd." -".g:tar_browseoptions." - "
Christian Brabandt3a5b3df2024-01-08 20:02:14 +0100193 elseif tarfile =~# '\.\(zst\|tzst\)$'
Bram Moolenaar23515b42020-11-29 14:36:24 +0100194 exe "sil! r! zstd --decompress --stdout -- ".shellescape(tarfile,1)." | ".g:tar_cmd." -".g:tar_browseoptions." - "
Corpulent Robinb69cd522025-02-06 21:10:49 +0100195 elseif tarfile =~# '\.\(lz4\|tlz4\)$'
196 exe "sil! r! lz4 --decompress --stdout -- ".shellescape(tarfile,1)." | ".g:tar_cmd." -".g:tar_browseoptions." - "
Bram Moolenaar910f66f2006-04-05 20:41:53 +0000197 else
Bram Moolenaared39e1d2008-08-09 17:55:22 +0000198 if tarfile =~ '^\s*-'
Bram Moolenaar5c736222010-01-06 20:54:52 +0100199 " A file name starting with a dash is taken as an option. Prepend ./ to avoid that.
Bram Moolenaared39e1d2008-08-09 17:55:22 +0000200 let tarfile = substitute(tarfile, '-', './-', '')
201 endif
Bram Moolenaar251e1912011-06-19 05:09:16 +0200202 exe "sil! r! ".g:tar_cmd." -".g:tar_browseoptions." ".shellescape(tarfile,1)
Bram Moolenaar910f66f2006-04-05 20:41:53 +0000203 endif
204 if v:shell_error != 0
Bram Moolenaarc81e5e72007-05-05 18:24:42 +0000205 redraw!
Bram Moolenaard68071d2006-05-02 22:08:30 +0000206 echohl WarningMsg | echo "***warning*** (tar#Browse) please check your g:tar_browseoptions<".g:tar_browseoptions.">"
Bram Moolenaard68071d2006-05-02 22:08:30 +0000207 return
208 endif
Christian Brabandt3d372312023-11-05 17:44:05 +0100209 "
Christian Brabandt67abf152023-11-14 17:15:17 +0100210 " The following should not be neccessary, since in case of errors the
211 " previous if statement should have caught the problem (because tar exited
212 " with a non-zero exit code).
213 " if line("$") == curlast || ( line("$") == (curlast + 1) &&
214 " \ getline("$") =~# '\c\<\%(warning\|error\|inappropriate\|unrecognized\)\>' &&
215 " \ getline("$") =~ '\s' )
216 " redraw!
217 " echohl WarningMsg | echo "***warning*** (tar#Browse) ".a:tarfile." doesn't appear to be a tar file" | echohl None
218 " keepj sil! %d
219 " let eikeep= &ei
220 " set ei=BufReadCmd,FileReadCmd
221 " exe "r ".fnameescape(a:tarfile)
222 " let &ei= eikeep
223 " keepj sil! 1d
224 " call Dret("tar#Browse : a:tarfile<".a:tarfile.">")
225 " return
226 " endif
Bram Moolenaara5792f52005-11-23 21:25:05 +0000227
Bram Moolenaar29634562020-01-09 21:46:04 +0100228 " set up maps supported for tar
Bram Moolenaara5792f52005-11-23 21:25:05 +0000229 setlocal noma nomod ro
Bram Moolenaar29634562020-01-09 21:46:04 +0100230 noremap <silent> <buffer> <cr> :call <SID>TarBrowseSelect()<cr>
Christian Brabandt3a5b3df2024-01-08 20:02:14 +0100231 noremap <silent> <buffer> x :call tar#Extract()<cr>
Bram Moolenaar29634562020-01-09 21:46:04 +0100232 if &mouse != ""
233 noremap <silent> <buffer> <leftmouse> <leftmouse>:call <SID>TarBrowseSelect()<cr>
234 endif
Bram Moolenaara5792f52005-11-23 21:25:05 +0000235
Bram Moolenaarbba577a2005-11-28 23:05:55 +0000236 let &report= repkeep
Bram Moolenaarab194812005-09-14 21:40:12 +0000237endfun
Bram Moolenaar87e25fd2005-07-27 21:13:01 +0000238
Bram Moolenaarab194812005-09-14 21:40:12 +0000239" ---------------------------------------------------------------------
Bram Moolenaara5792f52005-11-23 21:25:05 +0000240" TarBrowseSelect: {{{2
241fun! s:TarBrowseSelect()
Bram Moolenaarbba577a2005-11-28 23:05:55 +0000242 let repkeep= &report
243 set report=10
Bram Moolenaara5792f52005-11-23 21:25:05 +0000244 let fname= getline(".")
Bram Moolenaara5792f52005-11-23 21:25:05 +0000245
Bram Moolenaared39e1d2008-08-09 17:55:22 +0000246 if !exists("g:tar_secure") && fname =~ '^\s*-\|\s\+-'
247 redraw!
Bram Moolenaar5c736222010-01-06 20:54:52 +0100248 echohl WarningMsg | echo '***warning*** (tar#BrowseSelect) rejecting tarfile member<'.fname.'> because of embedded "-"'
Bram Moolenaared39e1d2008-08-09 17:55:22 +0000249 return
250 endif
251
Bram Moolenaara5792f52005-11-23 21:25:05 +0000252 " sanity check
253 if fname =~ '^"'
Bram Moolenaarbba577a2005-11-28 23:05:55 +0000254 let &report= repkeep
Bram Moolenaara5792f52005-11-23 21:25:05 +0000255 return
256 endif
257
Bram Moolenaar7fc0c062010-08-10 21:43:35 +0200258 " about to make a new window, need to use b:tarfile
259 let tarfile= b:tarfile
Bram Moolenaara5792f52005-11-23 21:25:05 +0000260 let curfile= expand("%")
Bram Moolenaarff034192013-04-24 18:51:19 +0200261 if has("win32unix") && executable("cygpath")
Bram Moolenaar910f66f2006-04-05 20:41:53 +0000262 " assuming cygwin
Bram Moolenaar5c736222010-01-06 20:54:52 +0100263 let tarfile=substitute(system("cygpath -u ".shellescape(tarfile,0)),'\n$','','e')
Bram Moolenaar910f66f2006-04-05 20:41:53 +0000264 endif
Bram Moolenaara5792f52005-11-23 21:25:05 +0000265
Bram Moolenaar29634562020-01-09 21:46:04 +0100266 " open a new window (tar#Read will read a file into it)
267 noswapfile new
Bram Moolenaar8c8de832008-06-24 22:58:06 +0000268 if !exists("g:tar_nomax") || g:tar_nomax == 0
269 wincmd _
270 endif
Bram Moolenaara5792f52005-11-23 21:25:05 +0000271 let s:tblfile_{winnr()}= curfile
Bram Moolenaar8c8de832008-06-24 22:58:06 +0000272 call tar#Read("tarfile:".tarfile.'::'.fname,1)
Bram Moolenaara5792f52005-11-23 21:25:05 +0000273 filetype detect
Bram Moolenaarff034192013-04-24 18:51:19 +0200274 set nomod
275 exe 'com! -buffer -nargs=? -complete=file TarDiff :call tar#Diff(<q-args>,"'.fnameescape(fname).'")'
Bram Moolenaara5792f52005-11-23 21:25:05 +0000276
Bram Moolenaarbba577a2005-11-28 23:05:55 +0000277 let &report= repkeep
Bram Moolenaara5792f52005-11-23 21:25:05 +0000278endfun
279
280" ---------------------------------------------------------------------
281" tar#Read: {{{2
282fun! tar#Read(fname,mode)
Bram Moolenaarbba577a2005-11-28 23:05:55 +0000283 let repkeep= &report
284 set report=10
Bram Moolenaar8c8de832008-06-24 22:58:06 +0000285 let tarfile = substitute(a:fname,'tarfile:\(.\{-}\)::.*$','\1','')
286 let fname = substitute(a:fname,'tarfile:.\{-}::\(.*\)$','\1','')
Christian Brabandt334a13b2025-03-02 19:33:51 +0100287 " be careful not to execute special crafted files
288 let escape_file = fname->fnameescape()
Lennart00129a8442024-11-11 22:39:30 +0100289
Corpulent Robinb69cd522025-02-06 21:10:49 +0100290 " changing the directory to the temporary earlier to allow tar to extract the file with permissions intact
Lennart00129a8442024-11-11 22:39:30 +0100291 if !exists("*mkdir")
292 redraw!
293 echohl Error | echo "***error*** (tar#Write) sorry, mkdir() doesn't work on your system" | echohl None
294 let &report= repkeep
295 return
296 endif
297
298 let curdir= getcwd()
299 let tmpdir= tempname()
300 let b:curdir= tmpdir
301 let b:tmpdir= curdir
302 if tmpdir =~ '\.'
303 let tmpdir= substitute(tmpdir,'\.[^.]*$','','e')
304 endif
305 call mkdir(tmpdir,"p")
306
307 " attempt to change to the indicated directory
308 try
309 exe "cd ".fnameescape(tmpdir)
310 catch /^Vim\%((\a\+)\)\=:E344/
311 redraw!
312 echohl Error | echo "***error*** (tar#Write) cannot cd to temporary directory" | Echohl None
313 let &report= repkeep
314 return
315 endtry
316
317 " place temporary files under .../_ZIPVIM_/
318 if isdirectory("_ZIPVIM_")
319 call s:Rmdir("_ZIPVIM_")
320 endif
321 call mkdir("_ZIPVIM_")
322 cd _ZIPVIM_
323
Bram Moolenaarff034192013-04-24 18:51:19 +0200324 if has("win32unix") && executable("cygpath")
Bram Moolenaar910f66f2006-04-05 20:41:53 +0000325 " assuming cygwin
Bram Moolenaar5c736222010-01-06 20:54:52 +0100326 let tarfile=substitute(system("cygpath -u ".shellescape(tarfile,0)),'\n$','','e')
Bram Moolenaar910f66f2006-04-05 20:41:53 +0000327 endif
Bram Moolenaara5792f52005-11-23 21:25:05 +0000328
Bram Moolenaar5c736222010-01-06 20:54:52 +0100329 if fname =~ '\.bz2$' && executable("bzcat")
330 let decmp= "|bzcat"
331 let doro = 1
Jim Zhou56957ed2025-02-28 18:06:14 +0100332 elseif fname =~ '\.bz3$' && executable("bz3cat")
333 let decmp= "|bz3cat"
334 let doro = 1
Bram Moolenaar29634562020-01-09 21:46:04 +0100335 elseif fname =~ '\.t\=gz$' && executable("zcat")
Bram Moolenaar8c8de832008-06-24 22:58:06 +0000336 let decmp= "|zcat"
337 let doro = 1
Bram Moolenaar5c736222010-01-06 20:54:52 +0100338 elseif fname =~ '\.lzma$' && executable("lzcat")
339 let decmp= "|lzcat"
Bram Moolenaar8c8de832008-06-24 22:58:06 +0000340 let doro = 1
Bram Moolenaar477db062010-07-28 18:17:41 +0200341 elseif fname =~ '\.xz$' && executable("xzcat")
342 let decmp= "|xzcat"
343 let doro = 1
Bram Moolenaar23515b42020-11-29 14:36:24 +0100344 elseif fname =~ '\.zst$' && executable("zstdcat")
345 let decmp= "|zstdcat"
346 let doro = 1
Corpulent Robinb69cd522025-02-06 21:10:49 +0100347 elseif fname =~ '\.lz4$' && executable("lz4cat")
348 let decmp= "|lz4cat"
349 let doro = 1
Bram Moolenaara5792f52005-11-23 21:25:05 +0000350 else
Bram Moolenaar8c8de832008-06-24 22:58:06 +0000351 let decmp=""
352 let doro = 0
Jim Zhou56957ed2025-02-28 18:06:14 +0100353 if fname =~ '\.bz2$\|\.bz3$\|\.gz$\|\.lzma$\|\.xz$\|\.zip$\|\.Z$'
Bram Moolenaar8c8de832008-06-24 22:58:06 +0000354 setlocal bin
355 endif
Bram Moolenaara5792f52005-11-23 21:25:05 +0000356 endif
Bram Moolenaar8c8de832008-06-24 22:58:06 +0000357
Bram Moolenaared39e1d2008-08-09 17:55:22 +0000358 if exists("g:tar_secure")
359 let tar_secure= " -- "
Bram Moolenaar8c8de832008-06-24 22:58:06 +0000360 else
Bram Moolenaared39e1d2008-08-09 17:55:22 +0000361 let tar_secure= " "
362 endif
Bram Moolenaar20aac6c2018-09-02 21:07:30 +0200363
Bram Moolenaar5c736222010-01-06 20:54:52 +0100364 if tarfile =~# '\.bz2$'
Bram Moolenaar251e1912011-06-19 05:09:16 +0200365 exe "sil! r! bzip2 -d -c -- ".shellescape(tarfile,1)."| ".g:tar_cmd." -".g:tar_readoptions." - ".tar_secure.shellescape(fname,1).decmp
Christian Brabandt334a13b2025-03-02 19:33:51 +0100366 exe "read ".escape_file
Christian Brabandt8ac975d2025-03-01 17:13:40 +0100367 elseif tarfile =~# '\.bz3$'
Jim Zhou56957ed2025-02-28 18:06:14 +0100368 exe "sil! r! bzip3 -d -c -- ".shellescape(tarfile,1)."| ".g:tar_cmd." -".g:tar_readoptions." - ".tar_secure.shellescape(fname,1).decmp
Christian Brabandt334a13b2025-03-02 19:33:51 +0100369 exe "read ".escape_file
Bram Moolenaar29634562020-01-09 21:46:04 +0100370 elseif tarfile =~# '\.\(gz\)$'
371 exe "sil! r! gzip -d -c -- ".shellescape(tarfile,1)."| ".g:tar_cmd." -".g:tar_readoptions." - ".tar_secure.shellescape(fname,1).decmp
Christian Brabandt334a13b2025-03-02 19:33:51 +0100372 exe "read ".escape_file
Bram Moolenaar29634562020-01-09 21:46:04 +0100373 elseif tarfile =~# '\(\.tgz\|\.tbz\|\.txz\)'
Christian Brabandta2507382025-03-02 22:23:28 +0100374 let filekind= s:Header(tarfile)
375 if filekind =~? "bzip2"
Bram Moolenaar29634562020-01-09 21:46:04 +0100376 exe "sil! r! bzip2 -d -c -- ".shellescape(tarfile,1)."| ".g:tar_cmd." -".g:tar_readoptions." - ".tar_secure.shellescape(fname,1).decmp
Christian Brabandt334a13b2025-03-02 19:33:51 +0100377 exe "read ".escape_file
Jim Zhou56957ed2025-02-28 18:06:14 +0100378 elseif filekind =~ "bzip3"
379 exe "sil! r! bzip3 -d -c -- ".shellescape(tarfile,1)."| ".g:tar_cmd." -".g:tar_readoptions." - ".tar_secure.shellescape(fname,1).decmp
Christian Brabandt334a13b2025-03-02 19:33:51 +0100380 exe "read ".escape_file
Christian Brabandta2507382025-03-02 22:23:28 +0100381 elseif filekind =~? "xz"
Bram Moolenaar29634562020-01-09 21:46:04 +0100382 exe "sil! r! xz -d -c -- ".shellescape(tarfile,1)."| ".g:tar_cmd." -".g:tar_readoptions." - ".tar_secure.shellescape(fname,1).decmp
Christian Brabandt334a13b2025-03-02 19:33:51 +0100383 exe "read ".escape_file
Christian Brabandta2507382025-03-02 22:23:28 +0100384 elseif filekind =~? "zstd"
Bram Moolenaar23515b42020-11-29 14:36:24 +0100385 exe "sil! r! zstd --decompress --stdout -- ".shellescape(tarfile,1)."| ".g:tar_cmd." -".g:tar_readoptions." - ".tar_secure.shellescape(fname,1).decmp
Christian Brabandt334a13b2025-03-02 19:33:51 +0100386 exe "read ".escape_file
Christian Brabandta2507382025-03-02 22:23:28 +0100387 elseif filekind =~? "gzip"
Bram Moolenaar29634562020-01-09 21:46:04 +0100388 exe "sil! r! gzip -d -c -- ".shellescape(tarfile,1)."| ".g:tar_cmd." -".g:tar_readoptions." - ".tar_secure.shellescape(fname,1).decmp
Christian Brabandt334a13b2025-03-02 19:33:51 +0100389 exe "read ".escape_file
Bram Moolenaar29634562020-01-09 21:46:04 +0100390 endif
391
Bram Moolenaared39e1d2008-08-09 17:55:22 +0000392 elseif tarfile =~# '\.lrp$'
Bram Moolenaard4a1aab2018-09-08 15:10:34 +0200393 exe "sil! r! cat -- ".shellescape(tarfile,1)." | gzip -d -c - | ".g:tar_cmd." -".g:tar_readoptions." - ".tar_secure.shellescape(fname,1).decmp
Christian Brabandt334a13b2025-03-02 19:33:51 +0100394 exe "read ".escape_file
Bram Moolenaar5c736222010-01-06 20:54:52 +0100395 elseif tarfile =~# '\.lzma$'
Bram Moolenaar251e1912011-06-19 05:09:16 +0200396 exe "sil! r! lzma -d -c -- ".shellescape(tarfile,1)."| ".g:tar_cmd." -".g:tar_readoptions." - ".tar_secure.shellescape(fname,1).decmp
Christian Brabandt334a13b2025-03-02 19:33:51 +0100397 exe "read ".escape_file
Bram Moolenaar477db062010-07-28 18:17:41 +0200398 elseif tarfile =~# '\.\(xz\|txz\)$'
Bram Moolenaar251e1912011-06-19 05:09:16 +0200399 exe "sil! r! xz --decompress --stdout -- ".shellescape(tarfile,1)." | ".g:tar_cmd." -".g:tar_readoptions." - ".tar_secure.shellescape(fname,1).decmp
Christian Brabandt334a13b2025-03-02 19:33:51 +0100400 exe "read ".escape_file
Corpulent Robinb69cd522025-02-06 21:10:49 +0100401 elseif tarfile =~# '\.\(lz4\|tlz4\)$'
402 exe "sil! r! lz4 --decompress --stdout -- ".shellescape(tarfile,1)." | ".g:tar_cmd." -".g:tar_readoptions." - ".tar_secure.shellescape(fname,1).decmp
Christian Brabandt334a13b2025-03-02 19:33:51 +0100403 exe "read ".escape_file
Bram Moolenaared39e1d2008-08-09 17:55:22 +0000404 else
405 if tarfile =~ '^\s*-'
Bram Moolenaar5c736222010-01-06 20:54:52 +0100406 " A file name starting with a dash is taken as an option. Prepend ./ to avoid that.
Bram Moolenaared39e1d2008-08-09 17:55:22 +0000407 let tarfile = substitute(tarfile, '-', './-', '')
408 endif
Bram Moolenaar5c736222010-01-06 20:54:52 +0100409 exe "silent r! ".g:tar_cmd." -".g:tar_readoptions.shellescape(tarfile,1)." ".tar_secure.shellescape(fname,1).decmp
Christian Brabandt334a13b2025-03-02 19:33:51 +0100410 exe "read ".escape_file
Lennart00129a8442024-11-11 22:39:30 +0100411 endif
412
413 redraw!
414
415if v:shell_error != 0
416 cd ..
417 call s:Rmdir("_ZIPVIM_")
418 exe "cd ".fnameescape(curdir)
419 echohl Error | echo "***error*** (tar#Read) sorry, unable to open or extract ".tarfile." with ".fname | echohl None
Bram Moolenaar8c8de832008-06-24 22:58:06 +0000420 endif
421
422 if doro
423 " because the reverse process of compressing changed files back into the tarball is not currently supported
424 setlocal ro
425 endif
426
Bram Moolenaar7fc0c062010-08-10 21:43:35 +0200427 let b:tarfile= a:fname
Bram Moolenaarc236c162008-07-13 17:41:49 +0000428 exe "file tarfile::".fnameescape(fname)
Bram Moolenaara5792f52005-11-23 21:25:05 +0000429
430 " cleanup
Bram Moolenaar251e1912011-06-19 05:09:16 +0200431 keepj sil! 0d
Bram Moolenaara5792f52005-11-23 21:25:05 +0000432 set nomod
433
Bram Moolenaarbba577a2005-11-28 23:05:55 +0000434 let &report= repkeep
Bram Moolenaara5792f52005-11-23 21:25:05 +0000435endfun
436
437" ---------------------------------------------------------------------
438" tar#Write: {{{2
439fun! tar#Write(fname)
Bram Moolenaarbba577a2005-11-28 23:05:55 +0000440 let repkeep= &report
441 set report=10
Lennart00129a8442024-11-11 22:39:30 +0100442 " temporary buffer variable workaround because too fucking tired. but it works now
443 let curdir= b:curdir
444 let tmpdir= b:tmpdir
Bram Moolenaara5792f52005-11-23 21:25:05 +0000445
Bram Moolenaared39e1d2008-08-09 17:55:22 +0000446 if !exists("g:tar_secure") && a:fname =~ '^\s*-\|\s\+-'
447 redraw!
Bram Moolenaar5c736222010-01-06 20:54:52 +0100448 echohl WarningMsg | echo '***warning*** (tar#Write) rejecting tarfile member<'.a:fname.'> because of embedded "-"'
Bram Moolenaared39e1d2008-08-09 17:55:22 +0000449 return
450 endif
451
Bram Moolenaarab194812005-09-14 21:40:12 +0000452 " sanity checks
Bram Moolenaar910f66f2006-04-05 20:41:53 +0000453 if !executable(g:tar_cmd)
Bram Moolenaarc81e5e72007-05-05 18:24:42 +0000454 redraw!
Bram Moolenaarbba577a2005-11-28 23:05:55 +0000455 let &report= repkeep
Bram Moolenaarab194812005-09-14 21:40:12 +0000456 return
457 endif
Bram Moolenaarab194812005-09-14 21:40:12 +0000458
Bram Moolenaar7fc0c062010-08-10 21:43:35 +0200459 let tarfile = substitute(b:tarfile,'tarfile:\(.\{-}\)::.*$','\1','')
460 let fname = substitute(b:tarfile,'tarfile:.\{-}::\(.*\)$','\1','')
Bram Moolenaara5792f52005-11-23 21:25:05 +0000461
462 " handle compressed archives
Bram Moolenaar5c736222010-01-06 20:54:52 +0100463 if tarfile =~# '\.bz2'
464 call system("bzip2 -d -- ".shellescape(tarfile,0))
465 let tarfile = substitute(tarfile,'\.bz2','','e')
466 let compress= "bzip2 -- ".shellescape(tarfile,0)
Jim Zhou56957ed2025-02-28 18:06:14 +0100467 elseif tarfile =~# '\.bz3'
468 call system("bzip3 -d -- ".shellescape(tarfile,0))
469 let tarfile = substitute(tarfile,'\.bz3','','e')
470 let compress= "bzip3 -- ".shellescape(tarfile,0)
Bram Moolenaar5c736222010-01-06 20:54:52 +0100471 elseif tarfile =~# '\.gz'
Bram Moolenaar29634562020-01-09 21:46:04 +0100472 call system("gzip -d -- ".shellescape(tarfile,0))
Bram Moolenaara5792f52005-11-23 21:25:05 +0000473 let tarfile = substitute(tarfile,'\.gz','','e')
Bram Moolenaar5c736222010-01-06 20:54:52 +0100474 let compress= "gzip -- ".shellescape(tarfile,0)
Bram Moolenaara5792f52005-11-23 21:25:05 +0000475 elseif tarfile =~# '\.tgz'
Bram Moolenaar29634562020-01-09 21:46:04 +0100476 call system("gzip -d -- ".shellescape(tarfile,0))
Bram Moolenaara5792f52005-11-23 21:25:05 +0000477 let tarfile = substitute(tarfile,'\.tgz','.tar','e')
Bram Moolenaar5c736222010-01-06 20:54:52 +0100478 let compress= "gzip -- ".shellescape(tarfile,0)
Bram Moolenaara5792f52005-11-23 21:25:05 +0000479 let tgz = 1
Bram Moolenaar477db062010-07-28 18:17:41 +0200480 elseif tarfile =~# '\.xz'
481 call system("xz -d -- ".shellescape(tarfile,0))
482 let tarfile = substitute(tarfile,'\.xz','','e')
483 let compress= "xz -- ".shellescape(tarfile,0)
Bram Moolenaar23515b42020-11-29 14:36:24 +0100484 elseif tarfile =~# '\.zst'
Christian Brabandt3a5b3df2024-01-08 20:02:14 +0100485 call system("zstd --decompress --rm -- ".shellescape(tarfile,0))
Bram Moolenaar23515b42020-11-29 14:36:24 +0100486 let tarfile = substitute(tarfile,'\.zst','','e')
Christian Brabandt3a5b3df2024-01-08 20:02:14 +0100487 let compress= "zstd --rm -- ".shellescape(tarfile,0)
Corpulent Robinb69cd522025-02-06 21:10:49 +0100488 elseif tarfile =~# '\.lz4'
489 call system("lz4 --decompress --rm -- ".shellescape(tarfile,0))
490 let tarfile = substitute(tarfile,'\.lz4','','e')
491 let compress= "lz4 --rm -- ".shellescape(tarfile,0)
Bram Moolenaar477db062010-07-28 18:17:41 +0200492 elseif tarfile =~# '\.lzma'
493 call system("lzma -d -- ".shellescape(tarfile,0))
494 let tarfile = substitute(tarfile,'\.lzma','','e')
495 let compress= "lzma -- ".shellescape(tarfile,0)
Bram Moolenaarab194812005-09-14 21:40:12 +0000496 endif
Christian Brabandta2507382025-03-02 22:23:28 +0100497 " Note: no support for name.tar.tbz/.txz/.tgz/.tlz4/.tzst
Bram Moolenaarab194812005-09-14 21:40:12 +0000498
Bram Moolenaarab194812005-09-14 21:40:12 +0000499 if v:shell_error != 0
Bram Moolenaarc81e5e72007-05-05 18:24:42 +0000500 redraw!
Bram Moolenaara5792f52005-11-23 21:25:05 +0000501 echohl Error | echo "***error*** (tar#Write) sorry, unable to update ".tarfile." with ".fname | echohl None
Bram Moolenaarab194812005-09-14 21:40:12 +0000502 else
Bram Moolenaara5792f52005-11-23 21:25:05 +0000503
Bram Moolenaar1cbe5f72005-12-29 22:51:09 +0000504 if fname =~ '/'
505 let dirpath = substitute(fname,'/[^/]\+$','','e')
Bram Moolenaarff034192013-04-24 18:51:19 +0200506 if has("win32unix") && executable("cygpath")
Bram Moolenaar5c736222010-01-06 20:54:52 +0100507 let dirpath = substitute(system("cygpath ".shellescape(dirpath, 0)),'\n','','e')
Bram Moolenaar1cbe5f72005-12-29 22:51:09 +0000508 endif
509 call mkdir(dirpath,"p")
510 endif
Bram Moolenaara5792f52005-11-23 21:25:05 +0000511 if tarfile !~ '/'
512 let tarfile= curdir.'/'.tarfile
513 endif
Bram Moolenaared39e1d2008-08-09 17:55:22 +0000514 if tarfile =~ '^\s*-'
515 " A file name starting with a dash may be taken as an option. Prepend ./ to avoid that.
516 let tarfile = substitute(tarfile, '-', './-', '')
517 endif
Christian Brabandt3a5b3df2024-01-08 20:02:14 +0100518
Bram Moolenaared39e1d2008-08-09 17:55:22 +0000519 if exists("g:tar_secure")
520 let tar_secure= " -- "
521 else
522 let tar_secure= " "
523 endif
Bram Moolenaar8c8de832008-06-24 22:58:06 +0000524 exe "w! ".fnameescape(fname)
Bram Moolenaarff034192013-04-24 18:51:19 +0200525 if has("win32unix") && executable("cygpath")
Bram Moolenaar5c736222010-01-06 20:54:52 +0100526 let tarfile = substitute(system("cygpath ".shellescape(tarfile,0)),'\n','','e')
Bram Moolenaara5792f52005-11-23 21:25:05 +0000527 endif
Christian Brabandt3a5b3df2024-01-08 20:02:14 +0100528
Bram Moolenaara5792f52005-11-23 21:25:05 +0000529 " delete old file from tarfile
Bram Moolenaar29634562020-01-09 21:46:04 +0100530 call system(g:tar_cmd." ".g:tar_delfile." ".shellescape(tarfile,0).tar_secure.shellescape(fname,0))
Bram Moolenaara5792f52005-11-23 21:25:05 +0000531 if v:shell_error != 0
Bram Moolenaarc81e5e72007-05-05 18:24:42 +0000532 redraw!
Bram Moolenaar8c8de832008-06-24 22:58:06 +0000533 echohl Error | echo "***error*** (tar#Write) sorry, unable to update ".fnameescape(tarfile)." with ".fnameescape(fname) | echohl None
Bram Moolenaara5792f52005-11-23 21:25:05 +0000534 else
Christian Brabandt3a5b3df2024-01-08 20:02:14 +0100535
536 " update tarfile with new file
Bram Moolenaar5c736222010-01-06 20:54:52 +0100537 call system(g:tar_cmd." -".g:tar_writeoptions." ".shellescape(tarfile,0).tar_secure.shellescape(fname,0))
Bram Moolenaara5792f52005-11-23 21:25:05 +0000538 if v:shell_error != 0
Bram Moolenaarc81e5e72007-05-05 18:24:42 +0000539 redraw!
Bram Moolenaar8c8de832008-06-24 22:58:06 +0000540 echohl Error | echo "***error*** (tar#Write) sorry, unable to update ".fnameescape(tarfile)." with ".fnameescape(fname) | echohl None
Bram Moolenaara5792f52005-11-23 21:25:05 +0000541 elseif exists("compress")
Bram Moolenaara5792f52005-11-23 21:25:05 +0000542 call system(compress)
543 if exists("tgz")
Bram Moolenaara5792f52005-11-23 21:25:05 +0000544 call rename(tarfile.".gz",substitute(tarfile,'\.tar$','.tgz','e'))
545 endif
546 endif
547 endif
548
549 " support writing tarfiles across a network
550 if s:tblfile_{winnr()} =~ '^\a\+://'
Bram Moolenaara5792f52005-11-23 21:25:05 +0000551 let tblfile= s:tblfile_{winnr()}
Bram Moolenaar29634562020-01-09 21:46:04 +0100552 1split|noswapfile enew
Bram Moolenaar5c736222010-01-06 20:54:52 +0100553 let binkeep= &l:binary
Bram Moolenaara5792f52005-11-23 21:25:05 +0000554 let eikeep = &ei
555 set binary ei=all
Bram Moolenaar29634562020-01-09 21:46:04 +0100556 exe "noswapfile e! ".fnameescape(tarfile)
Bram Moolenaara5792f52005-11-23 21:25:05 +0000557 call netrw#NetWrite(tblfile)
Bram Moolenaar5c736222010-01-06 20:54:52 +0100558 let &ei = eikeep
559 let &l:binary = binkeep
Bram Moolenaara5792f52005-11-23 21:25:05 +0000560 q!
561 unlet s:tblfile_{winnr()}
562 endif
Bram Moolenaarab194812005-09-14 21:40:12 +0000563 endif
Christian Brabandt3a5b3df2024-01-08 20:02:14 +0100564
Bram Moolenaarab194812005-09-14 21:40:12 +0000565 " cleanup and restore current directory
566 cd ..
Bram Moolenaara5792f52005-11-23 21:25:05 +0000567 call s:Rmdir("_ZIPVIM_")
Bram Moolenaarc236c162008-07-13 17:41:49 +0000568 exe "cd ".fnameescape(curdir)
Bram Moolenaarab194812005-09-14 21:40:12 +0000569 setlocal nomod
570
Bram Moolenaarbba577a2005-11-28 23:05:55 +0000571 let &report= repkeep
Bram Moolenaarab194812005-09-14 21:40:12 +0000572endfun
573
574" ---------------------------------------------------------------------
Bram Moolenaarff034192013-04-24 18:51:19 +0200575" tar#Diff: {{{2
576fun! tar#Diff(userfname,fname)
Bram Moolenaarff034192013-04-24 18:51:19 +0200577 let fname= a:fname
578 if a:userfname != ""
579 let fname= a:userfname
580 endif
581 if filereadable(fname)
582 " sets current file (from tarball) for diff'ing
583 " splits window vertically
584 " opens original file, sets it for diff'ing
585 " sets up b:tardiff_otherbuf variables so each buffer knows about the other (for closing purposes)
586 diffthis
587 wincmd v
Bram Moolenaar29634562020-01-09 21:46:04 +0100588 exe "noswapfile e ".fnameescape(fname)
Bram Moolenaarff034192013-04-24 18:51:19 +0200589 diffthis
590 else
591 redraw!
592 echo "***warning*** unable to read file<".fname.">"
593 endif
Bram Moolenaarff034192013-04-24 18:51:19 +0200594endfun
595
596" ---------------------------------------------------------------------
Bram Moolenaar29634562020-01-09 21:46:04 +0100597" tar#Extract: extract a file from a (possibly compressed) tar archive {{{2
598fun! tar#Extract()
Bram Moolenaar29634562020-01-09 21:46:04 +0100599
600 let repkeep= &report
601 set report=10
602 let fname= getline(".")
Bram Moolenaar29634562020-01-09 21:46:04 +0100603
604 if !exists("g:tar_secure") && fname =~ '^\s*-\|\s\+-'
605 redraw!
606 echohl WarningMsg | echo '***warning*** (tar#BrowseSelect) rejecting tarfile member<'.fname.'> because of embedded "-"'
Bram Moolenaar29634562020-01-09 21:46:04 +0100607 return
608 endif
609
610 " sanity check
611 if fname =~ '^"'
612 let &report= repkeep
Bram Moolenaar29634562020-01-09 21:46:04 +0100613 return
614 endif
615
616 let tarball = expand("%")
Bram Moolenaar29634562020-01-09 21:46:04 +0100617 let tarbase = substitute(tarball,'\..*$','','')
Bram Moolenaar29634562020-01-09 21:46:04 +0100618
Christian Brabandt470317f2025-04-16 17:13:28 +0200619 let extractcmd= s:WinPath(g:tar_extractcmd)
Bram Moolenaar29634562020-01-09 21:46:04 +0100620 if filereadable(tarbase.".tar")
Bram Moolenaar29634562020-01-09 21:46:04 +0100621 call system(extractcmd." ".shellescape(tarbase).".tar ".shellescape(fname))
622 if v:shell_error != 0
623 echohl Error | echo "***error*** ".extractcmd." ".tarbase.".tar ".fname.": failed!" | echohl NONE
Bram Moolenaar29634562020-01-09 21:46:04 +0100624 else
625 echo "***note*** successfully extracted ".fname
626 endif
627
628 elseif filereadable(tarbase.".tgz")
629 let extractcmd= substitute(extractcmd,"-","-z","")
Bram Moolenaar29634562020-01-09 21:46:04 +0100630 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
Bram Moolenaar29634562020-01-09 21:46:04 +0100633 else
634 echo "***note*** successfully extracted ".fname
635 endif
636
637 elseif filereadable(tarbase.".tar.gz")
638 let extractcmd= substitute(extractcmd,"-","-z","")
Bram Moolenaar29634562020-01-09 21:46:04 +0100639 call system(extractcmd." ".shellescape(tarbase).".tar.gz ".shellescape(fname))
640 if v:shell_error != 0
641 echohl Error | echo "***error*** ".extractcmd." ".tarbase.".tar.gz ".fname.": failed!" | echohl NONE
Bram Moolenaar29634562020-01-09 21:46:04 +0100642 else
643 echo "***note*** successfully extracted ".fname
644 endif
645
646 elseif filereadable(tarbase.".tbz")
647 let extractcmd= substitute(extractcmd,"-","-j","")
Bram Moolenaar29634562020-01-09 21:46:04 +0100648 call system(extractcmd." ".shellescape(tarbase).".tbz ".shellescape(fname))
649 if v:shell_error != 0
650 echohl Error | echo "***error*** ".extractcmd."j ".tarbase.".tbz ".fname.": failed!" | echohl NONE
Bram Moolenaar29634562020-01-09 21:46:04 +0100651 else
652 echo "***note*** successfully extracted ".fname
653 endif
654
655 elseif filereadable(tarbase.".tar.bz2")
656 let extractcmd= substitute(extractcmd,"-","-j","")
Bram Moolenaar29634562020-01-09 21:46:04 +0100657 call system(extractcmd." ".shellescape(tarbase).".tar.bz2 ".shellescape(fname))
658 if v:shell_error != 0
659 echohl Error | echo "***error*** ".extractcmd."j ".tarbase.".tar.bz2 ".fname.": failed!" | echohl NONE
Bram Moolenaar29634562020-01-09 21:46:04 +0100660 else
661 echo "***note*** successfully extracted ".fname
662 endif
663
Jim Zhou56957ed2025-02-28 18:06:14 +0100664 elseif filereadable(tarbase.".tar.bz3")
665 let extractcmd= substitute(extractcmd,"-","-j","")
666 call system(extractcmd." ".shellescape(tarbase).".tar.bz3 ".shellescape(fname))
667 if v:shell_error != 0
668 echohl Error | echo "***error*** ".extractcmd."j ".tarbase.".tar.bz3 ".fname.": failed!" | echohl NONE
669 else
670 echo "***note*** successfully extracted ".fname
671 endif
672
Bram Moolenaar29634562020-01-09 21:46:04 +0100673 elseif filereadable(tarbase.".txz")
674 let extractcmd= substitute(extractcmd,"-","-J","")
Bram Moolenaar29634562020-01-09 21:46:04 +0100675 call system(extractcmd." ".shellescape(tarbase).".txz ".shellescape(fname))
676 if v:shell_error != 0
677 echohl Error | echo "***error*** ".extractcmd." ".tarbase.".txz ".fname.": failed!" | echohl NONE
Bram Moolenaar29634562020-01-09 21:46:04 +0100678 else
679 echo "***note*** successfully extracted ".fname
680 endif
681
682 elseif filereadable(tarbase.".tar.xz")
683 let extractcmd= substitute(extractcmd,"-","-J","")
Bram Moolenaar29634562020-01-09 21:46:04 +0100684 call system(extractcmd." ".shellescape(tarbase).".tar.xz ".shellescape(fname))
685 if v:shell_error != 0
686 echohl Error | echo "***error*** ".extractcmd." ".tarbase.".tar.xz ".fname.": failed!" | echohl NONE
Bram Moolenaar29634562020-01-09 21:46:04 +0100687 else
688 echo "***note*** successfully extracted ".fname
689 endif
Bram Moolenaar23515b42020-11-29 14:36:24 +0100690
Christian Brabandt3a5b3df2024-01-08 20:02:14 +0100691 elseif filereadable(tarbase.".tzst")
Bram Moolenaar23515b42020-11-29 14:36:24 +0100692 let extractcmd= substitute(extractcmd,"-","--zstd","")
Christian Brabandt3a5b3df2024-01-08 20:02:14 +0100693 call system(extractcmd." ".shellescape(tarbase).".tzst ".shellescape(fname))
Bram Moolenaar23515b42020-11-29 14:36:24 +0100694 if v:shell_error != 0
Christian Brabandt3a5b3df2024-01-08 20:02:14 +0100695 echohl Error | echo "***error*** ".extractcmd." ".tarbase.".tzst ".fname.": failed!" | echohl NONE
Bram Moolenaar23515b42020-11-29 14:36:24 +0100696 else
697 echo "***note*** successfully extracted ".fname
698 endif
699
700 elseif filereadable(tarbase.".tar.zst")
701 let extractcmd= substitute(extractcmd,"-","--zstd","")
Christian Brabandt3a5b3df2024-01-08 20:02:14 +0100702 call system(extractcmd." ".shellescape(tarbase).".tar.zst ".shellescape(fname))
Bram Moolenaar23515b42020-11-29 14:36:24 +0100703 if v:shell_error != 0
704 echohl Error | echo "***error*** ".extractcmd." ".tarbase.".tar.zst ".fname.": failed!" | echohl NONE
Corpulent Robinb69cd522025-02-06 21:10:49 +0100705 else
706 echo "***note*** successfully extracted ".fname
707 endif
708
709 elseif filereadable(tarbase.".tlz4")
710 let extractcmd= substitute(extractcmd,"-","-I lz4","")
711 call system(extractcmd." ".shellescape(tarbase).".tlz4 ".shellescape(fname))
712 if v:shell_error != 0
713 echohl Error | echo "***error*** ".extractcmd." ".tarbase.".tlz4 ".fname.": failed!" | echohl NONE
714 else
715 echo "***note*** successfully extracted ".fname
716 endif
717
718 elseif filereadable(tarbase.".tar.lz4")
719 let extractcmd= substitute(extractcmd,"-","-I lz4","")
720 call system(extractcmd." ".shellescape(tarbase).".tar.lz4".shellescape(fname))
721 if v:shell_error != 0
722 echohl Error | echo "***error*** ".extractcmd." ".tarbase.".tar.lz4 ".fname.": failed!" | echohl NONE
Bram Moolenaar23515b42020-11-29 14:36:24 +0100723 else
724 echo "***note*** successfully extracted ".fname
725 endif
Bram Moolenaar29634562020-01-09 21:46:04 +0100726 endif
727
728 " restore option
729 let &report= repkeep
Bram Moolenaar29634562020-01-09 21:46:04 +0100730endfun
731
732" ---------------------------------------------------------------------
Bram Moolenaar5c736222010-01-06 20:54:52 +0100733" s:Rmdir: {{{2
Bram Moolenaarab194812005-09-14 21:40:12 +0000734fun! s:Rmdir(fname)
Bram Moolenaarab194812005-09-14 21:40:12 +0000735 if has("unix")
Bram Moolenaar5c736222010-01-06 20:54:52 +0100736 call system("/bin/rm -rf -- ".shellescape(a:fname,0))
Bram Moolenaarab194812005-09-14 21:40:12 +0000737 elseif has("win32") || has("win95") || has("win64") || has("win16")
738 if &shell =~? "sh$"
Bram Moolenaar5c736222010-01-06 20:54:52 +0100739 call system("/bin/rm -rf -- ".shellescape(a:fname,0))
Bram Moolenaarab194812005-09-14 21:40:12 +0000740 else
Bram Moolenaar5c736222010-01-06 20:54:52 +0100741 call system("del /S ".shellescape(a:fname,0))
Bram Moolenaarab194812005-09-14 21:40:12 +0000742 endif
743 endif
Bram Moolenaarab194812005-09-14 21:40:12 +0000744endfun
745
Christian Brabandta2507382025-03-02 22:23:28 +0100746" s:FileHeader: {{{2
747fun! s:Header(fname)
748 let header= readblob(a:fname, 0, 6)
749 if header[0:2] == str2blob(['BZh']) " bzip2 header
750 return "bzip2"
751 elseif header[0:2] == str2blob(['BZ3']) " bzip3 header
752 return "bzip3"
753 elseif header == str2blob(["\3757zXZ\n"]) " xz header
754 return "xz"
755 elseif header[0:3] == str2blob(["\x28\xB5\x2F\xFD"]) " zstd header
756 return "zstd"
757 elseif header[0:3] == str2blob(["\004\"M\030"]) " lz4 header
758 return "lz4"
759 elseif (header[0:1] == str2blob(["\037\235"]) ||
760 \ header[0:1] == str2blob(["\037\213"]) ||
761 \ header[0:1] == str2blob(["\037\236"]) ||
762 \ header[0:1] == str2blob(["\037\240"]) ||
763 \ header[0:1] == str2blob(["\037\036"]))
764 return "gzip"
765 endif
766 return "unknown"
767endfun
768
Bram Moolenaar8c8de832008-06-24 22:58:06 +0000769" ---------------------------------------------------------------------
Christian Brabandt470317f2025-04-16 17:13:28 +0200770" s:WinPath: {{{2
771fun! s:WinPath(path)
772 if (!g:netrw_cygwin || &shell !~ '\%(\<bash\>\|\<zsh\>\)\%(\.exe\)\=$') && has("win32")
773 " remove cygdrive prefix, if present
774 let path = substitute(a:path, '/cygdrive/\(.\)', '\1:', '')
775 " remove trailing slash (Win95)
776 let path = substitute(path, '\(\\\|/\)$', '', 'g')
777 " remove escaped spaces
778 let path = substitute(path, '\ ', ' ', 'g')
779 " convert slashes to backslashes
780 let path = substitute(path, '/', '\', 'g')
781 else
782 let path = a:path
783 endif
784
785 return path
786endfun
787
788" ---------------------------------------------------------------------
Bram Moolenaar5c736222010-01-06 20:54:52 +0100789" tar#Vimuntar: installs a tarball in the user's .vim / vimfiles directory {{{2
790fun! tar#Vimuntar(...)
Bram Moolenaar5c736222010-01-06 20:54:52 +0100791 let tarball = expand("%")
Bram Moolenaar5c736222010-01-06 20:54:52 +0100792 let tarbase = substitute(tarball,'\..*$','','')
Bram Moolenaar5c736222010-01-06 20:54:52 +0100793 let tarhome = expand("%:p")
794 if has("win32") || has("win95") || has("win64") || has("win16")
795 let tarhome= substitute(tarhome,'\\','/','g')
796 endif
797 let tarhome= substitute(tarhome,'/[^/]*$','','')
Bram Moolenaar5c736222010-01-06 20:54:52 +0100798 let tartail = expand("%:t")
Bram Moolenaar5c736222010-01-06 20:54:52 +0100799 let curdir = getcwd()
Bram Moolenaar5c736222010-01-06 20:54:52 +0100800 " set up vimhome
801 if a:0 > 0 && a:1 != ""
802 let vimhome= a:1
803 else
804 let vimhome= vimball#VimballHome()
805 endif
Bram Moolenaar5c736222010-01-06 20:54:52 +0100806
Bram Moolenaar5c736222010-01-06 20:54:52 +0100807 if simplify(curdir) != simplify(vimhome)
808 " copy (possibly compressed) tarball to .vim/vimfiles
Christian Brabandt470317f2025-04-16 17:13:28 +0200809 call system(s:WinPath(g:tar_copycmd)." ".shellescape(tartail)." ".shellescape(vimhome))
Bram Moolenaar5c736222010-01-06 20:54:52 +0100810 exe "cd ".fnameescape(vimhome)
811 endif
Bram Moolenaar5c736222010-01-06 20:54:52 +0100812
813 " if necessary, decompress the tarball; then, extract it
814 if tartail =~ '\.tgz'
Bram Moolenaar29634562020-01-09 21:46:04 +0100815 if executable("gunzip")
Bram Moolenaar5c736222010-01-06 20:54:52 +0100816 silent exe "!gunzip ".shellescape(tartail)
817 elseif executable("gzip")
818 silent exe "!gzip -d ".shellescape(tartail)
Bram Moolenaarc236c162008-07-13 17:41:49 +0000819 else
Bram Moolenaar6c391a72021-09-09 21:55:11 +0200820 echoerr "unable to decompress<".tartail."> on this system"
Bram Moolenaar5c736222010-01-06 20:54:52 +0100821 if simplify(curdir) != simplify(tarhome)
822 " remove decompressed tarball, restore directory
Bram Moolenaar5c736222010-01-06 20:54:52 +0100823 call delete(tartail.".tar")
Bram Moolenaar5c736222010-01-06 20:54:52 +0100824 exe "cd ".fnameescape(curdir)
825 endif
Bram Moolenaar5c736222010-01-06 20:54:52 +0100826 return
Bram Moolenaarc236c162008-07-13 17:41:49 +0000827 endif
Bram Moolenaar8c8de832008-06-24 22:58:06 +0000828 else
Bram Moolenaar5c736222010-01-06 20:54:52 +0100829 call vimball#Decompress(tartail,0)
Bram Moolenaar8c8de832008-06-24 22:58:06 +0000830 endif
Christian Brabandt470317f2025-04-16 17:13:28 +0200831 let extractcmd= s:WinPath(g:tar_extractcmd)
Bram Moolenaar5c736222010-01-06 20:54:52 +0100832 call system(extractcmd." ".shellescape(tarbase.".tar"))
833
834 " set up help
835 if filereadable("doc/".tarbase.".txt")
Bram Moolenaar5c736222010-01-06 20:54:52 +0100836 exe "helptags ".getcwd()."/doc"
837 endif
838
839 if simplify(tarhome) != simplify(vimhome)
840 " remove decompressed tarball, restore directory
841 call delete(vimhome."/".tarbase.".tar")
842 exe "cd ".fnameescape(curdir)
843 endif
Bram Moolenaar8c8de832008-06-24 22:58:06 +0000844endfun
845
Bram Moolenaar5c736222010-01-06 20:54:52 +0100846" =====================================================================
Bram Moolenaara5792f52005-11-23 21:25:05 +0000847" Modelines And Restoration: {{{1
848let &cpo= s:keepcpo
849unlet s:keepcpo
Bram Moolenaar8c8de832008-06-24 22:58:06 +0000850" vim:ts=8 fdm=marker