Mercurial > hg > RemoteEditor > vim7
annotate runtime/autoload/gzip.vim @ 49:000769ce6c9d default tip
Added tag v7-3-618 for changeset 67300faee616
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Wed, 01 Aug 2012 18:08:37 +0900 (2012-08-01) |
parents | e170173ecb68 |
children |
rev | line source |
---|---|
0 | 1 " Vim autoload file for editing compressed files. |
2 " Maintainer: Bram Moolenaar <Bram@vim.org> | |
34
e170173ecb68
before ack base protocol.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
3 " Last Change: 2008 Jul 04 |
0 | 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 | |
66 " Reset 'foldenable', otherwise line numbers get adjusted. | |
67 if has("folding") | |
68 let fen_save = &fen | |
69 setlocal nofen | |
70 endif | |
71 | |
72 " when filtering the whole buffer, it will become empty | |
73 let empty = line("'[") == 1 && line("']") == line("$") | |
74 let tmp = tempname() | |
75 let tmpe = tmp . "." . expand("<afile>:e") | |
34
e170173ecb68
before ack base protocol.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
76 if exists('*fnameescape') |
e170173ecb68
before ack base protocol.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
77 let tmp_esc = fnameescape(tmp) |
e170173ecb68
before ack base protocol.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
78 let tmpe_esc = fnameescape(tmpe) |
e170173ecb68
before ack base protocol.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
79 else |
e170173ecb68
before ack base protocol.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
80 let tmp_esc = escape(tmp, ' ') |
e170173ecb68
before ack base protocol.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
81 let tmpe_esc = escape(tmpe, ' ') |
e170173ecb68
before ack base protocol.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
82 endif |
0 | 83 " write the just read lines to a temp file "'[,']w tmp.gz" |
34
e170173ecb68
before ack base protocol.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
84 execute "silent '[,']w " . tmpe_esc |
0 | 85 " uncompress the temp file: call system("gzip -dn tmp.gz") |
86 call system(a:cmd . " " . s:escape(tmpe)) | |
87 if !filereadable(tmp) | |
88 " uncompress didn't work! Keep the compressed file then. | |
89 echoerr "Error: Could not read uncompressed file" | |
90 let ok = 0 | |
91 else | |
92 let ok = 1 | |
93 " delete the compressed lines; remember the line number | |
94 let l = line("'[") - 1 | |
95 if exists(":lockmarks") | |
96 lockmarks '[,']d _ | |
97 else | |
98 '[,']d _ | |
99 endif | |
100 " read in the uncompressed lines "'[-1r tmp" | |
101 " Use ++edit if the buffer was empty, keep the 'ff' and 'fenc' options. | |
102 setlocal nobin | |
103 if exists(":lockmarks") | |
104 if empty | |
34
e170173ecb68
before ack base protocol.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
105 execute "silent lockmarks " . l . "r ++edit " . tmp_esc |
0 | 106 else |
34
e170173ecb68
before ack base protocol.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
107 execute "silent lockmarks " . l . "r " . tmp_esc |
0 | 108 endif |
109 else | |
34
e170173ecb68
before ack base protocol.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
110 execute "silent " . l . "r " . tmp_esc |
0 | 111 endif |
112 | |
113 " if buffer became empty, delete trailing blank line | |
114 if empty | |
115 silent $delete _ | |
116 1 | |
117 endif | |
118 " delete the temp file and the used buffers | |
119 call delete(tmp) | |
34
e170173ecb68
before ack base protocol.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
120 silent! exe "bwipe " . tmp_esc |
e170173ecb68
before ack base protocol.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
121 silent! exe "bwipe " . tmpe_esc |
0 | 122 endif |
123 | |
124 " Restore saved option values. | |
125 let &pm = pm_save | |
126 let &cpo = cpo_save | |
127 let &l:ma = ma_save | |
128 if has("folding") | |
129 let &l:fen = fen_save | |
130 endif | |
131 | |
132 " When uncompressed the whole buffer, do autocommands | |
133 if ok && empty | |
34
e170173ecb68
before ack base protocol.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
134 if exists('*fnameescape') |
e170173ecb68
before ack base protocol.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
135 let fname = fnameescape(expand("%:r")) |
e170173ecb68
before ack base protocol.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
136 else |
e170173ecb68
before ack base protocol.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
137 let fname = escape(expand("%:r"), " \t\n*?[{`$\\%#'\"|!<") |
e170173ecb68
before ack base protocol.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
138 endif |
0 | 139 if &verbose >= 8 |
34
e170173ecb68
before ack base protocol.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
140 execute "doau BufReadPost " . fname |
0 | 141 else |
34
e170173ecb68
before ack base protocol.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
142 execute "silent! doau BufReadPost " . fname |
0 | 143 endif |
144 endif | |
145 endfun | |
146 | |
147 " After writing compressed file: Compress written file with "cmd" | |
148 fun gzip#write(cmd) | |
149 " don't do anything if the cmd is not supported | |
150 if s:check(a:cmd) | |
151 " Rename the file before compressing it. | |
152 let nm = resolve(expand("<afile>")) | |
153 let nmt = s:tempname(nm) | |
154 if rename(nm, nmt) == 0 | |
155 if exists("b:gzip_comp_arg") | |
34
e170173ecb68
before ack base protocol.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
156 call system(a:cmd . " " . b:gzip_comp_arg . " -- " . s:escape(nmt)) |
0 | 157 else |
34
e170173ecb68
before ack base protocol.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
158 call system(a:cmd . " -- " . s:escape(nmt)) |
0 | 159 endif |
160 call rename(nmt . "." . expand("<afile>:e"), nm) | |
161 endif | |
162 endif | |
163 endfun | |
164 | |
165 " Before appending to compressed file: Uncompress file with "cmd" | |
166 fun gzip#appre(cmd) | |
167 " don't do anything if the cmd is not supported | |
168 if s:check(a:cmd) | |
169 let nm = expand("<afile>") | |
170 | |
171 " for gzip check current compression level and set b:gzip_comp_arg. | |
172 silent! unlet b:gzip_comp_arg | |
173 if a:cmd[0] == 'g' | |
174 call s:set_compression(readfile(nm, "b", 1)[0]) | |
175 endif | |
176 | |
177 " Rename to a weird name to avoid the risk of overwriting another file | |
178 let nmt = expand("<afile>:p:h") . "/X~=@l9q5" | |
179 let nmte = nmt . "." . expand("<afile>:e") | |
180 if rename(nm, nmte) == 0 | |
181 if &patchmode != "" && getfsize(nm . &patchmode) == -1 | |
182 " Create patchmode file by creating the decompressed file new | |
34
e170173ecb68
before ack base protocol.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
183 call system(a:cmd . " -c -- " . s:escape(nmte) . " > " . s:escape(nmt)) |
0 | 184 call rename(nmte, nm . &patchmode) |
185 else | |
34
e170173ecb68
before ack base protocol.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
186 call system(a:cmd . " -- " . s:escape(nmte)) |
0 | 187 endif |
188 call rename(nmt, nm) | |
189 endif | |
190 endif | |
191 endfun | |
192 | |
193 " find a file name for the file to be compressed. Use "name" without an | |
194 " extension if possible. Otherwise use a weird name to avoid overwriting an | |
195 " existing file. | |
196 fun s:tempname(name) | |
197 let fn = fnamemodify(a:name, ":r") | |
198 if !filereadable(fn) && !isdirectory(fn) | |
199 return fn | |
200 endif | |
201 return fnamemodify(a:name, ":p:h") . "/X~=@l9q5" | |
202 endfun | |
203 | |
204 fun s:escape(name) | |
205 " shellescape() was added by patch 7.0.111 | |
206 if exists("*shellescape") | |
207 return shellescape(a:name) | |
208 endif | |
209 return "'" . a:name . "'" | |
210 endfun | |
211 | |
212 " vim: set sw=2 : |