Mercurial > vim
annotate runtime/autoload/gzip.vim @ 36533:90545c76016e draft default tip
runtime(tar): Update tar.vim to support permissions
Commit: https://github.com/vim/vim/commit/129a8446d23cd9cb4445fcfea259cba5e0487d29
Author: Lennart00 <73488709+Lennart00@users.noreply.github.com>
Date: Mon Nov 11 22:39:30 2024 +0100
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>
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Mon, 11 Nov 2024 22:45:02 +0100 |
parents | bd3ee5abdd7a |
children |
rev | line source |
---|---|
446 | 1 " Vim autoload file for editing compressed files. |
32770
4027cefc2aab
Farewell to Bram and dedicate upcoming Vim 9.1 to him (#12749)
Christian Brabandt <cb@256bit.org>
parents:
10244
diff
changeset
|
2 " Maintainer: The Vim Project <https://github.com/vim/vim> |
4027cefc2aab
Farewell to Bram and dedicate upcoming Vim 9.1 to him (#12749)
Christian Brabandt <cb@256bit.org>
parents:
10244
diff
changeset
|
3 " Last Change: 2023 Aug 10 |
4027cefc2aab
Farewell to Bram and dedicate upcoming Vim 9.1 to him (#12749)
Christian Brabandt <cb@256bit.org>
parents:
10244
diff
changeset
|
4 " Former Maintainer: Bram Moolenaar <Bram@vim.org> |
446 | 5 |
6 " These functions are used by the gzip plugin. | |
7 | |
8 " Function to check that executing "cmd [-f]" works. | |
9 " The result is cached in s:have_"cmd" for speed. | |
10 fun s:check(cmd) | |
11 let name = substitute(a:cmd, '\(\S*\).*', '\1', '') | |
12 if !exists("s:have_" . name) | |
33096
828bcb1a37e7
patch 9.0.1833: [security] runtime file fixes
Christian Brabandt <cb@256bit.org>
parents:
32770
diff
changeset
|
13 " safety check, don't execute anything from the current directory |
33716
bd3ee5abdd7a
runtime(dist): centralize safe executable check and add vim library (#13413)
Christian Brabandt <cb@256bit.org>
parents:
33196
diff
changeset
|
14 let f = dist#vim#IsSafeExecutable('gzip', name) |
33096
828bcb1a37e7
patch 9.0.1833: [security] runtime file fixes
Christian Brabandt <cb@256bit.org>
parents:
32770
diff
changeset
|
15 if !f |
828bcb1a37e7
patch 9.0.1833: [security] runtime file fixes
Christian Brabandt <cb@256bit.org>
parents:
32770
diff
changeset
|
16 echoerr "Warning: NOT executing " .. name .. " from current directory!" |
828bcb1a37e7
patch 9.0.1833: [security] runtime file fixes
Christian Brabandt <cb@256bit.org>
parents:
32770
diff
changeset
|
17 endif |
446 | 18 let e = executable(name) |
19 if e < 0 | |
20 let r = system(name . " --version") | |
21 let e = (r !~ "not found" && r != "") | |
22 endif | |
33096
828bcb1a37e7
patch 9.0.1833: [security] runtime file fixes
Christian Brabandt <cb@256bit.org>
parents:
32770
diff
changeset
|
23 exe "let s:have_" . name . "=" . (e && f) |
446 | 24 endif |
25 exe "return s:have_" . name | |
26 endfun | |
27 | |
28 " Set b:gzip_comp_arg to the gzip argument to be used for compression, based on | |
29 " the flags in the compressed file. | |
30 " The only compression methods that can be detected are max speed (-1) and max | |
31 " compression (-9). | |
32 fun s:set_compression(line) | |
33 " get the Compression Method | |
34 let l:cm = char2nr(a:line[2]) | |
35 " if it's 8 (DEFLATE), we can check for the compression level | |
36 if l:cm == 8 | |
37 " get the eXtra FLags | |
38 let l:xfl = char2nr(a:line[8]) | |
39 " max compression | |
40 if l:xfl == 2 | |
41 let b:gzip_comp_arg = "-9" | |
42 " min compression | |
43 elseif l:xfl == 4 | |
44 let b:gzip_comp_arg = "-1" | |
45 endif | |
46 endif | |
47 endfun | |
48 | |
49 | |
50 " After reading compressed file: Uncompress text in buffer with "cmd" | |
51 fun gzip#read(cmd) | |
52 " don't do anything if the cmd is not supported | |
53 if !s:check(a:cmd) | |
54 return | |
55 endif | |
56 | |
57 " for gzip check current compression level and set b:gzip_comp_arg. | |
58 silent! unlet b:gzip_comp_arg | |
59 if a:cmd[0] == 'g' | |
60 call s:set_compression(getline(1)) | |
61 endif | |
62 | |
63 " make 'patchmode' empty, we don't want a copy of the written file | |
64 let pm_save = &pm | |
65 set pm= | |
66 " remove 'a' and 'A' from 'cpo' to avoid the alternate file changes | |
67 let cpo_save = &cpo | |
68 set cpo-=a cpo-=A | |
69 " set 'modifiable' | |
70 let ma_save = &ma | |
71 setlocal ma | |
10244
876fbdd84e52
commit https://github.com/vim/vim/commit/2ec618c9feac4573b154510236ad8121c77d0eca
Christian Brabandt <cb@256bit.org>
parents:
6336
diff
changeset
|
72 " set 'write' |
876fbdd84e52
commit https://github.com/vim/vim/commit/2ec618c9feac4573b154510236ad8121c77d0eca
Christian Brabandt <cb@256bit.org>
parents:
6336
diff
changeset
|
73 let write_save = &write |
876fbdd84e52
commit https://github.com/vim/vim/commit/2ec618c9feac4573b154510236ad8121c77d0eca
Christian Brabandt <cb@256bit.org>
parents:
6336
diff
changeset
|
74 set write |
1190 | 75 " Reset 'foldenable', otherwise line numbers get adjusted. |
76 if has("folding") | |
77 let fen_save = &fen | |
78 setlocal nofen | |
79 endif | |
80 | |
446 | 81 " when filtering the whole buffer, it will become empty |
82 let empty = line("'[") == 1 && line("']") == line("$") | |
83 let tmp = tempname() | |
84 let tmpe = tmp . "." . expand("<afile>:e") | |
1592 | 85 if exists('*fnameescape') |
86 let tmp_esc = fnameescape(tmp) | |
87 let tmpe_esc = fnameescape(tmpe) | |
88 else | |
89 let tmp_esc = escape(tmp, ' ') | |
90 let tmpe_esc = escape(tmpe, ' ') | |
91 endif | |
446 | 92 " write the just read lines to a temp file "'[,']w tmp.gz" |
1592 | 93 execute "silent '[,']w " . tmpe_esc |
446 | 94 " uncompress the temp file: call system("gzip -dn tmp.gz") |
985 | 95 call system(a:cmd . " " . s:escape(tmpe)) |
446 | 96 if !filereadable(tmp) |
97 " uncompress didn't work! Keep the compressed file then. | |
98 echoerr "Error: Could not read uncompressed file" | |
1190 | 99 let ok = 0 |
446 | 100 else |
1190 | 101 let ok = 1 |
102 " delete the compressed lines; remember the line number | |
103 let l = line("'[") - 1 | |
104 if exists(":lockmarks") | |
105 lockmarks '[,']d _ | |
106 else | |
107 '[,']d _ | |
108 endif | |
109 " read in the uncompressed lines "'[-1r tmp" | |
110 " Use ++edit if the buffer was empty, keep the 'ff' and 'fenc' options. | |
111 setlocal nobin | |
112 if exists(":lockmarks") | |
113 if empty | |
1592 | 114 execute "silent lockmarks " . l . "r ++edit " . tmp_esc |
1190 | 115 else |
1592 | 116 execute "silent lockmarks " . l . "r " . tmp_esc |
1190 | 117 endif |
118 else | |
1592 | 119 execute "silent " . l . "r " . tmp_esc |
1190 | 120 endif |
121 | |
122 " if buffer became empty, delete trailing blank line | |
819 | 123 if empty |
1190 | 124 silent $delete _ |
125 1 | |
819 | 126 endif |
1190 | 127 " delete the temp file and the used buffers |
128 call delete(tmp) | |
1592 | 129 silent! exe "bwipe " . tmp_esc |
130 silent! exe "bwipe " . tmpe_esc | |
446 | 131 endif |
6336 | 132 " Store the OK flag, so that we can use it when writing. |
133 let b:uncompressOk = ok | |
446 | 134 |
1190 | 135 " Restore saved option values. |
446 | 136 let &pm = pm_save |
137 let &cpo = cpo_save | |
138 let &l:ma = ma_save | |
10244
876fbdd84e52
commit https://github.com/vim/vim/commit/2ec618c9feac4573b154510236ad8121c77d0eca
Christian Brabandt <cb@256bit.org>
parents:
6336
diff
changeset
|
139 let &write = write_save |
1190 | 140 if has("folding") |
141 let &l:fen = fen_save | |
142 endif | |
143 | |
446 | 144 " When uncompressed the whole buffer, do autocommands |
1190 | 145 if ok && empty |
1592 | 146 if exists('*fnameescape') |
147 let fname = fnameescape(expand("%:r")) | |
148 else | |
149 let fname = escape(expand("%:r"), " \t\n*?[{`$\\%#'\"|!<") | |
150 endif | |
446 | 151 if &verbose >= 8 |
1592 | 152 execute "doau BufReadPost " . fname |
446 | 153 else |
1592 | 154 execute "silent! doau BufReadPost " . fname |
446 | 155 endif |
156 endif | |
157 endfun | |
158 | |
159 " After writing compressed file: Compress written file with "cmd" | |
160 fun gzip#write(cmd) | |
6336 | 161 if exists('b:uncompressOk') && !b:uncompressOk |
162 echomsg "Not compressing file because uncompress failed; reset b:uncompressOk to compress anyway" | |
446 | 163 " don't do anything if the cmd is not supported |
6336 | 164 elseif s:check(a:cmd) |
446 | 165 " Rename the file before compressing it. |
166 let nm = resolve(expand("<afile>")) | |
167 let nmt = s:tempname(nm) | |
168 if rename(nm, nmt) == 0 | |
169 if exists("b:gzip_comp_arg") | |
1668 | 170 call system(a:cmd . " " . b:gzip_comp_arg . " -- " . s:escape(nmt)) |
446 | 171 else |
1668 | 172 call system(a:cmd . " -- " . s:escape(nmt)) |
446 | 173 endif |
174 call rename(nmt . "." . expand("<afile>:e"), nm) | |
175 endif | |
176 endif | |
177 endfun | |
178 | |
179 " Before appending to compressed file: Uncompress file with "cmd" | |
180 fun gzip#appre(cmd) | |
181 " don't do anything if the cmd is not supported | |
182 if s:check(a:cmd) | |
183 let nm = expand("<afile>") | |
184 | |
185 " for gzip check current compression level and set b:gzip_comp_arg. | |
186 silent! unlet b:gzip_comp_arg | |
187 if a:cmd[0] == 'g' | |
188 call s:set_compression(readfile(nm, "b", 1)[0]) | |
189 endif | |
190 | |
191 " Rename to a weird name to avoid the risk of overwriting another file | |
192 let nmt = expand("<afile>:p:h") . "/X~=@l9q5" | |
193 let nmte = nmt . "." . expand("<afile>:e") | |
194 if rename(nm, nmte) == 0 | |
195 if &patchmode != "" && getfsize(nm . &patchmode) == -1 | |
196 " Create patchmode file by creating the decompressed file new | |
1668 | 197 call system(a:cmd . " -c -- " . s:escape(nmte) . " > " . s:escape(nmt)) |
446 | 198 call rename(nmte, nm . &patchmode) |
199 else | |
1668 | 200 call system(a:cmd . " -- " . s:escape(nmte)) |
446 | 201 endif |
202 call rename(nmt, nm) | |
203 endif | |
204 endif | |
205 endfun | |
206 | |
207 " find a file name for the file to be compressed. Use "name" without an | |
208 " extension if possible. Otherwise use a weird name to avoid overwriting an | |
209 " existing file. | |
210 fun s:tempname(name) | |
211 let fn = fnamemodify(a:name, ":r") | |
212 if !filereadable(fn) && !isdirectory(fn) | |
213 return fn | |
214 endif | |
215 return fnamemodify(a:name, ":p:h") . "/X~=@l9q5" | |
216 endfun | |
217 | |
985 | 218 fun s:escape(name) |
219 " shellescape() was added by patch 7.0.111 | |
1132 | 220 if exists("*shellescape") |
985 | 221 return shellescape(a:name) |
222 endif | |
223 return "'" . a:name . "'" | |
224 endfun | |
225 | |
446 | 226 " vim: set sw=2 : |