diff options
author | Bram Moolenaar <Bram@vim.org> | 2021-07-27 21:17:32 +0200 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2021-07-27 21:17:32 +0200 |
commit | 5d7c2df536c17db4a9c61e0760bdcf78d0db7330 (patch) | |
tree | 74a24ee4dec7bed9866c328da2bf3ac00460ef77 /src | |
parent | 53ba05b09075f14227f9be831a22ed16f7cc26b2 (diff) | |
download | vim-git-5d7c2df536c17db4a9c61e0760bdcf78d0db7330.tar.gz |
patch 8.2.3228: cannot use a simple block for the :command argumentv8.2.3228
Problem: Cannot use a simple block for the :command argument. (Maarten
Tournoij)
Solution: Recognize a simple {} block. (issue #8623)
Diffstat (limited to 'src')
-rw-r--r-- | src/misc2.c | 21 | ||||
-rw-r--r-- | src/proto/misc2.pro | 2 | ||||
-rw-r--r-- | src/testdir/test_usercommands.vim | 18 | ||||
-rw-r--r-- | src/usercmd.c | 45 | ||||
-rw-r--r-- | src/version.c | 2 |
5 files changed, 74 insertions, 14 deletions
diff --git a/src/misc2.c b/src/misc2.c index 8e99b01a5..bc984b219 100644 --- a/src/misc2.c +++ b/src/misc2.c @@ -1488,7 +1488,6 @@ ga_grow_inner(garray_T *gap, int n) return OK; } -#if defined(FEAT_EVAL) || defined(FEAT_SEARCHPATH) || defined(PROTO) /* * For a growing array that contains a list of strings: concatenate all the * strings with a separating "sep". @@ -1524,27 +1523,27 @@ ga_concat_strings(garray_T *gap, char *sep) } return s; } -#endif -#if defined(FEAT_VIMINFO) || defined(FEAT_EVAL) || defined(PROTO) /* * Make a copy of string "p" and add it to "gap". - * When out of memory nothing changes. + * When out of memory nothing changes and FAIL is returned. */ - void + int ga_add_string(garray_T *gap, char_u *p) { char_u *cp = vim_strsave(p); - if (cp != NULL) + if (cp == NULL) + return FAIL; + + if (ga_grow(gap, 1) == FAIL) { - if (ga_grow(gap, 1) == OK) - ((char_u **)(gap->ga_data))[gap->ga_len++] = cp; - else - vim_free(cp); + vim_free(cp); + return FAIL; } + ((char_u **)(gap->ga_data))[gap->ga_len++] = cp; + return OK; } -#endif /* * Concatenate a string to a growarray which contains bytes. diff --git a/src/proto/misc2.pro b/src/proto/misc2.pro index 5f7d70927..5ecd5958f 100644 --- a/src/proto/misc2.pro +++ b/src/proto/misc2.pro @@ -43,7 +43,7 @@ void ga_init2(garray_T *gap, int itemsize, int growsize); int ga_grow(garray_T *gap, int n); int ga_grow_inner(garray_T *gap, int n); char_u *ga_concat_strings(garray_T *gap, char *sep); -void ga_add_string(garray_T *gap, char_u *p); +int ga_add_string(garray_T *gap, char_u *p); void ga_concat(garray_T *gap, char_u *s); void ga_append(garray_T *gap, int c); void append_ga_line(garray_T *gap); diff --git a/src/testdir/test_usercommands.vim b/src/testdir/test_usercommands.vim index f0f056f88..df8893709 100644 --- a/src/testdir/test_usercommands.vim +++ b/src/testdir/test_usercommands.vim @@ -622,4 +622,22 @@ func Test_usercmd_custom() delfunc T2 endfunc +func Test_usercmd_with_block() + command DoSomething { + g:didit = 'yes' + g:didmore = 'more' + } + DoSomething + call assert_equal('yes', g:didit) + call assert_equal('more', g:didmore) + unlet g:didit + unlet g:didmore + + let lines =<< trim END + command DoesNotEnd { + echo 'hello' + END + call CheckScriptFailure(lines, 'E1026:') +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/usercmd.c b/src/usercmd.c index 42b9014f3..09e7b26b3 100644 --- a/src/usercmd.c +++ b/src/usercmd.c @@ -115,6 +115,7 @@ static struct }; #define UC_BUFFER 1 // -buffer: local to current buffer +#define UC_VIM9 2 // {} argument: Vim9 syntax. /* * Search for a user command that matches "eap->cmd". @@ -872,10 +873,10 @@ uc_add_command( replace_termcodes(rep, &rep_buf, 0, NULL); if (rep_buf == NULL) { - // Can't replace termcodes - try using the string as is + // can't replace termcodes - try using the string as is rep_buf = vim_strsave(rep); - // Give up if out of memory + // give up if out of memory if (rep_buf == NULL) return FAIL; } @@ -955,6 +956,8 @@ uc_add_command( cmd->uc_def = def; cmd->uc_compl = compl; cmd->uc_script_ctx = current_sctx; + if (flags & UC_VIM9) + cmd->uc_script_ctx.sc_version = SCRIPT_VERSION_VIM9; #ifdef FEAT_EVAL cmd->uc_script_ctx.sc_lnum += SOURCING_LNUM; cmd->uc_compl_arg = compl_arg; @@ -1037,8 +1040,46 @@ ex_command(exarg_T *eap) (char_u *)_(e_complete_used_without_nargs), TRUE, TRUE); } else + { + char_u *tofree = NULL; + + if (*p == '{' && ends_excmd2(eap->arg, skipwhite(p + 1)) + && eap->getline != NULL) + { + garray_T ga; + char_u *line = NULL; + + ga_init2(&ga, sizeof(char_u *), 10); + if (ga_add_string(&ga, p) == FAIL) + return; + + // Read lines between '{' and '}'. Does not support nesting or + // here-doc constructs. + // + for (;;) + { + vim_free(line); + if ((line = eap->getline(':', eap->cookie, + 0, GETLINE_CONCAT_CONTBAR)) == NULL) + { + emsg(_(e_missing_rcurly)); + break; + } + if (ga_add_string(&ga, line) == FAIL) + break; + if (*skipwhite(line) == '}') + break; + } + vim_free(line); + p = tofree = ga_concat_strings(&ga, "\n"); + ga_clear_strings(&ga); + flags |= UC_VIM9; + } + uc_add_command(name, end - name, p, argt, def, flags, compl, compl_arg, addr_type_arg, eap->forceit); + vim_free(tofree); + } } /* diff --git a/src/version.c b/src/version.c index cdf5d4e4e..e38274ef3 100644 --- a/src/version.c +++ b/src/version.c @@ -756,6 +756,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 3228, +/**/ 3227, /**/ 3226, |