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