Patch 8.2.3297
Problem:    Cannot use all commands inside a {} block after :command and
            :autocmd.
Solution:   Do consider \n to separate commands. (closes #8620)
Files:      runtime/doc/map.txt, src/ex_docmd.c, src/proto/ex_docmd.pro,
            src/ex_eval.c, src/proto/ex_eval.pro, src/eval.c, src/evalvars.c,
            src/ex_cmds.c, src/syntax.c, src/userfunc.c, src/vim9compile.c,
            src/vim9script.c, src/errors.h, src/testdir/test_autocmd.vim,
            src/testdir/test_usercommands.vim


*** ../vim-8.2.3296/runtime/doc/map.txt 2021-08-01 14:52:05.554645412 +0200
--- runtime/doc/map.txt 2021-08-05 20:38:05.454379134 +0200
***************
*** 1561,1568 ****
                echo 'hello'
                g:calledMyCommand = true
            }
! No nesting is supported, inline functions cannot be used.  Using `:normal`
! directly does not work, you can use it indirectly with `:execute`.
  
  The replacement text {repl} for a user defined command is scanned for special
  escape sequences, using <...> notation.  Escape sequences are replaced with
--- 1580,1590 ----
                echo 'hello'
                g:calledMyCommand = true
            }
! <                                                     *E1231*
! There must be white space before the "{".  No nesting is supported, inline
! functions cannot be used.  Commands where a "|" may appear in the argument,
! such as commands with an expression argument, cannot be followed by a "|" and
! another command.
  
  The replacement text {repl} for a user defined command is scanned for special
  escape sequences, using <...> notation.  Escape sequences are replaced with
