blob: d0e706e83ac241762c923f8d7360a7ddc47b6103 [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','')
Bram Moolenaard68071d2006-05-02 22:08:30 +0000310 else
Bram Moolenaar519cc552021-11-16 19:18:26 +0000311 let zipfile = substitute(a:fname,'^.\{-}zipfile://\(.\{-}\)::[^\\].*$','\1','')
312 let fname = substitute(a:fname,'^.\{-}zipfile://.\{-}::\([^\\].*\)$','\1','')
Bram Moolenaard68071d2006-05-02 22:08:30 +0000313 endif
314" call Decho("zipfile<".zipfile.">")
315" call Decho("fname <".fname.">")
Bram Moolenaarc7486e02005-12-29 22:48:26 +0000316
317 if fname =~ '/'
318 let dirpath = substitute(fname,'/[^/]\+$','','e')
Bram Moolenaarff034192013-04-24 18:51:19 +0200319 if has("win32unix") && executable("cygpath")
Bram Moolenaarc236c162008-07-13 17:41:49 +0000320 let dirpath = substitute(system("cygpath ".s:Escape(dirpath,0)),'\n','','e')
Bram Moolenaarc7486e02005-12-29 22:48:26 +0000321 endif
Bram Moolenaar910f66f2006-04-05 20:41:53 +0000322" call Decho("mkdir(dirpath<".dirpath.">,p)")
Bram Moolenaarc7486e02005-12-29 22:48:26 +0000323 call mkdir(dirpath,"p")
324 endif
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000325 if zipfile !~ '/'
326 let zipfile= curdir.'/'.zipfile
327 endif
328" call Decho("zipfile<".zipfile."> fname<".fname.">")
329
Bram Moolenaarc236c162008-07-13 17:41:49 +0000330 exe "w! ".fnameescape(fname)
Bram Moolenaarff034192013-04-24 18:51:19 +0200331 if has("win32unix") && executable("cygpath")
Bram Moolenaarc236c162008-07-13 17:41:49 +0000332 let zipfile = substitute(system("cygpath ".s:Escape(zipfile,0)),'\n','','e')
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000333 endif
334
Bram Moolenaar9964e462007-05-05 17:54:07 +0000335 if (has("win32") || has("win95") || has("win64") || has("win16")) && &shell !~? 'sh$'
336 let fname = substitute(fname, '[', '[[]', 'g')
337 endif
338
Bram Moolenaare37d50a2008-08-06 17:06:04 +0000339" call Decho(g:zip_zipcmd." -u ".s:Escape(fnamemodify(zipfile,":p"),0)." ".s:Escape(fname,0))
340 call system(g:zip_zipcmd." -u ".s:Escape(fnamemodify(zipfile,":p"),0)." ".s:Escape(fname,0))
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000341 if v:shell_error != 0
Bram Moolenaar9964e462007-05-05 17:54:07 +0000342 redraw!
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000343 echohl Error | echo "***error*** (zip#Write) sorry, unable to update ".zipfile." with ".fname | echohl None
Bram Moolenaar9964e462007-05-05 17:54:07 +0000344" call inputsave()|call input("Press <cr> to continue")|call inputrestore()
Bram Moolenaara5792f52005-11-23 21:25:05 +0000345
346 elseif s:zipfile_{winnr()} =~ '^\a\+://'
347 " support writing zipfiles across a network
348 let netzipfile= s:zipfile_{winnr()}
Bram Moolenaar9964e462007-05-05 17:54:07 +0000349" call Decho("handle writing <".zipfile."> across network as <".netzipfile.">")
Bram Moolenaara5792f52005-11-23 21:25:05 +0000350 1split|enew
351 let binkeep= &binary
352 let eikeep = &ei
353 set binary ei=all
Bram Moolenaar29634562020-01-09 21:46:04 +0100354 exe "noswapfile e! ".fnameescape(zipfile)
Bram Moolenaara5792f52005-11-23 21:25:05 +0000355 call netrw#NetWrite(netzipfile)
356 let &ei = eikeep
357 let &binary = binkeep
358 q!
359 unlet s:zipfile_{winnr()}
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000360 endif
361
362 " cleanup and restore current directory
363 cd ..
364 call s:Rmdir("_ZIPVIM_")
Bram Moolenaar9964e462007-05-05 17:54:07 +0000365 call s:ChgDir(curdir,s:WARNING,"(zip#Write) unable to return to ".curdir."!")
366 call s:Rmdir(tmpdir)
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000367 setlocal nomod
368
Bram Moolenaar36c31f72005-11-28 23:01:53 +0000369 let &report= repkeep
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000370" call Dret("zip#Write")
371endfun
372
373" ---------------------------------------------------------------------
Bram Moolenaard0796902016-09-16 20:02:31 +0200374" zip#Extract: extract a file from a zip archive {{{2
375fun! zip#Extract()
376" call Dfunc("zip#Extract()")
377
378 let repkeep= &report
379 set report=10
380 let fname= getline(".")
381" call Decho("fname<".fname.">")
382
383 " sanity check
384 if fname =~ '^"'
385 let &report= repkeep
386" call Dret("zip#Extract")
387 return
388 endif
389 if fname =~ '/$'
390 redraw!
391 echohl Error | echo "***error*** (zip#Extract) Please specify a file, not a directory" | echohl None
392 let &report= repkeep
393" call Dret("zip#Extract")
394 return
395 endif
396
397 " extract the file mentioned under the cursor
398" call Decho("system(".g:zip_extractcmd." ".shellescape(b:zipfile)." ".shellescape(shell).")")
399 call system(g:zip_extractcmd." ".shellescape(b:zipfile)." ".shellescape(shell))
400" 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