[vim/vim] Using compiled functions in ftplugin breaks let statements in b:undo_ftplugin (Issue #9741)

93 views
Skip to first unread message

itchyny

unread,
Feb 10, 2022, 6:27:51 PM2/10/22
to vim/vim, Subscribed

Steps to reproduce

  1. Execute set ft=rust twice.
  2. Get following error.
Error detected while processing FileType Autocommands for "*"..function <SNR>5_LoadFTPlugin:
line    2:
E1126: Cannot use :let in Vim9 script

This is likely a breaking change by 3e79c97 .
The current rust ftplugin contains b:undo_ftplugin including let statements (https://github.com/vim/vim/blob/v8.2.4300/runtime/ftplugin/rust.vim#L151).
The undo ftplugin looks the similar problem too.
For compatibility of executing undo_* variables, maybe we should not migrate these functions to Vim9 script.

Expected behaviour

Shows no error.

Version of Vim

8.2.4300

Environment

macOS 12.2, iTerm2 3.4.12

Logs and stack traces

No response


Reply to this email directly, view it on GitHub.
Triage notifications on the go with GitHub Mobile for iOS or Android.
You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/issues/9741@github.com>

itchyny

unread,
Feb 10, 2022, 6:31:53 PM2/10/22
to vim/vim, Subscribed

The undo ftplugin looks the similar problem too.

Oops, I mean runtime/indent.vim.


Reply to this email directly, view it on GitHub.
Triage notifications on the go with GitHub Mobile for iOS or Android.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/issues/9741/1035641139@github.com>

matveyt

unread,
Feb 11, 2022, 2:46:31 AM2/11/22
to vim/vim, Subscribed

I guess that implies executing b:undo_ftplugin (as well as b:undo_indent) in legacy mode. However the problem is that legacy exe b:undo_ftplugin is still executed in the current mode (i.e. vim9script). Is that another bug?


Reply to this email directly, view it on GitHub.
Triage notifications on the go with GitHub Mobile for iOS or Android.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/issues/9741/1035951517@github.com>

Bram Moolenaar

unread,
Feb 11, 2022, 8:18:26 AM2/11/22
to vim/vim, Subscribed

Using "legacy exe" appears to fix it. What other problem do you see?


Reply to this email directly, view it on GitHub.
Triage notifications on the go with GitHub Mobile for iOS or Android.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/issues/9741/1036204829@github.com>

Bram Moolenaar

unread,
Feb 11, 2022, 8:31:01 AM2/11/22
to vim/vim, Subscribed

Closed #9741 via 92f645b.


Reply to this email directly, view it on GitHub.
Triage notifications on the go with GitHub Mobile for iOS or Android.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/issue/9741/issue_event/6051298879@github.com>

lacygoill

unread,
Feb 11, 2022, 10:24:53 AM2/11/22
to vim/vim, Subscribed

No, the issue persists. That's because :legacy is a modifier. Its effect stops at the next bar. We need to execute the variable from a legacy function. I'll try to send a patch later.


Reply to this email directly, view it on GitHub.
Triage notifications on the go with GitHub Mobile for iOS or Android.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/issues/9741/1036328639@github.com>

lacygoill

unread,
Feb 11, 2022, 10:26:40 AM2/11/22
to vim/vim, Subscribed

Actually, maybe it's a bug. Because here, :legacy doesn't stop at the bar:

:legacy execute 'eval 0 is# 0 | eval 0 is# 0'


Reply to this email directly, view it on GitHub.
Triage notifications on the go with GitHub Mobile for iOS or Android.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/issues/9741/1036330468@github.com>

lacygoill

unread,
Feb 11, 2022, 10:31:46 AM2/11/22
to vim/vim, Subscribed

Ah no, I was right, :legacy does stop at the bar in Vim9 context:

vim9script
legacy execute 'if true | eval 0 is# 0 | endif'
E15: Invalid expression: "is# 0 | endif"
E171: Missing :endif


Reply to this email directly, view it on GitHub.
Triage notifications on the go with GitHub Mobile for iOS or Android.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/issues/9741/1036335492@github.com>

lacygoill

unread,
Feb 11, 2022, 10:35:13 AM2/11/22
to vim/vim, Subscribed

So, it's a bug. Because other modifiers don't stop at the bar when they apply to an :executed string:

vim9script
silent execute 'echomsg "aaa" | echomsg "bbb"'
no message is logged


Reply to this email directly, view it on GitHub.
Triage notifications on the go with GitHub Mobile for iOS or Android.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/issues/9741/1036338802@github.com>

lacygoill

unread,
Feb 11, 2022, 10:38:37 AM2/11/22
to vim/vim, Subscribed

Actually, it's not even the bar which is problematic. It's the fact that the modifier is not applied at all with an :execute. And it's not specific to :legacy. Same issue with :vim9cmd:

:vim9cmd execute 'eval () => 123'


Reply to this email directly, view it on GitHub.
Triage notifications on the go with GitHub Mobile for iOS or Android.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/issues/9741/1036341825@github.com>

lacygoill

unread,
Feb 11, 2022, 10:42:58 AM2/11/22
to vim/vim, Subscribed

I noticed this issue a long time ago, but I thought it was working as intended. I think that :execute automatically runs the command at the script level. Here, the script is written in Vim9 context. Therefore, the command is executed in Vim9 context. IOW, :execute supersedes :legacy and :vim9cmd. The question is: should it? If it should, then there is no bug, and the solution is simply to execute b:undo_ftplugin from a legacy function.

diff --git a/runtime/ftplugin.vim b/runtime/ftplugin.vim
index 2500a7f27..01c092e8f 100644
--- a/runtime/ftplugin.vim
+++ b/runtime/ftplugin.vim
@@ -22,7 +22,7 @@ endif
 def LoadFTPlugin()
   if exists("b:undo_ftplugin")
     # We assume b:undo_ftplugin is using legacy script syntax
-    legacy exe b:undo_ftplugin
+    call s:UndoFtplugin()
     unlet! b:undo_ftplugin b:did_ftplugin
   endif
 
@@ -41,3 +41,7 @@ def LoadFTPlugin()
     endfor
   endif
 enddef
+
+function s:UndoFtplugin() abort
+  exe b:undo_ftplugin
+endfunction


Reply to this email directly, view it on GitHub.
Triage notifications on the go with GitHub Mobile for iOS or Android.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/issues/9741/1036345771@github.com>

matveyt

unread,
Feb 11, 2022, 12:03:55 PM2/11/22
to vim/vim, Subscribed

The question is: should it?

IMO, it should NOT. Consider also that both :execute and execute() do supersede, while :eval and eval() do not. This is really confusing.


Reply to this email directly, view it on GitHub.
Triage notifications on the go with GitHub Mobile for iOS or Android.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/issues/9741/1036420308@github.com>

Bram Moolenaar

unread,
Feb 11, 2022, 3:23:47 PM2/11/22
to vim/vim, Subscribed


> I noticed [this issue](https://github.com/lacygoill/wiki/blob/master/bug/vim.md#-72) a long time ago, but I thought it was working as intended. I think that `:execute` automatically runs the command at the script level. Here, the script is written in Vim9 context. Therefore, the command is executed in Vim9 context. IOW, `:execute` supersedes `:legacy` and `:vim9cmd`. The question is: should it? If it should, then there is no bug, and the solution is simply to execute `b:undo_ftplugin` from a legacy function.

> ```diff
> diff --git a/runtime/ftplugin.vim b/runtime/ftplugin.vim
> index 2500a7f27..01c092e8f 100644
> --- a/runtime/ftplugin.vim
> +++ b/runtime/ftplugin.vim
> @@ -22,7 +22,7 @@ endif
> def LoadFTPlugin()
> if exists("b:undo_ftplugin")
> # We assume b:undo_ftplugin is using legacy script syntax
> - legacy exe b:undo_ftplugin
> + call s:UndoFtplugin()
> unlet! b:undo_ftplugin b:did_ftplugin
> endif
>
> @@ -41,3 +41,7 @@ def LoadFTPlugin()
> endfor
> endif
> enddef
> +
> +function s:UndoFtplugin() abort
> + exe b:undo_ftplugin
> +endfunction
> ```

This looks more like a workaround than a solution. When using
"legacy exe" I would think most people expect "legacy" to apply to the
commands that "exe" will execute. It's mostly pointless otherwise.
Well, it could apply to evaluating the argument of ":execute" I suppose.
Would someone read it that way?

Let me make this work for :legacy and :vim9script. There might be other
modifiers that need to be handled like this, please come up with
examples if you can think of some.

--
The History of every major Galactic Civilization tends to pass through
three distinct and recognizable phases, those of Survival, Inquiry and
Sophistication, otherwise known as the How, Why and Where phases.
For instance, the first phase is characterized by the question 'How can
we eat?' the second by the question 'Why do we eat?' and the third by
the question 'Where shall we have lunch?'
-- Douglas Adams, "The Hitchhiker's Guide to the Galaxy"

/// Bram Moolenaar -- ***@***.*** -- http://www.Moolenaar.net \\\
/// \\\
\\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///


Reply to this email directly, view it on GitHub.
Triage notifications on the go with GitHub Mobile for iOS or Android.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/issues/9741/1036590842@github.com>

Wez Furlong

unread,
Feb 13, 2022, 9:15:04 AM2/13/22
to vim/vim, Subscribed

I just ran into this on Fedora 35 after installing today's critical updates. The error message is not easy to run down: it doesn't show a filename to give clues on what to look at, so I spent some time trying to figure out why vim9 was mentioned when I had vim8.2 and whether this was something I needed to fix in my dotfiles :-(

Is there scope for making that error messaging clearer?


Reply to this email directly, view it on GitHub.
Triage notifications on the go with GitHub Mobile for iOS or Android.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/issues/9741/1038147178@github.com>

Bram Moolenaar

unread,
Feb 13, 2022, 9:51:57 AM2/13/22
to vim/vim, Subscribed

It is working properly after the latest fixes, right?

It's difficult to give better error messages, since there are so many places involved.


Reply to this email directly, view it on GitHub.
Triage notifications on the go with GitHub Mobile for iOS or Android.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/issues/9741/1038171165@github.com>

Wez Furlong

unread,
Feb 13, 2022, 10:15:44 AM2/13/22
to vim/vim, Subscribed

this system just has the fedora vim packages installed, so my "fix" was to downgrade to an earlier version of the rpm(s). I know that's not super helpful for you, sorry!


Reply to this email directly, view it on GitHub.
Triage notifications on the go with GitHub Mobile for iOS or Android.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/issues/9741/1038186481@github.com>

lacygoill

unread,
Feb 13, 2022, 9:07:42 PM2/13/22
to vim/vim, Subscribed

For this kind of reasons, I've been thinking we should have a builtin package which populates the quickfix list with the last errors logged in :messages. Similar to cfilter-plugin.

I have something like that:

gif

But I still need to improve it in a corner case (the parsing doesn't fully handle an error given for a lambda which failed to compile). Also, not sure about the order of the display (first errors at the top vs at the bottom; in a given stack, last frame at the top vs at the bottom).


Reply to this email directly, view it on GitHub.
Triage notifications on the go with GitHub Mobile for iOS or Android.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/issues/9741/1038550098@github.com>

Josh Stone

unread,
Feb 16, 2022, 12:24:05 PM2/16/22
to vim/vim, Subscribed

I just ran into this on Fedora 35 after installing today's critical updates.

It is working properly after the latest fixes, right?

It's working for me with Fedora's update to vim-8.2.4386-1.fc35.


Reply to this email directly, view it on GitHub.
Triage notifications on the go with GitHub Mobile for iOS or Android.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/issues/9741/1041905251@github.com>

Reply all
Reply to author
Forward
0 new messages