-
Notifications
You must be signed in to change notification settings - Fork 1.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Detect $status being carried over from last command #6815
Comments
No. We show $status as it is, anything else is more confusing, because now interactive fish and script-fish behave differently. |
Fair enough. What about introducing a variable to detect "empty status"? Then it could be up to prompt authors to handle that specially (e.g. indicate that the status "carried over"), without affecting the default prompt. |
The motivation behind this request is that I print a "summary" for commands that don't exit 0, indicating the error code and time. But it's weird to see " ✘ 1 ⬥ set ⬥ 12:04:20" since |
Actually, thinking about this some more, I don't agree completely. My mental model is that at the prompt, the status is "clean", and the displayed status is whatever the result of the previous command was. I don't consider my entire shell session similar to a single fish script, but rather I consider it similar to a bunch of tiny fish scripts. So in my mind, the return value of a single command in interactive mode would be the same as the return value of But this is tangential, it's entirely possible that my mental model is in the minority, and adjusting that is not a big deal. The only problem here is that there's no way for me to detect the empty/carried-over status. |
I would argue that your mind is... well, wrong. The commandline is positively dripping in state that carries over. Any Your shell session is a single fish script. It's "read line, execute line, read line, execute line". I don't think papering over that does any good. |
Huh, I didn't realise In any case, all I really need here is some way to detect that the last command had an empty status. I guess it's possible to hack that with some |
Hmm, For I'm out of ideas on this problem. For now I'll just hack it with some checks against argv in my postexec function, but it would be nice to have a proper solution. |
Nope, can't hack it in postexec either 😞 Consider the pathological case:
If varname has invalid characters, then the exit status of 2 is actually caused by set, otherwise it's caused by the preceding command "return2". Since there's no way to know that from just the commandline, any attempts to do so will be wrong under certain circumstances. So any changes to support this must happen in the shell itself. |
Okay, I hacked something together in #6820 that "works on my machine":tm: This is just a proof of concept, but it could help further discussions by providing a concrete example implementation. |
I agree that the carried-over status is irritating and we should make it feel more natural. Reminds me of this thread on twitter. Changing the language semantics or lying about printf '$ false\n'
printf '%s[1]%s $ set -l a b\n' (set_color --bold red) (set_color normal)
printf '%s[1]%s $\n' (set_color $fish_color_autosuggestion) (set_color normal) |
That sounds good to me, even though I'm not very invested in what the default prompt looks like 😉 In my current implementation, that could be |
Another point in favour of adding some form of optional return, at least for the builtins, is Because
However, this function will always print only one value in "exit(s):", regardless of how long the previous pipeline was. That's because The fix in this instance is to first save For this reason, I strongly think optional return (at the very least for the |
In bash an assignment statement like
Yeah, I think that's what we need to fix the above: keep track of whether a command in a job actually changed I'm not sure what you mean by optional return for |
As opposed to blanket not returning from
I'm not sure about how to handle
It's possible my approach was overly complicated, but on my first attempt to get this working I discovered that there are many, many instances of At that point it's just a matter of whether you prefer having a second argument to |
For this issue, I think it would make sense to add a new status variable alongside Perhaps |
There are some complexities around introducing a new variable (either the "generation" or the "last_status"), when it comes to their values in the middle of a single prompt vs. multiple prompts. For example, if I run This also doesn't address the inconsistency between And because of the way It's possible I'm too focussed on one approach and I'm missing a much simpler solution. I'd love to hear your ideas on this topic. |
Referencing the PR, the first commit (223ab32) only handles the '&' case. This can be reasonably re-purposed to change last_status or update a generation variable instead (after resolving the multiple commands in one prompt issue). The second commit (c41568d) is the not-as-nice code (in my opinion) that ends up making If your concern is primarily with the first commit, then I can easily make changes to accommodate your proposal (with some discussion on how you want to handle non-interactive mode, since it's basically tied to the prompt rendering right now). |
@ridiculousfish Have you had a chance to look at this? I'd like to hear what your thoughts are on the problem I ran into with the |
@soumya92 Thank you for your patience, I am catching up. I like the
That leaves Thank you for the great contribution! |
@ridiculousfish Not a problem! Just making sure that the issue was not abandoned. I'll try to get something out this week that uses the approach you've outlined. I think the difference between handling |
Okay, so I tried the job_t::continue_job approach, but that fails the case of I think this is because Line 2199 in 3571754
job_t to be produced, and the last one ends up writing a held-over status, even though that status came from the one just before in the same commandline.
So I think I need to be able to track whether the status was set at any point in evaluating Before I go too deeply down a rabbit hole again, what are your thoughts on this matter? |
I get it - from fish's point of view these are indeed separate jobs, but as a user you would like an indication that that the status was set since the last prompt. How about a generation count, then? Every time a new status is set, increment the number. Then if the number hasn't changed since the last prompt, the status is a holdover. The gen count could potentially live in |
Ohh, yeah, that makes sense. For some reason when that was suggested earlier I just did not make the leap of putting in parser's libdata. I will put something together for review shortly. |
fish, version 3.1.0
I did not expect this:
I understand why this is happening, since both
set
and&
do not modify the status. And that behaviour is great for scripts.But it was still surprising to me that the [1] carried over in the prompt. Would it be possible for $status to be cleared somehow in preexec, so that it's only set to a non-zero value if it was explicitly caused by the last command? Or introduce a variable that could indicate that the previous command had no status?
(I tried
set status 0
in--on-event fish_preexec
, but as expected, that did not work)The text was updated successfully, but these errors were encountered: