Add eval & add input methods to MacVim, apply to file open
[MacVim.git] / runtime / autoload / tar.vim
blob6c172386c06f201fe758fb48aa422a776cd224b4
1 " tar.vim: Handles browsing tarfiles
2 "            AUTOLOAD PORTION
3 " Date:                 Sep 29, 2006
4 " Version:              11
5 " Maintainer:   Charles E Campbell, Jr <NdrOchip@ScampbellPfamily.AbizM-NOSPAM>
6 " License:              Vim License  (see vim's :help license)
8 "       Contains many ideas from Michael Toren's <tar.vim>
10 " Copyright:    Copyright (C) 2005 Charles E. Campbell, Jr. {{{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 "               tarPlugin.vim is provided *as is* and comes with no warranty
15 "               of any kind, either expressed or implied. By using this
16 "               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.
20 " ---------------------------------------------------------------------
21 " Load Once: {{{1
22 let s:keepcpo= &cpo
23 set cpo&vim
24 if &cp || exists("g:loaded_tar") || v:version < 700
25  finish
26 endif
27 let g:loaded_tar= "v11"
28 "call Decho("loading autoload/tar.vim")
30 " ---------------------------------------------------------------------
31 "  Default Settings: {{{1
32 if !exists("g:tar_browseoptions")
33  let g:tar_browseoptions= "Ptf"
34 endif
35 if !exists("g:tar_readoptions")
36  let g:tar_readoptions= "OPxf"
37 endif
38 if !exists("g:tar_cmd")
39  let g:tar_cmd= "tar"
40 endif
41 if !exists("g:tar_writeoptions")
42  let g:tar_writeoptions= "uf"
43 endif
44 if !exists("g:tar_shq")
45  if has("unix")
46   let g:tar_shq= "'"
47  else
48   let g:tar_shq= '"'
49  endif
50 endif
52 " ----------------
53 "  Functions: {{{1
54 " ----------------
56 " ---------------------------------------------------------------------
57 " tar#Browse: {{{2
58 fun! tar#Browse(tarfile)
59 "  call Dfunc("tar#Browse(tarfile<".a:tarfile.">)")
60   let repkeep= &report
61   set report=10
63   " sanity checks
64   if !executable(g:tar_cmd)
65    redraw!
66    echohl Error | echo '***error*** (tar#Browse) "'.g:tar_cmd.'" not available on your system'
67 "   call inputsave()|call input("Press <cr> to continue")|call inputrestore()
68    let &report= repkeep
69 "   call Dret("tar#Browse")
70    return
71   endif
72   if !filereadable(a:tarfile)
73 "   call Decho('a:tarfile<'.a:tarfile.'> not filereadable')
74    if a:tarfile !~# '^\a\+://'
75     " if its an url, don't complain, let url-handlers such as vim do its thing
76     redraw!
77     echohl Error | echo "***error*** (tar#Browse) File not readable<".a:tarfile.">" | echohl None
78 "    call inputsave()|call input("Press <cr> to continue")|call inputrestore()
79    endif
80    let &report= repkeep
81 "   call Dret("tar#Browse : file<".a:tarfile."> not readable")
82    return
83   endif
84   if &ma != 1
85    set ma
86   endif
87   let w:tarfile= a:tarfile
89   setlocal noswapfile
90   setlocal buftype=nofile
91   setlocal bufhidden=hide
92   setlocal nobuflisted
93   setlocal nowrap
94   set ft=tar
96   " give header
97 "  call Decho("printing header")
98   exe "$put ='".'\"'." tar.vim version ".g:loaded_tar."'"
99   exe "$put ='".'\"'." Browsing tarfile ".a:tarfile."'"
100   exe "$put ='".'\"'." Select a file with cursor and press ENTER"."'"
101   0d
102   $
104   let tarfile= a:tarfile
105   if has("win32") && executable("cygpath")
106    " assuming cygwin
107    let tarfile=substitute(system("cygpath -u ".tarfile),'\n$','','e')
108   endif
109   let curlast= line("$")
110   if tarfile =~# '\.\(gz\|tgz\)$'
111 "   call Decho("exe silent r! gzip -d -c ".g:tar_shq.tarfile.g:tar_shq."| ".g:tar_cmd." -".g:tar_browseoptions." - ")
112    exe "silent r! gzip -d -c ".g:tar_shq.tarfile.g:tar_shq."| ".g:tar_cmd." -".g:tar_browseoptions." - "
113   elseif tarfile =~# '\.bz2$'
114 "   call Decho("exe silent r! bzip2 -d -c ".g:tar_shq.tarfile.g:tar_shq."| ".g:tar_cmd." -".g:tar_browseoptions." - ")
115    exe "silent r! bzip2 -d -c ".g:tar_shq.tarfile.g:tar_shq."| ".g:tar_cmd." -".g:tar_browseoptions." - "
116   else
117 "   call Decho("exe silent r! ".g:tar_cmd." -".g:tar_browseoptions." ".g:tar_shq.tarfile.g:tar_shq)
118    exe "silent r! ".g:tar_cmd." -".g:tar_browseoptions." ".g:tar_shq.tarfile.g:tar_shq
119   endif
120   if v:shell_error != 0
121    redraw!
122    echohl WarningMsg | echo "***warning*** (tar#Browse) please check your g:tar_browseoptions<".g:tar_browseoptions.">"
123 "   call inputsave()|call input("Press <cr> to continue")|call inputrestore()
124 "   call Dret("tar#Browse : a:tarfile<".a:tarfile.">")
125    return
126   endif
127   if line("$") == curlast || ( line("$") == (curlast + 1) && getline("$") =~ '\c\%(warning\|error\|inappropriate\|unrecognized\)')
128    redraw!
129    echohl WarningMsg | echo "***warning*** (tar#Browse) ".a:tarfile." doesn't appear to be a tar file" | echohl None
130 "   call inputsave()|call input("Press <cr> to continue")|call inputrestore()
131    silent %d
132    let eikeep= &ei
133    set ei=BufReadCmd,FileReadCmd
134    exe "r ".a:tarfile
135    let &ei= eikeep
136    1d
137 "   call Dret("tar#Browse : a:tarfile<".a:tarfile.">")
138    return
139   endif
141   setlocal noma nomod ro
142   noremap <silent> <buffer> <cr> :call <SID>TarBrowseSelect()<cr>
144   let &report= repkeep
145 "  call Dret("tar#Browse : w:tarfile<".w:tarfile.">")
146 endfun
148 " ---------------------------------------------------------------------
149 " TarBrowseSelect: {{{2
150 fun! s:TarBrowseSelect()
151 "  call Dfunc("TarBrowseSelect() w:tarfile<".w:tarfile."> curfile<".expand("%").">")
152   let repkeep= &report
153   set report=10
154   let fname= getline(".")
155 "  call Decho("fname<".fname.">")
157   " sanity check
158   if fname =~ '^"'
159    let &report= repkeep
160 "   call Dret("TarBrowseSelect")
161    return
162   endif
164   " about to make a new window, need to use w:tarfile
165   let tarfile= w:tarfile
166   let curfile= expand("%")
167   if has("win32") && executable("cygpath")
168    " assuming cygwin
169    let tarfile=substitute(system("cygpath -u ".tarfile),'\n$','','e')
170   endif
172   new
173   wincmd _
174   let s:tblfile_{winnr()}= curfile
175   call tar#Read("tarfile:".tarfile.':'.fname,1)
176   filetype detect
178   let &report= repkeep
179 "  call Dret("TarBrowseSelect : s:tblfile_".winnr()."<".s:tblfile_{winnr()}.">")
180 endfun
182 " ---------------------------------------------------------------------
183 " tar#Read: {{{2
184 fun! tar#Read(fname,mode)
185 "  call Dfunc("tar#Read(fname<".a:fname.">,mode=".a:mode.")")
186   let repkeep= &report
187   set report=10
188   let tarfile = substitute(a:fname,'tarfile:\(.\{-}\):.*$','\1','')
189   let fname   = substitute(a:fname,'tarfile:.\{-}:\(.*\)$','\1','')
190   if has("win32") && executable("cygpath")
191    " assuming cygwin
192    let tarfile=substitute(system("cygpath -u ".tarfile),'\n$','','e')
193   endif
194 "  call Decho("tarfile<".tarfile.">")
195 "  call Decho("fname<".fname.">")
197   if tarfile =~# '\.\(gz\|tgz\)$'
198 "   call Decho("exe silent r! gzip -d -c ".g:tar_shq.tarfile.g:tar_shq."| ".g:tar_cmd." -OPxf - '".fname."'")
199    exe "silent r! gzip -d -c ".g:tar_shq.tarfile.g:tar_shq."| ".g:tar_cmd." -".g:tar_readoptions." - '".fname."'"
200   elseif tarfile =~# '\.bz2$'
201 "   call Decho("exe silent r! bzip2 -d -c ".g:tar_shq.tarfile.g:tar_shq."| ".g:tar_cmd." -".g:tar_readoptions." - '".fname."'")
202    exe "silent r! bzip2 -d -c ".g:tar_shq.tarfile.g:tar_shq."| ".g:tar_cmd." -".g:tar_readoptions." - '".fname."'"
203   else
204 "   call Decho("exe silent r! ".g:tar_cmd." -".g:tar_readoptions." ".g:tar_shq.tarfile.g:tar_shq." ".g:tar_shq.fname.g:tar_shq)
205    exe "silent r! ".g:tar_cmd." -".g:tar_readoptions." ".g:tar_shq.tarfile.g:tar_shq." ".g:tar_shq.fname.g:tar_shq
206   endif
207   let w:tarfile= a:fname
208   exe "file tarfile:".fname
210   " cleanup
211   0d
212   set nomod
214   let &report= repkeep
215 "  call Dret("tar#Read : w:tarfile<".w:tarfile.">")
216 endfun
218 " ---------------------------------------------------------------------
219 " tar#Write: {{{2
220 fun! tar#Write(fname)
221 "  call Dfunc("tar#Write(fname<".a:fname.">) w:tarfile<".w:tarfile."> tblfile_".winnr()."<".s:tblfile_{winnr()}.">")
222   let repkeep= &report
223   set report=10
225   " sanity checks
226   if !executable(g:tar_cmd)
227    redraw!
228    echohl Error | echo '***error*** (tar#Browse) "'.g:tar_cmd.'" not available on your system'
229 "   call inputsave()|call input("Press <cr> to continue")|call inputrestore()
230    let &report= repkeep
231 "   call Dret("tar#Write")
232    return
233   endif
234   if !exists("*mkdir")
235    redraw!
236    echohl Error | echo "***error*** (tar#Write) sorry, mkdir() doesn't work on your system" | echohl None
237 "   call inputsave()|call input("Press <cr> to continue")|call inputrestore()
238    let &report= repkeep
239 "   call Dret("tar#Write")
240    return
241   endif
243   let curdir= getcwd()
244   let tmpdir= tempname()
245 "  call Decho("orig tempname<".tmpdir.">")
246   if tmpdir =~ '\.'
247    let tmpdir= substitute(tmpdir,'\.[^.]*$','','e')
248   endif
249 "  call Decho("tmpdir<".tmpdir.">")
250   call mkdir(tmpdir,"p")
252   " attempt to change to the indicated directory
253   try
254    exe "cd ".escape(tmpdir,' \')
255   catch /^Vim\%((\a\+)\)\=:E344/
256    redraw!
257    echohl Error | echo "***error*** (tar#Write) cannot cd to temporary directory" | Echohl None
258 "   call inputsave()|call input("Press <cr> to continue")|call inputrestore()
259    let &report= repkeep
260 "   call Dret("tar#Write")
261    return
262   endtry
263 "  call Decho("current directory now: ".getcwd())
265   " place temporary files under .../_ZIPVIM_/
266   if isdirectory("_ZIPVIM_")
267    call s:Rmdir("_ZIPVIM_")
268   endif
269   call mkdir("_ZIPVIM_")
270   cd _ZIPVIM_
271 "  call Decho("current directory now: ".getcwd())
273   let tarfile = substitute(w:tarfile,'tarfile:\(.\{-}\):.*$','\1','')
274   let fname   = substitute(w:tarfile,'tarfile:.\{-}:\(.*\)$','\1','')
276   " handle compressed archives
277   if tarfile =~# '\.gz'
278    call system("gzip -d ".tarfile)
279    let tarfile = substitute(tarfile,'\.gz','','e')
280    let compress= "gzip '".tarfile."'"
281   elseif tarfile =~# '\.tgz'
282    call system("gzip -d ".tarfile)
283    let tarfile = substitute(tarfile,'\.tgz','.tar','e')
284    let compress= "gzip '".tarfile."'"
285    let tgz     = 1
286   elseif tarfile =~# '\.bz2'
287    call system("bzip2 -d ".tarfile)
288    let tarfile = substitute(tarfile,'\.bz2','','e')
289    let compress= "bzip2 '".tarfile."'"
290   endif
292   if v:shell_error != 0
293    redraw!
294    echohl Error | echo "***error*** (tar#Write) sorry, unable to update ".tarfile." with ".fname | echohl None
295 "   call inputsave()|call input("Press <cr> to continue")|call inputrestore()
296   else
298 "   call Decho("tarfile<".tarfile."> fname<".fname.">")
300    if fname =~ '/'
301     let dirpath = substitute(fname,'/[^/]\+$','','e')
302     if executable("cygpath")
303      let dirpath = substitute(system("cygpath ".dirpath),'\n','','e')
304     endif
305     call mkdir(dirpath,"p")
306    endif
307    if tarfile !~ '/'
308     let tarfile= curdir.'/'.tarfile
309    endif
310 "   call Decho("tarfile<".tarfile."> fname<".fname.">")
312    exe "w! ".fname
313    if executable("cygpath")
314     let tarfile = substitute(system("cygpath ".tarfile),'\n','','e')
315    endif
317    " delete old file from tarfile
318 "   call Decho("tar --delete -f '".tarfile."' '".fname."'")
319    call system("tar --delete -f '".tarfile."' '".fname."'")
320    if v:shell_error != 0
321     redraw!
322     echohl Error | echo "***error*** (tar#Write) sorry, unable to update ".tarfile." with ".fname | echohl None
323 "    call inputsave()|call input("Press <cr> to continue")|call inputrestore()
324    else
326     " update tarfile with new file 
327 "    call Decho("tar -".g:tar_writeoptions." '".tarfile."' '".fname."'")
328     call system("tar -".g:tar_writeoptions." '".tarfile."' '".fname."'")
329     if v:shell_error != 0
330      redraw!
331      echohl Error | echo "***error*** (tar#Write) sorry, unable to update ".tarfile." with ".fname | echohl None
332 "     call inputsave()|call input("Press <cr> to continue")|call inputrestore()
333     elseif exists("compress")
334 "     call Decho("call system(".compress.")")
335      call system(compress)
336      if exists("tgz")
337 "      call Decho("rename(".tarfile.".gz,".substitute(tarfile,'\.tar$','.tgz','e').")")
338       call rename(tarfile.".gz",substitute(tarfile,'\.tar$','.tgz','e'))
339      endif
340     endif
341    endif
343    " support writing tarfiles across a network
344    if s:tblfile_{winnr()} =~ '^\a\+://'
345 "    call Decho("handle writing <".tarfile."> across network to <".s:tblfile_{winnr()}.">")
346     let tblfile= s:tblfile_{winnr()}
347     1split|enew
348     let binkeep= &binary
349     let eikeep = &ei
350     set binary ei=all
351     exe "e! ".tarfile
352     call netrw#NetWrite(tblfile)
353     let &ei     = eikeep
354     let &binary = binkeep
355     q!
356     unlet s:tblfile_{winnr()}
357    endif
358   endif
359   
360   " cleanup and restore current directory
361   cd ..
362   call s:Rmdir("_ZIPVIM_")
363   exe "cd ".escape(curdir,' \')
364   setlocal nomod
366   let &report= repkeep
367 "  call Dret("tar#Write")
368 endfun
370 " ---------------------------------------------------------------------
371 " Rmdir: {{{2
372 fun! s:Rmdir(fname)
373 "  call Dfunc("Rmdir(fname<".a:fname.">)")
374   if has("unix")
375    call system("/bin/rm -rf ".a:fname)
376   elseif has("win32") || has("win95") || has("win64") || has("win16")
377    if &shell =~? "sh$"
378     call system("/bin/rm -rf ".a:fname)
379    else
380     call system("del /S ".a:fname)
381    endif
382   endif
383 "  call Dret("Rmdir")
384 endfun
386 " ------------------------------------------------------------------------
387 " Modelines And Restoration: {{{1
388 let &cpo= s:keepcpo
389 unlet s:keepcpo
390 "  vim:ts=8 fdm=marker