tar.vim 28 KB

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