Skip to content

Commit 129a844

Browse files
l0042158chrisbra
authored andcommitted
runtime(tar): Update tar.vim to support permissions
These changes enable tar.vim to keep permissions of files that were edited intact instead of replacing them with the default permissions. The major change for this is switching from "tar -OPxf", which reads out the contents of the selected file from an tar archive to stdout to "tar -pPxf" which extracts the selected file to the current directory with permissions intact This requirs the temporary directory to be created earlier. closes: #7379 Signed-off-by: Lennart00 <73488709+Lennart00@users.noreply.github.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
1 parent 4b9fa95 commit 129a844

1 file changed

Lines changed: 62 additions & 43 deletions

File tree

runtime/autoload/tar.vim

Lines changed: 62 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
" tar.vim: Handles browsing tarfiles
22
" AUTOLOAD PORTION
3-
" Date: Nov 14, 2023
3+
" Date: Nov 11, 2024
44
" Version: 32b (with modifications from the Vim Project)
55
" Maintainer: This runtime file is looking for a new maintainer.
66
" Former Maintainer: Charles E Campbell
@@ -23,7 +23,7 @@
2323
if &cp || exists("g:loaded_tar")
2424
finish
2525
endif
26-
let g:loaded_tar= "v32a"
26+
let g:loaded_tar= "v32b"
2727
if v:version < 702
2828
echohl WarningMsg
2929
echo "***warning*** this version of tar needs vim 7.2"
@@ -41,7 +41,7 @@ if !exists("g:tar_browseoptions")
4141
let g:tar_browseoptions= "Ptf"
4242
endif
4343
if !exists("g:tar_readoptions")
44-
let g:tar_readoptions= "OPxf"
44+
let g:tar_readoptions= "pPxf"
4545
endif
4646
if !exists("g:tar_cmd")
4747
let g:tar_cmd= "tar"
@@ -80,7 +80,7 @@ if !exists("g:tar_copycmd")
8080
let g:tar_copycmd= g:netrw_localcopycmd
8181
endif
8282
if !exists("g:tar_extractcmd")
83-
let g:tar_extractcmd= "tar -xf"
83+
let g:tar_extractcmd= "tar -pxf"
8484
endif
8585

8686
" set up shell quoting character
@@ -294,6 +294,41 @@ fun! tar#Read(fname,mode)
294294
set report=10
295295
let tarfile = substitute(a:fname,'tarfile:\(.\{-}\)::.*$','\1','')
296296
let fname = substitute(a:fname,'tarfile:.\{-}::\(.*\)$','\1','')
297+
298+
" changing the directory to the temporary earlier to allow tar to extract the file with permissions intact
299+
if !exists("*mkdir")
300+
redraw!
301+
echohl Error | echo "***error*** (tar#Write) sorry, mkdir() doesn't work on your system" | echohl None
302+
let &report= repkeep
303+
return
304+
endif
305+
306+
let curdir= getcwd()
307+
let tmpdir= tempname()
308+
let b:curdir= tmpdir
309+
let b:tmpdir= curdir
310+
if tmpdir =~ '\.'
311+
let tmpdir= substitute(tmpdir,'\.[^.]*$','','e')
312+
endif
313+
call mkdir(tmpdir,"p")
314+
315+
" attempt to change to the indicated directory
316+
try
317+
exe "cd ".fnameescape(tmpdir)
318+
catch /^Vim\%((\a\+)\)\=:E344/
319+
redraw!
320+
echohl Error | echo "***error*** (tar#Write) cannot cd to temporary directory" | Echohl None
321+
let &report= repkeep
322+
return
323+
endtry
324+
325+
" place temporary files under .../_ZIPVIM_/
326+
if isdirectory("_ZIPVIM_")
327+
call s:Rmdir("_ZIPVIM_")
328+
endif
329+
call mkdir("_ZIPVIM_")
330+
cd _ZIPVIM_
331+
297332
if has("win32unix") && executable("cygpath")
298333
" assuming cygwin
299334
let tarfile=substitute(system("cygpath -u ".shellescape(tarfile,0)),'\n$','','e')
@@ -332,9 +367,10 @@ fun! tar#Read(fname,mode)
332367

333368
if tarfile =~# '\.bz2$'
334369
exe "sil! r! bzip2 -d -c -- ".shellescape(tarfile,1)."| ".g:tar_cmd." -".g:tar_readoptions." - ".tar_secure.shellescape(fname,1).decmp
370+
exe "read ".fname
335371
elseif tarfile =~# '\.\(gz\)$'
336372
exe "sil! r! gzip -d -c -- ".shellescape(tarfile,1)."| ".g:tar_cmd." -".g:tar_readoptions." - ".tar_secure.shellescape(fname,1).decmp
337-
373+
exe "read ".fname
338374
elseif tarfile =~# '\(\.tgz\|\.tbz\|\.txz\)'
339375
if has("unix") && executable("file")
340376
let filekind= system("file ".shellescape(tarfile,1))
@@ -343,27 +379,44 @@ fun! tar#Read(fname,mode)
343379
endif
344380
if filekind =~ "bzip2"
345381
exe "sil! r! bzip2 -d -c -- ".shellescape(tarfile,1)."| ".g:tar_cmd." -".g:tar_readoptions." - ".tar_secure.shellescape(fname,1).decmp
382+
exe "read ".fname
346383
elseif filekind =~ "XZ"
347384
exe "sil! r! xz -d -c -- ".shellescape(tarfile,1)."| ".g:tar_cmd." -".g:tar_readoptions." - ".tar_secure.shellescape(fname,1).decmp
385+
exe "read ".fname
348386
elseif filekind =~ "Zstandard"
349387
exe "sil! r! zstd --decompress --stdout -- ".shellescape(tarfile,1)."| ".g:tar_cmd." -".g:tar_readoptions." - ".tar_secure.shellescape(fname,1).decmp
388+
exe "read ".fname
350389
else
351390
exe "sil! r! gzip -d -c -- ".shellescape(tarfile,1)."| ".g:tar_cmd." -".g:tar_readoptions." - ".tar_secure.shellescape(fname,1).decmp
391+
exe "read ".fname
352392
endif
353393