*** ../vim-8.2.3296/src/ex_docmd.c      2021-08-01 21:19:40.130538381 +0200
--- src/ex_docmd.c      2021-08-05 20:34:52.042934992 +0200
***************
*** 2314,2335 ****
        ea.do_ecmd_cmd = getargcmd(&ea.arg);
  
      /*
!      * Check for '|' to separate commands and '"' or '#' to start comments.
!      * Don't do this for ":read !cmd" and ":write !cmd".
!      */
!     if ((ea.argt & EX_TRLBAR) && !ea.usefilter)
!       separate_nextcmd(&ea);
! 
!     /*
!      * Check for <newline> to end a shell command.
       * Also do this for ":read !cmd", ":write !cmd" and ":global".
       * Any others?
       */
      else if (ea.cmdidx == CMD_bang
            || ea.cmdidx == CMD_terminal
            || ea.cmdidx == CMD_global
            || ea.cmdidx == CMD_vglobal
!           || ea.usefilter)
      {
        for (p = ea.arg; *p; ++p)
        {
--- 2314,2337 ----
        ea.do_ecmd_cmd = getargcmd(&ea.arg);
  
      /*
!      * For commands that do not use '|' inside their argument: Check for '|' 
to
!      * separate commands and '"' or '#' to start comments.
!      *
!      * Otherwise: Check for <newline> to end a shell command.
       * Also do this for ":read !cmd", ":write !cmd" and ":global".
+      * Also do this inside a { - } block after :command and :autocmd.
       * Any others?
       */
+     if ((ea.argt & EX_TRLBAR) && !ea.usefilter)
+     {
+       separate_nextcmd(&ea);
+     }
      else if (ea.cmdidx == CMD_bang
            || ea.cmdidx == CMD_terminal
            || ea.cmdidx == CMD_global
            || ea.cmdidx == CMD_vglobal
!           || ea.usefilter
!           || inside_block(&ea))
      {
        for (p = ea.arg; *p; ++p)
        {
***************
*** 5410,5415 ****
--- 5412,5432 ----
  }
  
  /*
+  * If "eap->nextcmd" is not set, check for a next command at "p".
+  */
+     void
+ set_nextcmd(exarg_T *eap, char_u *arg)
+ {
+     char_u *p = check_nextcmd(arg);
+ 
+     if (eap->nextcmd == NULL)
+       eap->nextcmd = p;
+     else if (p != NULL)
+       // cannot use "| command" inside a  {} block
+       semsg(_(e_cannot_use_bar_to_separate_commands_here_str), arg);
+ }
+ 
+ /*
   * - if there are more files to edit
   * - and this is the last window
   * - and forceit not used
***************
*** 7546,7552 ****
      else
        p = eap->arg + 1;
  
!     eap->nextcmd = check_nextcmd(p);
      p = skipwhite(p);
      if (*p != NUL && *p != (
  #ifdef FEAT_EVAL
--- 7563,7569 ----
      else
        p = eap->arg + 1;
  
!     set_nextcmd(eap, p);
      p = skipwhite(p);
      if (*p != NUL && *p != (
  #ifdef FEAT_EVAL
***************
*** 8580,8586 ****
            if (!ends_excmd2(eap->arg, p))
                eap->errmsg = ex_errmsg(e_trailing_arg, p);
            else
!               eap->nextcmd = check_nextcmd(p);
        }
      }
      if (!eap->skip)
--- 8597,8603 ----
            if (!ends_excmd2(eap->arg, p))
                eap->errmsg = ex_errmsg(e_trailing_arg, p);
            else
!               set_nextcmd(eap, p);
        }
      }
      if (!eap->skip)
*** ../vim-8.2.3296/src/proto/ex_docmd.pro      2021-08-01 21:19:40.130538381 
+0200
--- src/proto/ex_docmd.pro      2021-08-05 20:13:28.455007890 +0200
***************
*** 33,38 ****
--- 33,39 ----
  int ends_excmd2(char_u *cmd_start, char_u *cmd);
  char_u *find_nextcmd(char_u *p);
  char_u *check_nextcmd(char_u *p);
+ void set_nextcmd(exarg_T *eap, char_u *p);
  char_u *get_command_name(expand_T *xp, int idx);
  void not_exiting(void);
  int before_quit_autocmds(win_T *wp, int quit_all, int forceit);
*** ../vim-8.2.3296/src/ex_eval.c       2021-07-25 14:13:50.040566339 +0200
--- src/ex_eval.c       2021-08-05 19:27:31.462636805 +0200
***************
*** 1461,1466 ****
--- 1461,1478 ----
        leave_block(cstack);
  }
  
+     int
+ inside_block(exarg_T *eap)
+ {
+     cstack_T  *cstack = eap->cstack;
+     int               i;
+ 
+     for (i = 0; i <= cstack->cs_idx; ++i)
+       if (cstack->cs_flags[cstack->cs_idx] & CSF_BLOCK)
+           return TRUE;
+     return FALSE;
+ }
+ 
  /*
   * ":throw expr"
   */
*** ../vim-8.2.3296/src/proto/ex_eval.pro       2020-10-10 21:33:42.403033529 
+0200
--- src/proto/ex_eval.pro       2021-08-05 19:28:25.242498746 +0200
***************
*** 22,27 ****
--- 22,28 ----
  void ex_endwhile(exarg_T *eap);
  void ex_block(exarg_T *eap);
  void ex_endblock(exarg_T *eap);
+ int inside_block(exarg_T *eap);
  void ex_throw(exarg_T *eap);
  void do_throw(cstack_T *cstack);
  void ex_try(exarg_T *eap);
*** ../vim-8.2.3296/src/eval.c  2021-08-04 19:25:50.614808524 +0200
--- src/eval.c  2021-08-05 20:12:22.731262479 +0200
***************
*** 2314,2320 ****
      }
  
      if (eap != NULL)
!       eap->nextcmd = check_nextcmd(p);
  
      return ret;
  }
--- 2314,2320 ----
      }
  
      if (eap != NULL)
!       set_nextcmd(eap, p);
  
      return ret;
  }
***************
*** 6173,6179 ****
        clear_tv(&rettv);
        arg = skipwhite(arg);
      }
!     eap->nextcmd = check_nextcmd(arg);
      clear_evalarg(&evalarg, eap);
  
      if (eap->skip)
--- 6173,6179 ----
        clear_tv(&rettv);
        arg = skipwhite(arg);
      }
!     set_nextcmd(eap, arg);
      clear_evalarg(&evalarg, eap);
  
      if (eap->skip)
***************
*** 6317,6323 ****
      if (eap->skip)
        --emsg_skip;
  
