blob: 4aab91566187709c6b08228bf63ffa35ac753f63 [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)
Bram Moolenaar87e25fd2005-07-27 21:13:01 +000017"
Bram Moolenaara5792f52005-11-23 21:25:05 +000018" Contains many ideas from Michael Toren's <tar.vim>
Bram Moolenaar87e25fd2005-07-27 21:13:01 +000019"
Bram Moolenaar29634562020-01-09 21:46:04 +010020" Copyright: Copyright (C) 2005-2017 Charles E. Campbell {{{1
Bram Moolenaara5792f52005-11-23 21:25:05 +000021" Permission is hereby granted to use and distribute this code,
22" with or without modifications, provided that this copyright
23" notice is copied with it. Like anything else that's free,
Bram Moolenaar8c8de832008-06-24 22:58:06 +000024" tar.vim and tarPlugin.vim are provided *as is* and comes
25" with no warranty of any kind, either expressed or implied.
26" By using this plugin, you agree that in no event will the
27" copyright holder be liable for any damages resulting from
28" the use of this software.
Bram Moolenaarab194812005-09-14 21:40:12 +000029" ---------------------------------------------------------------------
Bram Moolenaarc81e5e72007-05-05 18:24:42 +000030" Load Once: {{{1
Bram Moolenaar5c736222010-01-06 20:54:52 +010031if &cp || exists("g:loaded_tar")
Bram Moolenaara5792f52005-11-23 21:25:05 +000032 finish
33endif
Lennart00129a8442024-11-11 22:39:30 +010034let g:loaded_tar= "v32b"
Bram Moolenaar5c736222010-01-06 20:54:52 +010035if v:version < 702
36 echohl WarningMsg
37 echo "***warning*** this version of tar needs vim 7.2"
38 echohl Normal
39 finish
Bram Moolenaar8c8de832008-06-24 22:58:06 +000040endif
Bram Moolenaar5c736222010-01-06 20:54:52 +010041let s:keepcpo= &cpo
42set cpo&vim
Bram Moolenaar87e25fd2005-07-27 21:13:01 +000043
Bram Moolenaara5792f52005-11-23 21:25:05 +000044" ---------------------------------------------------------------------
45" Default Settings: {{{1
46if !exists("g:tar_browseoptions")
47 let g:tar_browseoptions= "Ptf"
48endif
49if !exists("g:tar_readoptions")
Lennart00129a8442024-11-11 22:39:30 +010050 let g:tar_readoptions= "pPxf"
Bram Moolenaara5792f52005-11-23 21:25:05 +000051endif
Bram Moolenaar910f66f2006-04-05 20:41:53 +000052if !exists("g:tar_cmd")
53 let g:tar_cmd= "tar"
54endif
Bram Moolenaara5792f52005-11-23 21:25:05 +000055if !exists("g:tar_writeoptions")
56 let g:tar_writeoptions= "uf"
57endif
Bram Moolenaar29634562020-01-09 21:46:04 +010058if !exists("g:tar_delfile")
59 let g:tar_delfile="--delete -f"
60endif
Bram Moolenaar251e1912011-06-19 05:09:16 +020061if !exists("g:netrw_cygwin")
62 if has("win32") || has("win95") || has("win64") || has("win16")
63 if &shell =~ '\%(\<bash\>\|\<zsh\>\)\%(\.exe\)\=$'
64 let g:netrw_cygwin= 1
65 else
66 let g:netrw_cygwin= 0
67 endif
68 else
69 let g:netrw_cygwin= 0
70 endif
71endif
Bram Moolenaar5c736222010-01-06 20:54:52 +010072if !exists("g:tar_copycmd")
73 if !exists("g:netrw_localcopycmd")
74 if has("win32") || has("win95") || has("win64") || has("win16")
75 if g:netrw_cygwin
76 let g:netrw_localcopycmd= "cp"
77 else
78 let g:netrw_localcopycmd= "copy"
79 endif
80 elseif has("unix") || has("macunix")
81 let g:netrw_localcopycmd= "cp"
82 else
83 let g:netrw_localcopycmd= ""
84 endif
85 endif
86 let g:tar_copycmd= g:netrw_localcopycmd
87endif
Bram Moolenaar5c736222010-01-06 20:54:52 +010088if !exists("g:tar_extractcmd")
Lennart00129a8442024-11-11 22:39:30 +010089 let g:tar_extractcmd= "tar -pxf"
Bram Moolenaar5c736222010-01-06 20:54:52 +010090endif
Bram Moolenaar87e25fd2005-07-27 21:13:01 +000091
Bram Moolenaar8c8de832008-06-24 22:58:06 +000092" set up shell quoting character
93if !exists("g:tar_shq")
Bram Moolenaarff034192013-04-24 18:51:19 +020094 if exists("+shq") && exists("&shq") && &shq != ""
Bram Moolenaar8c8de832008-06-24 22:58:06 +000095 let g:tar_shq= &shq
96 elseif has("win32") || has("win95") || has("win64") || has("win16")
97 if exists("g:netrw_cygwin") && g:netrw_cygwin
98 let g:tar_shq= "'"
99 else
100 let g:tar_shq= '"'
101 endif
102 else
103 let g:tar_shq= "'"
104 endif
Bram Moolenaar8c8de832008-06-24 22:58:06 +0000105endif
106
Bram Moolenaara5792f52005-11-23 21:25:05 +0000107" ----------------
108" Functions: {{{1
109" ----------------
Bram Moolenaar87e25fd2005-07-27 21:13:01 +0000110
Bram Moolenaara5792f52005-11-23 21:25:05 +0000111" ---------------------------------------------------------------------
112" tar#Browse: {{{2
113fun! tar#Browse(tarfile)
Bram Moolenaarbba577a2005-11-28 23:05:55 +0000114 let repkeep= &report
115 set report=10
Bram Moolenaar87e25fd2005-07-27 21:13:01 +0000116
Bram Moolenaara5792f52005-11-23 21:25:05 +0000117 " sanity checks
Bram Moolenaar910f66f2006-04-05 20:41:53 +0000118 if !executable(g:tar_cmd)
Bram Moolenaarc81e5e72007-05-05 18:24:42 +0000119 redraw!
Bram Moolenaar910f66f2006-04-05 20:41:53 +0000120 echohl Error | echo '***error*** (tar#Browse) "'.g:tar_cmd.'" not available on your system'
Bram Moolenaarbba577a2005-11-28 23:05:55 +0000121 let &report= repkeep
Bram Moolenaara5792f52005-11-23 21:25:05 +0000122 return
123 endif
124 if !filereadable(a:tarfile)
125 if a:tarfile !~# '^\a\+://'
Bram Moolenaar8024f932020-01-14 19:29:13 +0100126 " if it's an url, don't complain, let url-handlers such as vim do its thing
Bram Moolenaarc81e5e72007-05-05 18:24:42 +0000127 redraw!
Bram Moolenaara5792f52005-11-23 21:25:05 +0000128 echohl Error | echo "***error*** (tar#Browse) File not readable<".a:tarfile.">" | echohl None
Bram Moolenaara5792f52005-11-23 21:25:05 +0000129 endif
Bram Moolenaarbba577a2005-11-28 23:05:55 +0000130 let &report= repkeep
Bram Moolenaara5792f52005-11-23 21:25:05 +0000131 return
132 endif
133 if &ma != 1
134 set ma
135 endif
Bram Moolenaar7fc0c062010-08-10 21:43:35 +0200136 let b:tarfile= a:tarfile
Bram Moolenaar87e25fd2005-07-27 21:13:01 +0000137
Bram Moolenaara5792f52005-11-23 21:25:05 +0000138 setlocal noswapfile
139 setlocal buftype=nofile
140 setlocal bufhidden=hide
141 setlocal nobuflisted
142 setlocal nowrap
143 set ft=tar
Bram Moolenaar87e25fd2005-07-27 21:13:01 +0000144
Bram Moolenaara5792f52005-11-23 21:25:05 +0000145 " give header
Bram Moolenaar8c8de832008-06-24 22:58:06 +0000146 let lastline= line("$")
147 call setline(lastline+1,'" tar.vim version '.g:loaded_tar)
148 call setline(lastline+2,'" Browsing tarfile '.a:tarfile)
149 call setline(lastline+3,'" Select a file with cursor and press ENTER')
Bram Moolenaar251e1912011-06-19 05:09:16 +0200150 keepj $put =''
Bram Moolenaar6be7f872012-01-20 21:08:56 +0100151 keepj sil! 0d
Bram Moolenaar251e1912011-06-19 05:09:16 +0200152 keepj $
Bram Moolenaar87e25fd2005-07-27 21:13:01 +0000153
Bram Moolenaar910f66f2006-04-05 20:41:53 +0000154 let tarfile= a:tarfile
Bram Moolenaarff034192013-04-24 18:51:19 +0200155 if has("win32unix") && executable("cygpath")
Bram Moolenaar910f66f2006-04-05 20:41:53 +0000156 " assuming cygwin
Bram Moolenaar5c736222010-01-06 20:54:52 +0100157 let tarfile=substitute(system("cygpath -u ".shellescape(tarfile,0)),'\n$','','e')
Bram Moolenaara5792f52005-11-23 21:25:05 +0000158 endif
Bram Moolenaard68071d2006-05-02 22:08:30 +0000159 let curlast= line("$")
Bram Moolenaar29634562020-01-09 21:46:04 +0100160
161 if tarfile =~# '\.\(gz\)$'
Bram Moolenaar29634562020-01-09 21:46:04 +0100162 exe "sil! r! gzip -d -c -- ".shellescape(tarfile,1)." | ".g:tar_cmd." -".g:tar_browseoptions." - "
163
Corpulent Robinb69cd522025-02-06 21:10:49 +0100164 elseif tarfile =~# '\.\(tgz\)$' || tarfile =~# '\.\(tbz\)$' || tarfile =~# '\.\(txz\)$' ||
165 \ tarfile =~# '\.\(tzst\)$' || tarfile =~# '\.\(tlz4\)$'
Christian Brabandta2507382025-03-02 22:23:28 +0100166 let header= s:Header(tarfile)
Bram Moolenaar29634562020-01-09 21:46:04 +0100167
Christian Brabandta2507382025-03-02 22:23:28 +0100168 if header =~? 'bzip2'
Bram Moolenaar29634562020-01-09 21:46:04 +0100169 exe "sil! r! bzip2 -d -c -- ".shellescape(tarfile,1)." | ".g:tar_cmd." -".g:tar_browseoptions." - "
Christian Brabandta2507382025-03-02 22:23:28 +0100170 elseif header =~? 'bzip3'
Jim Zhou56957ed2025-02-28 18:06:14 +0100171 exe "sil! r! bzip3 -d -c -- ".shellescape(tarfile,1)." | ".g:tar_cmd." -".g:tar_browseoptions." - "
Christian Brabandta2507382025-03-02 22:23:28 +0100172 elseif header =~? 'xz'
Bram Moolenaar29634562020-01-09 21:46:04 +0100173 exe "sil! r! xz -d -c -- ".shellescape(tarfile,1)." | ".g:tar_cmd." -".g:tar_browseoptions." - "
Christian Brabandta2507382025-03-02 22:23:28 +0100174 elseif header =~? 'zstd'
Bram Moolenaar23515b42020-11-29 14:36:24 +0100175 exe "sil! r! zstd --decompress --stdout -- ".shellescape(tarfile,1)." | ".g:tar_cmd." -".g:tar_browseoptions." - "
Christian Brabandta2507382025-03-02 22:23:28 +0100176 elseif header =~? 'lz4'
Corpulent Robinb69cd522025-02-06 21:10:49 +0100177 exe "sil! r! lz4 --decompress --stdout -- ".shellescape(tarfile,1)." | ".g:tar_cmd." -".g:tar_browseoptions." - "
Christian Brabandta2507382025-03-02 22:23:28 +0100178 elseif header =~? 'gzip'
Bram Moolenaar29634562020-01-09 21:46:04 +0100179 exe "sil! r! gzip -d -c -- ".shellescape(tarfile,1)." | ".g:tar_cmd." -".g:tar_browseoptions." - "
180 endif
181
Bram Moolenaar8c8de832008-06-24 22:58:06 +0000182 elseif tarfile =~# '\.lrp'
Bram Moolenaard4a1aab2018-09-08 15:10:34 +0200183 exe "sil! r! cat -- ".shellescape(tarfile,1)."|gzip -d -c -|".g:tar_cmd." -".g:tar_browseoptions." - "
Bram Moolenaar6be7f872012-01-20 21:08:56 +0100184 elseif tarfile =~# '\.\(bz2\|tbz\|tb2\)$'
Bram Moolenaar251e1912011-06-19 05:09:16 +0200185 exe "sil! r! bzip2 -d -c -- ".shellescape(tarfile,1)." | ".g:tar_cmd." -".g:tar_browseoptions." - "
Jim Zhou56957ed2025-02-28 18:06:14 +0100186 elseif tarfile =~# '\.\(bz3\|tb3\)$'
187 exe "sil! r! bzip3 -d -c -- ".shellescape(tarfile,1)." | ".g:tar_cmd." -".g:tar_browseoptions." - "
Bram Moolenaar6be7f872012-01-20 21:08:56 +0100188 elseif tarfile =~# '\.\(lzma\|tlz\)$'
Bram Moolenaar251e1912011-06-19 05:09:16 +0200189 exe "sil! r! lzma -d -c -- ".shellescape(tarfile,1)." | ".g:tar_cmd." -".g:tar_browseoptions." - "
Bram Moolenaar477db062010-07-28 18:17:41 +0200190 elseif tarfile =~# '\.\(xz\|txz\)$'
Bram Moolenaar251e1912011-06-19 05:09:16 +0200191 exe "sil! r! xz --decompress --stdout -- ".shellescape(tarfile,1)." | ".g:tar_cmd." -".g:tar_browseoptions." - "
Christian Brabandt3a5b3df2024-01-08 20:02:14 +0100192 elseif tarfile =~# '\.\(zst\|tzst\)$'
Bram Moolenaar23515b42020-11-29 14:36:24 +0100193 exe "sil! r! zstd --decompress --stdout -- ".shellescape(tarfile,1)." | ".g:tar_cmd." -".g:tar_browseoptions." - "
Corpulent Robinb69cd522025-02-06 21:10:49 +0100194 elseif tarfile =~# '\.\(lz4\|tlz4\)$'
195 exe "sil! r! lz4 --decompress --stdout -- ".shellescape(tarfile,1)." | ".g:tar_cmd." -".g:tar_browseoptions." - "
Bram Moolenaar910f66f2006-04-05 20:41:53 +0000196 else
Bram Moolenaared39e1d2008-08-09 17:55:22 +0000197 if tarfile =~ '^\s*-'
Bram Moolenaar5c736222010-01-06 20:54:52 +0100198 " A file name starting with a dash is taken as an option. Prepend ./ to avoid that.
Bram Moolenaared39e1d2008-08-09 17:55:22 +0000199 let tarfile = substitute(tarfile, '-', './-', '')
200 endif
Bram Moolenaar251e1912011-06-19 05:09:16 +0200201 exe "sil! r! ".g:tar_cmd." -".g:tar_browseoptions." ".shellescape(tarfile,1)
Bram Moolenaar910f66f2006-04-05 20:41:53 +0000202 endif
203 if v:shell_error != 0
Bram Moolenaarc81e5e72007-05-05 18:24:42 +0000204 redraw!
Bram Moolenaard68071d2006-05-02 22:08:30 +0000205 echohl WarningMsg | echo "***warning*** (tar#Browse) please check your g:tar_browseoptions<".g:tar_browseoptions.">"
Bram Moolenaard68071d2006-05-02 22:08:30 +0000206 return
207 endif
Christian Brabandt3d372312023-11-05 17:44:05 +0100208 "
Christian Brabandt67abf152023-11-14 17:15:17 +0100209 " The following should not be neccessary, since in case of errors the
210 " previous if statement should have caught the problem (because tar exited
211 " with a non-zero exit code).
212 " if line("$") == curlast || ( line("$") == (curlast + 1) &&
213 " \ getline("$") =~# '\c\<\%(warning\|error\|inappropriate\|unrecognized\)\>' &&
214 " \ getline("$") =~ '\s' )
215 " redraw!
216 " echohl WarningMsg | echo "***warning*** (tar#Browse) ".a:tarfile." doesn't appear to be a tar file" | echohl None
217 " keepj sil! %d
218 " let eikeep= &ei
219 " set ei=BufReadCmd,FileReadCmd
220 " exe "r ".fnameescape(a:tarfile)
221 " let &ei= eikeep
222 " keepj sil! 1d
223 " call Dret("tar#Browse : a:tarfile<".a:tarfile.">")
224 " return
225 " endif
Bram Moolenaara5792f52005-11-23 21:25:05 +0000226
Bram Moolenaar29634562020-01-09 21:46:04 +0100227 " set up maps supported for tar
Bram Moolenaara5792f52005-11-23 21:25:05 +0000228 setlocal noma nomod ro
Bram Moolenaar29634562020-01-09 21:46:04 +0100229 noremap <silent> <buffer> <cr> :call <SID>TarBrowseSelect()<cr>
Christian Brabandt3a5b3df2024-01-08 20:02:14 +0100230 noremap <silent> <buffer> x :call tar#Extract()<cr>
Bram Moolenaar29634562020-01-09 21:46:04 +0100231 if &mouse != ""
232 noremap <silent> <buffer> <leftmouse> <leftmouse>:call <SID>TarBrowseSelect()<cr>
233 endif
Bram Moolenaara5792f52005-11-23 21:25:05 +0000234
Bram Moolenaarbba577a2005-11-28 23:05:55 +0000235 let &report= repkeep
Bram Moolenaarab194812005-09-14 21:40:12 +0000236endfun
Bram Moolenaar87e25fd2005-07-27 21:13:01 +0000237
Bram Moolenaarab194812005-09-14 21:40:12 +0000238" ---------------------------------------------------------------------
Bram Moolenaara5792f52005-11-23 21:25:05 +0000239" TarBrowseSelect: {{{2
240fun! s:TarBrowseSelect()
Bram Moolenaarbba577a2005-11-28 23:05:55 +0000241 let repkeep= &report
242 set report=10
Bram Moolenaara5792f52005-11-23 21:25:05 +0000243 let fname= getline(".")
Bram Moolenaara5792f52005-11-23 21:25:05 +0000244
Bram Moolenaared39e1d2008-08-09 17:55:22 +0000245 if !exists("g:tar_secure") && fname =~ '^\s*-\|\s\+-'
246 redraw!
Bram Moolenaar5c736222010-01-06 20:54:52 +0100247 echohl WarningMsg | echo '***warning*** (tar#BrowseSelect) rejecting tarfile member<'.fname.'> because of embedded "-"'
Bram Moolenaared39e1d2008-08-09 17:55:22 +0000248 return
249 endif
250
Bram Moolenaara5792f52005-11-23 21:25:05 +0000251 " sanity check
252 if fname =~ '^"'
Bram Moolenaarbba577a2005-11-28 23:05:55 +0000253 let &report= repkeep
Bram Moolenaara5792f52005-11-23 21:25:05 +0000254 return
255 endif
256
Bram Moolenaar7fc0c062010-08-10 21:43:35 +0200257 " about to make a new window, need to use b:tarfile
258 let tarfile= b:tarfile
Bram Moolenaara5792f52005-11-23 21:25:05 +0000259 let curfile= expand("%")
Bram Moolenaarff034192013-04-24 18:51:19 +0200260 if has("win32unix") && executable("cygpath")
Bram Moolenaar910f66f2006-04-05 20:41:53 +0000261 " assuming cygwin
Bram Moolenaar5c736222010-01-06 20:54:52 +0100262 let tarfile=substitute(system("cygpath -u ".shellescape(tarfile,0)),'\n$','','e')
Bram Moolenaar910f66f2006-04-05 20:41:53 +0000263 endif
Bram Moolenaara5792f52005-11-23 21:25:05 +0000264
Bram Moolenaar29634562020-01-09 21:46:04 +0100265 " open a new window (tar#Read will read a file into it)
266 noswapfile new
Bram Moolenaar8c8de832008-06-24 22:58:06 +0000267 if !exists("g:tar_nomax") || g:tar_nomax == 0
268 wincmd _
269 endif
Bram Moolenaara5792f52005-11-23 21:25:05 +0000270 let s:tblfile_{winnr()}= curfile
Bram Moolenaar8c8de832008-06-24 22:58:06 +0000271 call tar#Read("tarfile:".tarfile.'::'.fname,1)
Bram Moolenaara5792f52005-11-23 21:25:05 +0000272 filetype detect
Bram Moolenaarff034192013-04-24 18:51:19 +0200273 set nomod
274 exe 'com! -buffer -nargs=? -complete=file TarDiff :call tar#Diff(<q-args>,"'.fnameescape(fname).'")'
Bram Moolenaara5792f52005-11-23 21:25:05 +0000275
Bram Moolenaarbba577a2005-11-28 23:05:55 +0000276 let &report= repkeep
Bram Moolenaara5792f52005-11-23 21:25:05 +0000277endfun
278
279" ---------------------------------------------------------------------
280" tar#Read: {{{2
281fun! tar#Read(fname,mode)
Bram Moolenaarbba577a2005-11-28 23:05:55 +0000282 let repkeep= &report
283 set report=10
Bram Moolenaar8c8de832008-06-24 22:58:06 +0000284 let tarfile = substitute(a:fname,'tarfile:\(.\{-}\)::.*$','\1','')
285 let fname = substitute(a:fname,'tarfile:.\{-}::\(.*\)$','\1','')
Christian Brabandt334a13b2025-03-02 19:33:51 +0100286 " be careful not to execute special crafted files
287 let escape_file = fname->fnameescape()
Lennart00129a8442024-11-11 22:39:30 +0100288
Corpulent Robinb69cd522025-02-06 21:10:49 +0100289 " changing the directory to the temporary earlier to allow tar to extract the file with permissions intact
Lennart00129a8442024-11-11 22:39:30 +0100290 if !exists("*mkdir")
291 redraw!
292 echohl Error | echo "***error*** (tar#Write) sorry, mkdir() doesn't work on your system" | echohl None
293 let &report= repkeep
294 return
295 endif
296
297 let curdir= getcwd()
298 let tmpdir= tempname()
299 let b:curdir= tmpdir
300 let b:tmpdir= curdir
301 if tmpdir =~ '\.'
302 let tmpdir= substitute(tmpdir,'\.[^.]*$','','e')
303 endif
304 call mkdir(tmpdir,"p")
305
306 " attempt to change to the indicated directory
307 try
308 exe "cd ".fnameescape(tmpdir)
309 catch /^Vim\%((\a\+)\)\=:E344/
310 redraw!
311 echohl Error | echo "***error*** (tar#Write) cannot cd to temporary directory" | Echohl None
312 let &report= repkeep
313 return
314 endtry
315
316 " place temporary files under .../_ZIPVIM_/
317 if isdirectory("_ZIPVIM_")
318 call s:Rmdir("_ZIPVIM_")
319 endif
320 call mkdir("_ZIPVIM_")
321 cd _ZIPVIM_
322
Bram Moolenaarff034192013-04-24 18:51:19 +0200323 if has("win32unix") && executable("cygpath")
Bram Moolenaar910f66f2006-04-05 20:41:53 +0000324 " assuming cygwin
Bram Moolenaar5c736222010-01-06 20:54:52 +0100325 let tarfile=substitute(system("cygpath -u ".shellescape(tarfile,0)),'\n$','','e')
Bram Moolenaar910f66f2006-04-05 20:41:53 +0000326 endif
Bram Moolenaara5792f52005-11-23 21:25:05 +0000327
Bram Moolenaar5c736222010-01-06 20:54:52 +0100328 if fname =~ '\.bz2$' && executable("bzcat")
329 let decmp= "|bzcat"
330 let doro = 1
Jim Zhou56957ed2025-02-28 18:06:14 +0100331 elseif fname =~ '\.bz3$' && executable("bz3cat")
332 let decmp= "|bz3cat"
333 let doro = 1
Bram Moolenaar29634562020-01-09 21:46:04 +0100334 elseif fname =~ '\.t\=gz$' && executable("zcat")
Bram Moolenaar8c8de832008-06-24 22:58:06 +0000335 let decmp= "|zcat"
336 let doro = 1
Bram Moolenaar5c736222010-01-06 20:54:52 +0100337 elseif fname =~ '\.lzma$' && executable("lzcat")
338 let decmp= "|lzcat"
Bram Moolenaar8c8de832008-06-24 22:58:06 +0000339 let doro = 1
Bram Moolenaar477db062010-07-28 18:17:41 +0200340 elseif fname =~ '\.xz$' && executable("xzcat")
341 let decmp= "|xzcat"
342 let doro = 1
Bram Moolenaar23515b42020-11-29 14:36:24 +0100343 elseif fname =~ '\.zst$' && executable("zstdcat")
344 let decmp= "|zstdcat"
345 let doro = 1
Corpulent Robinb69cd522025-02-06 21:10:49 +0100346 elseif fname =~ '\.lz4$' && executable("lz4cat")
347 let decmp= "|lz4cat"
348 let doro = 1
Bram Moolenaara5792f52005-11-23 21:25:05 +0000349 else
Bram Moolenaar8c8de832008-06-24 22:58:06 +0000350 let decmp=""
351 let doro = 0
Jim Zhou56957ed2025-02-28 18:06:14 +0100352 if fname =~ '\.bz2$\|\.bz3$\|\.gz$\|\.lzma$\|\.xz$\|\.zip$\|\.Z$'
Bram Moolenaar8c8de832008-06-24 22:58:06 +0000353 setlocal bin
354 endif
Bram Moolenaara5792f52005-11-23 21:25:05 +0000355 endif
Bram Moolenaar8c8de832008-06-24 22:58:06 +0000356
Bram Moolenaared39e1d2008-08-09 17:55:22 +0000357 if exists("g:tar_secure")
358 let tar_secure= " -- "
Bram Moolenaar8c8de832008-06-24 22:58:06 +0000359 else
Bram Moolenaared39e1d2008-08-09 17:55:22 +0000360 let tar_secure= " "
361 endif
Bram Moolenaar20aac6c2018-09-02 21:07:30 +0200362
Bram Moolenaar5c736222010-01-06 20:54:52 +0100363 if tarfile =~# '\.bz2$'
Bram Moolenaar251e1912011-06-19 05:09:16 +0200364 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 +0100365 exe "read ".escape_file
Christian Brabandt8ac975d2025-03-01 17:13:40 +0100366 elseif tarfile =~# '\.bz3$'
Jim Zhou56957ed2025-02-28 18:06:14 +0100367 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 +0100368 exe "read ".escape_file
Bram Moolenaar29634562020-01-09 21:46:04 +0100369 elseif tarfile =~# '\.\(gz\)$'
370 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 +0100371 exe "read ".escape_file
Bram Moolenaar29634562020-01-09 21:46:04 +0100372 elseif tarfile =~# '\(\.tgz\|\.tbz\|\.txz\)'
Christian Brabandta2507382025-03-02 22:23:28 +0100373 let filekind= s:Header(tarfile)
374 if filekind =~? "bzip2"
Bram Moolenaar29634562020-01-09 21:46:04 +0100375 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 +0100376 exe "read ".escape_file
Jim Zhou56957ed2025-02-28 18:06:14 +0100377 elseif filekind =~ "bzip3"
378 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 +0100379 exe "read ".escape_file
Christian Brabandta2507382025-03-02 22:23:28 +0100380 elseif filekind =~? "xz"
Bram Moolenaar29634562020-01-09 21:46:04 +0100381 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 +0100382 exe "read ".escape_file
Christian Brabandta2507382025-03-02 22:23:28 +0100383 elseif filekind =~? "zstd"
Bram Moolenaar23515b42020-11-29 14:36:24 +0100384 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 +0100385 exe "read ".escape_file
Christian Brabandta2507382025-03-02 22:23:28 +0100386 elseif filekind =~? "gzip"
Bram Moolenaar29634562020-01-09 21:46:04 +0100387 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 +0100388 exe "read ".escape_file
Bram Moolenaar29634562020-01-09 21:46:04 +0100389 endif
390
Bram Moolenaared39e1d2008-08-09 17:55:22 +0000391 elseif tarfile =~# '\.lrp$'
Bram Moolenaard4a1aab2018-09-08 15:10:34 +0200392 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 +0100393 exe "read ".escape_file
Bram Moolenaar5c736222010-01-06 20:54:52 +0100394 elseif tarfile =~# '\.lzma$'
Bram Moolenaar251e1912011-06-19 05:09:16 +0200395 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 +0100396 exe "read ".escape_file
Bram Moolenaar477db062010-07-28 18:17:41 +0200397 elseif tarfile =~# '\.\(xz\|txz\)$'
Bram Moolenaar251e1912011-06-19 05:09:16 +0200398 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 +0100399 exe "read ".escape_file
Corpulent Robinb69cd522025-02-06 21:10:49 +0100400 elseif tarfile =~# '\.\(lz4\|tlz4\)$'
401 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 +0100402 exe "read ".escape_file
Bram Moolenaared39e1d2008-08-09 17:55:22 +0000403 else
404 if tarfile =~ '^\s*-'
Bram Moolenaar5c736222010-01-06 20:54:52 +0100405 " A file name starting with a dash is taken as an option. Prepend ./ to avoid that.
Bram Moolenaared39e1d2008-08-09 17:55:22 +0000406 let tarfile = substitute(tarfile, '-', './-', '')
407 endif
Bram Moolenaar5c736222010-01-06 20:54:52 +0100408 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 +0100409 exe "read ".escape_file
Lennart00129a8442024-11-11 22:39:30 +0100410 endif
411
412 redraw!
413
414if v:shell_error != 0
415 cd ..
416 call s:Rmdir("_ZIPVIM_")
417 exe "cd ".fnameescape(curdir)
418 echohl Error | echo "***error*** (tar#Read) sorry, unable to open or extract ".tarfile." with ".fname | echohl None
Bram Moolenaar8c8de832008-06-24 22:58:06 +0000419 endif
420
421 if doro
422 " because the reverse process of compressing changed files back into the tarball is not currently supported
423 setlocal ro
424 endif
425
Bram Moolenaar7fc0c062010-08-10 21:43:35 +0200426 let b:tarfile= a:fname
Bram Moolenaarc236c162008-07-13 17:41:49 +0000427 exe "file tarfile::".fnameescape(fname)
Bram Moolenaara5792f52005-11-23 21:25:05 +0000428
429 " cleanup
Bram Moolenaar251e1912011-06-19 05:09:16 +0200430 keepj sil! 0d
Bram Moolenaara5792f52005-11-23 21:25:05 +0000431 set nomod
432
Bram Moolenaarbba577a2005-11-28 23:05:55 +0000433 let &report= repkeep
Bram Moolenaara5792f52005-11-23 21:25:05 +0000434endfun
435
436" ---------------------------------------------------------------------
437" tar#Write: {{{2
438fun! tar#Write(fname)
Bram Moolenaarbba577a2005-11-28 23:05:55 +0000439 let repkeep= &report
440 set report=10
Lennart00129a8442024-11-11 22:39:30 +0100441 " temporary buffer variable workaround because too fucking tired. but it works now
442 let curdir= b:curdir
443 let tmpdir= b:tmpdir
Bram Moolenaara5792f52005-11-23 21:25:05 +0000444
Bram Moolenaared39e1d2008-08-09 17:55:22 +0000445 if !exists("g:tar_secure") && a:fname =~ '^\s*-\|\s\+-'
446 redraw!
Bram Moolenaar5c736222010-01-06 20:54:52 +0100447 echohl WarningMsg | echo '***warning*** (tar#Write) rejecting tarfile member<'.a:fname.'> because of embedded "-"'
Bram Moolenaared39e1d2008-08-09 17:55:22 +0000448 return
449 endif
450
Bram Moolenaarab194812005-09-14 21:40:12 +0000451 " sanity checks
Bram Moolenaar910f66f2006-04-05 20:41:53 +0000452 if !executable(g:tar_cmd)
Bram Moolenaarc81e5e72007-05-05 18:24:42 +0000453 redraw!
Bram Moolenaarbba577a2005-11-28 23:05:55 +0000454 let &report= repkeep
Bram Moolenaarab194812005-09-14 21:40:12 +0000455 return
456 endif
Bram Moolenaarab194812005-09-14 21:40:12 +0000457
Bram Moolenaar7fc0c062010-08-10 21:43:35 +0200458 let tarfile = substitute(b:tarfile,'tarfile:\(.\{-}\)::.*$','\1','')
459 let fname = substitute(b:tarfile,'tarfile:.\{-}::\(.*\)$','\1','')
Bram Moolenaara5792f52005-11-23 21:25:05 +0000460
461 " handle compressed archives
Bram Moolenaar5c736222010-01-06 20:54:52 +0100462 if tarfile =~# '\.bz2'
463 call system("bzip2 -d -- ".shellescape(tarfile,0))
464 let tarfile = substitute(tarfile,'\.bz2','','e')
465 let compress= "bzip2 -- ".shellescape(tarfile,0)
Jim Zhou56957ed2025-02-28 18:06:14 +0100466 elseif tarfile =~# '\.bz3'
467 call system("bzip3 -d -- ".shellescape(tarfile,0))
468 let tarfile = substitute(tarfile,'\.bz3','','e')
469 let compress= "bzip3 -- ".shellescape(tarfile,0)
Bram Moolenaar5c736222010-01-06 20:54:52 +0100470 elseif tarfile =~# '\.gz'
Bram Moolenaar29634562020-01-09 21:46:04 +0100471 call system("gzip -d -- ".shellescape(tarfile,0))
Bram Moolenaara5792f52005-11-23 21:25:05 +0000472 let tarfile = substitute(tarfile,'\.gz','','e')
Bram Moolenaar5c736222010-01-06 20:54:52 +0100473 let compress= "gzip -- ".shellescape(tarfile,0)
Bram Moolenaara5792f52005-11-23 21:25:05 +0000474 elseif tarfile =~# '\.tgz'
Bram Moolenaar29634562020-01-09 21:46:04 +0100475 call system("gzip -d -- ".shellescape(tarfile,0))
Bram Moolenaara5792f52005-11-23 21:25:05 +0000476 let tarfile = substitute(tarfile,'\.tgz','.tar','e')
Bram Moolenaar5c736222010-01-06 20:54:52 +0100477 let compress= "gzip -- ".shellescape(tarfile,0)
Bram Moolenaara5792f52005-11-23 21:25:05 +0000478 let tgz = 1
Bram Moolenaar477db062010-07-28 18:17:41 +0200479 elseif tarfile =~# '\.xz'
480 call system("xz -d -- ".shellescape(tarfile,0))
481 let tarfile = substitute(tarfile,'\.xz','','e')
482 let compress= "xz -- ".shellescape(tarfile,0)
Bram Moolenaar23515b42020-11-29 14:36:24 +0100483 elseif tarfile =~# '\.zst'
Christian Brabandt3a5b3df2024-01-08 20:02:14 +0100484 call system("zstd --decompress --rm -- ".shellescape(tarfile,0))
Bram Moolenaar23515b42020-11-29 14:36:24 +0100485 let tarfile = substitute(tarfile,'\.zst','','e')
Christian Brabandt3a5b3df2024-01-08 20:02:14 +0100486 let compress= "zstd --rm -- ".shellescape(tarfile,0)
Corpulent Robinb69cd522025-02-06 21:10:49 +0100487 elseif tarfile =~# '\.lz4'
488 call system("lz4 --decompress --rm -- ".shellescape(tarfile,0))
489 let tarfile = substitute(tarfile,'\.lz4','','e')
490 let compress= "lz4 --rm -- ".shellescape(tarfile,0)
Bram Moolenaar477db062010-07-28 18:17:41 +0200491 elseif tarfile =~# '\.lzma'
492 call system("lzma -d -- ".shellescape(tarfile,0))
493 let tarfile = substitute(tarfile,'\.lzma','','e')
494 let compress= "lzma -- ".shellescape(tarfile,0)
Bram Moolenaarab194812005-09-14 21:40:12 +0000495 endif
Christian Brabandta2507382025-03-02 22:23:28 +0100496 " Note: no support for name.tar.tbz/.txz/.tgz/.tlz4/.tzst
Bram Moolenaarab194812005-09-14 21:40:12 +0000497
Bram Moolenaarab194812005-09-14 21:40:12 +0000498 if v:shell_error != 0
Bram Moolenaarc81e5e72007-05-05 18:24:42 +0000499 redraw!
Bram Moolenaara5792f52005-11-23 21:25:05 +0000500 echohl Error | echo "***error*** (tar#Write) sorry, unable to update ".tarfile." with ".fname | echohl None
Bram Moolenaarab194812005-09-14 21:40:12 +0000501 else
Bram Moolenaara5792f52005-11-23 21:25:05 +0000502
Bram Moolenaar1cbe5f72005-12-29 22:51:09 +0000503 if fname =~ '/'
504 let dirpath = substitute(fname,'/[^/]\+$','','e')
Bram Moolenaarff034192013-04-24 18:51:19 +0200505 if has("win32unix") && executable("cygpath")
Bram Moolenaar5c736222010-01-06 20:54:52 +0100506 let dirpath = substitute(system("cygpath ".shellescape(dirpath, 0)),'\n','','e')
Bram Moolenaar1cbe5f72005-12-29 22:51:09 +0000507 endif
508 call mkdir(dirpath,"p")
509 endif
Bram Moolenaara5792f52005-11-23 21:25:05 +0000510 if tarfile !~ '/'
511 let tarfile= curdir.'/'.tarfile
512 endif
Bram Moolenaared39e1d2008-08-09 17:55:22 +0000513 if tarfile =~ '^\s*-'
514 " A file name starting with a dash may be taken as an option. Prepend ./ to avoid that.
515 let tarfile = substitute(tarfile, '-', './-', '')
516 endif
Christian Brabandt3a5b3df2024-01-08 20:02:14 +0100517
Bram Moolenaared39e1d2008-08-09 17:55:22 +0000518 if exists("g:tar_secure")
519 let tar_secure= " -- "
520 else
521 let tar_secure= " "
522 endif
Bram Moolenaar8c8de832008-06-24 22:58:06 +0000523 exe "w! ".fnameescape(fname)
Bram Moolenaarff034192013-04-24 18:51:19 +0200524 if has("win32unix") && executable("cygpath")
Bram Moolenaar5c736222010-01-06 20:54:52 +0100525 let tarfile = substitute(system("cygpath ".shellescape(tarfile,0)),'\n','','e')
Bram Moolenaara5792f52005-11-23 21:25:05 +0000526 endif
Christian Brabandt3a5b3df2024-01-08 20:02:14 +0100527
Bram Moolenaara5792f52005-11-23 21:25:05 +0000528 " delete old file from tarfile
Bram Moolenaar29634562020-01-09 21:46:04 +0100529 call system(g:tar_cmd." ".g:tar_delfile." ".shellescape(tarfile,0).tar_secure.shellescape(fname,0))
Bram Moolenaara5792f52005-11-23 21:25:05 +0000530 if v:shell_error != 0
Bram Moolenaarc81e5e72007-05-05 18:24:42 +0000531 redraw!
Bram Moolenaar8c8de832008-06-24 22:58:06 +0000532 echohl Error | echo "***error*** (tar#Write) sorry, unable to update ".fnameescape(tarfile)." with ".fnameescape(fname) | echohl None
Bram Moolenaara5792f52005-11-23 21:25:05 +0000533 else
Christian Brabandt3a5b3df2024-01-08 20:02:14 +0100534
535 " update tarfile with new file
Bram Moolenaar5c736222010-01-06 20:54:52 +0100536 call system(g:tar_cmd." -".g:tar_writeoptions." ".shellescape(tarfile,0).tar_secure.shellescape(fname,0))
Bram Moolenaara5792f52005-11-23 21:25:05 +0000537 if v:shell_error != 0
Bram Moolenaarc81e5e72007-05-05 18:24:42 +0000538 redraw!
Bram Moolenaar8c8de832008-06-24 22:58:06 +0000539 echohl Error | echo "***error*** (tar#Write) sorry, unable to update ".fnameescape(tarfile)." with ".fnameescape(fname) | echohl None
Bram Moolenaara5792f52005-11-23 21:25:05 +0000540 elseif exists("compress")
Bram Moolenaara5792f52005-11-23 21:25:05 +0000541 call system(compress)
542 if exists("tgz")
Bram Moolenaara5792f52005-11-23 21:25:05 +0000543 call rename(tarfile.".gz",substitute(tarfile,'\.tar$','.tgz','e'))
544 endif
545 endif
546 endif
547
548 " support writing tarfiles across a network
549 if s:tblfile_{winnr()} =~ '^\a\+://'
Bram Moolenaara5792f52005-11-23 21:25:05 +0000550 let tblfile= s:tblfile_{winnr()}
Bram Moolenaar29634562020-01-09 21:46:04 +0100551 1split|noswapfile enew
Bram Moolenaar5c736222010-01-06 20:54:52 +0100552 let binkeep= &l:binary
Bram Moolenaara5792f52005-11-23 21:25:05 +0000553 let eikeep = &ei
554 set binary ei=all
Bram Moolenaar29634562020-01-09 21:46:04 +0100555 exe "noswapfile e! ".fnameescape(tarfile)
Bram Moolenaara5792f52005-11-23 21:25:05 +0000556 call netrw#NetWrite(tblfile)
Bram Moolenaar5c736222010-01-06 20:54:52 +0100557 let &ei = eikeep
558 let &l:binary = binkeep
Bram Moolenaara5792f52005-11-23 21:25:05 +0000559 q!
560 unlet s:tblfile_{winnr()}
561 endif
Bram Moolenaarab194812005-09-14 21:40:12 +0000562 endif
Christian Brabandt3a5b3df2024-01-08 20:02:14 +0100563
Bram Moolenaarab194812005-09-14 21:40:12 +0000564 " cleanup and restore current directory
565 cd ..
Bram Moolenaara5792f52005-11-23 21:25:05 +0000566 call s:Rmdir("_ZIPVIM_")
Bram Moolenaarc236c162008-07-13 17:41:49 +0000567 exe "cd ".fnameescape(curdir)
Bram Moolenaarab194812005-09-14 21:40:12 +0000568 setlocal nomod
569
Bram Moolenaarbba577a2005-11-28 23:05:55 +0000570 let &report= repkeep
Bram Moolenaarab194812005-09-14 21:40:12 +0000571endfun
572
573" ---------------------------------------------------------------------
Bram Moolenaarff034192013-04-24 18:51:19 +0200574" tar#Diff: {{{2
575fun! tar#Diff(userfname,fname)
Bram Moolenaarff034192013-04-24 18:51:19 +0200576 let fname= a:fname
577 if a:userfname != ""
578 let fname= a:userfname
579 endif
580 if filereadable(fname)
581 " sets current file (from tarball) for diff'ing
582 " splits window vertically
583 " opens original file, sets it for diff'ing
584 " sets up b:tardiff_otherbuf variables so each buffer knows about the other (for closing purposes)
585 diffthis
586 wincmd v
Bram Moolenaar29634562020-01-09 21:46:04 +0100587 exe "noswapfile e ".fnameescape(fname)
Bram Moolenaarff034192013-04-24 18:51:19 +0200588 diffthis
589 else
590 redraw!
591 echo "***warning*** unable to read file<".fname.">"
592 endif
Bram Moolenaarff034192013-04-24 18:51:19 +0200593endfun
594
595" ---------------------------------------------------------------------
Bram Moolenaar29634562020-01-09 21:46:04 +0100596" tar#Extract: extract a file from a (possibly compressed) tar archive {{{2
597fun! tar#Extract()
Bram Moolenaar29634562020-01-09 21:46:04 +0100598
599 let repkeep= &report
600 set report=10
601 let fname= getline(".")
Bram Moolenaar29634562020-01-09 21:46:04 +0100602
603 if !exists("g:tar_secure") && fname =~ '^\s*-\|\s\+-'
604 redraw!
605 echohl WarningMsg | echo '***warning*** (tar#BrowseSelect) rejecting tarfile member<'.fname.'> because of embedded "-"'
Bram Moolenaar29634562020-01-09 21:46:04 +0100606 return
607 endif
608
609 " sanity check
610 if fname =~ '^"'
611 let &report= repkeep
Bram Moolenaar29634562020-01-09 21:46:04 +0100612 return
613 endif
614
615 let tarball = expand("%")
Bram Moolenaar29634562020-01-09 21:46:04 +0100616 let tarbase = substitute(tarball,'\..*$','','')
Bram Moolenaar29634562020-01-09 21:46:04 +0100617
618 let extractcmd= netrw#WinPath(g:tar_extractcmd)
619 if filereadable(tarbase.".tar")
Bram Moolenaar29634562020-01-09 21:46:04 +0100620 call system(extractcmd." ".shellescape(tarbase).".tar ".shellescape(fname))
621 if v:shell_error != 0
622 echohl Error | echo "***error*** ".extractcmd." ".tarbase.".tar ".fname.": failed!" | echohl NONE
Bram Moolenaar29634562020-01-09 21:46:04 +0100623 else
624 echo "***note*** successfully extracted ".fname
625 endif
626
627 elseif filereadable(tarbase.".tgz")
628 let extractcmd= substitute(extractcmd,"-","-z","")
Bram Moolenaar29634562020-01-09 21:46:04 +0100629 call system(extractcmd." ".shellescape(tarbase).".tgz ".shellescape(fname))
630 if v:shell_error != 0
631 echohl Error | echo "***error*** ".extractcmd." ".tarbase.".tgz ".fname.": failed!" | echohl NONE
Bram Moolenaar29634562020-01-09 21:46:04 +0100632 else
633 echo "***note*** successfully extracted ".fname
634 endif
635
636 elseif filereadable(tarbase.".tar.gz")
637 let extractcmd= substitute(extractcmd,"-","-z","")
Bram Moolenaar29634562020-01-09 21:46:04 +0100638 call system(extractcmd." ".shellescape(tarbase).".tar.gz ".shellescape(fname))
639 if v:shell_error != 0
640 echohl Error | echo "***error*** ".extractcmd." ".tarbase.".tar.gz ".fname.": failed!" | echohl NONE
Bram Moolenaar29634562020-01-09 21:46:04 +0100641 else
642 echo "***note*** successfully extracted ".fname
643 endif
644
645 elseif filereadable(tarbase.".tbz")
646 let extractcmd= substitute(extractcmd,"-","-j","")
Bram Moolenaar29634562020-01-09 21:46:04 +0100647 call system(extractcmd." ".shellescape(tarbase).".tbz ".shellescape(fname))
648 if v:shell_error != 0
649 echohl Error | echo "***error*** ".extractcmd."j ".tarbase.".tbz ".fname.": failed!" | echohl NONE
Bram Moolenaar29634562020-01-09 21:46:04 +0100650 else
651 echo "***note*** successfully extracted ".fname
652 endif
653
654 elseif filereadable(tarbase.".tar.bz2")
655 let extractcmd= substitute(extractcmd,"-","-j","")
Bram Moolenaar29634562020-01-09 21:46:04 +0100656 call system(extractcmd." ".shellescape(tarbase).".tar.bz2 ".shellescape(fname))
657 if v:shell_error != 0
658 echohl Error | echo "***error*** ".extractcmd."j ".tarbase.".tar.bz2 ".fname.": failed!" | echohl NONE
Bram Moolenaar29634562020-01-09 21:46:04 +0100659 else
660 echo "***note*** successfully extracted ".fname
661 endif
662
Jim Zhou56957ed2025-02-28 18:06:14 +0100663 elseif filereadable(tarbase.".tar.bz3")
664 let extractcmd= substitute(extractcmd,"-","-j","")
665 call system(extractcmd." ".shellescape(tarbase).".tar.bz3 ".shellescape(fname))
666 if v:shell_error != 0
667 echohl Error | echo "***error*** ".extractcmd."j ".tarbase.".tar.bz3 ".fname.": failed!" | echohl NONE
668 else
669 echo "***note*** successfully extracted ".fname
670 endif
671
Bram Moolenaar29634562020-01-09 21:46:04 +0100672 elseif filereadable(tarbase.".txz")
673 let extractcmd= substitute(extractcmd,"-","-J","")
Bram Moolenaar29634562020-01-09 21:46:04 +0100674 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
Bram Moolenaar29634562020-01-09 21:46:04 +0100677 else
678 echo "***note*** successfully extracted ".fname
679 endif
680
681 elseif filereadable(tarbase.".tar.xz")
682 let extractcmd= substitute(extractcmd,"-","-J","")
Bram Moolenaar29634562020-01-09 21:46:04 +0100683 call system(extractcmd." ".shellescape(tarbase).".tar.xz ".shellescape(fname))
684 if v:shell_error != 0
685 echohl Error | echo "***error*** ".extractcmd." ".tarbase.".tar.xz ".fname.": failed!" | echohl NONE
Bram Moolenaar29634562020-01-09 21:46:04 +0100686 else
687 echo "***note*** successfully extracted ".fname
688 endif
Bram Moolenaar23515b42020-11-29 14:36:24 +0100689
Christian Brabandt3a5b3df2024-01-08 20:02:14 +0100690 elseif filereadable(tarbase.".tzst")
Bram Moolenaar23515b42020-11-29 14:36:24 +0100691 let extractcmd= substitute(extractcmd,"-","--zstd","")
Christian Brabandt3a5b3df2024-01-08 20:02:14 +0100692 call system(extractcmd." ".shellescape(tarbase).".tzst ".shellescape(fname))
Bram Moolenaar23515b42020-11-29 14:36:24 +0100693 if v:shell_error != 0
Christian Brabandt3a5b3df2024-01-08 20:02:14 +0100694 echohl Error | echo "***error*** ".extractcmd." ".tarbase.".tzst ".fname.": failed!" | echohl NONE
Bram Moolenaar23515b42020-11-29 14:36:24 +0100695 else
696 echo "***note*** successfully extracted ".fname
697 endif
698
699 elseif filereadable(tarbase.".tar.zst")
700 let extractcmd= substitute(extractcmd,"-","--zstd","")
Christian Brabandt3a5b3df2024-01-08 20:02:14 +0100701 call system(extractcmd." ".shellescape(tarbase).".tar.zst ".shellescape(fname))
Bram Moolenaar23515b42020-11-29 14:36:24 +0100702 if v:shell_error != 0
703 echohl Error | echo "***error*** ".extractcmd." ".tarbase.".tar.zst ".fname.": failed!" | echohl NONE
Corpulent Robinb69cd522025-02-06 21:10:49 +0100704 else
705 echo "***note*** successfully extracted ".fname
706 endif
707
708 elseif filereadable(tarbase.".tlz4")
709 let extractcmd= substitute(extractcmd,"-","-I lz4","")
710 call system(extractcmd." ".shellescape(tarbase).".tlz4 ".shellescape(fname))
711 if v:shell_error != 0
712 echohl Error | echo "***error*** ".extractcmd." ".tarbase.".tlz4 ".fname.": failed!" | echohl NONE
713 else
714 echo "***note*** successfully extracted ".fname
715 endif
716
717 elseif filereadable(tarbase.".tar.lz4")
718 let extractcmd= substitute(extractcmd,"-","-I lz4","")
719 call system(extractcmd." ".shellescape(tarbase).".tar.lz4".shellescape(fname))
720 if v:shell_error != 0
721 echohl Error | echo "***error*** ".extractcmd." ".tarbase.".tar.lz4 ".fname.": failed!" | echohl NONE
Bram Moolenaar23515b42020-11-29 14:36:24 +0100722 else
723 echo "***note*** successfully extracted ".fname
724 endif
Bram Moolenaar29634562020-01-09 21:46:04 +0100725 endif
726
727 " restore option
728 let &report= repkeep
Bram Moolenaar29634562020-01-09 21:46:04 +0100729endfun
730
731" ---------------------------------------------------------------------
Bram Moolenaar5c736222010-01-06 20:54:52 +0100732" s:Rmdir: {{{2
Bram Moolenaarab194812005-09-14 21:40:12 +0000733fun! s:Rmdir(fname)
Bram Moolenaarab194812005-09-14 21:40:12 +0000734 if has("unix")
Bram Moolenaar5c736222010-01-06 20:54:52 +0100735 call system("/bin/rm -rf -- ".shellescape(a:fname,0))
Bram Moolenaarab194812005-09-14 21:40:12 +0000736 elseif has("win32") || has("win95") || has("win64") || has("win16")
737 if &shell =~? "sh$"
Bram Moolenaar5c736222010-01-06 20:54:52 +0100738 call system("/bin/rm -rf -- ".shellescape(a:fname,0))
Bram Moolenaarab194812005-09-14 21:40:12 +0000739 else
Bram Moolenaar5c736222010-01-06 20:54:52 +0100740 call system("del /S ".shellescape(a:fname,0))
Bram Moolenaarab194812005-09-14 21:40:12 +0000741 endif
742 endif
Bram Moolenaarab194812005-09-14 21:40:12 +0000743endfun
744
Christian Brabandta2507382025-03-02 22:23:28 +0100745" s:FileHeader: {{{2
746fun! s:Header(fname)
747 let header= readblob(a:fname, 0, 6)
748 if header[0:2] == str2blob(['BZh']) " bzip2 header
749 return "bzip2"
750 elseif header[0:2] == str2blob(['BZ3']) " bzip3 header
751 return "bzip3"
752 elseif header == str2blob(["\3757zXZ\n"]) " xz header
753 return "xz"
754 elseif header[0:3] == str2blob(["\x28\xB5\x2F\xFD"]) " zstd header
755 return "zstd"
756 elseif header[0:3] == str2blob(["\004\"M\030"]) " lz4 header
757 return "lz4"
758 elseif (header[0:1] == str2blob(["\037\235"]) ||
759 \ header[0:1] == str2blob(["\037\213"]) ||
760 \ header[0:1] == str2blob(["\037\236"]) ||
761 \ header[0:1] == str2blob(["\037\240"]) ||
762 \ header[0:1] == str2blob(["\037\036"]))
763 return "gzip"
764 endif
765 return "unknown"
766endfun
767
Bram Moolenaar8c8de832008-06-24 22:58:06 +0000768" ---------------------------------------------------------------------
Bram Moolenaar5c736222010-01-06 20:54:52 +0100769" tar#Vimuntar: installs a tarball in the user's .vim / vimfiles directory {{{2
770fun! tar#Vimuntar(...)
Bram Moolenaar5c736222010-01-06 20:54:52 +0100771 let tarball = expand("%")
Bram Moolenaar5c736222010-01-06 20:54:52 +0100772 let tarbase = substitute(tarball,'\..*$','','')
Bram Moolenaar5c736222010-01-06 20:54:52 +0100773 let tarhome = expand("%:p")
774 if has("win32") || has("win95") || has("win64") || has("win16")
775 let tarhome= substitute(tarhome,'\\','/','g')
776 endif
777 let tarhome= substitute(tarhome,'/[^/]*$','','')
Bram Moolenaar5c736222010-01-06 20:54:52 +0100778 let tartail = expand("%:t")
Bram Moolenaar5c736222010-01-06 20:54:52 +0100779 let curdir = getcwd()
Bram Moolenaar5c736222010-01-06 20:54:52 +0100780 " set up vimhome
781 if a:0 > 0 && a:1 != ""
782 let vimhome= a:1
783 else
784 let vimhome= vimball#VimballHome()
785 endif
Bram Moolenaar5c736222010-01-06 20:54:52 +0100786
Bram Moolenaar5c736222010-01-06 20:54:52 +0100787 if simplify(curdir) != simplify(vimhome)
788 " copy (possibly compressed) tarball to .vim/vimfiles
Bram Moolenaar5c736222010-01-06 20:54:52 +0100789 call system(netrw#WinPath(g:tar_copycmd)." ".shellescape(tartail)." ".shellescape(vimhome))
Bram Moolenaar5c736222010-01-06 20:54:52 +0100790 exe "cd ".fnameescape(vimhome)
791 endif
Bram Moolenaar5c736222010-01-06 20:54:52 +0100792
793 " if necessary, decompress the tarball; then, extract it
794 if tartail =~ '\.tgz'
Bram Moolenaar29634562020-01-09 21:46:04 +0100795 if executable("gunzip")
Bram Moolenaar5c736222010-01-06 20:54:52 +0100796 silent exe "!gunzip ".shellescape(tartail)
797 elseif executable("gzip")
798 silent exe "!gzip -d ".shellescape(tartail)
Bram Moolenaarc236c162008-07-13 17:41:49 +0000799 else
Bram Moolenaar6c391a72021-09-09 21:55:11 +0200800 echoerr "unable to decompress<".tartail."> on this system"
Bram Moolenaar5c736222010-01-06 20:54:52 +0100801 if simplify(curdir) != simplify(tarhome)
802 " remove decompressed tarball, restore directory
Bram Moolenaar5c736222010-01-06 20:54:52 +0100803 call delete(tartail.".tar")
Bram Moolenaar5c736222010-01-06 20:54:52 +0100804 exe "cd ".fnameescape(curdir)
805 endif
Bram Moolenaar5c736222010-01-06 20:54:52 +0100806 return
Bram Moolenaarc236c162008-07-13 17:41:49 +0000807 endif
Bram Moolenaar8c8de832008-06-24 22:58:06 +0000808 else
Bram Moolenaar5c736222010-01-06 20:54:52 +0100809 call vimball#Decompress(tartail,0)
Bram Moolenaar8c8de832008-06-24 22:58:06 +0000810 endif
Bram Moolenaar5c736222010-01-06 20:54:52 +0100811 let extractcmd= netrw#WinPath(g:tar_extractcmd)
Bram Moolenaar5c736222010-01-06 20:54:52 +0100812 call system(extractcmd." ".shellescape(tarbase.".tar"))
813
814 " set up help
815 if filereadable("doc/".tarbase.".txt")
Bram Moolenaar5c736222010-01-06 20:54:52 +0100816 exe "helptags ".getcwd()."/doc"
817 endif
818
819 if simplify(tarhome) != simplify(vimhome)
820 " remove decompressed tarball, restore directory
821 call delete(vimhome."/".tarbase.".tar")
822 exe "cd ".fnameescape(curdir)
823 endif
Bram Moolenaar8c8de832008-06-24 22:58:06 +0000824endfun
825
Bram Moolenaar5c736222010-01-06 20:54:52 +0100826" =====================================================================
Bram Moolenaara5792f52005-11-23 21:25:05 +0000827" Modelines And Restoration: {{{1
828let &cpo= s:keepcpo
829unlet s:keepcpo
Bram Moolenaar8c8de832008-06-24 22:58:06 +0000830" vim:ts=8 fdm=marker