xref: /vim-8.2.3635/runtime/autoload/vimball.vim (revision cb03397a)
1" vimball.vim : construct a file containing both paths and files
2" Author:	Charles E. Campbell
3" Date:		Apr 11, 2016
4" Version:	37
5" GetLatestVimScripts: 1502 1 :AutoInstall: vimball.vim
6" Copyright: (c) 2004-2011 by Charles E. Campbell
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 = "v37"
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')
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 user specify the directory where the vimball is to be unpacked.
224   " If, however, the user did not specify a full path, set the home to be below the current directory
225   let home= expand(a:1)
226   if has("win32") || has("win95") || has("win64") || has("win16")
227	if home !~ '^\a:[/\\]'
228	 let home= getcwd().'/'.a:1
229	endif
230   elseif home !~ '^/'
231	let home= getcwd().'/'.a:1
232   endif
233  else
234   let home= vimball#VimballHome()
235  endif
236"  call Decho("home<".home.">")
237
238  " save current directory and remove older same-named vimball, if any
239  let curdir = getcwd()
240"  call Decho("home<".home.">")
241"  call Decho("curdir<".curdir.">")
242
243  call s:ChgDir(home)
244  let s:ok_unablefind= 1
245  call vimball#RmVimball(vimballfile)
246  unlet s:ok_unablefind
247
248  let linenr  = 4
249  let filecnt = 0
250
251  " give title to listing of (extracted) files from Vimball Archive
252  if a:really
253   echohl Title     | echomsg "Vimball Archive"         | echohl None
254  else
255   echohl Title     | echomsg "Vimball Archive Listing" | echohl None
256   echohl Statement | echomsg "files would be placed under: ".home | echohl None
257  endif
258
259  " apportion vimball contents to various files
260"  call Decho("exe tabn ".curtabnr)
261  exe "tabn ".curtabnr
262"  call Decho("linenr=".linenr." line$=".line("$"))
263  while 1 < linenr && linenr < line("$")
264   let fname   = substitute(getline(linenr),'\t\[\[\[1$','','')
265   let fname   = substitute(fname,'\\','/','g')
266   let fsize   = substitute(getline(linenr+1),'^\(\d\+\).\{-}$','\1','')+0
267   let fenc    = substitute(getline(linenr+1),'^\d\+\s*\(\S\{-}\)$','\1','')
268   let filecnt = filecnt + 1
269"   call Decho("fname<".fname."> fsize=".fsize." filecnt=".filecnt. " fenc=".fenc)
270
271   if a:really
272    echomsg "extracted <".fname.">: ".fsize." lines"
273   else
274    echomsg "would extract <".fname.">: ".fsize." lines"
275   endif
276"   call Decho("using L#".linenr.": will extract file<".fname.">")
277"   call Decho("using L#".(linenr+1).": fsize=".fsize)
278
279   " Allow AsNeeded/ directory to take place of plugin/ directory
280   " when AsNeeded/filename is filereadable or was present in VimballRecord
281   if fname =~ '\<plugin/'
282   	let anfname= substitute(fname,'\<plugin/','AsNeeded/','')
283	if filereadable(anfname) || (exists("s:VBRstring") && s:VBRstring =~# anfname)
284"	 call Decho("using anfname<".anfname."> instead of <".fname.">")
285	 let fname= anfname
286	endif
287   endif
288
289   " make directories if they don't exist yet
290   if a:really
291"    call Decho("making directories if they don't exist yet (fname<".fname.">)")
292    let fnamebuf= substitute(fname,'\\','/','g')
293	let dirpath = substitute(home,'\\','/','g')
294"	call Decho("init: fnamebuf<".fnamebuf.">")
295"	call Decho("init: dirpath <".dirpath.">")
296    while fnamebuf =~ '/'
297     let dirname  = dirpath."/".substitute(fnamebuf,'/.*$','','')
298	 let dirpath  = dirname
299     let fnamebuf = substitute(fnamebuf,'^.\{-}/\(.*\)$','\1','')
300"	 call Decho("dirname<".dirname.">")
301"	 call Decho("dirpath<".dirpath.">")
302     if !isdirectory(dirname)
303"      call Decho("making <".dirname.">")
304      if exists("g:vimball_mkdir")
305	   call system(g:vimball_mkdir." ".shellescape(dirname))
306      else
307       call mkdir(dirname)
308      endif
309	  call s:RecordInVar(home,"rmdir('".dirname."')")
310     endif
311    endwhile
312   endif
313   call s:ChgDir(home)
314
315   " grab specified qty of lines and place into "a" buffer
316   " (skip over path/filename and qty-lines)
317   let linenr   = linenr + 2
318   let lastline = linenr + fsize - 1
319"   call Decho("exe ".linenr.",".lastline."yank a")
320   " no point in handling a zero-length file
321   if lastline >= linenr
322    exe "silent ".linenr.",".lastline."yank a"
323
324    " copy "a" buffer into tab
325"   call Decho('copy "a buffer into tab#'.vbtabnr)
326    exe "tabn ".vbtabnr
327    setlocal ma
328    sil! %d
329    silent put a
330    1
331    sil! d
332
333    " write tab to file
334    if a:really
335     let fnamepath= home."/".fname
336"    call Decho("exe w! ".fnameescape(fnamepath))
337	if fenc != ""
338	 exe "silent w! ++enc=".fnameescape(fenc)." ".fnameescape(fnamepath)
339	else
340	 exe "silent w! ".fnameescape(fnamepath)
341	endif
342	echo "wrote ".fnameescape(fnamepath)
343	call s:RecordInVar(home,"call delete('".fnamepath."')")
344    endif
345
346    " return to tab with vimball
347"   call Decho("exe tabn ".curtabnr)
348    exe "tabn ".curtabnr
349
350    " set up help if its a doc/*.txt file
351"   call Decho("didhelp<".didhelp."> fname<".fname.">")
352    if a:really && didhelp == "" && fname =~ 'doc/[^/]\+\.\(txt\|..x\)$'
353    	let didhelp= substitute(fname,'^\(.*\<doc\)[/\\][^.]*\.\(txt\|..x\)$','\1','')
354"	call Decho("didhelp<".didhelp.">")
355    endif
356   endif
357
358   " update for next file
359"   call Decho("update linenr= [linenr=".linenr."] + [fsize=".fsize."] = ".(linenr+fsize))
360   let linenr= linenr + fsize
361  endwhile
362
363  " set up help
364"  call Decho("about to set up help: didhelp<".didhelp.">")
365  if didhelp != ""
366   let htpath= home."/".didhelp
367"   call Decho("exe helptags ".htpath)
368   exe "helptags ".fnameescape(htpath)
369   echo "did helptags"
370  endif
371
372  " make sure a "Press ENTER..." prompt appears to keep the messages showing!
373  while filecnt <= &ch
374   echomsg " "
375   let filecnt= filecnt + 1
376  endwhile
377
378  " record actions in <.VimballRecord>
379  call s:RecordInFile(home)
380
381  " restore events, delete tab and buffer
382  exe "sil! tabn ".vbtabnr
383  setlocal nomod bh=wipe
384  exe "sil! tabn ".curtabnr
385  exe "sil! tabc! ".vbtabnr
386  call vimball#RestoreSettings()
387  call s:ChgDir(curdir)
388
389"  call Dret("vimball#Vimball")
390endfun
391
392" ---------------------------------------------------------------------
393" vimball#RmVimball: remove any files, remove any directories made by any {{{2
394"               previous vimball extraction based on a file of the current
395"               name.
396"  Usage:  RmVimball  (assume current file is a vimball; remove)
397"          RmVimball vimballname
398fun! vimball#RmVimball(...)
399"  call Dfunc("vimball#RmVimball() a:0=".a:0)
400  if exists("g:vimball_norecord")
401"   call Dret("vimball#RmVimball : (g:vimball_norecord)")
402   return
403  endif
404
405  if a:0 == 0
406   let curfile= expand("%:tr")
407"   call Decho("case a:0=0: curfile<".curfile."> (used expand(%:tr))")
408  else
409   if a:1 =~ '[\/]'
410    call vimball#ShowMesg(s:USAGE,"RmVimball vimballname [path]")
411"    call Dret("vimball#RmVimball : suspect a:1<".a:1.">")
412    return
413   endif
414   let curfile= a:1
415"   call Decho("case a:0=".a:0.": curfile<".curfile.">")
416  endif
417  if curfile =~ '\.vmb$'
418   let curfile= substitute(curfile,'\.vmb','','')
419  elseif curfile =~ '\.vba$'
420   let curfile= substitute(curfile,'\.vba','','')
421  endif
422  if a:0 >= 2
423   let home= expand(a:2)
424  else
425   let home= vimball#VimballHome()
426  endif
427  let curdir = getcwd()
428"  call Decho("home   <".home.">")
429"  call Decho("curfile<".curfile.">")
430"  call Decho("curdir <".curdir.">")
431
432  call s:ChgDir(home)
433  if filereadable(".VimballRecord")
434"   call Decho(".VimballRecord is readable")
435"   call Decho("curfile<".curfile.">")
436   keepalt keepjumps 1split
437   sil! keepalt keepjumps e .VimballRecord
438   let keepsrch= @/
439"   call Decho('search for ^\M'.curfile.'.\m: ')
440"   call Decho('search for ^\M'.curfile.'.\m{vba|vmb}: ')
441"   call Decho('search for ^\M'.curfile.'\m[-0-9.]*\.{vba|vmb}: ')
442   if search('^\M'.curfile."\m: ".'cw')
443	let foundit= 1
444   elseif search('^\M'.curfile.".\mvmb: ",'cw')
445	let foundit= 2
446   elseif search('^\M'.curfile.'\m[-0-9.]*\.vmb: ','cw')
447	let foundit= 2
448   elseif search('^\M'.curfile.".\mvba: ",'cw')
449	let foundit= 1
450   elseif search('^\M'.curfile.'\m[-0-9.]*\.vba: ','cw')
451	let foundit= 1
452   else
453    let foundit = 0
454   endif
455   if foundit
456	if foundit == 1
457	 let exestring  = substitute(getline("."),'^\M'.curfile.'\m\S\{-}\.vba: ','','')
458	else
459	 let exestring  = substitute(getline("."),'^\M'.curfile.'\m\S\{-}\.vmb: ','','')
460	endif
461    let s:VBRstring= substitute(exestring,'call delete(','','g')
462    let s:VBRstring= substitute(s:VBRstring,"[')]",'','g')
463"	call Decho("exe ".exestring)
464	sil! keepalt keepjumps exe exestring
465	sil! keepalt keepjumps d
466	let exestring= strlen(substitute(exestring,'call delete(.\{-})|\=',"D","g"))
467"	call Decho("exestring<".exestring.">")
468	echomsg "removed ".exestring." files"
469   else
470    let s:VBRstring= ''
471	let curfile    = substitute(curfile,'\.vmb','','')
472"    call Decho("unable to find <".curfile."> in .VimballRecord")
473	if !exists("s:ok_unablefind")
474     call vimball#ShowMesg(s:WARNING,"(RmVimball) unable to find <".curfile."> in .VimballRecord")
475	endif
476   endif
477   sil! keepalt keepjumps g/^\s*$/d
478   sil! keepalt keepjumps wq!
479   let @/= keepsrch
480  endif
481  call s:ChgDir(curdir)
482
483"  call Dret("vimball#RmVimball")
484endfun
485
486" ---------------------------------------------------------------------
487" vimball#Decompress: attempts to automatically decompress vimballs {{{2
488fun! vimball#Decompress(fname,...)
489"  call Dfunc("Decompress(fname<".a:fname.">) a:0=".a:0)
490
491  " decompression:
492  if     expand("%") =~ '.*\.gz'  && executable("gunzip")
493   " handle *.gz with gunzip
494   silent exe "!gunzip ".shellescape(a:fname)
495   if v:shell_error != 0
496	call vimball#ShowMesg(s:WARNING,"(vimball#Decompress) gunzip may have failed with <".a:fname.">")
497   endif
498   let fname= substitute(a:fname,'\.gz$','','')
499   exe "e ".escape(fname,' \')
500   if a:0 == 0| call vimball#ShowMesg(s:USAGE,"Source this file to extract it! (:so %)") | endif
501
502  elseif expand("%") =~ '.*\.gz' && executable("gzip")
503   " handle *.gz with gzip -d
504   silent exe "!gzip -d ".shellescape(a:fname)
505   if v:shell_error != 0
506	call vimball#ShowMesg(s:WARNING,'(vimball#Decompress) "gzip -d" may have failed with <'.a:fname.">")
507   endif
508   let fname= substitute(a:fname,'\.gz$','','')
509   exe "e ".escape(fname,' \')
510   if a:0 == 0| call vimball#ShowMesg(s:USAGE,"Source this file to extract it! (:so %)") | endif
511
512  elseif expand("%") =~ '.*\.bz2' && executable("bunzip2")
513   " handle *.bz2 with bunzip2
514   silent exe "!bunzip2 ".shellescape(a:fname)
515   if v:shell_error != 0
516	call vimball#ShowMesg(s:WARNING,"(vimball#Decompress) bunzip2 may have failed with <".a:fname.">")
517   endif
518   let fname= substitute(a:fname,'\.bz2$','','')
519   exe "e ".escape(fname,' \')
520   if a:0 == 0| call vimball#ShowMesg(s:USAGE,"Source this file to extract it! (:so %)") | endif
521
522  elseif expand("%") =~ '.*\.bz2' && executable("bzip2")
523   " handle *.bz2 with bzip2 -d
524   silent exe "!bzip2 -d ".shellescape(a:fname)
525   if v:shell_error != 0
526	call vimball#ShowMesg(s:WARNING,'(vimball#Decompress) "bzip2 -d" may have failed with <'.a:fname.">")
527   endif
528   let fname= substitute(a:fname,'\.bz2$','','')
529   exe "e ".escape(fname,' \')
530   if a:0 == 0| call vimball#ShowMesg(s:USAGE,"Source this file to extract it! (:so %)") | endif
531
532  elseif expand("%") =~ '.*\.zip' && executable("unzip")
533   " handle *.zip with unzip
534   silent exe "!unzip ".shellescape(a:fname)
535   if v:shell_error != 0
536	call vimball#ShowMesg(s:WARNING,"(vimball#Decompress) unzip may have failed with <".a:fname.">")
537   endif
538   let fname= substitute(a:fname,'\.zip$','','')
539   exe "e ".escape(fname,' \')
540   if a:0 == 0| call vimball#ShowMesg(s:USAGE,"Source this file to extract it! (:so %)") | endif
541  endif
542
543  if a:0 == 0| setlocal noma bt=nofile fmr=[[[,]]] fdm=marker | endif
544
545"  call Dret("Decompress")
546endfun
547
548" ---------------------------------------------------------------------
549" vimball#ShowMesg: {{{2
550fun! vimball#ShowMesg(level,msg)
551"  call Dfunc("vimball#ShowMesg(level=".a:level." msg<".a:msg.">)")
552
553  let rulerkeep   = &ruler
554  let showcmdkeep = &showcmd
555  set noruler noshowcmd
556  redraw!
557
558  if &fo =~# '[ta]'
559   echomsg "***vimball*** ".a:msg
560  else
561   if a:level == s:WARNING || a:level == s:USAGE
562    echohl WarningMsg
563   elseif a:level == s:ERROR
564    echohl Error
565   endif
566   echomsg "***vimball*** ".a:msg
567   echohl None
568  endif
569
570  if a:level != s:USAGE
571   call inputsave()|let ok= input("Press <cr> to continue")|call inputrestore()
572  endif
573
574  let &ruler   = rulerkeep
575  let &showcmd = showcmdkeep
576
577"  call Dret("vimball#ShowMesg")
578endfun
579" =====================================================================
580" s:ChgDir: change directory (in spite of Windoze) {{{2
581fun! s:ChgDir(newdir)
582"  call Dfunc("ChgDir(newdir<".a:newdir.">)")
583  if (has("win32") || has("win95") || has("win64") || has("win16"))
584   try
585    exe 'silent cd '.fnameescape(substitute(a:newdir,'/','\\','g'))
586   catch  /^Vim\%((\a\+)\)\=:E/
587    call mkdir(fnameescape(substitute(a:newdir,'/','\\','g')))
588    exe 'silent cd '.fnameescape(substitute(a:newdir,'/','\\','g'))
589   endtry
590  else
591   try
592    exe 'silent cd '.fnameescape(a:newdir)
593   catch  /^Vim\%((\a\+)\)\=:E/
594    call mkdir(fnameescape(a:newdir))
595    exe 'silent cd '.fnameescape(a:newdir)
596   endtry
597  endif
598"  call Dret("ChgDir : curdir<".getcwd().">")
599endfun
600
601" ---------------------------------------------------------------------
602" s:RecordInVar: record a un-vimball command in the .VimballRecord file {{{2
603fun! 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 : "").">")
617endfun
618
619" ---------------------------------------------------------------------
620" s:RecordInFile: {{{2
621fun! 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
627
628  if exists("s:recordfile") || exists("s:recorddir")
629   let curdir= getcwd()
630   call s:ChgDir(a:home)
631   keepalt keepjumps 1split
632
633   let cmd= expand("%:tr").": "
634"   call Decho("cmd<".cmd.">")
635
636   sil! 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.">")
650
651   " put command into buffer, write .VimballRecord `file
652   keepalt keepjumps put=cmd
653   sil! keepalt keepjumps g/^\s*$/d
654   sil! keepalt keepjumps wq!
655   call s:ChgDir(curdir)
656
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
668
669"  call Dret("s:RecordInFile")
670endfun
671
672" ---------------------------------------------------------------------
673" vimball#VimballHome: determine/get home directory path (usually from rtp) {{{2
674fun! vimball#VimballHome()
675"  call Dfunc("vimball#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." ".shellescape(home).")")
702    call system(g:vimball_mkdir." ".shellescape(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("vimball#VimballHome <".home.">")
709  return home
710endfun
711
712" ---------------------------------------------------------------------
713" vimball#SaveSettings: {{{2
714fun! 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 = &l: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  = &l:ff
730  let s:swfkeep = &l:swf
731  if exists("+acd")
732   setlocal ei=all ve=all noacd nofen noic report=999 nohid bt= ma lz pm= ff=unix noswf
733  else
734   setlocal ei=all ve=all       nofen noic report=999 nohid bt= ma lz pm= ff=unix noswf
735  endif
736  " vimballs should be in unix format
737  setlocal ff=unix
738"  call Dret("SaveSettings")
739endfun
740
741" ---------------------------------------------------------------------
742" vimball#RestoreSettings: {{{2
743fun! vimball#RestoreSettings()
744"  call Dfunc("RestoreSettings()")
745  let @a      = s:regakeep
746  if exists("+acd")
747   let &acd   = s:acdkeep
748  endif
749  let &l:fen  = s:fenkeep
750  let &hidden = s:hidkeep
751  let &ic     = s:ickeep
752  let &lz     = s:lzkeep
753  let &pm     = s:pmkeep
754  let &report = s:repkeep
755  let &ve     = s:vekeep
756  let &ei     = s:eikeep
757  let &l:ff   = s:ffkeep
758  if s:makeep[0] != 0
759   " restore mark a
760"   call Decho("restore mark-a: makeep=".string(makeep))
761   call setpos("'a",s:makeep)
762  endif
763  if exists("+acd")
764   unlet s:acdkeep
765  endif
766  unlet s:regakeep s:eikeep s:fenkeep s:hidkeep s:ickeep s:repkeep s:vekeep s:makeep s:lzkeep s:pmkeep s:ffkeep
767"  call Dret("RestoreSettings")
768endfun
769
770let &cpo = s:keepcpo
771unlet s:keepcpo
772
773" ---------------------------------------------------------------------
774" Modelines: {{{1
775" vim: fdm=marker
776