blob: 79f707fbd8ccfccd63a78c073046c89f6bafe143 [file] [log] [blame]
Bram Moolenaar60a795a2005-09-16 21:55:43 +00001" zip.vim: Handles browsing zipfiles
Damien2cad9412024-07-24 20:07:00 +02002" AUTOLOAD PORTION
3" Date: Jul 24, 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:
Damien2cad9412024-07-24 20:07:00 +02008" 2024 Jun 16 by Vim Project: handle whitespace on Windows properly (#14998)
9" 2024 Jul 23 by Vim Project: fix 'x' command
10" 2024 Jul 24 by Vim Project: use delete() function
Bram Moolenaar9964e462007-05-05 17:54:07 +000011" License: Vim License (see vim's :help license)
Christian Brabandt1c673422024-06-15 14:49:24 +020012" Copyright: Copyright (C) 2005-2019 Charles E. Campbell {{{1
13" Permission is hereby granted to use and distribute this code,
14" with or without modifications, provided that this copyright
15" notice is copied with it. Like anything else that's free,
16" zip.vim and zipPlugin.vim are provided *as is* and comes with
17" no warranty of any kind, either expressed or implied. By using
18" this plugin, you agree that in no event will the copyright
19" holder be liable for any damages resulting from the use
20" of this software.
Bram Moolenaar60a795a2005-09-16 21:55:43 +000021
22" ---------------------------------------------------------------------
Bram Moolenaar9964e462007-05-05 17:54:07 +000023" Load Once: {{{1
Bram Moolenaar00a927d2010-05-14 23:24:24 +020024if &cp || exists("g:loaded_zip")
Bram Moolenaar60a795a2005-09-16 21:55:43 +000025 finish
26endif
Bram Moolenaar71badf92023-04-22 22:40:14 +010027let g:loaded_zip= "v33"
Bram Moolenaar00a927d2010-05-14 23:24:24 +020028if v:version < 702
29 echohl WarningMsg
Bram Moolenaard0796902016-09-16 20:02:31 +020030 echo "***warning*** this version of zip needs vim 7.2 or later"
Bram Moolenaar00a927d2010-05-14 23:24:24 +020031 echohl Normal
32 finish
33endif
34let s:keepcpo= &cpo
35set cpo&vim
Bram Moolenaar94f76b72013-07-04 22:50:40 +020036"DechoTabOn
Bram Moolenaar60a795a2005-09-16 21:55:43 +000037
Bram Moolenaardb552d602006-03-23 22:59:57 +000038let s:zipfile_escape = ' ?&;\'
Bram Moolenaar9964e462007-05-05 17:54:07 +000039let s:ERROR = 2
40let s:WARNING = 1
41let s:NOTE = 0
42
43" ---------------------------------------------------------------------
44" Global Values: {{{1
45if !exists("g:zip_shq")
Bram Moolenaar446cb832008-06-24 21:56:24 +000046 if &shq != ""
47 let g:zip_shq= &shq
48 elseif has("unix")
Bram Moolenaar9964e462007-05-05 17:54:07 +000049 let g:zip_shq= "'"
50 else
51 let g:zip_shq= '"'
52 endif
53endif
Bram Moolenaarccc18222007-05-10 18:25:20 +000054if !exists("g:zip_zipcmd")
55 let g:zip_zipcmd= "zip"
56endif
57if !exists("g:zip_unzipcmd")
58 let g:zip_unzipcmd= "unzip"
59endif
Bram Moolenaard0796902016-09-16 20:02:31 +020060if !exists("g:zip_extractcmd")
61 let g:zip_extractcmd= g:zip_unzipcmd
62endif
Bram Moolenaar60a795a2005-09-16 21:55:43 +000063
D. Ben Knoblecd8a3ea2023-11-04 05:11:17 -040064if !dist#vim#IsSafeExecutable('zip', g:zip_unzipcmd)
Christian Brabandt816fbcc2023-08-31 23:52:30 +020065 echoerr "Warning: NOT executing " .. g:zip_unzipcmd .. " from current directory!"
66 finish
67endif
Anton Sharonov67c951d2023-09-05 21:03:27 +020068
Bram Moolenaar60a795a2005-09-16 21:55:43 +000069" ----------------
70" Functions: {{{1
71" ----------------
72
73" ---------------------------------------------------------------------
74" zip#Browse: {{{2
75fun! zip#Browse(zipfile)
76" call Dfunc("zip#Browse(zipfile<".a:zipfile.">)")
Bram Moolenaarcb80aa22020-10-26 21:12:46 +010077 " sanity check: insure that the zipfile has "PK" as its first two letters
Bram Moolenaar94f76b72013-07-04 22:50:40 +020078 " (zipped files have a leading PK as a "magic cookie")
79 if !filereadable(a:zipfile) || readfile(a:zipfile, "", 1)[0] !~ '^PK'
Bram Moolenaar29634562020-01-09 21:46:04 +010080 exe "noswapfile noautocmd noswapfile e ".fnameescape(a:zipfile)
Bram Moolenaar94f76b72013-07-04 22:50:40 +020081" call Dret("zip#Browse : not a zipfile<".a:zipfile.">")
82 return
83" else " Decho
Bram Moolenaar8024f932020-01-14 19:29:13 +010084" call Decho("zip#Browse: a:zipfile<".a:zipfile."> passed PK test - it's a zip file")
Bram Moolenaar94f76b72013-07-04 22:50:40 +020085 endif
86
Bram Moolenaar36c31f72005-11-28 23:01:53 +000087 let repkeep= &report
88 set report=10
Bram Moolenaar60a795a2005-09-16 21:55:43 +000089
90 " sanity checks
Bram Moolenaare37d50a2008-08-06 17:06:04 +000091 if !exists("*fnameescape")
92 if &verbose > 1
Bram Moolenaar6c391a72021-09-09 21:55:11 +020093 echoerr "the zip plugin is not available (your vim doesn't support fnameescape())"
Bram Moolenaare37d50a2008-08-06 17:06:04 +000094 endif
95 return
96 endif
Bram Moolenaarccc18222007-05-10 18:25:20 +000097 if !executable(g:zip_unzipcmd)
Bram Moolenaar9964e462007-05-05 17:54:07 +000098 redraw!
Bram Moolenaar60a795a2005-09-16 21:55:43 +000099 echohl Error | echo "***error*** (zip#Browse) unzip not available on your system"
Bram Moolenaar9964e462007-05-05 17:54:07 +0000100" call inputsave()|call input("Press <cr> to continue")|call inputrestore()
Bram Moolenaar36c31f72005-11-28 23:01:53 +0000101 let &report= repkeep
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000102" call Dret("zip#Browse")
103 return
104 endif
105 if !filereadable(a:zipfile)
Bram Moolenaara5792f52005-11-23 21:25:05 +0000106 if a:zipfile !~# '^\a\+://'
Bram Moolenaar8024f932020-01-14 19:29:13 +0100107 " if it's an url, don't complain, let url-handlers such as vim do its thing
Bram Moolenaar9964e462007-05-05 17:54:07 +0000108 redraw!
Bram Moolenaara5792f52005-11-23 21:25:05 +0000109 echohl Error | echo "***error*** (zip#Browse) File not readable<".a:zipfile.">" | echohl None
Bram Moolenaar9964e462007-05-05 17:54:07 +0000110" call inputsave()|call input("Press <cr> to continue")|call inputrestore()
Bram Moolenaara5792f52005-11-23 21:25:05 +0000111 endif
Bram Moolenaar36c31f72005-11-28 23:01:53 +0000112 let &report= repkeep
Bram Moolenaara5792f52005-11-23 21:25:05 +0000113" call Dret("zip#Browse : file<".a:zipfile."> not readable")
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000114 return
115 endif
Bram Moolenaardb552d602006-03-23 22:59:57 +0000116" call Decho("passed sanity checks")
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000117 if &ma != 1
118 set ma
119 endif
Bram Moolenaarccc18222007-05-10 18:25:20 +0000120 let b:zipfile= a:zipfile
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000121
122 setlocal noswapfile
123 setlocal buftype=nofile
124 setlocal bufhidden=hide
125 setlocal nobuflisted
126 setlocal nowrap
Bram Moolenaar519cc552021-11-16 19:18:26 +0000127
128 " Oct 12, 2021: need to re-use Bram's syntax/tar.vim.
129 " Setting the filetype to zip doesn't do anything (currently),
130 " but it is perhaps less confusing to curious perusers who do
131 " a :echo &ft
132 setf zip
133 run! syntax/tar.vim
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000134
135 " give header
Bram Moolenaar251e1912011-06-19 05:09:16 +0200136 call append(0, ['" zip.vim version '.g:loaded_zip,
Bram Moolenaar6be7f872012-01-20 21:08:56 +0100137 \ '" Browsing zipfile '.a:zipfile,
138 \ '" Select a file with cursor and press ENTER'])
Bram Moolenaar251e1912011-06-19 05:09:16 +0200139 keepj $
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000140
Bram Moolenaare37d50a2008-08-06 17:06:04 +0000141" call Decho("exe silent r! ".g:zip_unzipcmd." -l -- ".s:Escape(a:zipfile,1))
Bram Moolenaar6be7f872012-01-20 21:08:56 +0100142 exe "keepj sil! r! ".g:zip_unzipcmd." -Z -1 -- ".s:Escape(a:zipfile,1)
Bram Moolenaard68071d2006-05-02 22:08:30 +0000143 if v:shell_error != 0
Bram Moolenaar9964e462007-05-05 17:54:07 +0000144 redraw!
Bram Moolenaarc236c162008-07-13 17:41:49 +0000145 echohl WarningMsg | echo "***warning*** (zip#Browse) ".fnameescape(a:zipfile)." is not a zip file" | echohl None
Bram Moolenaar9964e462007-05-05 17:54:07 +0000146" call inputsave()|call input("Press <cr> to continue")|call inputrestore()
Bram Moolenaar251e1912011-06-19 05:09:16 +0200147 keepj sil! %d
Bram Moolenaard68071d2006-05-02 22:08:30 +0000148 let eikeep= &ei
149 set ei=BufReadCmd,FileReadCmd
Bram Moolenaar251e1912011-06-19 05:09:16 +0200150 exe "keepj r ".fnameescape(a:zipfile)
Bram Moolenaard68071d2006-05-02 22:08:30 +0000151 let &ei= eikeep
Bram Moolenaar251e1912011-06-19 05:09:16 +0200152 keepj 1d
Bram Moolenaard68071d2006-05-02 22:08:30 +0000153" call Dret("zip#Browse")
154 return
155 endif
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000156
Bram Moolenaard0796902016-09-16 20:02:31 +0200157 " Maps associated with zip plugin
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000158 setlocal noma nomod ro
Bram Moolenaar29634562020-01-09 21:46:04 +0100159 noremap <silent> <buffer> <cr> :call <SID>ZipBrowseSelect()<cr>
160 noremap <silent> <buffer> x :call zip#Extract()<cr>
161 if &mouse != ""
162 noremap <silent> <buffer> <leftmouse> <leftmouse>:call <SID>ZipBrowseSelect()<cr>
163 endif
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000164
Bram Moolenaar36c31f72005-11-28 23:01:53 +0000165 let &report= repkeep
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000166" call Dret("zip#Browse")
167endfun
168
169" ---------------------------------------------------------------------
170" ZipBrowseSelect: {{{2
171fun! s:ZipBrowseSelect()
Bram Moolenaar71badf92023-04-22 22:40:14 +0100172 " call Dfunc("ZipBrowseSelect() zipfile<".((exists("b:zipfile"))? b:zipfile : "n/a")."> curfile<".expand("%").">")
Bram Moolenaar36c31f72005-11-28 23:01:53 +0000173 let repkeep= &report
174 set report=10
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000175 let fname= getline(".")
Bram Moolenaar71badf92023-04-22 22:40:14 +0100176 if !exists("b:zipfile")
177" call Dret("ZipBrowseSelect : b:zipfile doesn't exist!")
178 return
179 endif
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000180
181 " sanity check
182 if fname =~ '^"'
Bram Moolenaar36c31f72005-11-28 23:01:53 +0000183 let &report= repkeep
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000184" call Dret("ZipBrowseSelect")
185 return
186 endif
187 if fname =~ '/$'
Bram Moolenaar9964e462007-05-05 17:54:07 +0000188 redraw!
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000189 echohl Error | echo "***error*** (zip#Browse) Please specify a file, not a directory" | echohl None
Bram Moolenaar9964e462007-05-05 17:54:07 +0000190" call inputsave()|call input("Press <cr> to continue")|call inputrestore()
Bram Moolenaar36c31f72005-11-28 23:01:53 +0000191 let &report= repkeep
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000192" call Dret("ZipBrowseSelect")
193 return
194 endif
195
196" call Decho("fname<".fname.">")
197
198 " get zipfile to the new-window
Bram Moolenaarccc18222007-05-10 18:25:20 +0000199 let zipfile = b:zipfile
Bram Moolenaar29634562020-01-09 21:46:04 +0100200 let curfile = expand("%")
Bram Moolenaardb552d602006-03-23 22:59:57 +0000201" call Decho("zipfile<".zipfile.">")
202" call Decho("curfile<".curfile.">")
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000203
Bram Moolenaar29634562020-01-09 21:46:04 +0100204 noswapfile new
Bram Moolenaar446cb832008-06-24 21:56:24 +0000205 if !exists("g:zip_nomax") || g:zip_nomax == 0
206 wincmd _
207 endif
Bram Moolenaara5792f52005-11-23 21:25:05 +0000208 let s:zipfile_{winnr()}= curfile
Bram Moolenaar519cc552021-11-16 19:18:26 +0000209" call Decho("exe e ".fnameescape("zipfile://".zipfile.'::'.fname))
210 exe "noswapfile e ".fnameescape("zipfile://".zipfile.'::'.fname)
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000211 filetype detect
212
Bram Moolenaar36c31f72005-11-28 23:01:53 +0000213 let &report= repkeep
Bram Moolenaara5792f52005-11-23 21:25:05 +0000214" call Dret("ZipBrowseSelect : s:zipfile_".winnr()."<".s:zipfile_{winnr()}.">")
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000215endfun
216
217" ---------------------------------------------------------------------
218" zip#Read: {{{2
219fun! zip#Read(fname,mode)
Bram Moolenaar36c31f72005-11-28 23:01:53 +0000220 let repkeep= &report
221 set report=10
222
Bram Moolenaard68071d2006-05-02 22:08:30 +0000223 if has("unix")
Bram Moolenaar519cc552021-11-16 19:18:26 +0000224 let zipfile = substitute(a:fname,'zipfile://\(.\{-}\)::[^\\].*$','\1','')
225 let fname = substitute(a:fname,'zipfile://.\{-}::\([^\\].*\)$','\1','')
Bram Moolenaard68071d2006-05-02 22:08:30 +0000226 else
Bram Moolenaar519cc552021-11-16 19:18:26 +0000227 let zipfile = substitute(a:fname,'^.\{-}zipfile://\(.\{-}\)::[^\\].*$','\1','')
228 let fname = substitute(a:fname,'^.\{-}zipfile://.\{-}::\([^\\].*\)$','\1','')
Bram Moolenaarff034192013-04-24 18:51:19 +0200229 let fname = substitute(fname, '[', '[[]', 'g')
Bram Moolenaard68071d2006-05-02 22:08:30 +0000230 endif
Bram Moolenaard0796902016-09-16 20:02:31 +0200231 " sanity check
232 if !executable(substitute(g:zip_unzipcmd,'\s\+.*$','',''))
233 redraw!
234 echohl Error | echo "***error*** (zip#Read) sorry, your system doesn't appear to have the ".g:zip_unzipcmd." program" | echohl None
235" call inputsave()|call input("Press <cr> to continue")|call inputrestore()
236 let &report= repkeep
Bram Moolenaard0796902016-09-16 20:02:31 +0200237 return
238 endif
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000239
Bram Moolenaarff034192013-04-24 18:51:19 +0200240 " the following code does much the same thing as
241 " exe "keepj sil! r! ".g:zip_unzipcmd." -p -- ".s:Escape(zipfile,1)." ".s:Escape(fnameescape(fname),1)
Bram Moolenaar519cc552021-11-16 19:18:26 +0000242 " but allows zipfile://... entries in quickfix lists
Bram Moolenaarff034192013-04-24 18:51:19 +0200243 let temp = tempname()
244 let fn = expand('%:p')
Christian Brabandt1c673422024-06-15 14:49:24 +0200245 exe "sil! !".g:zip_unzipcmd." -p -- ".s:Escape(zipfile,1)." ".s:Escape(fname,1).' > '.temp
Bram Moolenaarff034192013-04-24 18:51:19 +0200246 sil exe 'keepalt file '.temp
247 sil keepj e!
248 sil exe 'keepalt file '.fnameescape(fn)
249 call delete(temp)
250
Bram Moolenaar251e1912011-06-19 05:09:16 +0200251 filetype detect
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000252
253 " cleanup
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000254 set nomod
255
Bram Moolenaar36c31f72005-11-28 23:01:53 +0000256 let &report= repkeep
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000257endfun
258
259" ---------------------------------------------------------------------
260" zip#Write: {{{2
261fun! zip#Write(fname)
Bram Moolenaar910f66f2006-04-05 20:41:53 +0000262" call Dfunc("zip#Write(fname<".a:fname.">) zipfile_".winnr()."<".s:zipfile_{winnr()}.">")
Bram Moolenaar36c31f72005-11-28 23:01:53 +0000263 let repkeep= &report
264 set report=10
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000265
266 " sanity checks
Bram Moolenaard0796902016-09-16 20:02:31 +0200267 if !executable(substitute(g:zip_zipcmd,'\s\+.*$','',''))
Bram Moolenaar9964e462007-05-05 17:54:07 +0000268 redraw!
Bram Moolenaard0796902016-09-16 20:02:31 +0200269 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 +0000270" call inputsave()|call input("Press <cr> to continue")|call inputrestore()
Bram Moolenaar36c31f72005-11-28 23:01:53 +0000271 let &report= repkeep
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000272" call Dret("zip#Write")
273 return
274 endif
275 if !exists("*mkdir")
Bram Moolenaar9964e462007-05-05 17:54:07 +0000276 redraw!
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000277 echohl Error | echo "***error*** (zip#Write) sorry, mkdir() doesn't work on your system" | echohl None
Bram Moolenaar9964e462007-05-05 17:54:07 +0000278" call inputsave()|call input("Press <cr> to continue")|call inputrestore()
Bram Moolenaar36c31f72005-11-28 23:01:53 +0000279 let &report= repkeep
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000280" call Dret("zip#Write")
281 return
282 endif
283
284 let curdir= getcwd()
285 let tmpdir= tempname()
286" call Decho("orig tempname<".tmpdir.">")
287 if tmpdir =~ '\.'
288 let tmpdir= substitute(tmpdir,'\.[^.]*$','','e')
289 endif
290" call Decho("tmpdir<".tmpdir.">")
291 call mkdir(tmpdir,"p")
292
293 " attempt to change to the indicated directory
Bram Moolenaar9964e462007-05-05 17:54:07 +0000294 if s:ChgDir(tmpdir,s:ERROR,"(zip#Write) cannot cd to temporary directory")
Bram Moolenaar36c31f72005-11-28 23:01:53 +0000295 let &report= repkeep
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000296" call Dret("zip#Write")
297 return
Bram Moolenaar9964e462007-05-05 17:54:07 +0000298 endif
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000299" call Decho("current directory now: ".getcwd())
300
301 " place temporary files under .../_ZIPVIM_/
302 if isdirectory("_ZIPVIM_")
Damien2cad9412024-07-24 20:07:00 +0200303 call delete("_ZIPVIM_", "rf")
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000304 endif
305 call mkdir("_ZIPVIM_")
306 cd _ZIPVIM_
307" call Decho("current directory now: ".getcwd())
308
Bram Moolenaard68071d2006-05-02 22:08:30 +0000309 if has("unix")
Bram Moolenaar519cc552021-11-16 19:18:26 +0000310 let zipfile = substitute(a:fname,'zipfile://\(.\{-}\)::[^\\].*$','\1','')
311 let fname = substitute(a:fname,'zipfile://.\{-}::\([^\\].*\)$','\1','')
Bram Moolenaard68071d2006-05-02 22:08:30 +0000312 else
Bram Moolenaar519cc552021-11-16 19:18:26 +0000313 let zipfile = substitute(a:fname,'^.\{-}zipfile://\(.\{-}\)::[^\\].*$','\1','')
314 let fname = substitute(a:fname,'^.\{-}zipfile://.\{-}::\([^\\].*\)$','\1','')
Bram Moolenaard68071d2006-05-02 22:08:30 +0000315 endif
316" call Decho("zipfile<".zipfile.">")
317" call Decho("fname <".fname.">")
Bram Moolenaarc7486e02005-12-29 22:48:26 +0000318
319 if fname =~ '/'
320 let dirpath = substitute(fname,'/[^/]\+$','','e')
Bram Moolenaarff034192013-04-24 18:51:19 +0200321 if has("win32unix") && executable("cygpath")
Bram Moolenaarc236c162008-07-13 17:41:49 +0000322 let dirpath = substitute(system("cygpath ".s:Escape(dirpath,0)),'\n','','e')
Bram Moolenaarc7486e02005-12-29 22:48:26 +0000323 endif
Bram Moolenaar910f66f2006-04-05 20:41:53 +0000324" call Decho("mkdir(dirpath<".dirpath.">,p)")
Bram Moolenaarc7486e02005-12-29 22:48:26 +0000325 call mkdir(dirpath,"p")
326 endif
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000327 if zipfile !~ '/'
328 let zipfile= curdir.'/'.zipfile
329 endif
330" call Decho("zipfile<".zipfile."> fname<".fname.">")
331
Bram Moolenaarc236c162008-07-13 17:41:49 +0000332 exe "w! ".fnameescape(fname)
Bram Moolenaarff034192013-04-24 18:51:19 +0200333 if has("win32unix") && executable("cygpath")
Bram Moolenaarc236c162008-07-13 17:41:49 +0000334 let zipfile = substitute(system("cygpath ".s:Escape(zipfile,0)),'\n','','e')
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000335 endif
336
Bram Moolenaar9964e462007-05-05 17:54:07 +0000337 if (has("win32") || has("win95") || has("win64") || has("win16")) && &shell !~? 'sh$'
338 let fname = substitute(fname, '[', '[[]', 'g')
339 endif
340
Bram Moolenaare37d50a2008-08-06 17:06:04 +0000341" call Decho(g:zip_zipcmd." -u ".s:Escape(fnamemodify(zipfile,":p"),0)." ".s:Escape(fname,0))
342 call system(g:zip_zipcmd." -u ".s:Escape(fnamemodify(zipfile,":p"),0)." ".s:Escape(fname,0))
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000343 if v:shell_error != 0
Bram Moolenaar9964e462007-05-05 17:54:07 +0000344 redraw!
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000345 echohl Error | echo "***error*** (zip#Write) sorry, unable to update ".zipfile." with ".fname | echohl None
Bram Moolenaar9964e462007-05-05 17:54:07 +0000346" call inputsave()|call input("Press <cr> to continue")|call inputrestore()
Bram Moolenaara5792f52005-11-23 21:25:05 +0000347
348 elseif s:zipfile_{winnr()} =~ '^\a\+://'
349 " support writing zipfiles across a network
350 let netzipfile= s:zipfile_{winnr()}
Bram Moolenaar9964e462007-05-05 17:54:07 +0000351" call Decho("handle writing <".zipfile."> across network as <".netzipfile.">")
Bram Moolenaara5792f52005-11-23 21:25:05 +0000352 1split|enew
353 let binkeep= &binary
354 let eikeep = &ei
355 set binary ei=all
Bram Moolenaar29634562020-01-09 21:46:04 +0100356 exe "noswapfile e! ".fnameescape(zipfile)
Bram Moolenaara5792f52005-11-23 21:25:05 +0000357 call netrw#NetWrite(netzipfile)
358 let &ei = eikeep
359 let &binary = binkeep
360 q!
361 unlet s:zipfile_{winnr()}
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000362 endif
Damien2cad9412024-07-24 20:07:00 +0200363
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000364 " cleanup and restore current directory
365 cd ..
Damien2cad9412024-07-24 20:07:00 +0200366 call delete("_ZIPVIM_", "rf")
Bram Moolenaar9964e462007-05-05 17:54:07 +0000367 call s:ChgDir(curdir,s:WARNING,"(zip#Write) unable to return to ".curdir."!")
Damien2cad9412024-07-24 20:07:00 +0200368 call delete(tmpdir, "rf")
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000369 setlocal nomod
370
Bram Moolenaar36c31f72005-11-28 23:01:53 +0000371 let &report= repkeep
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000372" call Dret("zip#Write")
373endfun
374
375" ---------------------------------------------------------------------
Bram Moolenaard0796902016-09-16 20:02:31 +0200376" zip#Extract: extract a file from a zip archive {{{2
377fun! zip#Extract()
378" call Dfunc("zip#Extract()")
379
380 let repkeep= &report
381 set report=10
382 let fname= getline(".")
383" call Decho("fname<".fname.">")
384
385 " sanity check
386 if fname =~ '^"'
387 let &report= repkeep
388" call Dret("zip#Extract")
389 return
390 endif
391 if fname =~ '/$'
392 redraw!
393 echohl Error | echo "***error*** (zip#Extract) Please specify a file, not a directory" | echohl None
394 let &report= repkeep
395" call Dret("zip#Extract")
396 return
397 endif
398
399 " extract the file mentioned under the cursor
Damien38ce71c2024-07-23 19:56:54 +0200400 call system($"{g:zip_extractcmd} {shellescape(b:zipfile)} {shellescape(fname)}")
Bram Moolenaard0796902016-09-16 20:02:31 +0200401" 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
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000460" ------------------------------------------------------------------------
461" Modelines And Restoration: {{{1
462let &cpo= s:keepcpo
463unlet s:keepcpo
Bram Moolenaarccc18222007-05-10 18:25:20 +0000464" vim:ts=8 fdm=marker