[vim/vim] cannot use vim9 block inside nested autocmd (Issue #20918)

4 views
Skip to first unread message

lacygoill

unread,
8:25 AM (12 hours ago) 8:25 AM
to vim/vim, Subscribed
lacygoill created an issue (vim/vim#20918)

Steps to reproduce

Run this shell command:

vim -Nu NONE -S <(tee <<'EOF'
    vim9script
    autocmd FileType fzf autocmd BufWinEnter * ++once {
        autocmd SafeState * ++once if true
            |     echo
            | endif
    }
EOF
)

An error is given:

E1128: } without {: }

Expected behavior

No error is given.

Version of Vim

9.2 Included patches: 1-894

Environment

Operating system: Debian GNU/Linux 13 (trixie)
Terminal: XTerm(398)
Value of $TERM: xterm-256color
Shell: GNU bash, version 5.2.37

Additional context

This works:

vim9script
autocmd BufWinEnter * ++once {
    autocmd SafeState * ++once if true
        |     echo
        | endif
}

It's a regression because the original code used to work a long time ago.
But I don't know when it broke, and I can't bisect the issue because I can't compile old Vim versions.
When I try, I get this error:

checking for tgetent()... configure: error: NOT FOUND!
      You need to install a terminal library; for example ncurses.
      Or specify the name of the library with --with-tlib.

Which I don't understand, because I have libncurses-dev installed.

If someone could tell me how to compile old Vim versions, I could bisect the issue.


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/issues/20918@github.com>

h_east

unread,
5:30 PM (3 hours ago) 5:30 PM
to vim/vim, Subscribed
h-east left a comment (vim/vim#20918)

At script level the block is only read when the argument of :autocmd starts
with "{". In your example the argument of the outer :autocmd is

autocmd BufWinEnter * ++once {

which ends with "{" but does not start with it, so the outer :autocmd keeps
just that one line. The lines after it are executed as ordinary script lines
and the final "}" gives E1128.

This is the documented limitation: |:autocmd-block| points at |:command-repl|,
which says "No nesting is supported". It is also not a regression. The check
has been "the argument starts with {" since patch 8.2.3268, which added blocks
for :autocmd in 2021.

In a :def function it does work, because there the block is recognized by a
trailing "{" instead. That went in as patch 8.2.3271, on the same day. So
this is a workaround for now:

    vim9script
    def Setup()
      
autocmd FileType fzf autocmd BufWinEnter * ++once {
          autocmd SafeState * ++once if true
              |     echo
              | endif
      }
    enddef
    Setup()

The registered autocmd then holds the whole block, and it fires as you expect.

Two rules for the same syntax is not a good state, and I will have a look at
making the script level accept a trailing "{" as well.

About building older versions: on Debian tgetent is in libtinfo, not in
libncurses. Configure with

./configure --with-tlib=tinfo


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/issues/20918/5160427706@github.com>

Reply all
Reply to author
Forward
0 new messages