Merged from the latest developing branch.
[MacVim.git] / runtime / autoload / vimball.vim
blobd69c64532d1520c3bbd6640b3a19d890dcf52673
1 " vimball.vim : construct a file containing both paths and files
2 " Author:       Charles E. Campbell, Jr.
3 " Date:         Jun 05, 2008
4 " Version:      27
5 " GetLatestVimScripts: 1502 1 :AutoInstall: vimball.vim
6 " Copyright: (c) 2004-2008 by Charles E. Campbell, Jr.
7 "            The VIM LICENSE applies to Vimball.vim, and Vimball.txt
8 "            (see |copyright|) except use "Vimball" instead of "Vim".
9 "            No warranty, express or implied.
10 "  *** ***   Use At-Your-Own-Risk!   *** ***
12 " ---------------------------------------------------------------------
13 "  Load Once: {{{1
14 if &cp || exists("g:loaded_vimball") || v:version < 700
15  finish
16 endif
17 let s:keepcpo        = &cpo
18 let g:loaded_vimball = "v27"
19 set cpo&vim
20 "DechoTabOn
22 " =====================================================================
23 " Constants: {{{1
24 if !exists("s:USAGE")
25  let s:USAGE   = 0
26  let s:WARNING = 1
27  let s:ERROR   = 2
29  " determine if cygwin is in use or not
30  if !exists("g:netrw_cygwin")
31   if has("win32") || has("win95") || has("win64") || has("win16")
32    if &shell =~ '\%(\<bash\>\|\<zsh\>\)\%(\.exe\)\=$'
33     let g:netrw_cygwin= 1
34    else
35     let g:netrw_cygwin= 0
36    endif
37   else
38    let g:netrw_cygwin= 0
39   endif
40  endif
42  " set up g:vimball_mkdir if the mkdir() call isn't defined
43  if !exists("*mkdir")
44   if exists("g:netrw_local_mkdir")
45    let g:vimball_mkdir= g:netrw_local_mkdir
46   elseif executable("mkdir")
47    let g:vimball_mkdir= "mkdir"
48   elseif executable("makedir")
49    let g:vimball_mkdir= "makedir"
50   endif
51   if !exists(g:vimball_mkdir)
52    call vimball#ShowMesg(s:WARNING,"(vimball) g:vimball_mkdir undefined")
53   endif
54  endif
56  " set up shell quoting character
57  if exists("g:vimball_shq") && !exists("g:netrw_shq")
58   let g:netrw_shq= g:vimball_shq
59  endif
60  if !exists("g:netrw_shq")
61   if exists("&shq") && &shq != ""
62    let g:netrw_shq= &shq
63   elseif has("win32") || has("win95") || has("win64") || has("win16")
64    if g:netrw_cygwin
65     let g:netrw_shq= "'"
66    else
67     let g:netrw_shq= '"'
68    endif
69   else
70    let g:netrw_shq= "'"
71   endif
72 " call Decho("g:netrw_shq<".g:netrw_shq.">")
73  endif
75  " set up escape string (used to protect paths)
76  if !exists("g:vimball_path_escape")
77   let g:vimball_path_escape= ' ;#%'
78  endif
79 endif
81 " =====================================================================
82 "  Functions: {{{1
84 " ---------------------------------------------------------------------
85 " vimball#MkVimball: creates a vimball given a list of paths to files {{{2
86 " Input:
87 "     line1,line2: a range of lines containing paths to files to be included in the vimball
88 "     writelevel : if true, force a write to filename.vba, even if it exists
89 "                  (usually accomplished with :MkVimball! ...
90 "     filename   : base name of file to be created (ie. filename.vba)
91 " Output: a filename.vba using vimball format:
92 "     path
93 "     filesize
94 "     [file]
95 "     path
96 "     filesize
97 "     [file]
98 fun! vimball#MkVimball(line1,line2,writelevel,...) range
99 "  call Dfunc("MkVimball(line1=".a:line1." line2=".a:line2." writelevel=".a:writelevel." vimballname<".a:1.">) a:0=".a:0)
100   if a:1 =~ '\.vim$' || a:1 =~ '\.txt$'
101    let vbname= substitute(a:1,'\.\a\{3}$','.vba','')
102   else
103    let vbname= a:1
104   endif
105   if vbname !~ '\.vba$'
106    let vbname= vbname.'.vba'
107   endif
108 "  call Decho("vbname<".vbname.">")
109   if a:1 =~ '[\/]'
110    call vimball#ShowMesg(s:ERROR,"(MkVimball) vimball name<".a:1."> should not include slashes")
111 "   call Dret("MkVimball : vimball name<".a:1."> should not include slashes")
112    return
113   endif
114   if !a:writelevel && filereadable(vbname)
115    call vimball#ShowMesg(s:ERROR,"(MkVimball) file<".vbname."> exists; use ! to insist")
116 "   call Dret("MkVimball : file<".vbname."> already exists; use ! to insist")
117    return
118   endif
120   " user option bypass
121   call vimball#SaveSettings()
123   if a:0 >= 2
124    " allow user to specify where to get the files
125    let home= expand(a:2)
126   else
127    " use first existing directory from rtp
128    let home= s:VimballHome()
129   endif
131   " save current directory
132   let curdir = getcwd()
133   call s:ChgDir(home)
135   " record current tab, initialize while loop index
136   let curtabnr = tabpagenr()
137   let linenr   = a:line1
138 "  call Decho("curtabnr=".curtabnr)
140   while linenr <= a:line2
141    let svfile  = getline(linenr)
142 "   call Decho("svfile<".svfile.">")
144    if !filereadable(svfile)
145     call vimball#ShowMesg(s:ERROR,"unable to read file<".svfile.">")
146         call s:ChgDir(curdir)
147         call vimball#RestoreSettings()
148 "    call Dret("MkVimball")
149     return
150    endif
152    " create/switch to mkvimball tab
153    if !exists("vbtabnr")
154     tabnew
155     silent! file Vimball
156     let vbtabnr= tabpagenr()
157    else
158     exe "tabn ".vbtabnr
159    endif
161    let lastline= line("$") + 1
162    if lastline == 2 && getline("$") == ""
163         call setline(1,'" Vimball Archiver by Charles E. Campbell, Jr., Ph.D.')
164         call setline(2,'UseVimball')
165         call setline(3,'finish')
166         let lastline= line("$") + 1
167    endif
168    call setline(lastline  ,substitute(svfile,'$','      [[[1',''))
169    call setline(lastline+1,0)
171    " write the file from the tab
172    let svfilepath= s:Path(svfile,'')
173 "   call Decho("exe $r ".fnameescape(svfilepath))
174    exe "$r ".fnameescape(svfilepath)
176    call setline(lastline+1,line("$") - lastline - 1)
177 "   call Decho("lastline=".lastline." line$=".line("$"))
179   " restore to normal tab
180    exe "tabn ".curtabnr
181    let linenr= linenr + 1
182   endwhile
184   " write the vimball
185   exe "tabn ".vbtabnr
186   call s:ChgDir(curdir)
187   setlocal ff=unix
188   if a:writelevel
189    let vbnamepath= s:Path(vbname,'')
190 "   call Decho("exe w! ".fnameescape(vbnamepath))
191    exe "w! ".fnameescape(vbnamepath)
192   else
193    let vbnamepath= s:Path(vbname,'')
194 "   call Decho("exe w ".fnameescape(vbnamepath))
195    exe "w ".fnameescape(vbnamepath)
196   endif
197 "  call Decho("Vimball<".vbname."> created")
198   echo "Vimball<".vbname."> created"
200   " remove the evidence
201   setlocal nomod bh=wipe
202   exe "tabn ".curtabnr
203   exe "tabc ".vbtabnr
205   " restore options
206   call vimball#RestoreSettings()
208 "  call Dret("MkVimball")
209 endfun
211 " ---------------------------------------------------------------------
212 " vimball#Vimball: extract and distribute contents from a vimball {{{2
213 "                  (invoked the the UseVimball command embedded in 
214 "                  vimballs' prologue)
215 fun! vimball#Vimball(really,...)
216 "  call Dfunc("vimball#Vimball(really=".a:really.") a:0=".a:0)
218   if v:version < 701 || (v:version == 701 && !has("patch299"))
219    echoerr "This version of vimball requires vim 7.1 with patch 299"
220 "   call Dret("vimball#Vimball : needs 7.1 with patch 299")
221    return
222   endif
224   if getline(1) !~ '^" Vimball Archiver by Charles E. Campbell, Jr., Ph.D.$'
225    echoerr "(Vimball) The current file does not appear to be a Vimball!"
226 "   call Dret("vimball#Vimball")
227    return
228   endif
230   " set up standard settings
231   call vimball#SaveSettings()
232   let curtabnr    = tabpagenr()
233   let vimballfile = expand("%:tr")
235   " set up vimball tab
236 "  call Decho("setting up vimball tab")
237   tabnew
238   silent! file Vimball
239   let vbtabnr= tabpagenr()
240   let didhelp= ""
242   " go to vim plugin home
243   if a:0 > 0
244    let home= expand(a:1)
245   else
246    let home= s:VimballHome()
247   endif
248 "  call Decho("home<".home.">")
250   " save current directory and remove older same-named vimball, if any
251   let curdir = getcwd()
252 "  call Decho("home<".home.">")
253 "  call Decho("curdir<".curdir.">")
255   call s:ChgDir(home)
256   let s:ok_unablefind= 1
257   call vimball#RmVimball(vimballfile)
258   unlet s:ok_unablefind
260   let linenr  = 4
261   let filecnt = 0
263   " give title to listing of (extracted) files from Vimball Archive
264   if a:really
265    echohl Title     | echomsg "Vimball Archive"         | echohl None
266   else             
267    echohl Title     | echomsg "Vimball Archive Listing" | echohl None
268    echohl Statement | echomsg "files would be placed under: ".home | echohl None
269   endif
271   " apportion vimball contents to various files
272 "  call Decho("exe tabn ".curtabnr)
273   exe "tabn ".curtabnr
274 "  call Decho("linenr=".linenr." line$=".line("$"))
275   while 1 < linenr && linenr < line("$")
276    let fname   = substitute(getline(linenr),'\t\[\[\[1$','','')
277    let fname   = substitute(fname,'\\','/','g')
278    let fsize   = getline(linenr+1)+0
279    let filecnt = filecnt + 1
280 "   call Decho("fname<".fname."> fsize=".fsize." filecnt=".filecnt)
282    if a:really
283     echomsg "extracted <".fname.">: ".fsize." lines"
284    else
285     echomsg "would extract <".fname.">: ".fsize." lines"
286    endif
287 "   call Decho("using L#".linenr.": will extract file<".fname.">")
288 "   call Decho("using L#".(linenr+1).": fsize=".fsize)
290    " Allow AsNeeded/ directory to take place of plugin/ directory
291    " when AsNeeded/filename is filereadable or was present in VimballRecord
292    if fname =~ '\<plugin/'
293         let anfname= substitute(fname,'\<plugin/','AsNeeded/','')
294         if filereadable(anfname) || (exists("s:VBRstring") && s:VBRstring =~ anfname)
295 "        call Decho("using anfname<".anfname."> instead of <".fname.">")
296          let fname= anfname
297         endif
298    endif
300    " make directories if they don't exist yet
301    if a:really
302 "    call Decho("making directories if they don't exist yet (fname<".fname.">)")
303     let fnamebuf= substitute(fname,'\\','/','g')
304         let dirpath = substitute(home,'\\','/','g')
305     while fnamebuf =~ '/'
306      let dirname  = dirpath."/".substitute(fnamebuf,'/.*$','','')
307          let dirpath  = dirname
308      let fnamebuf = substitute(fnamebuf,'^.\{-}/\(.*\)$','\1','')
309 "        call Decho("dirname<".dirname.">")
310      if !isdirectory(dirname)
311 "      call Decho("making <".dirname.">")
312       if exists("g:vimball_mkdir")
313            call system(g:vimball_mkdir." ".s:Escape(dirname))
314       else
315        call mkdir(dirname)
316       endif
317           call s:RecordInVar(home,"rmdir('".dirname."')")
318      endif
319     endwhile
320    endif
321    call s:ChgDir(home)
323    " grab specified qty of lines and place into "a" buffer
324    " (skip over path/filename and qty-lines)
325    let linenr   = linenr + 2
326    let lastline = linenr + fsize - 1
327 "   call Decho("exe ".linenr.",".lastline."yank a")
328    exe "silent ".linenr.",".lastline."yank a"
330    " copy "a" buffer into tab
331 "   call Decho('copy "a buffer into tab#'.vbtabnr)
332    exe "tabn ".vbtabnr
333    setlocal ma
334    silent! %d
335    silent put a
336    1
337    silent d
339    " write tab to file
340    if a:really
341     let fnamepath= s:Path(home."/".fname,'')
342 "    call Decho("exe w! ".fnameescape(fnamepath))
343         exe "silent w! ".fnameescape(fnamepath)
344     echo "wrote ".fnamepath
345         call s:RecordInVar(home,"call delete('".fnameescape(fnamepath)."')")
346    endif
348    " return to tab with vimball
349 "   call Decho("exe tabn ".curtabnr)
350    exe "tabn ".curtabnr
352    " set up help if its a doc/*.txt file
353 "   call Decho("didhelp<".didhelp."> fname<".fname.">")
354    if a:really && didhelp == "" && fname =~ 'doc/[^/]\+\.\(txt\|..x\)$'
355         let didhelp= substitute(fname,'^\(.*\<doc\)[/\\][^.]*\.\(txt\|..x\)$','\1','')
356 "       call Decho("didhelp<".didhelp.">")
357    endif
359    " update for next file
360 "   call Decho("update linenr= [linenr=".linenr."] + [fsize=".fsize."] = ".(linenr+fsize))
361    let linenr= linenr + fsize
362   endwhile
364   " set up help
365 "  call Decho("about to set up help: didhelp<".didhelp.">")
366   if didhelp != ""
367    let htpath= s:Path(home."/".didhelp,"")
368 "   call Decho("exe helptags ".htpath)
369    exe "helptags ".htpath
370    echo "did helptags"
371   endif
373   " make sure a "Press ENTER..." prompt appears to keep the messages showing!
374   while filecnt <= &ch
375    echomsg " "
376    let filecnt= filecnt + 1
377   endwhile
379   " record actions in <.VimballRecord>
380   call s:RecordInFile(home)
382   " restore events, delete tab and buffer
383   exe "tabn ".vbtabnr
384   setlocal nomod bh=wipe
385   exe "tabn ".curtabnr
386   exe "tabc ".vbtabnr
387   call vimball#RestoreSettings()
388   call s:ChgDir(curdir)
390 "  call Dret("vimball#Vimball")
391 endfun
393 " ---------------------------------------------------------------------
394 " vimball#RmVimball: remove any files, remove any directories made by any {{{2
395 "               previous vimball extraction based on a file of the current
396 "               name.
397 "  Usage:  RmVimball  (assume current file is a vimball; remove)
398 "          RmVimball vimballname
399 fun! vimball#RmVimball(...)
400 "  call Dfunc("vimball#RmVimball() a:0=".a:0)
401   if exists("g:vimball_norecord")
402 "   call Dret("vimball#RmVimball : (g:vimball_norecord)")
403    return
404   endif
406   if a:0 == 0
407    let curfile= expand("%:tr")
408 "   call Decho("case a:0=0: curfile<".curfile."> (used expand(%:tr))")
409   else
410    if a:1 =~ '[\/]'
411     call vimball#ShowMesg(s:USAGE,"RmVimball vimballname [path]")
412 "    call Dret("vimball#RmVimball : suspect a:1<".a:1.">")
413     return
414    endif
415    let curfile= a:1
416 "   call Decho("case a:0=".a:0.": curfile<".curfile.">")
417   endif
418   if curfile =~ '\.vba$'
419    let curfile= substitute(curfile,'\.vba','','')
420   endif
421   if a:0 >= 2
422    let home= expand(a:2)
423   else
424    let home= s:VimballHome()
425   endif
426   let curdir = getcwd()
427 "  call Decho("home   <".home.">")
428 "  call Decho("curfile<".curfile.">")
429 "  call Decho("curdir <".curdir.">")
431   call s:ChgDir(home)
432   if filereadable(".VimballRecord")
433 "   call Decho(".VimballRecord is readable")
434 "   call Decho("curfile<".curfile.">")
435    keepalt keepjumps 1split 
436    silent! keepalt keepjumps e .VimballRecord
437    let keepsrch= @/
438 "   call Decho("search for ^".curfile.".vba:")
439 "   call Decho("search for ^".curfile."[-0-9.]*.vba:")
440    if search('^'.curfile.": ".'cw')
441         let foundit= 1
442    elseif search('^'.curfile.".vba: ",'cw')
443         let foundit= 1
444    elseif search('^'.curfile.'[-0-9.]*.vba: ','cw')
445         let foundit= 1
446    else
447     let foundit = 0
448    endif
449    if foundit
450         let exestring  = substitute(getline("."),'^'.curfile.'\S\{-}\.vba: ','','')
451     let s:VBRstring= substitute(exestring,'call delete(','','g')
452     let s:VBRstring= substitute(s:VBRstring,"[')]",'','g')
453 "       call Decho("exe ".exestring)
454         silent! keepalt keepjumps exe exestring
455         silent! keepalt keepjumps d
456         let exestring= strlen(substitute(exestring,'call delete(.\{-})|\=',"D","g"))
457 "       call Decho("exestring<".exestring.">")
458         echomsg "removed ".exestring." files"
459    else
460     let s:VBRstring= ''
461         let curfile    = substitute(curfile,'\.vba','','')
462 "    call Decho("unable to find <".curfile."> in .VimballRecord")
463         if !exists("s:ok_unablefind")
464      call vimball#ShowMesg(s:WARNING,"(RmVimball) unable to find <".curfile."> in .VimballRecord")
465         endif
466    endif
467    silent! keepalt keepjumps g/^\s*$/d
468    silent! keepalt keepjumps wq!
469    let @/= keepsrch
470   endif
471   call s:ChgDir(curdir)
473 "  call Dret("vimball#RmVimball")
474 endfun
476 " ---------------------------------------------------------------------
477 " vimball#Decompress: attempts to automatically decompress vimballs {{{2
478 fun! vimball#Decompress(fname)
479 "  call Dfunc("Decompress(fname<".a:fname.">)")
481   " decompression:
482   if     expand("%") =~ '.*\.gz'  && executable("gunzip")
483    " handle *.gz with gunzip
484    silent exe "!gunzip ".s:Escape(a:fname)
485    if v:shell_error != 0
486         call vimball#ShowMesg(s:WARNING,"(vimball#Decompress) gunzip may have failed with <".a:fname.">")
487    endif
488    let fname= substitute(a:fname,'\.gz$','','')
489    exe "e ".escape(fname,' \')
490    call vimball#ShowMesg(s:USAGE,"Source this file to extract it! (:so %)")
492   elseif expand("%") =~ '.*\.gz' && executable("gzip")
493    " handle *.gz with gzip -d
494    silent exe "!gzip -d ".s:Escape(a:fname)
495    if v:shell_error != 0
496         call vimball#ShowMesg(s:WARNING,'(vimball#Decompress) "gzip -d" may have failed with <'.a:fname.">")
497    endif
498    let fname= substitute(a:fname,'\.gz$','','')
499    exe "e ".escape(fname,' \')
500    call vimball#ShowMesg(s:USAGE,"Source this file to extract it! (:so %)")
502   elseif expand("%") =~ '.*\.bz2' && executable("bunzip2")
503    " handle *.bz2 with bunzip2
504    silent exe "!bunzip2 ".s:Escape(a:fname)
505    if v:shell_error != 0
506         call vimball#ShowMesg(s:WARNING,"(vimball#Decompress) bunzip2 may have failed with <".a:fname.">")
507    endif
508    let fname= substitute(a:fname,'\.bz2$','','')
509    exe "e ".escape(fname,' \')
510    call vimball#ShowMesg(s:USAGE,"Source this file to extract it! (:so %)")
512   elseif expand("%") =~ '.*\.bz2' && executable("bzip2")
513    " handle *.bz2 with bzip2 -d
514    silent exe "!bzip2 -d ".s:Escape(a:fname)
515    if v:shell_error != 0
516         call vimball#ShowMesg(s:WARNING,'(vimball#Decompress) "bzip2 -d" may have failed with <'.a:fname.">")
517    endif
518    let fname= substitute(a:fname,'\.bz2$','','')
519    exe "e ".escape(fname,' \')
520    call vimball#ShowMesg(s:USAGE,"Source this file to extract it! (:so %)")
522   elseif expand("%") =~ '.*\.zip' && executable("unzip")
523    " handle *.zip with unzip
524    silent exe "!unzip ".s:Escape(a:fname)
525    if v:shell_error != 0
526         call vimball#ShowMesg(s:WARNING,"(vimball#Decompress) unzip may have failed with <".a:fname.">")
527    endif
528    let fname= substitute(a:fname,'\.zip$','','')
529    exe "e ".escape(fname,' \')
530    call vimball#ShowMesg(s:USAGE,"Source this file to extract it! (:so %)")
531   endif
533   set noma bt=nofile fmr=[[[,]]] fdm=marker
535 "  call Dret("Decompress")
536 endfun
538 " ---------------------------------------------------------------------
539 " vimball#ShowMesg: {{{2
540 fun! vimball#ShowMesg(level,msg)
541 "  call Dfunc("vimball#ShowMesg(level=".a:level." msg<".a:msg.">)")
542   let rulerkeep   = &ruler
543   let showcmdkeep = &showcmd
544   set noruler noshowcmd
545   redraw!
547   if &fo =~ '[ta]'
548    echomsg "***vimball*** " a:msg
549   else
550    if a:level == s:WARNING || a:level == s:USAGE
551     echohl WarningMsg
552    elseif a:level == s:ERROR
553     echohl Error
554    endif
555    echomsg "***vimball*** " a:msg
556    echohl None
557   endif
559   if a:level != s:USAGE
560    call inputsave()|let ok= input("Press <cr> to continue")|call inputrestore()
561   endif
563   let &ruler   = rulerkeep
564   let &showcmd = showcmdkeep
566 "  call Dret("vimball#ShowMesg")
567 endfun
568 " =====================================================================
569 " s:ChgDir: change directory (in spite of Windoze) {{{2
570 fun! s:ChgDir(newdir)
571 "  call Dfunc("ChgDir(newdir<".a:newdir.">)")
572   if (has("win32") || has("win95") || has("win64") || has("win16"))
573    exe 'silent cd '.fnameescape(substitute(a:newdir,'/','\\','g'))
574   else
575    exe 'silent cd '.fnameescape(a:newdir)
576   endif
577 "  call Dret("ChgDir : curdir<".getcwd().">")
578 endfun
580 " ---------------------------------------------------------------------
581 " s:Path: prepend and append quotes and do escaping {{{2
582 fun! s:Path(cmd,quote)
583 "  call Dfunc("Path(cmd<".a:cmd."> quote<".a:quote.">) vimball_path_escape<".g:vimball_path_escape.">")
584   if (has("win32") || has("win95") || has("win64") || has("win16"))
585 "   let cmdpath= a:quote.substitute(a:cmd,'/','\\','g').a:quote
586    let cmdpath= a:quote.substitute(a:cmd,'\\','/','g').a:quote
587 "   call Decho("cmdpath<".cmdpath."> (win32 mod)")
588   else
589    let cmdpath= a:quote.a:cmd.a:quote
590 "   call Decho("cmdpath<".cmdpath."> (not-win32 mod)")
591   endif
592   if a:quote == "" && g:vimball_path_escape !~ ' '
593    let cmdpath= escape(cmdpath,' ')
594 "   call Decho("cmdpath<".cmdpath."> (empty quote case)")
595   endif
596   let cmdpath= escape(cmdpath,g:vimball_path_escape)
597 "  call Dret("Path <".cmdpath.">")
598   return cmdpath
599 endfun
601 " ---------------------------------------------------------------------
602 " s:RecordInVar: record a un-vimball command in the .VimballRecord file {{{2
603 fun! s:RecordInVar(home,cmd)
604 "  call Dfunc("RecordInVar(home<".a:home."> cmd<".a:cmd.">)")
605   if a:cmd =~ '^rmdir'
606 "   if !exists("s:recorddir")
607 "    let s:recorddir= substitute(a:cmd,'^rmdir',"call s:Rmdir",'')
608 "   else
609 "    let s:recorddir= s:recorddir."|".substitute(a:cmd,'^rmdir',"call s:Rmdir",'')
610 "   endif
611   elseif !exists("s:recordfile")
612    let s:recordfile= a:cmd
613   else
614    let s:recordfile= s:recordfile."|".a:cmd
615   endif
616 "  call Dret("RecordInVar : s:recordfile<".(exists("s:recordfile")? s:recordfile : "")."> s:recorddir<".(exists("s:recorddir")? s:recorddir : "").">")
617 endfun
619 " ---------------------------------------------------------------------
620 " s:RecordInFile: {{{2
621 fun! s:RecordInFile(home)
622 "  call Dfunc("s:RecordInFile()")
623   if exists("g:vimball_norecord")
624 "   call Dret("s:RecordInFile : g:vimball_norecord")
625    return
626   endif
628   if exists("s:recordfile") || exists("s:recorddir")
629    let curdir= getcwd()
630    call s:ChgDir(a:home)
631    keepalt keepjumps 1split 
633    let cmd= expand("%:tr").": "
634 "   call Decho("cmd<".cmd.">")
636    silent! keepalt keepjumps e .VimballRecord
637    setlocal ma
638    $
639    if exists("s:recordfile") && exists("s:recorddir")
640         let cmd= cmd.s:recordfile."|".s:recorddir
641    elseif exists("s:recorddir")
642         let cmd= cmd.s:recorddir
643    elseif exists("s:recordfile")
644         let cmd= cmd.s:recordfile
645    else
646 "    call Dret("s:RecordInFile : neither recordfile nor recorddir exist")
647         return
648    endif
649 "   call Decho("cmd<".cmd.">")
651    " put command into buffer, write .VimballRecord `file
652    keepalt keepjumps put=cmd
653    silent! keepalt keepjumps g/^\s*$/d
654    silent! keepalt keepjumps wq!
655    call s:ChgDir(curdir)
657    if exists("s:recorddir")
658 "       call Decho("unlet s:recorddir<".s:recorddir.">")
659         unlet s:recorddir
660    endif
661    if exists("s:recordfile")
662 "       call Decho("unlet s:recordfile<".s:recordfile.">")
663         unlet s:recordfile
664    endif
665   else
666 "   call Decho("s:record[file|dir] doesn't exist")
667   endif
669 "  call Dret("s:RecordInFile")
670 endfun
672 " ---------------------------------------------------------------------
673 " s:VimballHome: determine/get home directory path (usually from rtp) {{{2
674 fun! s:VimballHome()
675 "  call Dfunc("VimballHome()")
676   if exists("g:vimball_home")
677    let home= g:vimball_home
678   else
679    " go to vim plugin home
680    for home in split(&rtp,',') + ['']
681     if isdirectory(home) && filewritable(home) | break | endif
682         let basehome= substitute(home,'[/\\]\.vim$','','')
683     if isdirectory(basehome) && filewritable(basehome)
684          let home= basehome."/.vim"
685          break
686         endif
687    endfor
688    if home == ""
689     " just pick the first directory
690     let home= substitute(&rtp,',.*$','','')
691    endif
692    if (has("win32") || has("win95") || has("win64") || has("win16"))
693     let home= substitute(home,'/','\\','g')
694    endif
695   endif
696   " insure that the home directory exists
697 "  call Decho("picked home<".home.">")
698   if !isdirectory(home)
699    if exists("g:vimball_mkdir")
700 "       call Decho("home<".home."> isn't a directory -- making it now with g:vimball_mkdir<".g:vimball_mkdir.">")
701 "    call Decho("system(".g:vimball_mkdir." ".s:Escape(home).")")
702     call system(g:vimball_mkdir." ".s:Escape(home))
703    else
704 "       call Decho("home<".home."> isn't a directory -- making it now with mkdir()")
705     call mkdir(home)
706    endif
707   endif
708 "  call Dret("VimballHome <".home.">")
709   return home
710 endfun
712 " ---------------------------------------------------------------------
713 " vimball#SaveSettings: {{{2
714 fun! vimball#SaveSettings()
715 "  call Dfunc("SaveSettings()")
716   let s:makeep  = getpos("'a")
717   let s:regakeep= @a
718   if exists("&acd")
719    let s:acdkeep = &acd
720   endif
721   let s:eikeep  = &ei
722   let s:fenkeep = &fen
723   let s:hidkeep = &hidden
724   let s:ickeep  = &ic
725   let s:lzkeep  = &lz
726   let s:pmkeep  = &pm
727   let s:repkeep = &report
728   let s:vekeep  = &ve
729   let s:ffkeep  = &ff
730   if exists("&acd")
731    setlocal ei=all ve=all noacd nofen noic report=999 nohid bt= ma lz pm= ff=unix
732   else
733    setlocal ei=all ve=all       nofen noic report=999 nohid bt= ma lz pm= ff=unix
734   endif
735   " vimballs should be in unix format
736   setlocal ff=unix
737 "  call Dret("SaveSettings")
738 endfun
740 " ---------------------------------------------------------------------
741 " vimball#RestoreSettings: {{{2
742 fun! vimball#RestoreSettings()
743 "  call Dfunc("RestoreSettings()")
744   let @a      = s:regakeep
745   if exists("&acd")
746    let &acd   = s:acdkeep
747   endif
748   let &fen    = s:fenkeep
749   let &hidden = s:hidkeep
750   let &ic     = s:ickeep
751   let &lz     = s:lzkeep
752   let &pm     = s:pmkeep
753   let &report = s:repkeep
754   let &ve     = s:vekeep
755   let &ei     = s:eikeep
756   let &ff     = s:ffkeep
757   if s:makeep[0] != 0
758    " restore mark a
759 "   call Decho("restore mark-a: makeep=".string(makeep))
760    call setpos("'a",s:makeep)
761   endif
762   if exists("&acd")
763    unlet s:acdkeep
764   endif
765   unlet s:regakeep s:eikeep s:fenkeep s:hidkeep s:ickeep s:repkeep s:vekeep s:makeep s:lzkeep s:pmkeep s:ffkeep
766 "  call Dret("RestoreSettings")
767 endfun
769 " ---------------------------------------------------------------------
770 " s:Escape: {{{2
771 fun s:Escape(name)
772   " shellescape() was added by patch 7.0.111
773   if exists("*shellescape")
774     return shellescape(a:name)
775   endif
776   return g:netrw_shq . a:name . g:netrw_shq
777 endfun
779 " ---------------------------------------------------------------------
780 "  Restore:
781 let &cpo= s:keepcpo
782 unlet s:keepcpo
784 " ---------------------------------------------------------------------
785 " Modelines: {{{1
786 " vim: fdm=marker