To: vim_dev@googlegroups.com Subject: Patch 8.2.3228 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ 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 -- Bram@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 ///