!     eap->nextcmd = check_nextcmd(arg);
  }
  
  /*
--- 6317,6323 ----
      if (eap->skip)
        --emsg_skip;
  
!     set_nextcmd(eap, arg);
  }
  
  /*
*** ../vim-8.2.3296/src/evalvars.c      2021-07-28 21:25:45.360602797 +0200
--- src/evalvars.c      2021-08-05 20:14:04.414872230 +0200
***************
*** 812,818 ****
            list_func_vars(&first);
            list_vim_vars(&first);
        }
!       eap->nextcmd = check_nextcmd(arg);
      }
      else if (expr[0] == '=' && expr[1] == '<' && expr[2] == '<')
      {
--- 812,818 ----
            list_func_vars(&first);
            list_vim_vars(&first);
        }
!       set_nextcmd(eap, arg);
      }
      else if (expr[0] == '=' && expr[1] == '<' && expr[2] == '<')
      {
***************
*** 1629,1635 ****
        arg = skipwhite(name_end);
      } while (!ends_excmd2(name_end, arg));
  
!     eap->nextcmd = check_nextcmd(arg);
  }
  
      static int
--- 1629,1635 ----
        arg = skipwhite(name_end);
      } while (!ends_excmd2(name_end, arg));
  
!     set_nextcmd(eap, arg);
  }
  
      static int
*** ../vim-8.2.3296/src/ex_cmds.c       2021-07-21 22:20:30.062401737 +0200
--- src/ex_cmds.c       2021-08-05 20:14:58.090674037 +0200
***************
*** 450,456 ****
            unique = TRUE;
        else if (*p == '"')     // comment start
            break;
!       else if (check_nextcmd(p) != NULL)
        {
            eap->nextcmd = check_nextcmd(p);
            break;
--- 450,456 ----
            unique = TRUE;
        else if (*p == '"')     // comment start
            break;
!       else if (eap->nextcmd == NULL && check_nextcmd(p) != NULL)
        {
            eap->nextcmd = check_nextcmd(p);
            break;
***************
*** 3930,3936 ****
      cmd = skipwhite(cmd);
      if (*cmd && *cmd != '"')      // if not end-of-line or comment
      {
!       eap->nextcmd = check_nextcmd(cmd);
        if (eap->nextcmd == NULL)
        {
            semsg(_(e_trailing_arg), cmd);
--- 3930,3936 ----
      cmd = skipwhite(cmd);
      if (*cmd && *cmd != '"')      // if not end-of-line or comment
      {
!       set_nextcmd(eap, cmd);
        if (eap->nextcmd == NULL)
        {
            semsg(_(e_trailing_arg), cmd);
*** ../vim-8.2.3296/src/syntax.c        2021-07-20 21:07:32.968058851 +0200
--- src/syntax.c        2021-08-05 20:18:00.198034391 +0200
***************
*** 3789,3795 ****
      static void
  syn_cmd_reset(exarg_T *eap, int syncing UNUSED)
  {
!     eap->nextcmd = check_nextcmd(eap->arg);
      if (!eap->skip)
      {
        set_internal_string_var((char_u *)"syntax_cmd", (char_u *)"reset");
--- 3789,3795 ----
      static void
  syn_cmd_reset(exarg_T *eap, int syncing UNUSED)
  {
!     set_nextcmd(eap, eap->arg);
      if (!eap->skip)
      {
        set_internal_string_var((char_u *)"syntax_cmd", (char_u *)"reset");
***************
*** 3821,3827 ****
  {
      char_u    buf[100];
  
!     eap->nextcmd = check_nextcmd(eap->arg);
      if (!eap->skip)
      {
        STRCPY(buf, "so ");
--- 3821,3827 ----
  {
      char_u    buf[100];
  
!     set_nextcmd(eap, eap->arg);
      if (!eap->skip)
      {
        STRCPY(buf, "so ");
***************
*** 3928,3934 ****
            arg = skipwhite(arg_end);
        }
      }
!     eap->nextcmd = check_nextcmd(arg);
  }
  
      static void
--- 3928,3934 ----
            arg = skipwhite(arg_end);
        }
      }
!     set_nextcmd(eap, arg);
  }
  
      static void
***************
*** 4921,4927 ****
      }
  
      if (rest != NULL)
!       eap->nextcmd = check_nextcmd(rest);
      else
        semsg(_(e_invarg2), arg);
  
--- 4921,4927 ----
      }
  
      if (rest != NULL)
!       set_nextcmd(eap, rest);
      else
        semsg(_(e_invarg2), arg);
  
***************
*** 4978,4984 ****
        /*
         * Check for trailing command and illegal trailing arguments.
         */
