blob: 5842741b79bc862a9bc05ea86b86e96fc7e0295a [file] [log] [blame]
Bram Moolenaar60a795a2005-09-16 21:55:43 +00001" zip.vim: Handles browsing zipfiles
2" AUTOLOAD PORTION
Bram Moolenaar446cb832008-06-24 21:56:24 +00003" Date: Jun 12, 2008
4" Version: 18
Bram Moolenaar9964e462007-05-05 17:54:07 +00005" Maintainer: Charles E Campbell, Jr <NdrOchip@ScampbellPfamily.AbizM-NOSPAM>
6" License: Vim License (see vim's :help license)
Bram Moolenaar446cb832008-06-24 21:56:24 +00007" Copyright: Copyright (C) 2005-2008 Charles E. Campbell, Jr. {{{1
Bram Moolenaar60a795a2005-09-16 21:55:43 +00008" Permission is hereby granted to use and distribute this code,
9" with or without modifications, provided that this copyright
10" notice is copied with it. Like anything else that's free,
Bram Moolenaar446cb832008-06-24 21:56:24 +000011" zip.vim and zipPlugin.vim are provided *as is* and comes with
12" no warranty of any kind, either expressed or implied. By using
13" this plugin, you agree that in no event will the copyright
Bram Moolenaar60a795a2005-09-16 21:55:43 +000014" holder be liable for any damages resulting from the use
15" of this software.
16
17" ---------------------------------------------------------------------
Bram Moolenaar9964e462007-05-05 17:54:07 +000018" Load Once: {{{1
Bram Moolenaar60a795a2005-09-16 21:55:43 +000019let s:keepcpo= &cpo
20set cpo&vim
Bram Moolenaar9964e462007-05-05 17:54:07 +000021if &cp || exists("g:loaded_zip") || v:version < 700
Bram Moolenaar60a795a2005-09-16 21:55:43 +000022 finish
23endif
24
Bram Moolenaar446cb832008-06-24 21:56:24 +000025let g:loaded_zip = "v18"
Bram Moolenaardb552d602006-03-23 22:59:57 +000026let s:zipfile_escape = ' ?&;\'
Bram Moolenaar9964e462007-05-05 17:54:07 +000027let s:ERROR = 2
28let s:WARNING = 1
29let s:NOTE = 0
30
31" ---------------------------------------------------------------------
32" Global Values: {{{1
33if !exists("g:zip_shq")
Bram Moolenaar446cb832008-06-24 21:56:24 +000034 if &shq != ""
35 let g:zip_shq= &shq
36 elseif has("unix")
Bram Moolenaar9964e462007-05-05 17:54:07 +000037 let g:zip_shq= "'"
38 else
39 let g:zip_shq= '"'
40 endif
41endif
Bram Moolenaarccc18222007-05-10 18:25:20 +000042if !exists("g:zip_zipcmd")
43 let g:zip_zipcmd= "zip"
44endif
45if !exists("g:zip_unzipcmd")
46 let g:zip_unzipcmd= "unzip"
47endif
Bram Moolenaar60a795a2005-09-16 21:55:43 +000048
49" ----------------
50" Functions: {{{1
51" ----------------
52
53" ---------------------------------------------------------------------
54" zip#Browse: {{{2
55fun! zip#Browse(zipfile)
56" call Dfunc("zip#Browse(zipfile<".a:zipfile.">)")
Bram Moolenaar36c31f72005-11-28 23:01:53 +000057 let repkeep= &report
58 set report=10
Bram Moolenaar60a795a2005-09-16 21:55:43 +000059
60 " sanity checks
Bram Moolenaarccc18222007-05-10 18:25:20 +000061 if !executable(g:zip_unzipcmd)
Bram Moolenaar9964e462007-05-05 17:54:07 +000062 redraw!
Bram Moolenaar60a795a2005-09-16 21:55:43 +000063 echohl Error | echo "***error*** (zip#Browse) unzip not available on your system"
Bram Moolenaar9964e462007-05-05 17:54:07 +000064" call inputsave()|call input("Press <cr> to continue")|call inputrestore()
Bram Moolenaar36c31f72005-11-28 23:01:53 +000065 let &report= repkeep
Bram Moolenaar60a795a2005-09-16 21:55:43 +000066" call Dret("zip#Browse")
67 return
68 endif
69 if !filereadable(a:zipfile)
Bram Moolenaara5792f52005-11-23 21:25:05 +000070 if a:zipfile !~# '^\a\+://'
71 " if its an url, don't complain, let url-handlers such as vim do its thing
Bram Moolenaar9964e462007-05-05 17:54:07 +000072 redraw!
Bram Moolenaara5792f52005-11-23 21:25:05 +000073 echohl Error | echo "***error*** (zip#Browse) File not readable<".a:zipfile.">" | echohl None
Bram Moolenaar9964e462007-05-05 17:54:07 +000074" call inputsave()|call input("Press <cr> to continue")|call inputrestore()
Bram Moolenaara5792f52005-11-23 21:25:05 +000075 endif
Bram Moolenaar36c31f72005-11-28 23:01:53 +000076 let &report= repkeep
Bram Moolenaara5792f52005-11-23 21:25:05 +000077" call Dret("zip#Browse : file<".a:zipfile."> not readable")
Bram Moolenaar60a795a2005-09-16 21:55:43 +000078 return
79 endif
Bram Moolenaardb552d602006-03-23 22:59:57 +000080" call Decho("passed sanity checks")
Bram Moolenaar60a795a2005-09-16 21:55:43 +000081 if &ma != 1
82 set ma
83 endif
Bram Moolenaarccc18222007-05-10 18:25:20 +000084 let b:zipfile= a:zipfile
Bram Moolenaar60a795a2005-09-16 21:55:43 +000085
86 setlocal noswapfile
87 setlocal buftype=nofile
88 setlocal bufhidden=hide
89 setlocal nobuflisted
90 setlocal nowrap
91 set ft=tar
92
93 " give header
94 exe "$put ='".'\"'." zip.vim version ".g:loaded_zip."'"
95 exe "$put ='".'\"'." Browsing zipfile ".a:zipfile."'"
96 exe "$put ='".'\"'." Select a file with cursor and press ENTER"."'"
97 $put =''
98 0d
99 $
100
Bram Moolenaarccc18222007-05-10 18:25:20 +0000101" call Decho("exe silent r! ".g:zip_unzipcmd." -l ".s:QuoteFileDir(a:zipfile))
102 exe "silent r! ".g:zip_unzipcmd." -l ".s:QuoteFileDir(a:zipfile)
Bram Moolenaard68071d2006-05-02 22:08:30 +0000103 if v:shell_error != 0
Bram Moolenaar9964e462007-05-05 17:54:07 +0000104 redraw!
Bram Moolenaard68071d2006-05-02 22:08:30 +0000105 echohl WarningMsg | echo "***warning*** (zip#Browse) ".a:zipfile." is not a zip file" | echohl None
Bram Moolenaar9964e462007-05-05 17:54:07 +0000106" call inputsave()|call input("Press <cr> to continue")|call inputrestore()
Bram Moolenaard68071d2006-05-02 22:08:30 +0000107 silent %d
108 let eikeep= &ei
109 set ei=BufReadCmd,FileReadCmd
110 exe "r ".a:zipfile
111 let &ei= eikeep
112 1d
113" call Dret("zip#Browse")
114 return
115 endif
Bram Moolenaar910f66f2006-04-05 20:41:53 +0000116" call Decho("line 6: ".getline(6))
117 let namecol= stridx(getline(6),'Name') + 1
118" call Decho("namecol=".namecol)
119 4,$g/^\s*----/d
120 4,$g/^\s*\a/d
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000121 $d
Bram Moolenaar4c3f5362006-04-11 21:38:50 +0000122 if namecol > 0
123 exe 'silent 4,$s/^.*\%'.namecol.'c//'
124 endif
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000125
126 setlocal noma nomod ro
127 noremap <silent> <buffer> <cr> :call <SID>ZipBrowseSelect()<cr>
128
Bram Moolenaar36c31f72005-11-28 23:01:53 +0000129 let &report= repkeep
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000130" call Dret("zip#Browse")
131endfun
132
133" ---------------------------------------------------------------------
134" ZipBrowseSelect: {{{2
135fun! s:ZipBrowseSelect()
Bram Moolenaarccc18222007-05-10 18:25:20 +0000136" call Dfunc("ZipBrowseSelect() zipfile<".b:zipfile."> curfile<".expand("%").">")
Bram Moolenaar36c31f72005-11-28 23:01:53 +0000137 let repkeep= &report
138 set report=10
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000139 let fname= getline(".")
140
141 " sanity check
142 if fname =~ '^"'
Bram Moolenaar36c31f72005-11-28 23:01:53 +0000143 let &report= repkeep
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000144" call Dret("ZipBrowseSelect")
145 return
146 endif
147 if fname =~ '/$'
Bram Moolenaar9964e462007-05-05 17:54:07 +0000148 redraw!
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000149 echohl Error | echo "***error*** (zip#Browse) Please specify a file, not a directory" | echohl None
Bram Moolenaar9964e462007-05-05 17:54:07 +0000150" call inputsave()|call input("Press <cr> to continue")|call inputrestore()
Bram Moolenaar36c31f72005-11-28 23:01:53 +0000151 let &report= repkeep
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000152" call Dret("ZipBrowseSelect")
153 return
154 endif
155
156" call Decho("fname<".fname.">")
157
158 " get zipfile to the new-window
Bram Moolenaarccc18222007-05-10 18:25:20 +0000159 let zipfile = b:zipfile
Bram Moolenaar910f66f2006-04-05 20:41:53 +0000160 let curfile= expand("%")
Bram Moolenaardb552d602006-03-23 22:59:57 +0000161" call Decho("zipfile<".zipfile.">")
162" call Decho("curfile<".curfile.">")
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000163
164 new
Bram Moolenaar446cb832008-06-24 21:56:24 +0000165 if !exists("g:zip_nomax") || g:zip_nomax == 0
166 wincmd _
167 endif
Bram Moolenaara5792f52005-11-23 21:25:05 +0000168 let s:zipfile_{winnr()}= curfile
Bram Moolenaard68071d2006-05-02 22:08:30 +0000169" call Decho("exe e zipfile:".escape(zipfile,s:zipfile_escape).'::'.escape(fname,s:zipfile_escape))
170 exe "e zipfile:".escape(zipfile,s:zipfile_escape).'::'.escape(fname,s:zipfile_escape)
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000171 filetype detect
172
Bram Moolenaar36c31f72005-11-28 23:01:53 +0000173 let &report= repkeep
Bram Moolenaara5792f52005-11-23 21:25:05 +0000174" call Dret("ZipBrowseSelect : s:zipfile_".winnr()."<".s:zipfile_{winnr()}.">")
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000175endfun
176
177" ---------------------------------------------------------------------
178" zip#Read: {{{2
179fun! zip#Read(fname,mode)
180" call Dfunc("zip#Read(fname<".a:fname.">,mode=".a:mode.")")
Bram Moolenaar36c31f72005-11-28 23:01:53 +0000181 let repkeep= &report
182 set report=10
183
Bram Moolenaard68071d2006-05-02 22:08:30 +0000184 if has("unix")
185 let zipfile = substitute(a:fname,'zipfile:\(.\{-}\)::[^\\].*$','\1','')
186 let fname = substitute(a:fname,'zipfile:.\{-}::\([^\\].*\)$','\1','')
187 else
188 let zipfile = substitute(a:fname,'^.\{-}zipfile:\(.\{-}\)::[^\\].*$','\1','')
189 let fname = substitute(a:fname,'^.\{-}zipfile:.\{-}::\([^\\].*\)$','\1','')
Bram Moolenaar9964e462007-05-05 17:54:07 +0000190 let fname = substitute(fname, '[', '[[]', 'g')
Bram Moolenaard68071d2006-05-02 22:08:30 +0000191 endif
192" call Decho("zipfile<".zipfile.">")
193" call Decho("fname <".fname.">")
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000194
Bram Moolenaarccc18222007-05-10 18:25:20 +0000195" call Decho("exe r! ".g:zip_unzipcmd." -p ".s:QuoteFileDir(zipfile)." ".s:QuoteFileDir(fname))
196 exe "silent r! ".g:zip_unzipcmd." -p ".s:QuoteFileDir(zipfile)." ".s:QuoteFileDir(fname)
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000197
198 " cleanup
199 0d
200 set nomod
201
Bram Moolenaar36c31f72005-11-28 23:01:53 +0000202 let &report= repkeep
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000203" call Dret("zip#Read")
204endfun
205
206" ---------------------------------------------------------------------
207" zip#Write: {{{2
208fun! zip#Write(fname)
Bram Moolenaar910f66f2006-04-05 20:41:53 +0000209" call Dfunc("zip#Write(fname<".a:fname.">) zipfile_".winnr()."<".s:zipfile_{winnr()}.">")
Bram Moolenaar36c31f72005-11-28 23:01:53 +0000210 let repkeep= &report
211 set report=10
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000212
213 " sanity checks
Bram Moolenaarccc18222007-05-10 18:25:20 +0000214 if !executable(g:zip_zipcmd)
Bram Moolenaar9964e462007-05-05 17:54:07 +0000215 redraw!
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000216 echohl Error | echo "***error*** (zip#Write) sorry, your system doesn't appear to have the zip pgm" | echohl None
Bram Moolenaar9964e462007-05-05 17:54:07 +0000217" call inputsave()|call input("Press <cr> to continue")|call inputrestore()
Bram Moolenaar36c31f72005-11-28 23:01:53 +0000218 let &report= repkeep
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000219" call Dret("zip#Write")
220 return
221 endif
222 if !exists("*mkdir")
Bram Moolenaar9964e462007-05-05 17:54:07 +0000223 redraw!
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000224 echohl Error | echo "***error*** (zip#Write) sorry, mkdir() doesn't work on your system" | echohl None
Bram Moolenaar9964e462007-05-05 17:54:07 +0000225" call inputsave()|call input("Press <cr> to continue")|call inputrestore()
Bram Moolenaar36c31f72005-11-28 23:01:53 +0000226 let &report= repkeep
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000227" call Dret("zip#Write")
228 return
229 endif
230
231 let curdir= getcwd()
232 let tmpdir= tempname()
233" call Decho("orig tempname<".tmpdir.">")
234 if tmpdir =~ '\.'
235 let tmpdir= substitute(tmpdir,'\.[^.]*$','','e')
236 endif
237" call Decho("tmpdir<".tmpdir.">")
238 call mkdir(tmpdir,"p")
239
240 " attempt to change to the indicated directory
Bram Moolenaar9964e462007-05-05 17:54:07 +0000241 if s:ChgDir(tmpdir,s:ERROR,"(zip#Write) cannot cd to temporary directory")
Bram Moolenaar36c31f72005-11-28 23:01:53 +0000242 let &report= repkeep
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000243" call Dret("zip#Write")
244 return
Bram Moolenaar9964e462007-05-05 17:54:07 +0000245 endif
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000246" call Decho("current directory now: ".getcwd())
247
248 " place temporary files under .../_ZIPVIM_/
249 if isdirectory("_ZIPVIM_")
250 call s:Rmdir("_ZIPVIM_")
251 endif
252 call mkdir("_ZIPVIM_")
253 cd _ZIPVIM_
254" call Decho("current directory now: ".getcwd())
255
Bram Moolenaard68071d2006-05-02 22:08:30 +0000256 if has("unix")
257 let zipfile = substitute(a:fname,'zipfile:\(.\{-}\)::[^\\].*$','\1','')
258 let fname = substitute(a:fname,'zipfile:.\{-}::\([^\\].*\)$','\1','')
259 else
260 let zipfile = substitute(a:fname,'^.\{-}zipfile:\(.\{-}\)::[^\\].*$','\1','')
261 let fname = substitute(a:fname,'^.\{-}zipfile:.\{-}::\([^\\].*\)$','\1','')
262 endif
263" call Decho("zipfile<".zipfile.">")
264" call Decho("fname <".fname.">")
Bram Moolenaarc7486e02005-12-29 22:48:26 +0000265
266 if fname =~ '/'
267 let dirpath = substitute(fname,'/[^/]\+$','','e')
268 if executable("cygpath")
269 let dirpath = substitute(system("cygpath ".dirpath),'\n','','e')
270 endif
Bram Moolenaar910f66f2006-04-05 20:41:53 +0000271" call Decho("mkdir(dirpath<".dirpath.">,p)")
Bram Moolenaarc7486e02005-12-29 22:48:26 +0000272 call mkdir(dirpath,"p")
273 endif
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000274 if zipfile !~ '/'
275 let zipfile= curdir.'/'.zipfile
276 endif
277" call Decho("zipfile<".zipfile."> fname<".fname.">")
278
Bram Moolenaar910f66f2006-04-05 20:41:53 +0000279 exe "w! ".escape(fname,s:zipfile_escape)
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000280 if executable("cygpath")
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000281 let zipfile = substitute(system("cygpath ".zipfile),'\n','','e')
282 endif
283
Bram Moolenaar9964e462007-05-05 17:54:07 +0000284 if (has("win32") || has("win95") || has("win64") || has("win16")) && &shell !~? 'sh$'
285 let fname = substitute(fname, '[', '[[]', 'g')
286 endif
287
Bram Moolenaarccc18222007-05-10 18:25:20 +0000288" call Decho(g:zip_zipcmd." -u ".s:QuoteFileDir(zipfile)." ".s:QuoteFileDir(fname))
289 call system(g:zip_zipcmd." -u ".s:QuoteFileDir(zipfile)." ".s:QuoteFileDir(fname))
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000290 if v:shell_error != 0
Bram Moolenaar9964e462007-05-05 17:54:07 +0000291 redraw!
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000292 echohl Error | echo "***error*** (zip#Write) sorry, unable to update ".zipfile." with ".fname | echohl None
Bram Moolenaar9964e462007-05-05 17:54:07 +0000293" call inputsave()|call input("Press <cr> to continue")|call inputrestore()
Bram Moolenaara5792f52005-11-23 21:25:05 +0000294
295 elseif s:zipfile_{winnr()} =~ '^\a\+://'
296 " support writing zipfiles across a network
297 let netzipfile= s:zipfile_{winnr()}
Bram Moolenaar9964e462007-05-05 17:54:07 +0000298" call Decho("handle writing <".zipfile."> across network as <".netzipfile.">")
Bram Moolenaara5792f52005-11-23 21:25:05 +0000299 1split|enew
300 let binkeep= &binary
301 let eikeep = &ei
302 set binary ei=all
Bram Moolenaar9964e462007-05-05 17:54:07 +0000303 exe "e! ".zipfile
Bram Moolenaara5792f52005-11-23 21:25:05 +0000304 call netrw#NetWrite(netzipfile)
305 let &ei = eikeep
306 let &binary = binkeep
307 q!
308 unlet s:zipfile_{winnr()}
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000309 endif
310
311 " cleanup and restore current directory
312 cd ..
313 call s:Rmdir("_ZIPVIM_")
Bram Moolenaar9964e462007-05-05 17:54:07 +0000314 call s:ChgDir(curdir,s:WARNING,"(zip#Write) unable to return to ".curdir."!")
315 call s:Rmdir(tmpdir)
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000316 setlocal nomod
317
Bram Moolenaar36c31f72005-11-28 23:01:53 +0000318 let &report= repkeep
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000319" call Dret("zip#Write")
320endfun
321
322" ---------------------------------------------------------------------
Bram Moolenaar9964e462007-05-05 17:54:07 +0000323" QuoteFileDir: {{{2
324fun! s:QuoteFileDir(fname)
325" call Dfunc("QuoteFileDir(fname<".a:fname.">)")
Bram Moolenaar446cb832008-06-24 21:56:24 +0000326 if has("*shellescape")
327 let qnameq= shellescape(a:fname)
328 else
329 let qnameq= g:zip_shq.escape(a:fname,g:zip_shq).g:zip_shq
330 endif
331" call Dret("QuoteFileDir <".qnameq.">")
332 return qnameq
Bram Moolenaar9964e462007-05-05 17:54:07 +0000333endfun
334
335" ---------------------------------------------------------------------
336" ChgDir: {{{2
337fun! s:ChgDir(newdir,errlvl,errmsg)
338" call Dfunc("ChgDir(newdir<".a:newdir."> errlvl=".a:errlvl." errmsg<".a:errmsg.">)")
339
340 if (has("win32") || has("win95") || has("win64") || has("win16")) && &shell !~? 'sh$'
341 let newdir= escape(a:newdir,' ')
342 else
343 let newdir= escape(a:newdir,'\ ')
344 endif
345
346 try
347 exe "cd ".newdir
348 catch /^Vim\%((\a\+)\)\=:E344/
349 redraw!
350 if a:errlvl == s:NOTE
351 echo "***note*** ".a:errmsg
352 elseif a:errlvl == s:WARNING
353 echohl WarningMsg | echo "***warning*** ".a:errmsg | echohl NONE
354 elseif a:errlvl == s:ERROR
355 echohl Error | echo "***error*** ".a:errmsg | echohl NONE
356 endif
357" call inputsave()|call input("Press <cr> to continue")|call inputrestore()
358" call Dret("ChgDir 1")
359 return 1
360 endtry
361
362" call Dret("ChgDir 0")
363 return 0
364endfun
365
366" ---------------------------------------------------------------------
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000367" Rmdir: {{{2
368fun! s:Rmdir(fname)
369" call Dfunc("Rmdir(fname<".a:fname.">)")
Bram Moolenaar9964e462007-05-05 17:54:07 +0000370 if (has("win32") || has("win95") || has("win64") || has("win16")) && &shell !~? 'sh$'
371 call system("rmdir /S/Q ".s:QuoteFileDir(a:fname))
372 else
373 call system("/bin/rm -rf ".s:QuoteFileDir(a:fname))
Bram Moolenaar60a795a2005-09-16 21:55:43 +0000374 endif
375" call Dret("Rmdir")
376endfun
377
378" ------------------------------------------------------------------------
379" Modelines And Restoration: {{{1
380let &cpo= s:keepcpo
381unlet s:keepcpo
Bram Moolenaarccc18222007-05-10 18:25:20 +0000382" vim:ts=8 fdm=marker