Mercurial > vim
annotate runtime/autoload/zip.vim @ 9529:581d5131629f v7.4.2045
commit https://github.com/vim/vim/commit/5ef2e762844e0eb1f5b213bd58e6bc38bdb69dac
Author: Bram Moolenaar <Bram@vim.org>
Date: Fri Jul 15 21:29:35 2016 +0200
patch 7.4.2045
Problem: Memory leak when using a function callback.
Solution: Don't save the function name when it's in the partial.
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Fri, 15 Jul 2016 21:30:07 +0200 |
parents | 71e066e10a47 |
children | b7da8d4c594c |
rev | line source |
---|---|
530 | 1 " zip.vim: Handles browsing zipfiles |
2 " AUTOLOAD PORTION | |
5130
71e066e10a47
updated for version 7.3.1308
Bram Moolenaar <bram@vim.org>
parents:
4339
diff
changeset
|
3 " Date: Jul 02, 2013 |
71e066e10a47
updated for version 7.3.1308
Bram Moolenaar <bram@vim.org>
parents:
4339
diff
changeset
|
4 " Version: 27 |
4339 | 5 " Maintainer: Charles E Campbell <NdrOchip@ScampbellPfamily.AbizM-NOSPAM> |
1121 | 6 " License: Vim License (see vim's :help license) |
5130
71e066e10a47
updated for version 7.3.1308
Bram Moolenaar <bram@vim.org>
parents:
4339
diff
changeset
|
7 " Copyright: Copyright (C) 2005-2013 Charles E. Campbell {{{1 |
530 | 8 " Permission is hereby granted to use and distribute this code, |
9 " with or without modifications, provided that this copyright | |
10 " notice is copied with it. Like anything else that's free, | |
1621 | 11 " zip.vim and zipPlugin.vim are provided *as is* and comes with |
12 " no warranty of any kind, either expressed or implied. By using | |
13 " this plugin, you agree that in no event will the copyright | |
530 | 14 " holder be liable for any damages resulting from the use |
15 " of this software. | |
5130
71e066e10a47
updated for version 7.3.1308
Bram Moolenaar <bram@vim.org>
parents:
4339
diff
changeset
|
16 "redraw!|call DechoSep()|call inputsave()|call input("Press <cr> to continue")|call inputrestore() |
530 | 17 |
18 " --------------------------------------------------------------------- | |
1121 | 19 " Load Once: {{{1 |
2152 | 20 if &cp || exists("g:loaded_zip") |
21 finish | |
22 endif | |
5130
71e066e10a47
updated for version 7.3.1308
Bram Moolenaar <bram@vim.org>
parents:
4339
diff
changeset
|
23 let g:loaded_zip= "v27" |
2152 | 24 if v:version < 702 |
25 echohl WarningMsg | |
26 echo "***warning*** this version of zip needs vim 7.2" | |
27 echohl Normal | |
28 finish | |
29 endif | |
530 | 30 let s:keepcpo= &cpo |
31 set cpo&vim | |
5130
71e066e10a47
updated for version 7.3.1308
Bram Moolenaar <bram@vim.org>
parents:
4339
diff
changeset
|
32 "DechoTabOn |
530 | 33 |
798 | 34 let s:zipfile_escape = ' ?&;\' |
1121 | 35 let s:ERROR = 2 |
36 let s:WARNING = 1 | |
37 let s:NOTE = 0 | |
38 | |
39 " --------------------------------------------------------------------- | |
40 " Global Values: {{{1 | |
41 if !exists("g:zip_shq") | |
1621 | 42 if &shq != "" |
43 let g:zip_shq= &shq | |
44 elseif has("unix") | |
1121 | 45 let g:zip_shq= "'" |
46 else | |
47 let g:zip_shq= '"' | |
48 endif | |
49 endif | |
1214 | 50 if !exists("g:zip_zipcmd") |
51 let g:zip_zipcmd= "zip" | |
52 endif | |
53 if !exists("g:zip_unzipcmd") | |
54 let g:zip_unzipcmd= "unzip" | |
55 endif | |
530 | 56 |
57 " ---------------- | |
58 " Functions: {{{1 | |
59 " ---------------- | |
60 | |
61 " --------------------------------------------------------------------- | |
62 " zip#Browse: {{{2 | |
63 fun! zip#Browse(zipfile) | |
64 " call Dfunc("zip#Browse(zipfile<".a:zipfile.">)") | |
5130
71e066e10a47
updated for version 7.3.1308
Bram Moolenaar <bram@vim.org>
parents:
4339
diff
changeset
|
65 " sanity check: insure that the zipfile has "PK" as its first two letters |
71e066e10a47
updated for version 7.3.1308
Bram Moolenaar <bram@vim.org>
parents:
4339
diff
changeset
|
66 " (zipped files have a leading PK as a "magic cookie") |
71e066e10a47
updated for version 7.3.1308
Bram Moolenaar <bram@vim.org>
parents:
4339
diff
changeset
|
67 if !filereadable(a:zipfile) || readfile(a:zipfile, "", 1)[0] !~ '^PK' |
71e066e10a47
updated for version 7.3.1308
Bram Moolenaar <bram@vim.org>
parents:
4339
diff
changeset
|
68 exe "noautocmd e ".fnameescape(a:zipfile) |
71e066e10a47
updated for version 7.3.1308
Bram Moolenaar <bram@vim.org>
parents:
4339
diff
changeset
|
69 " call Dret("zip#Browse : not a zipfile<".a:zipfile.">") |
71e066e10a47
updated for version 7.3.1308
Bram Moolenaar <bram@vim.org>
parents:
4339
diff
changeset
|
70 return |
71e066e10a47
updated for version 7.3.1308
Bram Moolenaar <bram@vim.org>
parents:
4339
diff
changeset
|
71 " else " Decho |
71e066e10a47
updated for version 7.3.1308
Bram Moolenaar <bram@vim.org>
parents:
4339
diff
changeset
|
72 " call Decho("zip#Browse: a:zipfile<".a:zipfile."> passed PK test - its a zip file") |
71e066e10a47
updated for version 7.3.1308
Bram Moolenaar <bram@vim.org>
parents:
4339
diff
changeset
|
73 endif |
71e066e10a47
updated for version 7.3.1308
Bram Moolenaar <bram@vim.org>
parents:
4339
diff
changeset
|
74 |
568 | 75 let repkeep= &report |
76 set report=10 | |
530 | 77 |
78 " sanity checks | |
1698 | 79 if !exists("*fnameescape") |
80 if &verbose > 1 | |
81 echoerr "the zip plugin is not available (your vim doens't support fnameescape())" | |
82 endif | |
83 return | |
84 endif | |
1214 | 85 if !executable(g:zip_unzipcmd) |
1121 | 86 redraw! |
530 | 87 echohl Error | echo "***error*** (zip#Browse) unzip not available on your system" |
1121 | 88 " call inputsave()|call input("Press <cr> to continue")|call inputrestore() |
568 | 89 let &report= repkeep |
530 | 90 " call Dret("zip#Browse") |
91 return | |
92 endif | |
93 if !filereadable(a:zipfile) | |
557 | 94 if a:zipfile !~# '^\a\+://' |
95 " if its an url, don't complain, let url-handlers such as vim do its thing | |
1121 | 96 redraw! |
557 | 97 echohl Error | echo "***error*** (zip#Browse) File not readable<".a:zipfile.">" | echohl None |
1121 | 98 " call inputsave()|call input("Press <cr> to continue")|call inputrestore() |
557 | 99 endif |
568 | 100 let &report= repkeep |
557 | 101 " call Dret("zip#Browse : file<".a:zipfile."> not readable") |
530 | 102 return |
103 endif | |
798 | 104 " call Decho("passed sanity checks") |
530 | 105 if &ma != 1 |
106 set ma | |
107 endif | |
1214 | 108 let b:zipfile= a:zipfile |
530 | 109 |
110 setlocal noswapfile | |
111 setlocal buftype=nofile | |
112 setlocal bufhidden=hide | |
113 setlocal nobuflisted | |
114 setlocal nowrap | |
115 set ft=tar | |
116 | |
117 " give header | |
2908 | 118 call append(0, ['" zip.vim version '.g:loaded_zip, |
3281 | 119 \ '" Browsing zipfile '.a:zipfile, |
120 \ '" Select a file with cursor and press ENTER']) | |
2908 | 121 keepj $ |
530 | 122 |
1698 | 123 " call Decho("exe silent r! ".g:zip_unzipcmd." -l -- ".s:Escape(a:zipfile,1)) |
3281 | 124 exe "keepj sil! r! ".g:zip_unzipcmd." -Z -1 -- ".s:Escape(a:zipfile,1) |
857 | 125 if v:shell_error != 0 |
1121 | 126 redraw! |
1668 | 127 echohl WarningMsg | echo "***warning*** (zip#Browse) ".fnameescape(a:zipfile)." is not a zip file" | echohl None |
1121 | 128 " call inputsave()|call input("Press <cr> to continue")|call inputrestore() |
2908 | 129 keepj sil! %d |
857 | 130 let eikeep= &ei |
131 set ei=BufReadCmd,FileReadCmd | |
2908 | 132 exe "keepj r ".fnameescape(a:zipfile) |
857 | 133 let &ei= eikeep |
2908 | 134 keepj 1d |
857 | 135 " call Dret("zip#Browse") |
136 return | |
137 endif | |
530 | 138 |
139 setlocal noma nomod ro | |
140 noremap <silent> <buffer> <cr> :call <SID>ZipBrowseSelect()<cr> | |
141 | |
568 | 142 let &report= repkeep |
530 | 143 " call Dret("zip#Browse") |
144 endfun | |
145 | |
146 " --------------------------------------------------------------------- | |
147 " ZipBrowseSelect: {{{2 | |
148 fun! s:ZipBrowseSelect() | |
1214 | 149 " call Dfunc("ZipBrowseSelect() zipfile<".b:zipfile."> curfile<".expand("%").">") |
568 | 150 let repkeep= &report |
151 set report=10 | |
530 | 152 let fname= getline(".") |
153 | |
154 " sanity check | |
155 if fname =~ '^"' | |
568 | 156 let &report= repkeep |
530 | 157 " call Dret("ZipBrowseSelect") |
158 return | |
159 endif | |
160 if fname =~ '/$' | |
1121 | 161 redraw! |
530 | 162 echohl Error | echo "***error*** (zip#Browse) Please specify a file, not a directory" | echohl None |
1121 | 163 " call inputsave()|call input("Press <cr> to continue")|call inputrestore() |
568 | 164 let &report= repkeep |
530 | 165 " call Dret("ZipBrowseSelect") |
166 return | |
167 endif | |
168 | |
169 " call Decho("fname<".fname.">") | |
170 | |
171 " get zipfile to the new-window | |
1214 | 172 let zipfile = b:zipfile |
819 | 173 let curfile= expand("%") |
798 | 174 " call Decho("zipfile<".zipfile.">") |
175 " call Decho("curfile<".curfile.">") | |
530 | 176 |
177 new | |
1621 | 178 if !exists("g:zip_nomax") || g:zip_nomax == 0 |
179 wincmd _ | |
180 endif | |
557 | 181 let s:zipfile_{winnr()}= curfile |
1668 | 182 " call Decho("exe e ".fnameescape("zipfile:".zipfile.'::'.fname)) |
183 exe "e ".fnameescape("zipfile:".zipfile.'::'.fname) | |
530 | 184 filetype detect |
185 | |
568 | 186 let &report= repkeep |
557 | 187 " call Dret("ZipBrowseSelect : s:zipfile_".winnr()."<".s:zipfile_{winnr()}.">") |
530 | 188 endfun |
189 | |
190 " --------------------------------------------------------------------- | |
191 " zip#Read: {{{2 | |
192 fun! zip#Read(fname,mode) | |
193 " call Dfunc("zip#Read(fname<".a:fname.">,mode=".a:mode.")") | |
568 | 194 let repkeep= &report |
195 set report=10 | |
196 | |
857 | 197 if has("unix") |
198 let zipfile = substitute(a:fname,'zipfile:\(.\{-}\)::[^\\].*$','\1','') | |
199 let fname = substitute(a:fname,'zipfile:.\{-}::\([^\\].*\)$','\1','') | |
200 else | |
201 let zipfile = substitute(a:fname,'^.\{-}zipfile:\(.\{-}\)::[^\\].*$','\1','') | |
202 let fname = substitute(a:fname,'^.\{-}zipfile:.\{-}::\([^\\].*\)$','\1','') | |
4339 | 203 let fname = substitute(fname, '[', '[[]', 'g') |
857 | 204 endif |
205 " call Decho("zipfile<".zipfile.">") | |
206 " call Decho("fname <".fname.">") | |
530 | 207 |
4339 | 208 " the following code does much the same thing as |
209 " exe "keepj sil! r! ".g:zip_unzipcmd." -p -- ".s:Escape(zipfile,1)." ".s:Escape(fnameescape(fname),1) | |
210 " but allows zipfile:... entries in quickfix lists | |
211 let temp = tempname() | |
5130
71e066e10a47
updated for version 7.3.1308
Bram Moolenaar <bram@vim.org>
parents:
4339
diff
changeset
|
212 " call Decho("using temp file<".temp.">") |
4339 | 213 let fn = expand('%:p') |
214 exe "sil! !".g:zip_unzipcmd." -p -- ".s:Escape(zipfile,1)." ".s:Escape(fnameescape(fname),1).' > '.temp | |
215 " call Decho("exe sil! !".g:zip_unzipcmd." -p -- ".s:Escape(zipfile,1)." ".s:Escape(fnameescape(fname),1).' > '.temp) | |
216 sil exe 'keepalt file '.temp | |
217 sil keepj e! | |
218 sil exe 'keepalt file '.fnameescape(fn) | |
219 call delete(temp) | |
220 | |
2908 | 221 filetype detect |
530 | 222 |
223 " cleanup | |
5130
71e066e10a47
updated for version 7.3.1308
Bram Moolenaar <bram@vim.org>
parents:
4339
diff
changeset
|
224 " keepj 0d " used to be needed for the ...r! ... method |
530 | 225 set nomod |
226 | |
568 | 227 let &report= repkeep |
530 | 228 " call Dret("zip#Read") |
229 endfun | |
230 | |
231 " --------------------------------------------------------------------- | |
232 " zip#Write: {{{2 | |
233 fun! zip#Write(fname) | |
819 | 234 " call Dfunc("zip#Write(fname<".a:fname.">) zipfile_".winnr()."<".s:zipfile_{winnr()}.">") |
568 | 235 let repkeep= &report |
236 set report=10 | |
530 | 237 |
238 " sanity checks | |
1214 | 239 if !executable(g:zip_zipcmd) |
1121 | 240 redraw! |
530 | 241 echohl Error | echo "***error*** (zip#Write) sorry, your system doesn't appear to have the zip pgm" | echohl None |
1121 | 242 " call inputsave()|call input("Press <cr> to continue")|call inputrestore() |
568 | 243 let &report= repkeep |
530 | 244 " call Dret("zip#Write") |
245 return | |
246 endif | |
247 if !exists("*mkdir") | |
1121 | 248 redraw! |
530 | 249 echohl Error | echo "***error*** (zip#Write) sorry, mkdir() doesn't work on your system" | echohl None |
1121 | 250 " call inputsave()|call input("Press <cr> to continue")|call inputrestore() |
568 | 251 let &report= repkeep |
530 | 252 " call Dret("zip#Write") |
253 return | |
254 endif | |
255 | |
256 let curdir= getcwd() | |
257 let tmpdir= tempname() | |
258 " call Decho("orig tempname<".tmpdir.">") | |
259 if tmpdir =~ '\.' | |
260 let tmpdir= substitute(tmpdir,'\.[^.]*$','','e') | |
261 endif | |
262 " call Decho("tmpdir<".tmpdir.">") | |
263 call mkdir(tmpdir,"p") | |
264 | |
265 " attempt to change to the indicated directory | |
1121 | 266 if s:ChgDir(tmpdir,s:ERROR,"(zip#Write) cannot cd to temporary directory") |
568 | 267 let &report= repkeep |
530 | 268 " call Dret("zip#Write") |
269 return | |
1121 | 270 endif |
530 | 271 " call Decho("current directory now: ".getcwd()) |
272 | |
273 " place temporary files under .../_ZIPVIM_/ | |
274 if isdirectory("_ZIPVIM_") | |
275 call s:Rmdir("_ZIPVIM_") | |
276 endif | |
277 call mkdir("_ZIPVIM_") | |
278 cd _ZIPVIM_ | |
279 " call Decho("current directory now: ".getcwd()) | |
280 | |
857 | 281 if has("unix") |
282 let zipfile = substitute(a:fname,'zipfile:\(.\{-}\)::[^\\].*$','\1','') | |
283 let fname = substitute(a:fname,'zipfile:.\{-}::\([^\\].*\)$','\1','') | |
284 else | |
285 let zipfile = substitute(a:fname,'^.\{-}zipfile:\(.\{-}\)::[^\\].*$','\1','') | |
286 let fname = substitute(a:fname,'^.\{-}zipfile:.\{-}::\([^\\].*\)$','\1','') | |
287 endif | |
288 " call Decho("zipfile<".zipfile.">") | |
289 " call Decho("fname <".fname.">") | |
623 | 290 |
291 if fname =~ '/' | |
292 let dirpath = substitute(fname,'/[^/]\+$','','e') | |
4339 | 293 if has("win32unix") && executable("cygpath") |
1668 | 294 let dirpath = substitute(system("cygpath ".s:Escape(dirpath,0)),'\n','','e') |
623 | 295 endif |
819 | 296 " call Decho("mkdir(dirpath<".dirpath.">,p)") |
623 | 297 call mkdir(dirpath,"p") |
298 endif | |
530 | 299 if zipfile !~ '/' |
300 let zipfile= curdir.'/'.zipfile | |
301 endif | |
302 " call Decho("zipfile<".zipfile."> fname<".fname.">") | |
303 | |
1668 | 304 exe "w! ".fnameescape(fname) |
4339 | 305 if has("win32unix") && executable("cygpath") |
1668 | 306 let zipfile = substitute(system("cygpath ".s:Escape(zipfile,0)),'\n','','e') |
530 | 307 endif |
308 | |
1121 | 309 if (has("win32") || has("win95") || has("win64") || has("win16")) && &shell !~? 'sh$' |
310 let fname = substitute(fname, '[', '[[]', 'g') | |
311 endif | |
312 | |
1698 | 313 " call Decho(g:zip_zipcmd." -u ".s:Escape(fnamemodify(zipfile,":p"),0)." ".s:Escape(fname,0)) |
314 call system(g:zip_zipcmd." -u ".s:Escape(fnamemodify(zipfile,":p"),0)." ".s:Escape(fname,0)) | |
530 | 315 if v:shell_error != 0 |
1121 | 316 redraw! |
530 | 317 echohl Error | echo "***error*** (zip#Write) sorry, unable to update ".zipfile." with ".fname | echohl None |
1121 | 318 " call inputsave()|call input("Press <cr> to continue")|call inputrestore() |
557 | 319 |
320 elseif s:zipfile_{winnr()} =~ '^\a\+://' | |
321 " support writing zipfiles across a network | |
322 let netzipfile= s:zipfile_{winnr()} | |
1121 | 323 " call Decho("handle writing <".zipfile."> across network as <".netzipfile.">") |
557 | 324 1split|enew |
325 let binkeep= &binary | |
326 let eikeep = &ei | |
327 set binary ei=all | |
1668 | 328 exe "e! ".fnameescape(zipfile) |
557 | 329 call netrw#NetWrite(netzipfile) |
330 let &ei = eikeep | |
331 let &binary = binkeep | |
332 q! | |
333 unlet s:zipfile_{winnr()} | |
530 | 334 endif |
335 | |
336 " cleanup and restore current directory | |
337 cd .. | |
338 call s:Rmdir("_ZIPVIM_") | |
1121 | 339 call s:ChgDir(curdir,s:WARNING,"(zip#Write) unable to return to ".curdir."!") |
340 call s:Rmdir(tmpdir) | |
530 | 341 setlocal nomod |
342 | |
568 | 343 let &report= repkeep |
530 | 344 " call Dret("zip#Write") |
345 endfun | |
346 | |
347 " --------------------------------------------------------------------- | |
1668 | 348 " s:Escape: {{{2 |
349 fun! s:Escape(fname,isfilt) | |
350 " call Dfunc("QuoteFileDir(fname<".a:fname."> isfilt=".a:isfilt.")") | |
351 if exists("*shellescape") | |
352 if a:isfilt | |
353 let qnameq= shellescape(a:fname,1) | |
354 else | |
355 let qnameq= shellescape(a:fname) | |
356 endif | |
1621 | 357 else |
358 let qnameq= g:zip_shq.escape(a:fname,g:zip_shq).g:zip_shq | |
359 endif | |
360 " call Dret("QuoteFileDir <".qnameq.">") | |
361 return qnameq | |
1121 | 362 endfun |
363 | |
364 " --------------------------------------------------------------------- | |
365 " ChgDir: {{{2 | |
366 fun! s:ChgDir(newdir,errlvl,errmsg) | |
367 " call Dfunc("ChgDir(newdir<".a:newdir."> errlvl=".a:errlvl." errmsg<".a:errmsg.">)") | |
368 | |
369 try | |
1698 | 370 exe "cd ".fnameescape(a:newdir) |
1121 | 371 catch /^Vim\%((\a\+)\)\=:E344/ |
372 redraw! | |
373 if a:errlvl == s:NOTE | |
374 echo "***note*** ".a:errmsg | |
375 elseif a:errlvl == s:WARNING | |
376 echohl WarningMsg | echo "***warning*** ".a:errmsg | echohl NONE | |
377 elseif a:errlvl == s:ERROR | |
378 echohl Error | echo "***error*** ".a:errmsg | echohl NONE | |
379 endif | |
380 " call inputsave()|call input("Press <cr> to continue")|call inputrestore() | |
381 " call Dret("ChgDir 1") | |
382 return 1 | |
383 endtry | |
384 | |
385 " call Dret("ChgDir 0") | |
386 return 0 | |
387 endfun | |
388 | |
389 " --------------------------------------------------------------------- | |
1668 | 390 " s:Rmdir: {{{2 |
530 | 391 fun! s:Rmdir(fname) |
392 " call Dfunc("Rmdir(fname<".a:fname.">)") | |
1121 | 393 if (has("win32") || has("win95") || has("win64") || has("win16")) && &shell !~? 'sh$' |
1668 | 394 call system("rmdir /S/Q ".s:Escape(a:fname,0)) |
1121 | 395 else |
1668 | 396 call system("/bin/rm -rf ".s:Escape(a:fname,0)) |
530 | 397 endif |
398 " call Dret("Rmdir") | |
399 endfun | |
400 | |
401 " ------------------------------------------------------------------------ | |
402 " Modelines And Restoration: {{{1 | |
403 let &cpo= s:keepcpo | |
404 unlet s:keepcpo | |
1214 | 405 " vim:ts=8 fdm=marker |