" vimball.vim : construct a file containing both paths and files
" Maintainer: This runtime file is looking for a new maintainer.
" Original Author: Charles E. Campbell
-" Date: Jun 29, 2026
+" Date: Jul 23, 2026
" Version: 37 (with modifications from the Vim Project)
" GetLatestVimScripts: 1502 1 :AutoInstall: vimball.vim
" Copyright: (c) 2004-2011 by Charles E. Campbell
finish
endif
let g:loaded_vimball = "v37"
-if v:version < 704
+if v:version < 900
echohl WarningMsg
- echo "***warning*** this version of vimball needs vim 7.4"
+ echo "***warning*** this version of vimball needs vim 9.0"
echohl Normal
finish
endif
bw! Vimball
call s:ChgDir(curdir)
return
+ elseif fname =~? '\%(^\|/\)\.VimballRecord$'
+ echomsg "(Vimball) Forbidding .VimballRecord filename, aborting..."
+ exe "tabn ".curtabnr
+ bw! Vimball
+ call s:ChgDir(curdir)
+ return
endif
if a:really
let fnamebuf = substitute(fnamebuf,'^.\{-}/\(.*\)$','\1','')
if !isdirectory(dirname)
call mkdir(dirname)
- call s:RecordInVar(home,"rmdir('".dirname."')")
+ call s:RecordDirInVar(dirname)
endif
endwhile
endif
exe "silent w! ".fnameescape(fnamepath)
endif
echo "wrote ".fnameescape(fnamepath)
- call s:RecordInVar(home,"call delete('".escape(fnamepath, '"''|')."')")
+ call s:RecordInVar(fnamepath)
endif
" return to tab with vimball
endif
let s:VBRstring= substitute(exestring,'call delete(','','g')
let s:VBRstring= substitute(s:VBRstring,"[')]",'','g')
- sil! keepalt keepjumps exe exestring
+ let nr_files= 0
+ for line in split(exestring, '|')
+ if line !~ '^call delete(''[^'']\{-}''\(,"d"\)\?)$'
+ echomsg "ignoring .VimballRecord entry: " line
+ else
+ sil! keepalt keepjumps exe line
+ let nr_files+= 1
+ endif
+ endfor
sil! keepalt keepjumps d
- let exestring= strlen(substitute(exestring,'call delete(.\{-})|\=',"D","g"))
- echomsg "removed ".exestring." files"
+ echomsg "removed ".nr_files." files"
else
let s:VBRstring= ''
let curfile = substitute(curfile,'\.vmb','','')
endfun
" ---------------------------------------------------------------------
-" s:RecordInVar: record a un-vimball command in the .VimballRecord file {{{2
-fun! s:RecordInVar(home,cmd)
+" s:RecordInVar: record a un-vimball file deletion in the .VimballRecord file {{{2
+fun! s:RecordInVar(file)
if !exists("s:recordfile")
- let s:recordfile= a:cmd
- else
- let s:recordfile= s:recordfile."|".a:cmd
+ let s:recordfile=[]
+ endif
+ call add(s:recordfile, $'call delete({string(a:file)})')
+endfun
+
+" s:RecordDirInVar: record a un-vimball dir deletion in the .VimballRecord file {{{2
+fun! s:RecordDirInVar(dir)
+ if !exists("s:recorddir")
+ let s:recorddir = []
endif
+ call add(s:recorddir, $'call delete({string(a:dir)},"d")')
endfun
" ---------------------------------------------------------------------
setlocal ma
$
if exists("s:recordfile") && exists("s:recorddir")
- let cmd= cmd.s:recordfile."|".s:recorddir
+ let cmd= cmd.join(s:recordfile, '|')."|".join(s:recorddir, '|')
elseif exists("s:recorddir")
- let cmd= cmd.s:recorddir
+ let cmd= cmd.join(s:recorddir, '|')
elseif exists("s:recordfile")
- let cmd= cmd.s:recordfile
+ let cmd= cmd.join(s:recordfile, '|')
else
return
endif
call assert_true(filereadable('.VimballRecord'))
let record = readfile('.VimballRecord')
call assert_equal(1, record->len())
- call assert_match('^Xtest.vmb: rmdir.*call delete(', record[0])
+ call assert_match('^Xtest.vmb: call delete(''.\{-}'')|call delete(''.\{-}'',"d")$', record[0])
call s:teardown()
endfunc
call assert_match('(Vimball) Forbidding strange filename:.* aborting\.\.\.', mess)
call s:teardown()
endfunc
+
+func Test_vimball_VimballRecord_filenames()
+ call s:Mkvimball()
+ call delete('XVimball', 'rf')
+ sp Xtest.vmb
+ 4s#.*\ze\t#.VimballRecord#
+ so %
+ call feedkeys("\<cr>", "it")
+
+ let mess = execute(':mess')->split('\n')[-1]
+ call assert_match('(Vimball) Forbidding .VimballRecord filename.* aborting\.\.\.', mess)
+ call assert_false(filereadable('.VimballRecord'))
+ call s:teardown()
+endfunc