blob: 34bcad3368d13f92b8642e04c884359838b0423e [file] [log] [blame]
Bram Moolenaar60a795a2005-09-16 21:55:43 +00001" zip.vim: Handles browsing zipfiles
2" AUTOLOAD PORTION
Damien38ce71c2024-07-23 19:56:54 +02003" Date: Jul 23, 2024
Bram Moolenaar71badf92023-04-22 22:40:14 +01004" Version: 33
Christian Brabandtf9ca1392024-02-19 20:37:11 +01005" Maintainer: This runtime file is looking for a new maintainer.
6" Former Maintainer: Charles E Campbell
Christian Brabandt1c673422024-06-15 14:49:24 +02007" Last Change:
8" 2024 Jun 16 by Vim Project: handle whitespace on Windows properly (#14998)
Damien38ce71c2024-07-23 19:56:54 +02009" 2024 Jul 23 by Vim Project: fix 'x' command
Bram Moolenaar9964e462007-05-05 17:54:07 +000010" License: Vim License (see vim's :help license)
Christian Brabandt1c673422024-06-15 14:49:24 +020011" Copyright: Copyright (C) 2005-2019 Charles E. Campbell {{{1
12" Permission is hereby granted to use and distribute this code,
13" with or without modifications, provided that this copyright
14" notice is copied with it. Like anything else that's free,
15" zip.vim and zipPlugin.vim are provided *as is* and comes with
16" no warranty of any kind, either expressed or implied. By using
17" this plugin, you agree that in no event will the copyright
18" holder be liable for any damages resulting from the use
19" of this software.
Bram Moolenaar60a795a2005-09-16 21:55:43 +000020
21" ---------------------------------------------------------------------
Bram Moolenaar9964e462007-05-05 17:54:07 +000022" Load Once: {{{1
Bram Moolenaar00a927d2010-05-14 23:24:24 +020023if &cp || exists("g:loaded_zip")
Bram Moolenaar60a795a2005-09-16 21:55:43 +000024 finish
25endif
Bram Moolenaar71badf92023-04-22 22:40:14 +010026let g:loaded_zip= "v33"
Bram Moolenaar00a927d2010-05-14 23:24:24 +020027if v:version < 702
28 echohl WarningMsg
Bram Moolenaard0796902016-09-16 20:02:31 +020029 echo "***warning*** this version of zip needs vim 7.2 or later"
Bram Moolenaar00a927d2010-05-14 23:24:24 +020030 echohl Normal
31 finish
32endif
33let s:keepcpo= &cpo
34set cpo&vim
Bram Moolenaar94f76b72013-07-04 22:50:40 +020035"DechoTabOn
Bram Moolenaar60a795a2005-09-16 21:55:43 +000036
Bram Moolenaardb552d602006-03-23 22:59:57 +000037let s:zipfile_escape = ' ?&;\'
Bram Moolenaar9964e462007-05-05 17:54:07 +000038let s:ERROR = 2
39let s:WARNING = 1
40let s:NOTE = 0
41
42" ---------------------------------------------------------------------
43" Global Values: {{{1
44if !exists("g:zip_shq")
Bram Moolenaar446cb832008-06-24 21:56:24 +000045 if &shq != ""
46 let g:zip_shq= &shq
47 elseif has("unix")
Bram Moolenaar9964e462007-05-05 17:54:07 +000048 let g:zip_shq= "'"
49 else
50 let g:zip_shq= '"'
51 endif
52endif
Bram Moolenaarccc18222007-05-10 18:25:20 +000053if !exists("g:zip_zipcmd")
54 let g:zip_zipcmd= "zip"
55endif
56if !exists("g:zip_unzipcmd")
57 let g:zip_unzipcmd= "unzip"
58endif
Bram Moolenaard0796902016-09-16 20:02:31 +020059if !exists("g:zip_extractcmd")
60 let g:zip_extractcmd= g:zip_unzipcmd
61endif
Bram Moolenaar60a795a2005-09-16 21:55:43 +000062
D. Ben Knoblecd8a3ea2023-11-04 05:11:17 -040063if !dist#vim#IsSafeExecutable('zip', g:zip_unzipcmd)
Christian Brabandt816fbcc2023-08-31 23:52:30 +020064 echoerr "Warning: NOT executing " .. g:zip_unzipcmd .. " from current directory!"
65 finish
66endif
Anton Sharonov67c951d2023-09-05 21:03:27 +020067
Bram Moolenaar60a795a2005-09-16 21:55:43 +000068" ----------------
69" Functions: {{{1
70" ----------------
71
72" ---------------------------------------------------------------------
73" zip#Browse: {{{2
74fun! zip#Browse(zipfile)
75" call Dfunc("zip#Browse(zipfile<".a:zipfile.">)")
Bram Moolenaarcb80aa22020-10-26 21:12:46 +010076 " sanity check: insure that the zipfile has "PK" as its first two letters
Bram Moolenaar94f76b72013-07-04 22:50:40 +020077 " (zipped files have a leading PK as a "magic cookie")
78 if !filereadable(a:zipfile) || readfile(a:zipfile, "", 1)[0] !~ '^PK'
Bram Moolenaar29634562020-01-09 21:46:04 +010079 exe "noswapfile noautocmd noswapfile e ".fnameescape(a:zipfile)
Bram Moolenaar94f76b72013-07-04 22:50:40 +020080" call Dret("zip#Browse : not a zipfile<".a:zipfile.">")
81 return
82" else " Decho
Bram Moolenaar8024f932020-01-14 19:29:13 +010083" call Decho("zip#Browse: a:zipfile<".a:zipfile."> passed PK test - it's a zip file")
Bram Moolenaar94f76b72013-07-04 22:50:40 +020084 endif
85
Bram Moolenaar36c31f72005-11-28 23:01:53 +000086 let repkeep= &report
87 set report=10
Bram Moolenaar60a795a2005-09-16 21:55:43 +000088
89 " sanity checks
Bram Moolenaare37d50a2008-08-06 17:06:04 +000090 if !exists("*fnameescape")
91 if &verbose > 1
Bram Moolenaar6c391a72021-09-09 21:55:11 +020092 echoerr "the zip plugin is not available (your vim doesn't support fnameescape())"
Bram Moolenaare37d50a2008-08-06 17:06:04 +000093 endif
94 return
95 endif
Bram Moolenaarccc18222007-05-10 18:25:20 +000096 if !executable(g:zip_unzipcmd)
Bram Moolenaar9964e462007-05-05 17:54:07 +000097 redraw!
Bram Moolenaar60a795a2005-09-16 21:55:43 +000098 echohl Error | echo "***error*** (zip#Browse) unzip not available on your system"
Bram Moolenaar9964e462007-05-05 17:54:07 +000099" call inputsave()|call input("Press <cr> to continue")|call inputrestore()
Bram Moolenaar36c31f72005-11-28 23:01:53 +0000100 let &report= repkeep
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000101" call Dret("zip#Browse")
102 return
103 endif
104 if !filereadable(a:zipfile)
Bram Moolenaara5792f52005-11-23 21:25:05 +0000105 if a:zipfile !~# '^\a\+://'
Bram Moolenaar8024f932020-01-14 19:29:13 +0100106 " if it's an url, don't complain, let url-handlers such as vim do its thing
Bram Moolenaar9964e462007-05-05 17:54:07 +0000107 redraw!
Bram Moolenaara5792f52005-11-23 21:25:05 +0000108 echohl Error | echo "***error*** (zip#Browse) File not readable<".a:zipfile.">" | echohl None
Bram Moolenaar9964e462007-05-05 17:54:07 +0000109" call inputsave()|call input("Press <cr> to continue")|call inputrestore()
Bram Moolenaara5792f52005-11-23 21:25:05 +0000110 endif
Bram Moolenaar36c31f72005-11-28 23:01:53 +0000111 let &report= repkeep
Bram Moolenaara5792f52005-11-23 21:25:05 +0000112" call Dret("zip#Browse : file<".a:zipfile."> not readable")
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000113 return
114 endif
Bram Moolenaardb552d602006-03-23 22:59:57 +0000115" call Decho("passed sanity checks")
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000116 if &ma != 1
117 set ma
118 endif
Bram Moolenaarccc18222007-05-10 18:25:20 +0000119 let b:zipfile= a:zipfile
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000120
121 setlocal noswapfile
122 setlocal buftype=nofile
123 setlocal bufhidden=hide
124 setlocal nobuflisted
125 setlocal nowrap
Bram Moolenaar519cc552021-11-16 19:18:26 +0000126
127 " Oct 12, 2021: need to re-use Bram's syntax/tar.vim.
128 " Setting the filetype to zip doesn't do anything (currently),
129 " but it is perhaps less confusing to curious perusers who do
130 " a :echo &ft
131 setf zip
132 run! syntax/tar.vim
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000133
134 " give header
Bram Moolenaar251e1912011-06-19 05:09:16 +0200135 call append(0, ['" zip.vim version '.g:loaded_zip,
Bram Moolenaar6be7f872012-01-20 21:08:56 +0100136 \ '" Browsing zipfile '.a:zipfile,
137 \ '" Select a file with cursor and press ENTER'])
Bram Moolenaar251e1912011-06-19 05:09:16 +0200138 keepj $
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000139
Bram Moolenaare37d50a2008-08-06 17:06:04 +0000140" call Decho("exe silent r! ".g:zip_unzipcmd." -l -- ".s:Escape(a:zipfile,1))
Bram Moolenaar6be7f872012-01-20 21:08:56 +0100141 exe "keepj sil! r! ".g:zip_unzipcmd." -Z -1 -- ".s:Escape(a:zipfile,1)
Bram Moolenaard68071d2006-05-02 22:08:30 +0000142 if v:shell_error != 0
Bram Moolenaar9964e462007-05-05 17:54:07 +0000143 redraw!
Bram Moolenaarc236c162008-07-13 17:41:49 +0000144 echohl WarningMsg | echo "***warning*** (zip#Browse) ".fnameescape(a:zipfile)." is not a zip file" | echohl None
Bram Moolenaar9964e462007-05-05 17:54:07 +0000145" call inputsave()|call input("Press <cr> to continue")|call inputrestore()
Bram Moolenaar251e1912011-06-19 05:09:16 +0200146 keepj sil! %d
Bram Moolenaard68071d2006-05-02 22:08:30 +0000147 let eikeep= &ei
148 set ei=BufReadCmd,FileReadCmd
Bram Moolenaar251e1912011-06-19 05:09:16 +0200149 exe "keepj r ".fnameescape(a:zipfile)
Bram Moolenaard68071d2006-05-02 22:08:30 +0000150 let &ei= eikeep
Bram Moolenaar251e1912011-06-19 05:09:16 +0200151 keepj 1d
Bram Moolenaard68071d2006-05-02 22:08:30 +0000152" call Dret("zip#Browse")
153 return
154 endif
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000155
Bram Moolenaard0796902016-09-16 20:02:31 +0200156 " Maps associated with zip plugin
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000157 setlocal noma nomod ro
Bram Moolenaar29634562020-01-09 21:46:04 +0100158 noremap <silent> <buffer> <cr> :call <SID>ZipBrowseSelect()<cr>
159 noremap <silent> <buffer> x :call zip#Extract()<cr>
160 if &mouse != ""
161 noremap <silent> <buffer> <leftmouse> <leftmouse>:call <SID>ZipBrowseSelect()<cr>
162 endif
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000163
Bram Moolenaar36c31f72005-11-28 23:01:53 +0000164 let &report= repkeep
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000165" call Dret("zip#Browse")
166endfun
167
168" ---------------------------------------------------------------------
169" ZipBrowseSelect: {{{2
170fun! s:ZipBrowseSelect()
Bram Moolenaar71badf92023-04-22 22:40:14 +0100171 " call Dfunc("ZipBrowseSelect() zipfile<".((exists("b:zipfile"))? b:zipfile : "n/a")."> curfile<".expand("%").">")
Bram Moolenaar36c31f72005-11-28 23:01:53 +0000172 let repkeep= &report
173 set report=10
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000174 let fname= getline(".")
Bram Moolenaar71badf92023-04-22 22:40:14 +0100175 if !exists("b:zipfile")
176" call Dret("ZipBrowseSelect : b:zipfile doesn't exist!")
177 return
178 endif
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000179
180 " sanity check
181 if fname =~ '^"'
Bram Moolenaar36c31f72005-11-28 23:01:53 +0000182 let &report= repkeep
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000183" call Dret("ZipBrowseSelect")
184 return
185 endif
186 if fname =~ '/$'
Bram Moolenaar9964e462007-05-05 17:54:07 +0000187 redraw!
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000188 echohl Error | echo "***error*** (zip#Browse) Please specify a file, not a directory" | echohl None
Bram Moolenaar9964e462007-05-05 17:54:07 +0000189" call inputsave()|call input("Press <cr> to continue")|call inputrestore()
Bram Moolenaar36c31f72005-11-28 23:01:53 +0000190 let &report= repkeep
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000191" call Dret("ZipBrowseSelect")
192 return
193 endif
194
195" call Decho("fname<".fname.">")
196
197 " get zipfile to the new-window
Bram Moolenaarccc18222007-05-10 18:25:20 +0000198 let zipfile = b:zipfile
Bram Moolenaar29634562020-01-09 21:46:04 +0100199 let curfile = expand("%")
Bram Moolenaardb552d602006-03-23 22:59:57 +0000200" call Decho("zipfile<".zipfile.">")
201" call Decho("curfile<".curfile.">")
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000202
Bram Moolenaar29634562020-01-09 21:46:04 +0100203 noswapfile new
Bram Moolenaar446cb832008-06-24 21:56:24 +0000204 if !exists("g:zip_nomax") || g:zip_nomax == 0
205 wincmd _
206 endif
Bram Moolenaara5792f52005-11-23 21:25:05 +0000207 let s:zipfile_{winnr()}= curfile
Bram Moolenaar519cc552021-11-16 19:18:26 +0000208" call Decho("exe e ".fnameescape("zipfile://".zipfile.'::'.fname))
209 exe "noswapfile e ".fnameescape("zipfile://".zipfile.'::'.fname)
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000210 filetype detect
211
Bram Moolenaar36c31f72005-11-28 23:01:53 +0000212 let &report= repkeep
Bram Moolenaara5792f52005-11-23 21:25:05 +0000213" call Dret("ZipBrowseSelect : s:zipfile_".winnr()."<".s:zipfile_{winnr()}.">")
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000214endfun
215
216" ---------------------------------------------------------------------
217" zip#Read: {{{2
218fun! zip#Read(fname,mode)
Bram Moolenaar36c31f72005-11-28 23:01:53 +0000219 let repkeep= &report
220 set report=10
221
Bram Moolenaard68071d2006-05-02 22:08:30 +0000222 if has("unix")
Bram Moolenaar519cc552021-11-16 19:18:26 +0000223 let zipfile = substitute(a:fname,'zipfile://\(.\{-}\)::[^\\].*$','\1','')
224 let fname = substitute(a:fname,'zipfile://.\{-}::\([^\\].*\)$','\1','')
Bram Moolenaard68071d2006-05-02 22:08:30 +0000225 else
Bram Moolenaar519cc552021-11-16 19:18:26 +0000226 let zipfile = substitute(a:fname,'^.\{-}zipfile://\(.\{-}\)::[^\\].*$','\1','')
227 let fname = substitute(a:fname,'^.\{-}zipfile://.\{-}::\([^\\].*\)$','\1','')
Bram Moolenaarff034192013-04-24 18:51:19 +0200228 let fname = substitute(fname, '[', '[[]', 'g')
Bram Moolenaard68071d2006-05-02 22:08:30 +0000229 endif
Bram Moolenaard0796902016-09-16 20:02:31 +0200230 " sanity check
231 if !executable(substitute(g:zip_unzipcmd,'\s\+.*$','',''))
232 redraw!
233 echohl Error | echo "***error*** (zip#Read) sorry, your system doesn't appear to have the ".g:zip_unzipcmd." program" | echohl None
234" call inputsave()|call input("Press <cr> to continue")|call inputrestore()
235 let &report= repkeep
Bram Moolenaard0796902016-09-16 20:02:31 +0200236 return
237 endif
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000238
Bram Moolenaarff034192013-04-24 18:51:19 +0200239 " the following code does much the same thing as
240 " exe "keepj sil! r! ".g:zip_unzipcmd." -p -- ".s:Escape(zipfile,1)." ".s:Escape(fnameescape(fname),1)
Bram Moolenaar519cc552021-11-16 19:18:26 +0000241 " but allows zipfile://... entries in quickfix lists
Bram Moolenaarff034192013-04-24 18:51:19 +0200242 let temp = tempname()
243 let fn = expand('%:p')
Christian Brabandt1c673422024-06-15 14:49:24 +0200244 exe "sil! !".g:zip_unzipcmd." -p -- ".s:Escape(zipfile,1)." ".s:Escape(fname,1).' > '.temp
Bram Moolenaarff034192013-04-24 18:51:19 +0200245 sil exe 'keepalt file '.temp
246 sil keepj e!
247 sil exe 'keepalt file '.fnameescape(fn)
248 call delete(temp)
249
Bram Moolenaar251e1912011-06-19 05:09:16 +0200250 filetype detect
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000251
252 " cleanup
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000253 set nomod
254
Bram Moolenaar36c31f72005-11-28 23:01:53 +0000255 let &report= repkeep
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000256endfun
257
258" ---------------------------------------------------------------------
259" zip#Write: {{{2
260fun! zip#Write(fname)
Bram Moolenaar910f66f2006-04-05 20:41:53 +0000261" call Dfunc("zip#Write(fname<".a:fname.">) zipfile_".winnr()."<".s:zipfile_{winnr()}.">")
Bram Moolenaar36c31f72005-11-28 23:01:53 +0000262 let repkeep= &report
263 set report=10
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000264
265 " sanity checks
Bram Moolenaard0796902016-09-16 20:02:31 +0200266 if !executable(substitute(g:zip_zipcmd,'\s\+.*$','',''))
Bram Moolenaar9964e462007-05-05 17:54:07 +0000267 redraw!
Bram Moolenaard0796902016-09-16 20:02:31 +0200268 echohl Error | echo "***error*** (zip#Write) sorry, your system doesn't appear to have the ".g:zip_zipcmd." program" | echohl None
Bram Moolenaar9964e462007-05-05 17:54:07 +0000269" call inputsave()|call input("Press <cr> to continue")|call inputrestore()
Bram Moolenaar36c31f72005-11-28 23:01:53 +0000270 let &report= repkeep
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000271" call Dret("zip#Write")
272 return
273 endif
274 if !exists("*mkdir")
Bram Moolenaar9964e462007-05-05 17:54:07 +0000275 redraw!
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000276 echohl Error | echo "***error*** (zip#Write) sorry, mkdir() doesn't work on your system" | echohl None
Bram Moolenaar9964e462007-05-05 17:54:07 +0000277" call inputsave()|call input("Press <cr> to continue")|call inputrestore()
Bram Moolenaar36c31f72005-11-28 23:01:53 +0000278 let &report= repkeep
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000279" call Dret("zip#Write")
280 return
281 endif
282
283 let curdir= getcwd()
284 let tmpdir= tempname()
285" call Decho("orig tempname<".tmpdir.">")
286 if tmpdir =~ '\.'
287 let tmpdir= substitute(tmpdir,'\.[^.]*$','','e')
288 endif
289" call Decho("tmpdir<".tmpdir.">")
290 call mkdir(tmpdir,"p")
291
292 " attempt to change to the indicated directory
Bram Moolenaar9964e462007-05-05 17:54:07 +0000293 if s:ChgDir(tmpdir,s:ERROR,"(zip#Write) cannot cd to temporary directory")
Bram Moolenaar36c31f72005-11-28 23:01:53 +0000294 let &report= repkeep
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000295" call Dret("zip#Write")
296 return
Bram Moolenaar9964e462007-05-05 17:54:07 +0000297 endif
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000298" call Decho("current directory now: ".getcwd())
299
300 " place temporary files under .../_ZIPVIM_/
301 if isdirectory("_ZIPVIM_")
302 call s:Rmdir("_ZIPVIM_")
303 endif
304 call mkdir("_ZIPVIM_")
305 cd _ZIPVIM_
306" call Decho("current directory now: ".getcwd())
307
Bram Moolenaard68071d2006-05-02 22:08:30 +0000308 if has("unix")
Bram Moolenaar519cc552021-11-16 19:18:26 +0000309 let zipfile = substitute(a:fname,'zipfile://\(.\{-}\)::[^\\].*$','\1','')
310 let fname = substitute(a:fname,'zipfile://.\{-}::\([^\\].*\)$','\1','')
Bram Moolenaard68071d2006-05-02 22:08:30 +0000311 else
Bram Moolenaar519cc552021-11-16 19:18:26 +0000312 let zipfile = substitute(a:fname,'^.\{-}zipfile://\(.\{-}\)::[^\\].*$','\1','')
313 let fname = substitute(a:fname,'^.\{-}zipfile://.\{-}::\([^\\].*\)$','\1','')
Bram Moolenaard68071d2006-05-02 22:08:30 +0000314 endif
315" call Decho("zipfile<".zipfile.">")
316" call Decho("fname <".fname.">")
Bram Moolenaarc7486e02005-12-29 22:48:26 +0000317
318 if fname =~ '/'
319 let dirpath = substitute(fname,'/[^/]\+$','','e')
Bram Moolenaarff034192013-04-24 18:51:19 +0200320 if has("win32unix") && executable("cygpath")
Bram Moolenaarc236c162008-07-13 17:41:49 +0000321 let dirpath = substitute(system("cygpath ".s:Escape(dirpath,0)),'\n','','e')
Bram Moolenaarc7486e02005-12-29 22:48:26 +0000322 endif
Bram Moolenaar910f66f2006-04-05 20:41:53 +0000323" call Decho("mkdir(dirpath<".dirpath.">,p)")
Bram Moolenaarc7486e02005-12-29 22:48:26 +0000324 call mkdir(dirpath,"p")
325 endif
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000326 if zipfile !~ '/'
327 let zipfile= curdir.'/'.zipfile
328 endif
329" call Decho("zipfile<".zipfile."> fname<".fname.">")
330
Bram Moolenaarc236c162008-07-13 17:41:49 +0000331 exe "w! ".fnameescape(fname)
Bram Moolenaarff034192013-04-24 18:51:19 +0200332 if has("win32unix") && executable("cygpath")
Bram Moolenaarc236c162008-07-13 17:41:49 +0000333 let zipfile = substitute(system("cygpath ".s:Escape(zipfile,0)),'\n','','e')
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000334 endif
335
Bram Moolenaar9964e462007-05-05 17:54:07 +0000336 if (has("win32") || has("win95") || has("win64") || has("win16")) && &shell !~? 'sh$'
337 let fname = substitute(fname, '[', '[[]', 'g')
338 endif
339
Bram Moolenaare37d50a2008-08-06 17:06:04 +0000340" call Decho(g:zip_zipcmd." -u ".s:Escape(fnamemodify(zipfile,":p"),0)." ".s:Escape(fname,0))
341 call system(g:zip_zipcmd." -u ".s:Escape(fnamemodify(zipfile,":p"),0)." ".s:Escape(fname,0))
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000342 if v:shell_error != 0
Bram Moolenaar9964e462007-05-05 17:54:07 +0000343 redraw!
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000344 echohl Error | echo "***error*** (zip#Write) sorry, unable to update ".zipfile." with ".fname | echohl None
Bram Moolenaar9964e462007-05-05 17:54:07 +0000345" call inputsave()|call input("Press <cr> to continue")|call inputrestore()
Bram Moolenaara5792f52005-11-23 21:25:05 +0000346
347 elseif s:zipfile_{winnr()} =~ '^\a\+://'
348 " support writing zipfiles across a network
349 let netzipfile= s:zipfile_{winnr()}
Bram Moolenaar9964e462007-05-05 17:54:07 +0000350" call Decho("handle writing <".zipfile."> across network as <".netzipfile.">")
Bram Moolenaara5792f52005-11-23 21:25:05 +0000351 1split|enew
352 let binkeep= &binary
353 let eikeep = &ei
354 set binary ei=all
Bram Moolenaar29634562020-01-09 21:46:04 +0100355 exe "noswapfile e! ".fnameescape(zipfile)
Bram Moolenaara5792f52005-11-23 21:25:05 +0000356 call netrw#NetWrite(netzipfile)
357 let &ei = eikeep
358 let &binary = binkeep
359 q!
360 unlet s:zipfile_{winnr()}
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000361 endif
362
363 " cleanup and restore current directory
364 cd ..
365 call s:Rmdir("_ZIPVIM_")
Bram Moolenaar9964e462007-05-05 17:54:07 +0000366 call s:ChgDir(curdir,s:WARNING,"(zip#Write) unable to return to ".curdir."!")
367 call s:Rmdir(tmpdir)
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000368 setlocal nomod
369
Bram Moolenaar36c31f72005-11-28 23:01:53 +0000370 let &report= repkeep
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000371" call Dret("zip#Write")
372endfun
373
374" ---------------------------------------------------------------------
Bram Moolenaard0796902016-09-16 20:02:31 +0200375" zip#Extract: extract a file from a zip archive {{{2
376fun! zip#Extract()
377" call Dfunc("zip#Extract()")
378
379 let repkeep= &report
380 set report=10
381 let fname= getline(".")
382" call Decho("fname<".fname.">")
383
384 " sanity check
385 if fname =~ '^"'
386 let &report= repkeep
387" call Dret("zip#Extract")
388 return
389 endif
390 if fname =~ '/$'
391 redraw!
392 echohl Error | echo "***error*** (zip#Extract) Please specify a file, not a directory" | echohl None
393 let &report= repkeep
394" call Dret("zip#Extract")
395 return
396 endif
397
398 " extract the file mentioned under the cursor
Damien38ce71c2024-07-23 19:56:54 +0200399 call system($"{g:zip_extractcmd} {shellescape(b:zipfile)} {shellescape(fname)}")
Bram Moolenaard0796902016-09-16 20:02:31 +0200400" call Decho("zipfile<".b:zipfile.">")
401 if v:shell_error != 0
402 echohl Error | echo "***error*** ".g:zip_extractcmd." ".b:zipfile." ".fname.": failed!" | echohl NONE
403 elseif !filereadable(fname)
404 echohl Error | echo "***error*** attempted to extract ".fname." but it doesn't appear to be present!"
405 else
406 echo "***note*** successfully extracted ".fname
407 endif
408
409 " restore option
410 let &report= repkeep
411
412" call Dret("zip#Extract")
413endfun
414
415" ---------------------------------------------------------------------
Bram Moolenaarc236c162008-07-13 17:41:49 +0000416" s:Escape: {{{2
417fun! s:Escape(fname,isfilt)
Bram Moolenaarc236c162008-07-13 17:41:49 +0000418 if exists("*shellescape")
419 if a:isfilt
420 let qnameq= shellescape(a:fname,1)
421 else
422 let qnameq= shellescape(a:fname)
423 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +0000424 else
425 let qnameq= g:zip_shq.escape(a:fname,g:zip_shq).g:zip_shq
426 endif
Christian Brabandt1c673422024-06-15 14:49:24 +0200427 if exists("+shellslash") && &shellslash && &shell =~ "cmd.exe"
428 " renormalize directory separator on Windows
429 let qnameq=substitute(qnameq, '/', '\\', 'g')
430 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +0000431 return qnameq
Bram Moolenaar9964e462007-05-05 17:54:07 +0000432endfun
433
434" ---------------------------------------------------------------------
435" ChgDir: {{{2
436fun! s:ChgDir(newdir,errlvl,errmsg)
437" call Dfunc("ChgDir(newdir<".a:newdir."> errlvl=".a:errlvl." errmsg<".a:errmsg.">)")
438
Bram Moolenaar9964e462007-05-05 17:54:07 +0000439 try
Bram Moolenaare37d50a2008-08-06 17:06:04 +0000440 exe "cd ".fnameescape(a:newdir)
Bram Moolenaar9964e462007-05-05 17:54:07 +0000441 catch /^Vim\%((\a\+)\)\=:E344/
442 redraw!
443 if a:errlvl == s:NOTE
444 echo "***note*** ".a:errmsg
445 elseif a:errlvl == s:WARNING
446 echohl WarningMsg | echo "***warning*** ".a:errmsg | echohl NONE
447 elseif a:errlvl == s:ERROR
448 echohl Error | echo "***error*** ".a:errmsg | echohl NONE
449 endif
450" call inputsave()|call input("Press <cr> to continue")|call inputrestore()
451" call Dret("ChgDir 1")
452 return 1
453 endtry
454
455" call Dret("ChgDir 0")
456 return 0
457endfun
458
459" ---------------------------------------------------------------------
Bram Moolenaarc236c162008-07-13 17:41:49 +0000460" s:Rmdir: {{{2
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000461fun! s:Rmdir(fname)
462" call Dfunc("Rmdir(fname<".a:fname.">)")
Bram Moolenaar9964e462007-05-05 17:54:07 +0000463 if (has("win32") || has("win95") || has("win64") || has("win16")) && &shell !~? 'sh$'
Bram Moolenaarc236c162008-07-13 17:41:49 +0000464 call system("rmdir /S/Q ".s:Escape(a:fname,0))
Bram Moolenaar9964e462007-05-05 17:54:07 +0000465 else
Bram Moolenaarc236c162008-07-13 17:41:49 +0000466 call system("/bin/rm -rf ".s:Escape(a:fname,0))
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000467 endif
468" call Dret("Rmdir")
469endfun
470
471" ------------------------------------------------------------------------
472" Modelines And Restoration: {{{1
473let &cpo= s:keepcpo
474unlet s:keepcpo
Bram Moolenaarccc18222007-05-10 18:25:20 +0000475" vim:ts=8 fdm=marker