tar.vim 30 KB

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