Expose previous command's exit status as variable
Background
It is often useful to get the "exit status" of a previous command in a shell session. Many shells expose this as $?. This can be used for a variety of purposes, including but not limited to altering the current prompt.
Elvish handles exceptions in a generally more predictable and safe manner compared to its fellow shells, but even then it may be useful to know if the previous command was $ok or with an error
Proposed solution
Expose a variable (bash uses $?, which is opaque, fish uses $status) that holds either the previous exception, or $ok. This can be thought of as wrapping the eval of each command executed interactively in a ?() and storing the return.
One note: this will necessarily be a feature of the REPL instead of the language itself. There are two reasons: When executing code non-interactively, an exception will always break out of the current scope, so a $status variable wouldn't make sense. For instance, in this code:
fail error # [1]
echo $status # [2]
The code on [2] is never executed, because the exception in [1] would break out of the current scope. To capture exceptions, an outer scope must be introduced with a try/catch form.
However, in a REPL, the code on [1] and [2] can be executed separately, and in that case a $status will make sense. As such it would also make sense to put this variable in the edit: namespace instead of the builtin namespace.
FWIW, See issue #1029 for how a hypothetical after-cmd hook would behave that is part of the builtin: namespace rather than edit:. That would allow capturing this information and used in whatever form the user desires. Such as displaying in their prompt.
I believe the implementation of edit:after-command added by commit e2f810048 on 2021-03-15 resolves this issue.
This should be closed. A variable such as the POSIX $? isn't useful in Elvish. If you want to display the exit status in your prompt (why?) you can use the edit:after-command hook to capture the exception that occurs when an external command exits with a non-zero status.