summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2022-09-05 21:21:25 +0100
committerBram Moolenaar <Bram@vim.org>2022-09-05 21:21:25 +0100
commit86d87256c4005c6215da5af2597fbf6f6304421f (patch)
treeafccb6cd2b198c0c81f064e7d7de5cce316d52a6
parentccfde4d028e891a41e3548323c3d47b06fb0b83e (diff)
downloadvim-git-86d87256c4005c6215da5af2597fbf6f6304421f.tar.gz
patch 9.0.0390: cannot use a partial with :deferv9.0.0390
Problem: Cannot use a partial with :defer. Solution: Add the partial arguments before the other arguments. Disallow using a dictionary.
-rw-r--r--src/errors.h4
-rw-r--r--src/testdir/test_user_func.vim25
-rw-r--r--src/userfunc.c31
-rw-r--r--src/version.c2
4 files changed, 57 insertions, 5 deletions
diff --git a/src/errors.h b/src/errors.h
index 44eb9db9f..2ed62a2af 100644
--- a/src/errors.h
+++ b/src/errors.h
@@ -3326,3 +3326,7 @@ EXTERN char e_non_null_list_required_for_argument_nr[]
#endif
EXTERN char e_window_unexpectedly_close_while_searching_for_tags[]
INIT(= N_("E1299: Window unexpectedly closed while searching for tags"));
+#ifdef FEAT_EVAL
+EXTERN char e_cannot_use_partial_with_dictionary_for_defer[]
+ INIT(= N_("E1300: Cannot use a partial with dictionary for :defer"));
+#endif
diff --git a/src/testdir/test_user_func.vim b/src/testdir/test_user_func.vim
index af05812c6..4ea771119 100644
--- a/src/testdir/test_user_func.vim
+++ b/src/testdir/test_user_func.vim
@@ -529,8 +529,11 @@ func Test_funcdef_alloc_failure()
bw!
endfunc
-func AddDefer(arg)
- call extend(g:deferred, [a:arg])
+func AddDefer(arg1, ...)
+ call extend(g:deferred, [a:arg1])
+ if a:0 == 1
+ call extend(g:deferred, [a:1])
+ endif
endfunc
func WithDeferTwo()
@@ -550,6 +553,13 @@ func WithDeferOne()
call extend(g:deferred, ['end One'])
endfunc
+func WithPartialDefer()
+ call extend(g:deferred, ['in Partial'])
+ let Part = funcref('AddDefer', ['arg1'])
+ defer Part("arg2")
+ call extend(g:deferred, ['end Partial'])
+endfunc
+
func Test_defer()
let g:deferred = []
call WithDeferOne()
@@ -558,6 +568,17 @@ func Test_defer()
unlet g:deferred
call assert_equal('', glob('Xfuncdefer'))
+
+ call assert_fails('defer delete("Xfuncdefer")->Another()', 'E488:')
+ call assert_fails('defer delete("Xfuncdefer").member', 'E488:')
+
+ let g:deferred = []
+ call WithPartialDefer()
+ call assert_equal(['in Partial', 'end Partial', 'arg1', 'arg2'], g:deferred)
+ unlet g:deferred
+
+ let Part = funcref('AddDefer', ['arg1'], {})
+ call assert_fails('defer Part("arg2")', 'E1300:')
endfunc
diff --git a/src/userfunc.c b/src/userfunc.c
index 9ac681f20..0ee276b3c 100644
--- a/src/userfunc.c
+++ b/src/userfunc.c
@@ -5567,17 +5567,42 @@ ex_call_inner(
* Returns FAIL or OK.
*/
static int
-ex_defer_inner(char_u *name, char_u **arg, evalarg_T *evalarg)
+ex_defer_inner(
+ char_u *name,
+ char_u **arg,
+ partial_T *partial,
+ evalarg_T *evalarg)
{
typval_T argvars[MAX_FUNC_ARGS + 1]; // vars for arguments
+ int partial_argc = 0; // number of partial arguments
int argcount = 0; // number of arguments found
+ int r;
if (current_funccal == NULL)
{
semsg(_(e_str_not_inside_function), "defer");
return FAIL;
}
- if (get_func_arguments(arg, evalarg, FALSE, argvars, &argcount) == FAIL)
+ if (partial != NULL)
+ {
+ if (partial->pt_dict != NULL)
+ {
+ emsg(_(e_cannot_use_partial_with_dictionary_for_defer));
+ return FAIL;
+ }
+ if (partial->pt_argc > 0)
+ {
+ int i;
+
+ partial_argc = partial->pt_argc;
+ for (i = 0; i < partial_argc; ++i)
+ copy_tv(&partial->pt_argv[i], &argvars[i]);
+ }
+ }
+ r = get_func_arguments(arg, evalarg, FALSE,
+ argvars + partial_argc, &argcount);
+ argcount += partial_argc;
+ if (r == FAIL)
{
while (--argcount >= 0)
clear_tv(&argvars[argcount]);
@@ -5738,7 +5763,7 @@ ex_call(exarg_T *eap)
if (eap->cmdidx == CMD_defer)
{
arg = startarg;
- failed = ex_defer_inner(name, &arg, &evalarg) == FAIL;
+ failed = ex_defer_inner(name, &arg, partial, &evalarg) == FAIL;
}
else
{
diff --git a/src/version.c b/src/version.c
index b114c2760..76ce3a16d 100644
--- a/src/version.c
+++ b/src/version.c
@@ -704,6 +704,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 390,
+/**/
389,
/**/
388,