Add set --no-event to change a variable without triggering an event#10480
Conversation
This allows running `set` without triggering any event handlers. That is useful, for example, if you want to set a variable in an event handler for that variable - we could do it, for example, in the fish_user_path or fish_key_bindings handlers. This is something the `block` builtin was supposed to be for, but it never really worked because it only allows suppressing the event for the duration, they would fire later. See fish-shell#9030. Because it is possible to abuse this, we only have a long-option so that people see what is up.
This is how we can use it in a backwards-compatible way. Eventually we would remove the compatibility guff.
There was a problem hiding this comment.
Tho the binding functions have basically been rewritten to handle the new bind notation, I'm not entirely sure how an old fish accidentally running the new version would work?
I'd rather not introduce backwards compat workarounds into the codebase if we're not sure they're necessary. The only case I think we have to support is "user upgrades fish, is still running old fish because they haven't started a new session."¹ I don't think there's a way to re-exec the old fish binary (we always load it from the disk) so the new version of startup-only code (like the key bindings) should theoretically never be seen/executed by the older fish install, no?
If there's a situation I'm not seeing, then by all means, please enlighten me. Otherwise, we have never supported multi-versioning of fish and standalone, unpackaged builds of fish should be using the share/ directory from the source code distribution and not from $(PREFIX)/usr/share, right?
¹ For the record, we have shipped upgrades in the past that broke this scenario. It's obvious what's happened if you are intimately familiar with fish, but I pity those that had an OS auto-update in the background and then started seeing random script errors when sourcing various completions or autoloading now-incompatible functions.
To be clear: Working around a lack of --no-event is necessary. I was talking about how an old fish would interpret the new bind sequences - it would probably error out a lot, but I think there's enough there that the bindings should still be enough to at least reexec fish?
The problem is that fish reloads functions that have changed on-disk. So you have a long-running fish session, you upgrade fish, and in that long-running fish session something triggers a binding change. If that happens after it reloaded the function, you've now run You now have a hanging fish that is impossible to kill from inside. I believe that's egregious and should not be allowed. We could improve this in other ways, like e.g. removing the auto-reloading of functions because it's a major PITA on upgrade. But the important part is that we sometimes need to do something to not make it horrible when people upgrade. (of course I have also tried to accomodate people who get newer functions for older fishes, within reason - that won't happen here because the function's been 90% rewritten already) |
|
The case you describe would indeed by terrible, but there's something I'm missing:
When and where does this happen? I always have to constantly EDIT: We actually had to add a workaround for this to the |
|
Weird, that's supposed to happen. Regardless, even if it didn't, the failure mode here is sufficiently terrible that a bit of effort is warranted - even if someone ran an old fish and switched to vi-mode they'd trigger this, and it would kill their bindings. It's also just a couple of lines, so I feel like we're already having more of a discussion about it than it really warrants. Are you okay with the feature itself? |
|
Yeah, I think the feature itself makes sense and simplifies a lot of the trickier cases involving events. It's a straightforward escape hatch. |
Description
As mentioned in #9030 this adds a
--no-eventoption toset, so you can set or erase a variable without triggering the event.Example:
There is no short option because this is an advanced option that should be used with care.
This does what a potential use of the
blockbuiltin would do in a simpler way, and it can be used to remove one of the gnarliest parts of our key binding functions: They set the variable, causing the handler to be run, which then runs the function again.This upgrades our functions to use
--no-event, but notably in a way that it'll handle being run by older fishes. This is necessary because otherwise we'd be left with no bindings at all. Tho the binding functions have basically been rewritten to handle the new bind notation, I'm not entirely sure how an old fish accidentally running the new version would work?TODOs: