blob: fdd1a155ff7db2cf95dd8182b8149e9f6890bf47 [file] [log] [blame]
Bram Moolenaar60a795a2005-09-16 21:55:43 +00001" zip.vim: Handles browsing zipfiles
2" AUTOLOAD PORTION
Bram Moolenaar71badf92023-04-22 22:40:14 +01003" Date: Mar 12, 2023
4" 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)
Bram Moolenaar9964e462007-05-05 17:54:07 +00009" License: Vim License (see vim's :help license)
Christian Brabandt1c673422024-06-15 14:49:24 +020010" Copyright: Copyright (C) 2005-2019 Charles E. Campbell {{{1
11" Permission is hereby granted to use and distribute this code,
12" with or without modifications, provided that this copyright
13" notice is copied with it. Like anything else that's free,
14" zip.vim and zipPlugin.vim are provided *as is* and comes with
15" no warranty of any kind, either expressed or implied. By using
16" this plugin, you agree that in no event will the copyright
17" holder be liable for any damages resulting from the use
18" of this software.
Bram Moolenaar60a795a2005-09-16 21:55:43 +000019
20" ---------------------------------------------------------------------
Bram Moolenaar9964e462007-05-05 17:54:07 +000021" Load Once: {{{1
Bram Moolenaar00a927d2010-05-14 23:24:24 +020022if &cp || exists("g:loaded_zip")
Bram Moolenaar60a795a2005-09-16 21:55:43 +000023 finish
24endif
Bram Moolenaar71badf92023-04-22 22:40:14 +010025let g:loaded_zip= "v33"
Bram Moolenaar00a927d2010-05-14 23:24:24 +020026if v:version < 702
27 echohl WarningMsg
Bram Moolenaard0796902016-09-16 20:02:31 +020028 echo "***warning*** this version of zip needs vim 7.2 or later"
Bram Moolenaar00a927d2010-05-14 23:24:24 +020029 echohl Normal
30 finish
31endif
32let s:keepcpo= &cpo
33set cpo&vim
Bram Moolenaar94f76b72013-07-04 22:50:40 +020034"DechoTabOn
Bram Moolenaar60a795a2005-09-16 21:55:43 +000035
Bram Moolenaardb552d602006-03-23 22:59:57 +000036let s:zipfile_escape = ' ?&;\'
Bram Moolenaar9964e462007-05-05 17:54:07 +000037let s:ERROR = 2
38let s:WARNING = 1
39let s:NOTE = 0
40
41" ---------------------------------------------------------------------
42" Global Values: {{{1
43if !exists("g:zip_shq")
Bram Moolenaar446cb832008-06-24 21:56:24 +000044 if &shq != ""
45 let g:zip_shq= &shq
46 elseif has("unix")
Bram Moolenaar9964e462007-05-05 17:54:07 +000047 let g:zip_shq= "'"
48 else
49 let g:zip_shq= '"'
50 endif
51endif
Bram Moolenaarccc18222007-05-10 18:25:20 +000052if !exists("g:zip_zipcmd")
53 let g:zip_zipcmd= "zip"
54endif
55if !exists("g:zip_unzipcmd")
56 let g:zip_unzipcmd= "unzip"
57endif
Bram Moolenaard0796902016-09-16 20:02:31 +020058if !exists("g:zip_extractcmd")
59 let g:zip_extractcmd= g:zip_unzipcmd
60endif
Bram Moolenaar60a795a2005-09-16 21:55:43 +000061
D. Ben Knoblecd8a3ea2023-11-04 05:11:17 -040062if !dist#vim#IsSafeExecutable('zip', g:zip_unzipcmd)
Christian Brabandt816fbcc2023-08-31 23:52:30 +020063 echoerr "Warning: NOT executing " .. g:zip_unzipcmd .. " from current directory!"
64 finish
65endif
Anton Sharonov67c951d2023-09-05 21:03:27 +020066
Bram Moolenaar60a795a2005-09-16 21:55:43 +000067" ----------------
68" Functions: {{{1
69" ----------------
70
71" ---------------------------------------------------------------------
72" zip#Browse: {{{2
73fun! zip#Browse(zipfile)
74" call Dfunc("zip#Browse(zipfile<".a:zipfile.">)")
Bram Moolenaarcb80aa22020-10-26 21:12:46 +010075 " sanity check: insure that the zipfile has "PK" as its first two letters
Bram Moolenaar94f76b72013-07-04 22:50:40 +020076 " (zipped files have a leading PK as a "magic cookie")
77 if !filereadable(a:zipfile) || readfile(a:zipfile, "", 1)[0] !~ '^PK'
Bram Moolenaar29634562020-01-09 21:46:04 +010078 exe "noswapfile noautocmd noswapfile e ".fnameescape(a:zipfile)
Bram Moolenaar94f76b72013-07-04 22:50:40 +020079" call Dret("zip#Browse : not a zipfile<".a:zipfile.">")
80 return
81" else " Decho
Bram Moolenaar8024f932020-01-14 19:29:13 +010082" call Decho("zip#Browse: a:zipfile<".a:zipfile."> passed PK test - it's a zip file")
Bram Moolenaar94f76b72013-07-04 22:50:40 +020083 endif
84
Bram Moolenaar36c31f72005-11-28 23:01:53 +000085 let repkeep= &report
86 set report=10
Bram Moolenaar60a795a2005-09-16 21:55:43 +000087
88 " sanity checks
Bram Moolenaare37d50a2008-08-06 17:06:04 +000089 if !exists("*fnameescape")
90 if &verbose > 1
Bram Moolenaar6c391a72021-09-09 21:55:11 +020091 echoerr "the zip plugin is not available (your vim doesn't support fnameescape())"
Bram Moolenaare37d50a2008-08-06 17:06:04 +000092 endif
93 return
94 endif
Bram Moolenaarccc18222007-05-10 18:25:20 +000095 if !executable(g:zip_unzipcmd)
Bram Moolenaar9964e462007-05-05 17:54:07 +000096 redraw!
Bram Moolenaar60a795a2005-09-16 21:55:43 +000097 echohl Error | echo "***error*** (zip#Browse) unzip not available on your system"
Bram Moolenaar9964e462007-05-05 17:54:07 +000098" call inputsave()|call input("Press <cr> to continue")|call inputrestore()
Bram Moolenaar36c31f72005-11-28 23:01:53 +000099 let &report= repkeep
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000100" call Dret("zip#Browse")
101 return
102 endif
103 if !filereadable(a:zipfile)
Bram Moolenaara5792f52005-11-23 21:25:05 +0000104 if a:zipfile !~# '^\a\+://'
Bram Moolenaar8024f932020-01-14 19:29:13 +0100105 " if it's an url, don't complain, let url-handlers such as vim do its thing
Bram Moolenaar9964e462007-05-05 17:54:07 +0000106 redraw!
Bram Moolenaara5792f52005-11-23 21:25:05 +0000107 echohl Error | echo "***error*** (zip#Browse) File not readable<".a:zipfile.">" | echohl None
Bram Moolenaar9964e462007-05-05 17:54:07 +0000108" call inputsave()|call input("Press <cr> to continue")|call inputrestore()
Bram Moolenaara5792f52005-11-23 21:25:05 +0000109 endif
Bram Moolenaar36c31f72005-11-28 23:01:53 +0000110 let &report= repkeep
Bram Moolenaara5792f52005-11-23 21:25:05 +0000111" call Dret("zip#Browse : file<".a:zipfile."> not readable")
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000112 return
113 endif
Bram Moolenaardb552d602006-03-23 22:59:57 +0000114" call Decho("passed sanity checks")
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000115 if &ma != 1
116 set ma
117 endif
Bram Moolenaarccc18222007-05-10 18:25:20 +0000118 let b:zipfile= a:zipfile
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000119
120 setlocal noswapfile
121 setlocal buftype=nofile
122 setlocal bufhidden=hide
123 setlocal nobuflisted
124 setlocal nowrap
Bram Moolenaar519cc552021-11-16 19:18:26 +0000125
126 " Oct 12, 2021: need to re-use Bram's syntax/tar.vim.
127 " Setting the filetype to zip doesn't do anything (currently),
128 " but it is perhaps less confusing to curious perusers who do
129 " a :echo &ft
130 setf zip
131 run! syntax/tar.vim
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000132
133 " give header
Bram Moolenaar251e1912011-06-19 05:09:16 +0200134 call append(0, ['" zip.vim version '.g:loaded_zip,
Bram Moolenaar6be7f872012-01-20 21:08:56 +0100135 \ '" Browsing zipfile '.a:zipfile,
136 \ '" Select a file with cursor and press ENTER'])
Bram Moolenaar251e1912011-06-19 05:09:16 +0200137 keepj $
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000138
Bram Moolenaare37d50a2008-08-06 17:06:04 +0000139" call Decho("exe silent r! ".g:zip_unzipcmd." -l -- ".s:Escape(a:zipfile,1))
Bram Moolenaar6be7f872012-01-20 21:08:56 +0100140 exe "keepj sil! r! ".g:zip_unzipcmd." -Z -1 -- ".s:Escape(a:zipfile,1)
Bram Moolenaard68071d2006-05-02 22:08:30 +0000141 if v:shell_error != 0
Bram Moolenaar9964e462007-05-05 17:54:07 +0000142 redraw!
Bram Moolenaarc236c162008-07-13 17:41:49 +0000143 echohl WarningMsg | echo "***warning*** (zip#Browse) ".fnameescape(a:zipfile)." is not a zip file" | echohl None
Bram Moolenaar9964e462007-05-05 17:54:07 +0000144" call inputsave()|call input("Press <cr> to continue")|call inputrestore()
Bram Moolenaar251e1912011-06-19 05:09:16 +0200145 keepj sil! %d
Bram Moolenaard68071d2006-05-02 22:08:30 +0000146 let eikeep= &ei
147 set ei=BufReadCmd,FileReadCmd
Bram Moolenaar251e1912011-06-19 05:09:16 +0200148 exe "keepj r ".fnameescape(a:zipfile)
Bram Moolenaard68071d2006-05-02 22:08:30 +0000149 let &ei= eikeep
Bram Moolenaar251e1912011-06-19 05:09:16 +0200150 keepj 1d
Bram Moolenaard68071d2006-05-02 22:08:30 +0000151" call Dret("zip#Browse")
152 return
153 endif
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000154
Bram Moolenaard0796902016-09-16 20:02:31 +0200155 " Maps associated with zip plugin
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000156 setlocal noma nomod ro
Bram Moolenaar29634562020-01-09 21:46:04 +0100157 noremap <silent> <buffer> <cr> :call <SID>ZipBrowseSelect()<cr>
158 noremap <silent> <buffer> x :call zip#Extract()<cr>
159 if &mouse != ""
160 noremap <silent> <buffer> <leftmouse> <leftmouse>:call <SID>ZipBrowseSelect()<cr>
161 endif
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000162
Bram Moolenaar36c31f72005-11-28 23:01:53 +0000163 let &report= repkeep
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000164" call Dret("zip#Browse")
165endfun
166
167" ---------------------------------------------------------------------
168" ZipBrowseSelect: {{{2
169fun! s:ZipBrowseSelect()
Bram Moolenaar71badf92023-04-22 22:40:14 +0100170 " call Dfunc("ZipBrowseSelect() zipfile<".((exists("b:zipfile"))? b:zipfile : "n/a")."> curfile<".expand("%").">")
Bram Moolenaar36c31f72005-11-28 23:01:53 +0000171 let repkeep= &report
172 set report=10
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000173 let fname= getline(".")
Bram Moolenaar71badf92023-04-22 22:40:14 +0100174 if !exists("b:zipfile")
175" call Dret("ZipBrowseSelect : b:zipfile doesn't exist!")
176 return
177 endif
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000178
179 " sanity check
180 if fname =~ '^"'
Bram Moolenaar36c31f72005-11-28 23:01:53 +0000181 let &report= repkeep
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000182" call Dret("ZipBrowseSelect")
183 return
184 endif
185 if fname =~ '/$'
Bram Moolenaar9964e462007-05-05 17:54:07 +0000186 redraw!
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000187 echohl Error | echo "***error*** (zip#Browse) Please specify a file, not a directory" | echohl None
Bram Moolenaar9964e462007-05-05 17:54:07 +0000188" call inputsave()|call input("Press <cr> to continue")|call inputrestore()
Bram Moolenaar36c31f72005-11-28 23:01:53 +0000189 let &report= repkeep
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000190" call Dret("ZipBrowseSelect")
191 return
192 endif
193
194" call Decho("fname<".fname.">")
195
196 " get zipfile to the new-window
Bram Moolenaarccc18222007-05-10 18:25:20 +0000197 let zipfile = b:zipfile
Bram Moolenaar29634562020-01-09 21:46:04 +0100198 let curfile = expand("%")
Bram Moolenaardb552d602006-03-23 22:59:57 +0000199" call Decho("zipfile<".zipfile.">")
200" call Decho("curfile<".curfile.">")
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000201
Bram Moolenaar29634562020-01-09 21:46:04 +0100202 noswapfile new
Bram Moolenaar446cb832008-06-24 21:56:24 +0000203 if !exists("g:zip_nomax") || g:zip_nomax == 0
204 wincmd _
205 endif
Bram Moolenaara5792f52005-11-23 21:25:05 +0000206 let s:zipfile_{winnr()}= curfile
Bram Moolenaar519cc552021-11-16 19:18:26 +0000207" call Decho("exe e ".fnameescape("zipfile://".zipfile.'::'.fname))
208 exe "noswapfile e ".fnameescape("zipfile://".zipfile.'::'.fname)
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000209 filetype detect
210
Bram Moolenaar36c31f72005-11-28 23:01:53 +0000211 let &report= repkeep
Bram Moolenaara5792f52005-11-23 21:25:05 +0000212" call Dret("ZipBrowseSelect : s:zipfile_".winnr()."<".s:zipfile_{winnr()}.">")
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000213endfun
214
215" ---------------------------------------------------------------------
216" zip#Read: {{{2
217fun! zip#Read(fname,mode)
Bram Moolenaar36c31f72005-11-28 23:01:53 +0000218 let repkeep= &report
219 set report=10
220
Bram Moolenaard68071d2006-05-02 22:08:30 +0000221 if has("unix")
Bram Moolenaar519cc552021-11-16 19:18:26 +0000222 let zipfile = substitute(a:fname,'zipfile://\(.\{-}\)::[^\\].*$','\1','')
223 let fname = substitute(a:fname,'zipfile://.\{-}::\([^\\].*\)$','\1','')
Bram Moolenaard68071d2006-05-02 22:08:30 +0000224 else
Bram Moolenaar519cc552021-11-16 19:18:26 +0000225 let zipfile = substitute(a:fname,'^.\{-}zipfile://\(.\{-}\)::[^\\].*$','\1','')
226 let fname = substitute(a:fname,'^.\{-}zipfile://.\{-}::\([^\\].*\)$','\1','')
Bram Moolenaarff034192013-04-24 18:51:19 +0200227 let fname = substitute(fname, '[', '[[]', 'g')
Bram Moolenaard68071d2006-05-02 22:08:30 +0000228 endif
Bram Moolenaard0796902016-09-16 20:02:31 +0200229 " sanity check
230 if !executable(substitute(g:zip_unzipcmd,'\s\+.*$','',''))
231 redraw!
232 echohl Error | echo "***error*** (zip#Read) sorry, your system doesn't appear to have the ".g:zip_unzipcmd." program" | echohl None
233" call inputsave()|call input("Press <cr> to continue")|call inputrestore()
234 let &report= repkeep
Bram Moolenaard0796902016-09-16 20:02:31 +0200235 return
236 endif
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000237
Bram Moolenaarff034192013-04-24 18:51:19 +0200238 " the following code does much the same thing as
239 " exe "keepj sil! r! ".g:zip_unzipcmd." -p -- ".s:Escape(zipfile,1)." ".s:Escape(fnameescape(fname),1)
Bram Moolenaar519cc552021-11-16 19:18:26 +0000240 " but allows zipfile://... entries in quickfix lists
Bram Moolenaarff034192013-04-24 18:51:19 +0200241 let temp = tempname()
242 let fn = expand('%:p')
Christian Brabandt1c673422024-06-15 14:49:24 +0200243 exe "sil! !".g:zip_unzipcmd." -p -- ".s:Escape(zipfile,1)." ".s:Escape(fname,1).' > '.temp
Bram Moolenaarff034192013-04-24 18:51:19 +0200244 sil exe 'keepalt file '.temp
245 sil keepj e!
246 sil exe 'keepalt file '.fnameescape(fn)
247 call delete(temp)
248
Bram Moolenaar251e1912011-06-19 05:09:16 +0200249 filetype detect
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000250
251 " cleanup
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000252 set nomod
253
Bram Moolenaar36c31f72005-11-28 23:01:53 +0000254 let &report= repkeep
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000255endfun
256
257" ---------------------------------------------------------------------
258" zip#Write: {{{2
259fun! zip#Write(fname)
Bram Moolenaar910f66f2006-04-05 20:41:53 +0000260" call Dfunc("zip#Write(fname<".a:fname.">) zipfile_".winnr()."<".s:zipfile_{winnr()}.">")
Bram Moolenaar36c31f72005-11-28 23:01:53 +0000261 let repkeep= &report
262 set report=10
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000263
264 " sanity checks
Bram Moolenaard0796902016-09-16 20:02:31 +0200265 if !executable(substitute(g:zip_zipcmd,'\s\+.*$','',''))
Bram Moolenaar9964e462007-05-05 17:54:07 +0000266 redraw!
Bram Moolenaard0796902016-09-16 20:02:31 +0200267 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 +0000268" call inputsave()|call input("Press <cr> to continue")|call inputrestore()
Bram Moolenaar36c31f72005-11-28 23:01:53 +0000269 let &report= repkeep
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000270" call Dret("zip#Write")
271 return
272 endif
273 if !exists("*mkdir")
Bram Moolenaar9964e462007-05-05 17:54:07 +0000274 redraw!
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000275 echohl Error | echo "***error*** (zip#Write) sorry, mkdir() doesn't work on your system" | echohl None
Bram Moolenaar9964e462007-05-05 17:54:07 +0000276" call inputsave()|call input("Press <cr> to continue")|call inputrestore()
Bram Moolenaar36c31f72005-11-28 23:01:53 +0000277 let &report= repkeep
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000278" call Dret("zip#Write")
279 return
280 endif
281
282 let curdir= getcwd()
283 let tmpdir= tempname()
284" call Decho("orig tempname<".tmpdir.">")
285 if tmpdir =~ '\.'
286 let tmpdir= substitute(tmpdir,'\.[^.]*$','','e')
287 endif
288" call Decho("tmpdir<".tmpdir.">")
289 call mkdir(tmpdir,"p")
290
291 " attempt to change to the indicated directory
Bram Moolenaar9964e462007-05-05 17:54:07 +0000292 if s:ChgDir(tmpdir,s:ERROR,"(zip#Write) cannot cd to temporary directory")
Bram Moolenaar36c31f72005-11-28 23:01:53 +0000293 let &report= repkeep
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000294" call Dret("zip#Write")
295 return
Bram Moolenaar9964e462007-05-05 17:54:07 +0000296 endif
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000297" call Decho("current directory now: ".getcwd())
298
299 " place temporary files under .../_ZIPVIM_/
300 if isdirectory("_ZIPVIM_")
301 call s:Rmdir("_ZIPVIM_")
302 endif
303 call mkdir("_ZIPVIM_")
304 cd _ZIPVIM_
305" call Decho("current directory now: ".getcwd())
306
Bram Moolenaard68071d2006-05-02 22:08:30 +0000307 if has("unix")
Bram Moolenaar519cc552021-11-16 19:18:26 +0000308 let zipfile = substitute(a:fname,'zipfile://\(.\{-}\)::[^\\].*$','\1','')
309 let fname = substitute(a:fname,'zipfile://.\{-}::\([^\\].*\)$','\1','')
Christian Brabandt1c673422024-06-15 14:49:24 +0200310 let fname = fnameescape(fname)
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
399" call Decho("system(".g:zip_extractcmd." ".shellescape(b:zipfile)." ".shellescape(shell).")")
400 call system(g:zip_extractcmd." ".shellescape(b:zipfile)." ".shellescape(shell))
401" call Decho("zipfile<".b:zipfile.">")
402 if v:shell_error != 0
403 echohl Error | echo "***error*** ".g:zip_extractcmd." ".b:zipfile." ".fname.": failed!" | echohl NONE
404 elseif !filereadable(fname)
405 echohl Error | echo "***error*** attempted to extract ".fname." but it doesn't appear to be present!"
406 else
407 echo "***note*** successfully extracted ".fname
408 endif
409
410 " restore option
411 let &report= repkeep
412
413" call Dret("zip#Extract")
414endfun
415
416" ---------------------------------------------------------------------
Bram Moolenaarc236c162008-07-13 17:41:49 +0000417" s:Escape: {{{2
418fun! s:Escape(fname,isfilt)
Bram Moolenaarc236c162008-07-13 17:41:49 +0000419 if exists("*shellescape")
420 if a:isfilt
421 let qnameq= shellescape(a:fname,1)
422 else
423 let qnameq= shellescape(a:fname)
424 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +0000425 else
426 let qnameq= g:zip_shq.escape(a:fname,g:zip_shq).g:zip_shq
427 endif
Christian Brabandt1c673422024-06-15 14:49:24 +0200428 if exists("+shellslash") && &shellslash && &shell =~ "cmd.exe"
429 " renormalize directory separator on Windows
430 let qnameq=substitute(qnameq, '/', '\\', 'g')
431 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +0000432 return qnameq
Bram Moolenaar9964e462007-05-05 17:54:07 +0000433endfun
434
435" ---------------------------------------------------------------------
436" ChgDir: {{{2
437fun! s:ChgDir(newdir,errlvl,errmsg)
438" call Dfunc("ChgDir(newdir<".a:newdir."> errlvl=".a:errlvl." errmsg<".a:errmsg.">)")
439
Bram Moolenaar9964e462007-05-05 17:54:07 +0000440 try
Bram Moolenaare37d50a2008-08-06 17:06:04 +0000441 exe "cd ".fnameescape(a:newdir)
Bram Moolenaar9964e462007-05-05 17:54:07 +0000442 catch /^Vim\%((\a\+)\)\=:E344/
443 redraw!
444 if a:errlvl == s:NOTE
445 echo "***note*** ".a:errmsg
446 elseif a:errlvl == s:WARNING
447 echohl WarningMsg | echo "***warning*** ".a:errmsg | echohl NONE
448 elseif a:errlvl == s:ERROR
449 echohl Error | echo "***error*** ".a:errmsg | echohl NONE
450 endif
451" call inputsave()|call input("Press <cr> to continue")|call inputrestore()
452" call Dret("ChgDir 1")
453 return 1
454 endtry
455
456" call Dret("ChgDir 0")
457 return 0
458endfun
459
460" ---------------------------------------------------------------------
Bram Moolenaarc236c162008-07-13 17:41:49 +0000461" s:Rmdir: {{{2
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000462fun! s:Rmdir(fname)
463" call Dfunc("Rmdir(fname<".a:fname.">)")
Bram Moolenaar9964e462007-05-05 17:54:07 +0000464 if (has("win32") || has("win95") || has("win64") || has("win16")) && &shell !~? 'sh$'
Bram Moolenaarc236c162008-07-13 17:41:49 +0000465 call system("rmdir /S/Q ".s:Escape(a:fname,0))
Bram Moolenaar9964e462007-05-05 17:54:07 +0000466 else
Bram Moolenaarc236c162008-07-13 17:41:49 +0000467 call system("/bin/rm -rf ".s:Escape(a:fname,0))
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000468 endif
469" call Dret("Rmdir")
470endfun
471
472" ------------------------------------------------------------------------
473" Modelines And Restoration: {{{1
474let &cpo= s:keepcpo
475unlet s:keepcpo
Bram Moolenaarccc18222007-05-10 18:25:20 +0000476" vim:ts=8 fdm=marker