blob: 7e833fe5ad35a7e030e73d9cd3aef935235b37d6 [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
Damienf0e9b722024-08-05 20:21:18 +02003" Date: Aug 05, 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
Damienf0e9b722024-08-05 20:21:18 +020011" 2024 Jul 30 by Vim Project: fix opening remote zipfile
zeertzjqc5bdd662024-08-04 18:35:50 +020012" 2024 Aug 04 by Vim Project: escape '[' in name of file to be extracted
Damienf0e9b722024-08-05 20:21:18 +020013" 2024 Aug 05 by Vim Project: workaround for the FreeBSD's unzip
Christian Brabandta63f66e2024-08-05 20:47:34 +020014" 2024 Aug 05 by Vim Project: clean-up and make it work with shellslash on Windows
Bram Moolenaar9964e462007-05-05 17:54:07 +000015" License: Vim License (see vim's :help license)
Christian Brabandt1c673422024-06-15 14:49:24 +020016" Copyright: Copyright (C) 2005-2019 Charles E. Campbell {{{1
17" Permission is hereby granted to use and distribute this code,
18" with or without modifications, provided that this copyright
19" notice is copied with it. Like anything else that's free,
20" zip.vim and zipPlugin.vim are provided *as is* and comes with
21" no warranty of any kind, either expressed or implied. By using
22" this plugin, you agree that in no event will the copyright
23" holder be liable for any damages resulting from the use
24" of this software.
Bram Moolenaar60a795a2005-09-16 21:55:43 +000025
26" ---------------------------------------------------------------------
Bram Moolenaar9964e462007-05-05 17:54:07 +000027" Load Once: {{{1
Bram Moolenaar00a927d2010-05-14 23:24:24 +020028if &cp || exists("g:loaded_zip")
Bram Moolenaar60a795a2005-09-16 21:55:43 +000029 finish
30endif
Bram Moolenaar71badf92023-04-22 22:40:14 +010031let g:loaded_zip= "v33"
Bram Moolenaar00a927d2010-05-14 23:24:24 +020032if v:version < 702
33 echohl WarningMsg
Christian Brabandt120c0dd2024-08-05 20:51:47 +020034 echomsg "***warning*** this version of zip needs vim 7.2 or later"
Bram Moolenaar00a927d2010-05-14 23:24:24 +020035 echohl Normal
36 finish
37endif
38let s:keepcpo= &cpo
39set cpo&vim
Bram Moolenaar60a795a2005-09-16 21:55:43 +000040
Bram Moolenaardb552d602006-03-23 22:59:57 +000041let s:zipfile_escape = ' ?&;\'
Bram Moolenaar9964e462007-05-05 17:54:07 +000042let s:ERROR = 2
43let s:WARNING = 1
44let s:NOTE = 0
45
46" ---------------------------------------------------------------------
47" Global Values: {{{1
48if !exists("g:zip_shq")
Bram Moolenaar446cb832008-06-24 21:56:24 +000049 if &shq != ""
50 let g:zip_shq= &shq
51 elseif has("unix")
Bram Moolenaar9964e462007-05-05 17:54:07 +000052 let g:zip_shq= "'"
53 else
54 let g:zip_shq= '"'
55 endif
56endif
Bram Moolenaarccc18222007-05-10 18:25:20 +000057if !exists("g:zip_zipcmd")
58 let g:zip_zipcmd= "zip"
59endif
60if !exists("g:zip_unzipcmd")
61 let g:zip_unzipcmd= "unzip"
62endif
Bram Moolenaard0796902016-09-16 20:02:31 +020063if !exists("g:zip_extractcmd")
64 let g:zip_extractcmd= g:zip_unzipcmd
65endif
Bram Moolenaar60a795a2005-09-16 21:55:43 +000066
D. Ben Knoblecd8a3ea2023-11-04 05:11:17 -040067if !dist#vim#IsSafeExecutable('zip', g:zip_unzipcmd)
Christian Brabandt816fbcc2023-08-31 23:52:30 +020068 echoerr "Warning: NOT executing " .. g:zip_unzipcmd .. " from current directory!"
69 finish
70endif
Anton Sharonov67c951d2023-09-05 21:03:27 +020071
Bram Moolenaar60a795a2005-09-16 21:55:43 +000072" ----------------
73" Functions: {{{1
74" ----------------
75
76" ---------------------------------------------------------------------
77" zip#Browse: {{{2
78fun! zip#Browse(zipfile)
Damienc4be0662024-07-30 19:14:35 +020079 " sanity check: ensure that the zipfile has "PK" as its first two letters
80 " (zip files have a leading PK as a "magic cookie")
81 if filereadable(a:zipfile) && readblob(a:zipfile, 0, 2) != 0z50.4B
82 exe "noswapfile noautocmd e " .. fnameescape(a:zipfile)
Bram Moolenaar94f76b72013-07-04 22:50:40 +020083 return
Bram Moolenaar94f76b72013-07-04 22:50:40 +020084 endif
85
Christian Brabandt19636be2024-08-05 21:00:07 +020086 let dict = s:SetSaneOpts()
Bram Moolenaar60a795a2005-09-16 21:55:43 +000087
88 " sanity checks
Bram Moolenaarccc18222007-05-10 18:25:20 +000089 if !executable(g:zip_unzipcmd)
Bram Moolenaar9964e462007-05-05 17:54:07 +000090 redraw!
Christian Brabandt120c0dd2024-08-05 20:51:47 +020091 echohl Error | echomsg "***error*** (zip#Browse) unzip not available on your system"
Christian Brabandt19636be2024-08-05 21:00:07 +020092 call s:RestoreOpts(dict)
Bram Moolenaar60a795a2005-09-16 21:55:43 +000093 return
94 endif
95 if !filereadable(a:zipfile)
Bram Moolenaara5792f52005-11-23 21:25:05 +000096 if a:zipfile !~# '^\a\+://'
Bram Moolenaar8024f932020-01-14 19:29:13 +010097 " if it's an url, don't complain, let url-handlers such as vim do its thing
Bram Moolenaar9964e462007-05-05 17:54:07 +000098 redraw!
Christian Brabandt120c0dd2024-08-05 20:51:47 +020099 echohl Error | echomsg "***error*** (zip#Browse) File not readable<".a:zipfile.">" | echohl None
Bram Moolenaara5792f52005-11-23 21:25:05 +0000100 endif
Christian Brabandt19636be2024-08-05 21:00:07 +0200101 call s:RestoreOpts(dict)
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000102 return
103 endif
104 if &ma != 1
105 set ma
106 endif
Bram Moolenaarccc18222007-05-10 18:25:20 +0000107 let b:zipfile= a:zipfile
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000108
109 setlocal noswapfile
110 setlocal buftype=nofile
111 setlocal bufhidden=hide
112 setlocal nobuflisted
113 setlocal nowrap
Bram Moolenaar519cc552021-11-16 19:18:26 +0000114
115 " Oct 12, 2021: need to re-use Bram's syntax/tar.vim.
116 " Setting the filetype to zip doesn't do anything (currently),
117 " but it is perhaps less confusing to curious perusers who do
118 " a :echo &ft
119 setf zip
120 run! syntax/tar.vim
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000121
122 " give header
Bram Moolenaar251e1912011-06-19 05:09:16 +0200123 call append(0, ['" zip.vim version '.g:loaded_zip,
Bram Moolenaar6be7f872012-01-20 21:08:56 +0100124 \ '" Browsing zipfile '.a:zipfile,
125 \ '" Select a file with cursor and press ENTER'])
Bram Moolenaar251e1912011-06-19 05:09:16 +0200126 keepj $
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000127
Damienf0e9b722024-08-05 20:21:18 +0200128 exe $"keepj sil r! {g:zip_unzipcmd} -Z1 -- {s:Escape(a:zipfile, 1)}"
Bram Moolenaard68071d2006-05-02 22:08:30 +0000129 if v:shell_error != 0
Bram Moolenaar9964e462007-05-05 17:54:07 +0000130 redraw!
Christian Brabandt120c0dd2024-08-05 20:51:47 +0200131 echohl WarningMsg | echomsg "***warning*** (zip#Browse) ".fnameescape(a:zipfile)." is not a zip file" | echohl None
Bram Moolenaar251e1912011-06-19 05:09:16 +0200132 keepj sil! %d
Bram Moolenaard68071d2006-05-02 22:08:30 +0000133 let eikeep= &ei
134 set ei=BufReadCmd,FileReadCmd
Bram Moolenaar251e1912011-06-19 05:09:16 +0200135 exe "keepj r ".fnameescape(a:zipfile)
Bram Moolenaard68071d2006-05-02 22:08:30 +0000136 let &ei= eikeep
Bram Moolenaar251e1912011-06-19 05:09:16 +0200137 keepj 1d
Christian Brabandt19636be2024-08-05 21:00:07 +0200138 call s:RestoreOpts(dict)
Bram Moolenaard68071d2006-05-02 22:08:30 +0000139 return
140 endif
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000141
Bram Moolenaard0796902016-09-16 20:02:31 +0200142 " Maps associated with zip plugin
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000143 setlocal noma nomod ro
Bram Moolenaar29634562020-01-09 21:46:04 +0100144 noremap <silent> <buffer> <cr> :call <SID>ZipBrowseSelect()<cr>
145 noremap <silent> <buffer> x :call zip#Extract()<cr>
146 if &mouse != ""
147 noremap <silent> <buffer> <leftmouse> <leftmouse>:call <SID>ZipBrowseSelect()<cr>
148 endif
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000149
Christian Brabandt19636be2024-08-05 21:00:07 +0200150 call s:RestoreOpts(dict)
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000151endfun
152
153" ---------------------------------------------------------------------
154" ZipBrowseSelect: {{{2
155fun! s:ZipBrowseSelect()
Christian Brabandt19636be2024-08-05 21:00:07 +0200156 let dict = s:SetSaneOpts()
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000157 let fname= getline(".")
Bram Moolenaar71badf92023-04-22 22:40:14 +0100158 if !exists("b:zipfile")
Christian Brabandt19636be2024-08-05 21:00:07 +0200159 call s:RestoreOpts(dict)
Bram Moolenaar71badf92023-04-22 22:40:14 +0100160 return
161 endif
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000162
163 " sanity check
164 if fname =~ '^"'
Christian Brabandt19636be2024-08-05 21:00:07 +0200165 call s:RestoreOpts(dict)
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000166 return
167 endif
168 if fname =~ '/$'
Bram Moolenaar9964e462007-05-05 17:54:07 +0000169 redraw!
Christian Brabandt120c0dd2024-08-05 20:51:47 +0200170 echohl Error | echomsg "***error*** (zip#Browse) Please specify a file, not a directory" | echohl None
Christian Brabandt19636be2024-08-05 21:00:07 +0200171 call s:RestoreOpts(dict)
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000172 return
173 endif
174
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000175 " get zipfile to the new-window
Bram Moolenaarccc18222007-05-10 18:25:20 +0000176 let zipfile = b:zipfile
Bram Moolenaar29634562020-01-09 21:46:04 +0100177 let curfile = expand("%")
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000178
Bram Moolenaar29634562020-01-09 21:46:04 +0100179 noswapfile new
Bram Moolenaar446cb832008-06-24 21:56:24 +0000180 if !exists("g:zip_nomax") || g:zip_nomax == 0
181 wincmd _
182 endif
Bram Moolenaara5792f52005-11-23 21:25:05 +0000183 let s:zipfile_{winnr()}= curfile
Bram Moolenaar519cc552021-11-16 19:18:26 +0000184 exe "noswapfile e ".fnameescape("zipfile://".zipfile.'::'.fname)
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000185 filetype detect
186
Christian Brabandt19636be2024-08-05 21:00:07 +0200187 call s:RestoreOpts(dict)
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000188endfun
189
190" ---------------------------------------------------------------------
191" zip#Read: {{{2
192fun! zip#Read(fname,mode)
Christian Brabandt19636be2024-08-05 21:00:07 +0200193 let dict = s:SetSaneOpts()
Bram Moolenaar36c31f72005-11-28 23:01:53 +0000194
Bram Moolenaard68071d2006-05-02 22:08:30 +0000195 if has("unix")
Bram Moolenaar519cc552021-11-16 19:18:26 +0000196 let zipfile = substitute(a:fname,'zipfile://\(.\{-}\)::[^\\].*$','\1','')
197 let fname = substitute(a:fname,'zipfile://.\{-}::\([^\\].*\)$','\1','')
Bram Moolenaard68071d2006-05-02 22:08:30 +0000198 else
Bram Moolenaar519cc552021-11-16 19:18:26 +0000199 let zipfile = substitute(a:fname,'^.\{-}zipfile://\(.\{-}\)::[^\\].*$','\1','')
200 let fname = substitute(a:fname,'^.\{-}zipfile://.\{-}::\([^\\].*\)$','\1','')
Bram Moolenaard68071d2006-05-02 22:08:30 +0000201 endif
zeertzjqc5bdd662024-08-04 18:35:50 +0200202 let fname = substitute(fname, '[', '[[]', 'g')
Bram Moolenaard0796902016-09-16 20:02:31 +0200203 " sanity check
204 if !executable(substitute(g:zip_unzipcmd,'\s\+.*$','',''))
205 redraw!
Christian Brabandt120c0dd2024-08-05 20:51:47 +0200206 echohl Error | echomsg "***error*** (zip#Read) sorry, your system doesn't appear to have the ".g:zip_unzipcmd." program" | echohl None
Christian Brabandt19636be2024-08-05 21:00:07 +0200207 call s:RestoreOpts(dict)
Bram Moolenaard0796902016-09-16 20:02:31 +0200208 return
209 endif
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000210
Bram Moolenaarff034192013-04-24 18:51:19 +0200211 " the following code does much the same thing as
zeertzjqc5bdd662024-08-04 18:35:50 +0200212 " exe "keepj sil! r! ".g:zip_unzipcmd." -p -- ".s:Escape(zipfile,1)." ".s:Escape(fname,1)
Bram Moolenaar519cc552021-11-16 19:18:26 +0000213 " but allows zipfile://... entries in quickfix lists
Bram Moolenaarff034192013-04-24 18:51:19 +0200214 let temp = tempname()
215 let fn = expand('%:p')
Damienf0e9b722024-08-05 20:21:18 +0200216 exe "sil !".g:zip_unzipcmd." -p -- ".s:Escape(zipfile,1)." ".s:Escape(fname,1).' > '.temp
Bram Moolenaarff034192013-04-24 18:51:19 +0200217 sil exe 'keepalt file '.temp
218 sil keepj e!
219 sil exe 'keepalt file '.fnameescape(fn)
220 call delete(temp)
221
Bram Moolenaar251e1912011-06-19 05:09:16 +0200222 filetype detect
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000223
224 " cleanup
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000225 set nomod
226
Christian Brabandt19636be2024-08-05 21:00:07 +0200227 call s:RestoreOpts(dict)
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000228endfun
229
230" ---------------------------------------------------------------------
231" zip#Write: {{{2
232fun! zip#Write(fname)
Christian Brabandt19636be2024-08-05 21:00:07 +0200233 let dict = s:SetSaneOpts()
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000234
235 " sanity checks
Bram Moolenaard0796902016-09-16 20:02:31 +0200236 if !executable(substitute(g:zip_zipcmd,'\s\+.*$','',''))
Bram Moolenaar9964e462007-05-05 17:54:07 +0000237 redraw!
Christian Brabandt120c0dd2024-08-05 20:51:47 +0200238 echohl Error | echomsg "***error*** (zip#Write) sorry, your system doesn't appear to have the ".g:zip_zipcmd." program" | echohl None
Christian Brabandt19636be2024-08-05 21:00:07 +0200239 call s:RestoreOpts(dict)
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000240 return
241 endif
242 if !exists("*mkdir")
Bram Moolenaar9964e462007-05-05 17:54:07 +0000243 redraw!
Christian Brabandt120c0dd2024-08-05 20:51:47 +0200244 echohl Error | echomsg "***error*** (zip#Write) sorry, mkdir() doesn't work on your system" | echohl None
Christian Brabandt19636be2024-08-05 21:00:07 +0200245 call s:RestoreOpts(dict)
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000246 return
247 endif
248
249 let curdir= getcwd()
250 let tmpdir= tempname()
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000251 if tmpdir =~ '\.'
252 let tmpdir= substitute(tmpdir,'\.[^.]*$','','e')
253 endif
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000254 call mkdir(tmpdir,"p")
255
256 " attempt to change to the indicated directory
Bram Moolenaar9964e462007-05-05 17:54:07 +0000257 if s:ChgDir(tmpdir,s:ERROR,"(zip#Write) cannot cd to temporary directory")
Christian Brabandt19636be2024-08-05 21:00:07 +0200258 call s:RestoreOpts(dict)
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000259 return
Bram Moolenaar9964e462007-05-05 17:54:07 +0000260 endif
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000261
262 " place temporary files under .../_ZIPVIM_/
263 if isdirectory("_ZIPVIM_")
Damien2cad9412024-07-24 20:07:00 +0200264 call delete("_ZIPVIM_", "rf")
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000265 endif
266 call mkdir("_ZIPVIM_")
267 cd _ZIPVIM_
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000268
Bram Moolenaard68071d2006-05-02 22:08:30 +0000269 if has("unix")
Bram Moolenaar519cc552021-11-16 19:18:26 +0000270 let zipfile = substitute(a:fname,'zipfile://\(.\{-}\)::[^\\].*$','\1','')
271 let fname = substitute(a:fname,'zipfile://.\{-}::\([^\\].*\)$','\1','')
Bram Moolenaard68071d2006-05-02 22:08:30 +0000272 else
Bram Moolenaar519cc552021-11-16 19:18:26 +0000273 let zipfile = substitute(a:fname,'^.\{-}zipfile://\(.\{-}\)::[^\\].*$','\1','')
274 let fname = substitute(a:fname,'^.\{-}zipfile://.\{-}::\([^\\].*\)$','\1','')
Bram Moolenaard68071d2006-05-02 22:08:30 +0000275 endif
Bram Moolenaarc7486e02005-12-29 22:48:26 +0000276
277 if fname =~ '/'
278 let dirpath = substitute(fname,'/[^/]\+$','','e')
Bram Moolenaarff034192013-04-24 18:51:19 +0200279 if has("win32unix") && executable("cygpath")
Bram Moolenaarc236c162008-07-13 17:41:49 +0000280 let dirpath = substitute(system("cygpath ".s:Escape(dirpath,0)),'\n','','e')
Bram Moolenaarc7486e02005-12-29 22:48:26 +0000281 endif
282 call mkdir(dirpath,"p")
283 endif
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000284 if zipfile !~ '/'
285 let zipfile= curdir.'/'.zipfile
286 endif
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000287
Bram Moolenaarc236c162008-07-13 17:41:49 +0000288 exe "w! ".fnameescape(fname)
Bram Moolenaarff034192013-04-24 18:51:19 +0200289 if has("win32unix") && executable("cygpath")
Bram Moolenaarc236c162008-07-13 17:41:49 +0000290 let zipfile = substitute(system("cygpath ".s:Escape(zipfile,0)),'\n','','e')
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000291 endif
292
Bram Moolenaar9964e462007-05-05 17:54:07 +0000293 if (has("win32") || has("win95") || has("win64") || has("win16")) && &shell !~? 'sh$'
294 let fname = substitute(fname, '[', '[[]', 'g')
295 endif
296
Bram Moolenaare37d50a2008-08-06 17:06:04 +0000297 call system(g:zip_zipcmd." -u ".s:Escape(fnamemodify(zipfile,":p"),0)." ".s:Escape(fname,0))
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000298 if v:shell_error != 0
Bram Moolenaar9964e462007-05-05 17:54:07 +0000299 redraw!
Christian Brabandt120c0dd2024-08-05 20:51:47 +0200300 echohl Error | echomsg "***error*** (zip#Write) sorry, unable to update ".zipfile." with ".fname | echohl None
Bram Moolenaara5792f52005-11-23 21:25:05 +0000301
302 elseif s:zipfile_{winnr()} =~ '^\a\+://'
303 " support writing zipfiles across a network
304 let netzipfile= s:zipfile_{winnr()}
Bram Moolenaara5792f52005-11-23 21:25:05 +0000305 1split|enew
306 let binkeep= &binary
307 let eikeep = &ei
308 set binary ei=all
Bram Moolenaar29634562020-01-09 21:46:04 +0100309 exe "noswapfile e! ".fnameescape(zipfile)
Bram Moolenaara5792f52005-11-23 21:25:05 +0000310 call netrw#NetWrite(netzipfile)
311 let &ei = eikeep
312 let &binary = binkeep
313 q!
314 unlet s:zipfile_{winnr()}
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000315 endif
Damien2cad9412024-07-24 20:07:00 +0200316
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000317 " cleanup and restore current directory
318 cd ..
Damien2cad9412024-07-24 20:07:00 +0200319 call delete("_ZIPVIM_", "rf")
Bram Moolenaar9964e462007-05-05 17:54:07 +0000320 call s:ChgDir(curdir,s:WARNING,"(zip#Write) unable to return to ".curdir."!")
Damien2cad9412024-07-24 20:07:00 +0200321 call delete(tmpdir, "rf")
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000322 setlocal nomod
323
Christian Brabandt19636be2024-08-05 21:00:07 +0200324 call s:RestoreOpts(dict)
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000325endfun
326
327" ---------------------------------------------------------------------
Bram Moolenaard0796902016-09-16 20:02:31 +0200328" zip#Extract: extract a file from a zip archive {{{2
329fun! zip#Extract()
Bram Moolenaard0796902016-09-16 20:02:31 +0200330
Christian Brabandt19636be2024-08-05 21:00:07 +0200331 let dict = s:SetSaneOpts()
Bram Moolenaard0796902016-09-16 20:02:31 +0200332 let fname= getline(".")
Bram Moolenaard0796902016-09-16 20:02:31 +0200333
334 " sanity check
335 if fname =~ '^"'
Christian Brabandt19636be2024-08-05 21:00:07 +0200336 call s:RestoreOpts(dict)
Bram Moolenaard0796902016-09-16 20:02:31 +0200337 return
338 endif
339 if fname =~ '/$'
340 redraw!
Christian Brabandt120c0dd2024-08-05 20:51:47 +0200341 echohl Error | echomsg "***error*** (zip#Extract) Please specify a file, not a directory" | echohl None
Christian Brabandt19636be2024-08-05 21:00:07 +0200342 call s:RestoreOpts(dict)
Bram Moolenaard0796902016-09-16 20:02:31 +0200343 return
344 endif
345
346 " extract the file mentioned under the cursor
Damien38ce71c2024-07-23 19:56:54 +0200347 call system($"{g:zip_extractcmd} {shellescape(b:zipfile)} {shellescape(fname)}")
Bram Moolenaard0796902016-09-16 20:02:31 +0200348 if v:shell_error != 0
Christian Brabandt120c0dd2024-08-05 20:51:47 +0200349 echohl Error | echomsg "***error*** ".g:zip_extractcmd." ".b:zipfile." ".fname.": failed!" | echohl NONE
Bram Moolenaard0796902016-09-16 20:02:31 +0200350 elseif !filereadable(fname)
Christian Brabandt120c0dd2024-08-05 20:51:47 +0200351 echohl Error | echomsg "***error*** attempted to extract ".fname." but it doesn't appear to be present!"
Bram Moolenaard0796902016-09-16 20:02:31 +0200352 else
Christian Brabandt120c0dd2024-08-05 20:51:47 +0200353 echomsg "***note*** successfully extracted ".fname
Bram Moolenaard0796902016-09-16 20:02:31 +0200354 endif
355
356 " restore option
Christian Brabandt19636be2024-08-05 21:00:07 +0200357 call s:RestoreOpts(dict)
Bram Moolenaard0796902016-09-16 20:02:31 +0200358
Bram Moolenaard0796902016-09-16 20:02:31 +0200359endfun
360
361" ---------------------------------------------------------------------
Bram Moolenaarc236c162008-07-13 17:41:49 +0000362" s:Escape: {{{2
363fun! s:Escape(fname,isfilt)
Bram Moolenaarc236c162008-07-13 17:41:49 +0000364 if exists("*shellescape")
365 if a:isfilt
366 let qnameq= shellescape(a:fname,1)
367 else
368 let qnameq= shellescape(a:fname)
369 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +0000370 else
371 let qnameq= g:zip_shq.escape(a:fname,g:zip_shq).g:zip_shq
372 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +0000373 return qnameq
Bram Moolenaar9964e462007-05-05 17:54:07 +0000374endfun
375
376" ---------------------------------------------------------------------
Christian Brabandt19636be2024-08-05 21:00:07 +0200377" s:ChgDir: {{{2
Bram Moolenaar9964e462007-05-05 17:54:07 +0000378fun! s:ChgDir(newdir,errlvl,errmsg)
Bram Moolenaar9964e462007-05-05 17:54:07 +0000379 try
Bram Moolenaare37d50a2008-08-06 17:06:04 +0000380 exe "cd ".fnameescape(a:newdir)
Bram Moolenaar9964e462007-05-05 17:54:07 +0000381 catch /^Vim\%((\a\+)\)\=:E344/
382 redraw!
383 if a:errlvl == s:NOTE
Christian Brabandt120c0dd2024-08-05 20:51:47 +0200384 echomsg "***note*** ".a:errmsg
Bram Moolenaar9964e462007-05-05 17:54:07 +0000385 elseif a:errlvl == s:WARNING
Christian Brabandt120c0dd2024-08-05 20:51:47 +0200386 echohl WarningMsg | echomsg "***warning*** ".a:errmsg | echohl NONE
Bram Moolenaar9964e462007-05-05 17:54:07 +0000387 elseif a:errlvl == s:ERROR
Christian Brabandt120c0dd2024-08-05 20:51:47 +0200388 echohl Error | echomsg "***error*** ".a:errmsg | echohl NONE
Bram Moolenaar9964e462007-05-05 17:54:07 +0000389 endif
Bram Moolenaar9964e462007-05-05 17:54:07 +0000390 return 1
391 endtry
392
Bram Moolenaar9964e462007-05-05 17:54:07 +0000393 return 0
394endfun
395
Christian Brabandt19636be2024-08-05 21:00:07 +0200396" ---------------------------------------------------------------------
397" s:SetSaneOpts: {{{2
398fun! s:SetSaneOpts()
399 let dict = {}
400 let dict.report = &report
401 let dict.shellslash = &shellslash
402
403 let &report = 10
404 let &shellslash = 0
405
406 return dict
407endfun
408
409" ---------------------------------------------------------------------
410" s:RestoreOpts: {{{2
411fun! s:RestoreOpts(dict)
412 for [key, val] in items(a:dict)
413 exe $"let &{key} = {val}"
414 endfor
415endfun
416
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000417" ------------------------------------------------------------------------
418" Modelines And Restoration: {{{1
419let &cpo= s:keepcpo
420unlet s:keepcpo
Bram Moolenaarccc18222007-05-10 18:25:20 +0000421" vim:ts=8 fdm=marker