!       eap->nextcmd = check_nextcmd(rest);
        if (!ends_excmd2(eap->cmd, rest) || eap->skip)
            rest = NULL;
        else if (ga_grow(&curwin->w_s->b_syn_patterns, 1) != FAIL
--- 4978,4984 ----
        /*
         * Check for trailing command and illegal trailing arguments.
         */
!       set_nextcmd(eap, rest);
        if (!ends_excmd2(eap->cmd, rest) || eap->skip)
            rest = NULL;
        else if (ga_grow(&curwin->w_s->b_syn_patterns, 1) != FAIL
***************
*** 5218,5224 ****
         * Check for trailing garbage or command.
         * If OK, add the item.
         */
!       eap->nextcmd = check_nextcmd(rest);
        if (!ends_excmd(*rest) || eap->skip)
            rest = NULL;
        else if (ga_grow(&(curwin->w_s->b_syn_patterns), pat_count) != FAIL
--- 5218,5224 ----
         * Check for trailing garbage or command.
         * If OK, add the item.
         */
!       set_nextcmd(eap, rest);
        if (!ends_excmd(*rest) || eap->skip)
            rest = NULL;
        else if (ga_grow(&(curwin->w_s->b_syn_patterns), pat_count) != FAIL
***************
*** 5896,5902 ****
        semsg(_("E404: Illegal arguments: %s"), arg_start);
      else if (!finished)
      {
!       eap->nextcmd = check_nextcmd(arg_start);
        redraw_curbuf_later(SOME_VALID);
        syn_stack_free_all(curwin->w_s);        // Need to recompute all syntax.
      }
--- 5896,5902 ----
        semsg(_("E404: Illegal arguments: %s"), arg_start);
      else if (!finished)
      {
!       set_nextcmd(eap, arg_start);
        redraw_curbuf_later(SOME_VALID);
        syn_stack_free_all(curwin->w_s);        // Need to recompute all syntax.
      }
*** ../vim-8.2.3296/src/userfunc.c      2021-08-01 22:01:25.985012239 +0200
--- src/userfunc.c      2021-08-05 20:20:05.501617362 +0200
***************
*** 3842,3848 ****
      {
        if (!eap->skip)
            list_functions(NULL);
!       eap->nextcmd = check_nextcmd(eap->arg);
        return NULL;
      }
  
--- 3842,3848 ----
      {
        if (!eap->skip)
            list_functions(NULL);
!       set_nextcmd(eap, eap->arg);
        return NULL;
      }
  
***************
*** 3869,3875 ****
        }
        if (*p == '/')
            ++p;
!       eap->nextcmd = check_nextcmd(p);
        return NULL;
      }
  
--- 3869,3875 ----
        }
        if (*p == '/')
            ++p;
!       set_nextcmd(eap, p);
        return NULL;
      }
  
***************
*** 3947,3953 ****
            semsg(_(e_trailing_arg), p);
            goto ret_free;
        }
!       eap->nextcmd = check_nextcmd(p);
        if (eap->nextcmd != NULL)
            *p = NUL;
        if (!eap->skip && !got_int)
--- 3947,3953 ----
            semsg(_(e_trailing_arg), p);
            goto ret_free;
        }
!       set_nextcmd(eap, p);
        if (eap->nextcmd != NULL)
            *p = NUL;
        if (!eap->skip && !got_int)
***************
*** 4655,4661 ****
        semsg(_(e_trailing_arg), p);
        return;
      }
!     eap->nextcmd = check_nextcmd(p);
      if (eap->nextcmd != NULL)
        *p = NUL;
  
--- 4655,4661 ----
        semsg(_(e_trailing_arg), p);
        return;
      }
!     set_nextcmd(eap, p);
      if (eap->nextcmd != NULL)
        *p = NUL;
  
***************
*** 4844,4850 ****
      if (returning)
        eap->nextcmd = NULL;
      else if (eap->nextcmd == NULL)        // no argument
!       eap->nextcmd = check_nextcmd(arg);
  
      if (eap->skip)
        --emsg_skip;
--- 4844,4850 ----
      if (returning)
        eap->nextcmd = NULL;
      else if (eap->nextcmd == NULL)        // no argument
!       set_nextcmd(eap, arg);
  
      if (eap->skip)
        --emsg_skip;
***************
*** 5004,5010 ****
            }
        }
        else
!           eap->nextcmd = check_nextcmd(arg);
      }
  
  end:
--- 5004,5010 ----
            }
        }
        else
!           set_nextcmd(eap, arg);
      }
  
  end:
*** ../vim-8.2.3296/src/vim9compile.c   2021-08-05 19:01:12.294746361 +0200
--- src/vim9compile.c   2021-08-05 20:20:17.717577500 +0200
***************
*** 5691,5697 ****
        name_end = skip_regexp(name_start + 1, '/', TRUE);
        if (*name_end == '/')
            ++name_end;
