-*eval.txt* For Vim version 7.1. Last change: 2007 Jul 25
+*eval.txt* For Vim version 7.1. Last change: 2007 Sep 25
VIM REFERENCE MANUAL by Bram Moolenaar
foldtextresult( {lnum}) String text for closed fold at {lnum}
foreground( ) Number bring the Vim window to the foreground
function( {name}) Funcref reference to function {name}
-garbagecollect() none free memory, breaking cyclic references
+garbagecollect( [at_exit]) none free memory, breaking cyclic references
get( {list}, {idx} [, {def}]) any get item {idx} from {list} or {def}
get( {dict}, {key} [, {def}]) any get item {key} from {dict} or {def}
getbufline( {expr}, {lnum} [, {end}])
{name} can be a user defined function or an internal function.
-garbagecollect() *garbagecollect()*
+garbagecollect([at_exit]) *garbagecollect()*
Cleanup unused |Lists| and |Dictionaries| that have circular
references. There is hardly ever a need to invoke this
function, as it is automatically done when Vim runs out of
This is useful if you have deleted a very big |List| and/or
|Dictionary| with circular references in a script that runs
for a long time.
+ When the optional "at_exit" argument is one, garbage
+ collection will also be done when exiting Vim, if it wasn't
+ done before. This is useful when checking for memory leaks.
get({list}, {idx} [, {default}]) *get()*
Get item {idx} from |List| {list}. When this item is not
/* Only do this once. */
want_garbage_collect = FALSE;
may_garbage_collect = FALSE;
+ garbage_collect_at_exit = FALSE;
/*
* 1. Go through all accessible variables and mark all lists and dicts
{"foldtextresult", 1, 1, f_foldtextresult},
{"foreground", 0, 0, f_foreground},
{"function", 1, 1, f_function},
- {"garbagecollect", 0, 0, f_garbagecollect},
+ {"garbagecollect", 0, 1, f_garbagecollect},
{"get", 2, 3, f_get},
{"getbufline", 2, 3, f_getbufline},
{"getbufvar", 2, 2, f_getbufvar},
/* This is postponed until we are back at the toplevel, because we may be
* using Lists and Dicts internally. E.g.: ":echo [garbagecollect()]". */
want_garbage_collect = TRUE;
+
+ if (argvars[0].v_type != VAR_UNKNOWN && get_tv_number(&argvars[0]) == 1)
+ garbage_collect_at_exit = TRUE;
}
/*
#endif
#ifdef FEAT_EVAL
-/* Garbage collection can only take place when we are sure there are no Lists
+/*
+ * Garbage collection can only take place when we are sure there are no Lists
* or Dictionaries being used internally. This is flagged with
* "may_garbage_collect" when we are at the toplevel.
* "want_garbage_collect" is set by the garbagecollect() function, which means
- * we do garbage collection before waiting for a char at the toplevel. */
+ * we do garbage collection before waiting for a char at the toplevel.
+ * "garbage_collect_at_exit" indicates garbagecollect(1) was called.
+ */
EXTERN int may_garbage_collect INIT(= FALSE);
EXTERN int want_garbage_collect INIT(= FALSE);
+EXTERN int garbage_collect_at_exit INIT(= FALSE);
/* ID of script being sourced or was sourced to define the current function. */
EXTERN scid_T current_SID INIT(= 0);
#ifdef FEAT_CSCOPE
cs_end();
#endif
+#ifdef FEAT_EVAL
+ if (garbage_collect_at_exit)
+ garbage_collect();
+#endif
mch_exit(exitval);
}
# Uncomment this line for using valgrind.
# The output goes into a file "valgrind.$PID" (sorry, no test number).
-# VALGRIND = valgrind --tool=memcheck --num-callers=15 --logfile=valgrind
+# VALGRIND = valgrind --tool=memcheck --leak-check=yes --num-callers=15 --logfile=valgrind
SCRIPTS = test1.out test2.out test3.out test4.out test5.out test6.out \
test7.out test8.out test9.out test10.out test11.out \
$(SCRIPTS) $(SCRIPTS_GUI): $(VIMPROG)
clean:
- -rm -rf *.out *.failed *.rej *.orig test.log tiny.vim small.vim mbyte.vim test.ok X* viminfo
+ -rm -rf *.out *.failed *.rej *.orig test.log tiny.vim small.vim mbyte.vim test.ok X* valgrind.pid* viminfo
test1.out: test1.in
-rm -f $*.failed tiny.vim small.vim mbyte.vim test.ok X* viminfo
fi"
-rm -rf X* test.ok viminfo
+test49.out: test49.vim
+
+test60.out: test60.vim
+
nolog:
-echo Test results: >test.log
: let tt = "o\<C-V>65\<C-V>x42\<C-V>o103 \<C-V>33a\<C-V>xfg\<C-V>o78\<Esc>"
:endif
:exe "normal " . tt
+:unlet tt
:.w >>test.out
:set vb
/^Piece
: endif
: endif
:endwhile
+:unlet i j
:'t,$w! test.out
:qa!
ENDTEST
---*---
(one
(two
-[(one again\e:$-5,$wq! test.out
+[(one again\e:$-5,$w! test.out
+:delfunc Table
+:delfunc Compute
+:delfunc Expr1
+:delfunc Expr2
+:delfunc ListItem
+:delfunc ListReset
+:unlet retval counter
+:q!
ENDTEST
here
/kk$
:call append("$", foldlevel("."))
:/^last/+1,$w! test.out
+:delfun Flvl
:qa!
ENDTEST
:call append("$", two)
:call append("$", three)
:$-2,$w! test.out
+:unlet one two three
:qa!
ENDTEST
This is a test of the script language.
If after adding a new test, the test output doesn't appear properly in
-test49.failed, try to add one ore more "G"s at the line before ENDTEST.
+test49.failed, try to add one ore more "G"s at the line ending in "test.out"
STARTTEST
:so small.vim
:se nocp nomore viminfo+=nviminfo
:so test49.vim
-GGGGGGGGGG"rp:.-,$wq! test.out
+GGGGGGGGGGGGGG"rp:.-,$w! test.out
+:"
+:" make valgrind happy
+:redir => funclist
+:silent func
+:redir END
+:for line in split(funclist, "\n")
+: let name = matchstr(line, 'function \zs[A-Z]\w*\ze(')
+: if name != ''
+: exe "delfunc " . name
+: endif
+:endfor
+:for v in keys(g:)
+: silent! exe "unlet " . v
+:endfor
+:unlet v
+:qa!
ENDTEST
Results of test49.vim:
:endfun
:call Test(1, 2, [3, 4], {5: 6}) " This may take a while
:"
+:delfunc Test
+:unlet dict
+:call garbagecollect(1)
+:"
:/^start:/,$wq! test.out
ENDTEST
fun s:DoNothing()
call append(line('$'), "nothing line")
endfun
-nnoremap <buffer> _x :call <SID>DoNothing()<bar>call <SID>DoLast()<cr>
+nnoremap <buffer> _x :call <SID>DoNothing()<bar>call <SID>DoLast()<bar>delfunc <SID>DoNothing<bar>delfunc <SID>DoLast<cr>
end:
:$put =str
`m]s:let [str, a] = spellbadword()
:$put =str
+:unlet str a
:"
:" Postponed prefixes
:call TestOne('2', '1')
:" NOSLITSUGS
:call TestOne('8', '8')
:"
+:" clean up for valgrind
+:delfunc TestOne
+:set spl= enc=latin1
+:"
gg:/^test output:/,$wq! test.out
ENDTEST
:$put =str
`m]s:let [str, a] = spellbadword()
:$put =str
+:unlet str a
:"
:" Postponed prefixes
:call TestOne('2', '1')
:call TestOne('6', '6')
:call TestOne('7', '7')
:"
+:" clean up for valgrind
+:delfunc TestOne
+:set spl= enc=latin1
+:"
gg:/^test output:/,$wq! test.out
ENDTEST
redir END
endfunction
:call TestExists()
+:delfunc TestExists
+:delfunc RunTest
+:delfunc TestFuncArg
:edit! test.out
:set ff=unix
:w
else
echo "FAILED"
endif
+unlet str
:let nr = tabpagenr()
:q
:call append(line('$'), 'tab page ' . nr)
+:unlet nr
:"
:" Open three tab pages and use ":tabdo"
:0tabnew
:q!
:call append(line('$'), line1)
:call append(line('$'), line2)
+:unlet line1 line2
:"
:"
:/^Results/,$w! test.out
:else
: let @r .= "FAILED\n"
:endif
-:" --- Check that "matchdelete()" returns 0 if succesfull and otherwise -1.
+:" --- Check that "matchdelete()" returns 0 if successful and otherwise -1.
:let @r .= "*** Test 6: "
:let m = matchadd("MyGroup1", "TODO")
:let r1 = matchdelete(m)
:" --- Check that "setmatches()" will not add two matches with the same ID. The
:" --- expected behaviour (for now) is to add the first match but not the
:" --- second and to return 0 (even though it is a matter of debate whether
-:" --- this can be considered succesfull behaviour).
+:" --- this can be considered successful behaviour).
:let @r .= "*** Test 9: "
:let r1 = setmatches([{'group': 'MyGroup1', 'pattern': 'TODO', 'priority': 10, 'id': 1}, {'group': 'MyGroup2', 'pattern': 'FIXME', 'priority': 10, 'id': 1}])
:if getmatches() == [{'group': 'MyGroup1', 'pattern': 'TODO', 'priority': 10, 'id': 1}] && r1 == 0
:endif
:call clearmatches()
:unlet r1
-:" --- Check that "setmatches()" returns 0 if succesfull and otherwise -1.
+:" --- Check that "setmatches()" returns 0 if successful and otherwise -1.
:" --- (A range of valid and invalid input values are tried out to generate the
:" --- return values.)
:let @r .= "*** Test 10: "
: $put ='ERROR: pat: \"' . t[0] . '\", text: \"' . t[1] . '\", submatch ' . i . ': \"' . l[i] . '\", expected: \"' . e . '\"'
: endif
: endfor
+: unlet i
: endif
:endfor
+:unlet t tl e l
:/^Results/,$wq! test.out
ENDTEST
static int included_patches[] =
{ /* Add new patch number below this line */
+/**/
+ 120,
/**/
119,
/**/