[vim/vim] cannot use a {} block in a nested :autocmd (PR #20933)

5 views
Skip to first unread message

h_east

unread,
Aug 3, 2026, 4:58:17 PM (19 hours ago) Aug 3
to vim/vim, Subscribed
Problem:  At script level a "{" block is only recognized when it is the
          whole argument of :autocmd or :command, so an :autocmd that is
          the command of another :autocmd cannot use a block.  In a :def
          function a trailing "{" is accepted instead, and there any
          command ending in "{", such as "normal! {", is mistaken for the
          start of a block.
Solution: Locate the block by following the argument of the command,
          descending into a nested :autocmd or :command, and use that
          everywhere a block needs to be recognized.

fixes: #20918


Two different rules were used to recognize a {} block after :autocmd and
:command, and each is wrong in the opposite direction.

At script level a block is only recognized when the command argument is {
and nothing else (patch 8.2.3268). So an :autocmd that is the command of
another :autocmd cannot use one:

vim9script
autocmd FileType fzf autocmd BufWinEnter * ++once {
    echo 'hello'
}

The outer argument ends with { but does not consist of it, so no block is
read. The lines after it run as ordinary script lines and the final } gives
E1128.

In a :def function the check is the reverse (patch 8.2.3271, same day): the
line starts a block when it ends in { and begins with au or com. Nesting
works there, but a command that merely happens to end in { is taken for a
block:

vim9script
def Setup()
  autocmd BufReadPost * normal! {
  echo 'after'
enddef

normal! { moves to the previous paragraph. The rest of the function is
swallowed while looking for } and E1171 is given.

Both now use one function, find_cmd_block_start(). It returns the { when
the command argument is { at the end of the line, and follows the argument of
a nested :autocmd or :command to look there too. A trailing { belonging
to some other command is not a block start.

UC_VIM9 is now set only for the command that owns the block, so an :autocmd
with one nested in it keeps the syntax of its own script.

Nesting the blocks themselves is still not supported, as documented.


You can view, comment on, or merge this pull request online at:

  https://github.com/vim/vim/pull/20933

Commit Summary

  • 34a9b39 cannot use a {} block in a nested :autocmd

File Changes

(11 files)

Patch Links:


Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications, keep track of coding agent tasks and review pull requests on the go with GitHub Mobile for iOS and Android. Download it today!
You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/pull/20933@github.com>

Reply all
Reply to author
Forward
0 new messages