Patch 8.2.3228
Problem: Cannot use a simple block for the :command argument. (Maarten
Tournoij)
Solution: Recognize a simple {} block. (issue #8623)
Files: runtime/doc/map.txt, src/misc2.c, src/proto/
misc2.pro,
src/usercmd.c, src/testdir/test_usercommands.vim
*** ../vim-8.2.3227/runtime/doc/map.txt 2021-03-17 13:28:01.906755797 +0100
--- runtime/doc/map.txt 2021-07-27 21:12:32.708623101 +0200
***************
*** 1553,1558 ****
--- 1572,1587 ----
Replacement text ~
+ The {repl} argument is normally one long string, possibly with "|" separated
+ commands. A special case is when the argument is "{", then the following
+ lines, up to a line starting with "}" are used and |Vim9| syntax applies.
+ Example: >
+ :command MyCommand {
+ echo 'hello'
+ g:calledMyCommand = true
+ }
+ No nesting is supported.
+
The replacement text {repl} for a user defined command is scanned for special
escape sequences, using <...> notation. Escape sequences are replaced with
values from the entered command line, and all other text is copied unchanged.
*** ../vim-8.2.3227/src/misc2.c 2021-07-26 22:19:05.376122583 +0200
--- src/misc2.c 2021-07-27 20:34:33.511041394 +0200
***************
*** 1488,1494 ****
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".
--- 1488,1493 ----
***************
*** 1524,1550 ****
}
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.
*/
! void
ga_add_string(garray_T *gap, char_u *p)
{
char_u *cp = vim_strsave(p);
! if (cp != NULL)
{
! if (ga_grow(gap, 1) == OK)
! ((char_u **)(gap->ga_data))[gap->ga_len++] = cp;
! else
! vim_free(cp);
}
}
- #endif
/*
* Concatenate a string to a growarray which contains bytes.
--- 1523,1549 ----
}
return s;
}
/*
* Make a copy of string "p" and add it to "gap".
! * When out of memory nothing changes and FAIL is returned.
*/
! int
ga_add_string(garray_T *gap, char_u *p)
{
char_u *cp = vim_strsave(p);
! if (cp == NULL)
! return FAIL;
!
! if (ga_grow(gap, 1) == FAIL)
{
! vim_free(cp);
! return FAIL;
}
+ ((char_u **)(gap->ga_data))[gap->ga_len++] = cp;
+ return OK;
}
/*
* Concatenate a string to a growarray which contains bytes.
*** ../vim-8.2.3227/src/proto/
misc2.pro 2021-07-10 21:28:55.327050110 +0200
--- src/proto/
misc2.pro 2021-07-27 20:35:44.354776628 +0200
***************
*** 43,49 ****
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);
void ga_concat(garray_T *gap, char_u *s);
void ga_append(garray_T *gap, int c);
void append_ga_line(garray_T *gap);
--- 43,49 ----
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);
! 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);
*** ../vim-8.2.3227/src/usercmd.c 2021-07-11 19:12:00.045760328 +0200
--- src/usercmd.c 2021-07-27 21:15:17.096083955 +0200
***************
*** 115,120 ****
--- 115,121 ----
};
#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,881 ****
replace_termcodes(rep, &rep_buf, 0, NULL);
if (rep_buf == NULL)
{
! // Can't replace termcodes - try using the string as is
rep_buf = vim_strsave(rep);
! // Give up if out of memory
if (rep_buf == NULL)
return FAIL;
}
--- 873,882 ----
replace_termcodes(rep, &rep_buf, 0, NULL);
if (rep_buf == NULL)
{
! // can't replace termcodes - try using the string as is
rep_buf = vim_strsave(rep);
! // give up if out of memory
if (rep_buf == NULL)
return FAIL;
}
***************
*** 955,960 ****
--- 956,963 ----
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,1044 ****
--- 1040,1085 ----
(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);
+ }
}
/*
*** ../vim-8.2.3227/src/testdir/test_usercommands.vim 2021-07-11 19:12:00.045760328 +0200
--- src/testdir/test_usercommands.vim 2021-07-27 21:15:33.464032136 +0200
***************
*** 622,625 ****
--- 622,643 ----
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
*** ../vim-8.2.3227/src/version.c 2021-07-26 22:19:05.384122565 +0200
--- src/version.c 2021-07-27 21:15:49.763980813 +0200
***************
*** 757,758 ****
--- 757,760 ----
{ /* Add new patch number below this line */
+ /**/
+ 3228,
/**/
--
Vi is clearly superior to emacs, since "vi" has only two characters
(and two keystrokes), while "emacs" has five. (Randy C. Ford)
/// Bram Moolenaar -- Br...@Moolenaar.net --
http://www.Moolenaar.net \\\
/// \\\
\\\ sponsor Vim, vote for features --
http://www.Vim.org/sponsor/ ///
\\\ help me help AIDS victims --
http://ICCF-Holland.org ///