354394
elseif tarfile =~# '\.lrp$'
355395
exe "sil! r! cat -- ".shellescape(tarfile,1)." | gzip -d -c - | ".g:tar_cmd." -".g:tar_readoptions." - ".tar_secure.shellescape(fname,1).decmp
396+
exe "read ".fname
356397
elseif tarfile =~# '\.lzma$'
357398
exe "sil! r! lzma -d -c -- ".shellescape(tarfile,1)."| ".g:tar_cmd." -".g:tar_readoptions." - ".tar_secure.shellescape(fname,1).decmp
399+
exe "read ".fname
358400
elseif tarfile =~# '\.\(xz\|txz\)$'
359401
exe "sil! r! xz --decompress --stdout -- ".shellescape(tarfile,1)." | ".g:tar_cmd." -".g:tar_readoptions." - ".tar_secure.shellescape(fname,1).decmp
402+
exe "read ".fname
360403
else
361404
if tarfile =~ '^\s*-'
362405
" A file name starting with a dash is taken as an option. Prepend ./ to avoid that.
363406
let tarfile = substitute(tarfile, '-', './-', '')
364407
endif
365408
" call Decho("8: exe silent r! ".g:tar_cmd." -".g:tar_readoptions.tar_secure.shellescape(tarfile,1)." ".shellescape(fname,1).decmp)
366409
exe "silent r! ".g:tar_cmd." -".g:tar_readoptions.shellescape(tarfile,1)." ".tar_secure.shellescape(fname,1).decmp
410+
exe "read ".fname
411+
endif
412+
413+
redraw!
414+
415+
if v:shell_error != 0
416+
cd ..
417+
call s:Rmdir("_ZIPVIM_")
418+
exe "cd ".fnameescape(curdir)
419+
echohl Error | echo "***error*** (tar#Read) sorry, unable to open or extract ".tarfile." with ".fname | echohl None
367420
endif
368421

369422
if doro
@@ -388,6 +441,10 @@ fun! tar#Write(fname)
388441
" call Dfunc("tar#Write(fname<".a:fname.">) b:tarfile<".b:tarfile."> tblfile_".winnr()."<".s:tblfile_{winnr()}.">")
389442
let repkeep= &report
390443
set report=10
444+
445+
" temporary buffer variable workaround because too fucking tired. but it works now
446+
let curdir= b:curdir
447+
let tmpdir= b:tmpdir
391448

392449
if !exists("g:tar_secure") && a:fname =~ '^\s*-\|\s\+-'
393450
redraw!
@@ -404,44 +461,6 @@ fun! tar#Write(fname)
404461
" call Dret("tar#Write")
405462
return
406463
endif
407-
if !exists("*mkdir")
408-
redraw!
409-
" call Decho("***error*** (tar#Write) sorry, mkdir() doesn't work on your system")
410-
echohl Error | echo "***error*** (tar#Write) sorry, mkdir() doesn't work on your system" | echohl None
411-
let &report= repkeep
412-
" call Dret("tar#Write")
413-
return
414-
endif
415-
416-
let curdir= getcwd()
417-
let tmpdir= tempname()
418-
" call Decho("orig tempname<".tmpdir.">")
419-
if tmpdir =~ '\.'
420-
let tmpdir= substitute(tmpdir,'\.[^.]*$','','e')
421-
endif
422-
" call Decho("tmpdir<".tmpdir.">")
423-
call mkdir(tmpdir,"p")
424-
425-
" attempt to change to the indicated directory
426-
try
427-
exe "cd ".fnameescape(tmpdir)
428-
catch /^Vim\%((\a\+)\)\=:E344/
429-
redraw!
430-
" call Decho("***error*** (tar#Write) cannot cd to temporary directory")
431-
echohl Error | echo "***error*** (tar#Write) cannot cd to temporary directory" | Echohl None
432-
let &report= repkeep
433-
" call Dret("tar#Write")
434-
return
435-
endtry
436-
" call Decho("current directory now: ".getcwd())
437-
438-
" place temporary files under .../_ZIPVIM_/
439-
if isdirectory("_ZIPVIM_")
440-
call s:Rmdir("_ZIPVIM_")
441-
endif
442-
call mkdir("_ZIPVIM_")
443-
cd _ZIPVIM_
444-
" call Decho("current directory now: ".getcwd())
445464

446465
let tarfile = substitute(b:tarfile,'tarfile:\(.\{-}\)::.*$','\1','')
447466
let fname = substitute(b:tarfile,'tarfile:.\{-}::\(.*\)$','\1','')

0 commit comments

Comments
 (0)