!       eap->nextcmd = check_nextcmd(name_end);
      }
      if (name_end == name_start || *skipwhite(name_end) != '(')
      {
--- 5691,5697 ----
        name_end = skip_regexp(name_start + 1, '/', TRUE);
        if (*name_end == '/')
            ++name_end;
!       set_nextcmd(eap, name_end);
      }
      if (name_end == name_start || *skipwhite(name_end) != '(')
      {
*** ../vim-8.2.3296/src/vim9script.c    2021-07-29 22:48:50.103129907 +0200
--- src/vim9script.c    2021-08-05 20:20:28.917541061 +0200
***************
*** 311,317 ****
      cmd_end = handle_import(eap->arg, NULL, current_sctx.sc_sid,
                                                               &evalarg, NULL);
      if (cmd_end != NULL)
!       eap->nextcmd = check_nextcmd(cmd_end);
      clear_evalarg(&evalarg, eap);
  }
  
--- 311,317 ----
      cmd_end = handle_import(eap->arg, NULL, current_sctx.sc_sid,
                                                               &evalarg, NULL);
      if (cmd_end != NULL)
!       set_nextcmd(eap, cmd_end);
      clear_evalarg(&evalarg, eap);
  }
  
*** ../vim-8.2.3296/src/errors.h        2021-08-04 19:25:50.614808524 +0200
--- src/errors.h        2021-08-05 20:34:28.183003921 +0200
***************
*** 643,646 ****
  EXTERN char e_expected_dictionary_for_using_key_str_but_got_str[]
        INIT(= N_("E1229: Expected dictionary for using key \"%s\", but got 
%s"));
  EXTERN char e_encryption_sodium_mlock_failed[]
!       INIT(= N_("E1230: encryption: sodium_mlock() failed"));
--- 643,648 ----
  EXTERN char e_expected_dictionary_for_using_key_str_but_got_str[]
        INIT(= N_("E1229: Expected dictionary for using key \"%s\", but got 
%s"));
  EXTERN char e_encryption_sodium_mlock_failed[]
!       INIT(= N_("E1230: Encryption: sodium_mlock() failed"));
! EXTERN char e_cannot_use_bar_to_separate_commands_here_str[]
!       INIT(= N_("E1231: Cannot use a bar to separate commands here: %s"));
*** ../vim-8.2.3296/src/testdir/test_autocmd.vim        2021-08-01 
14:52:05.558645405 +0200
--- src/testdir/test_autocmd.vim        2021-08-05 19:35:56.697417515 +0200
***************
*** 2816,2826 ****
--- 2816,2834 ----
              setlocal matchpairs+=<:>
              /<start
            }
+     au CursorHold * {
+         autocmd BufReadPre * ++once echo 'one' | echo 'two'
+         g:gotSafeState = 77
+       }
    augroup END
  
    let expected = "\n--- Autocommands ---\nblock_testing  BufRead\n    *.xml   
  {^@            setlocal matchpairs+=<:>^@            /<start^@          }"
    call assert_equal(expected, execute('au BufReadPost *.xml'))
  
+   doautocmd CursorHold
+   call assert_equal(77, g:gotSafeState)
+   unlet g:gotSafeState
+ 
    augroup block_testing
      au!
    augroup END
*** ../vim-8.2.3296/src/testdir/test_usercommands.vim   2021-07-28 
15:54:51.168064387 +0200
--- src/testdir/test_usercommands.vim   2021-08-05 20:37:25.854492552 +0200
***************
*** 645,650 ****
--- 645,658 ----
           echo 'hello'
    END
    call CheckScriptFailure(lines, 'E1026:')
+ 
+   let lines =<< trim END
+       command BarCommand {
+          echo 'hello' | echo 'there'
+         }
+       BarCommand
+   END
+   call CheckScriptFailure(lines, 'E1231:')
  endfunc
  
  " vim: shiftwidth=2 sts=2 expandtab
*** ../vim-8.2.3296/src/version.c       2021-08-05 19:01:12.294746361 +0200
--- src/version.c       2021-08-05 20:27:20.188262338 +0200
***************
*** 757,758 ****
--- 757,760 ----
  {   /* Add new patch number below this line */
+ /**/
+     3297,
  /**/

-- 
You know you use Vim too much when you have this alias in your
~/.bashrc file: alias :e=/bin/vim             (Eljay Love-Jensen)

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///                                                                      \\\
\\\        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/202108051840.175IewFK1377773%40masaka.moolenaar.net.

Raspunde prin e-mail lui