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