-
Notifications
You must be signed in to change notification settings - Fork 8
Prompt improvements, primarily for zsh users #240
base: master
Are you sure you want to change the base?
Conversation
I've had these changes live on my workstation for the past four weeks with no issues, on macOS zsh with ktx and maws and correct whitespace:
|
echo " (maws keys expired)" | ||
PROMPT_BASH_CODE = r''' | ||
function maws_profile { | ||
if [[ -n $MAWS_PROMPT ]]; then |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also it's always good to quote shell variables to avoid unexpected behavior when the value in the variable contains spaces or other oddities.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd used
[
instead of[[
to be most broadly compatible.[
is a POSIX standard whereas[[
is a bash extension that comes from KSH.What would you think about retaining the POSIX standard
[
across this code?
The original code for PROMPT_BASH_CODE
already took for granted that the shell was bash or bash-compatible (the use of $(date +%s)
, specifically), and would not only fail with syntax errors but also fail to modify the user's prompt (the assumption that PS1
is the prompt), each time they eval the output of maws; in a brief chat with someone else, they just don't eval maws output and grab the environment variables instead. I don't expect this patch makes that scenario any worse for them, and I'm not taking "support non-bash-compatible prompts" into the scope of the pull request.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also it's always good to quote shell variables to avoid unexpected behavior when the value in the variable contains spaces or other oddities.
When working with bash-specific conditionals inside [[
... ]]
, overquoting not only is unnecessary but can break functionality of regular expressions and string-prefix/suffix comparisons. The specified bash code passes all shellcheck reviews and the only warning is an SC2016 false positive, as we're specifically avoiding string interpolation in a case where virtually everyone else is expecting to interpolate (because we're deferring interpolation until prompt eval time).
I would be more wary if this were not PROMPT_BASH_CODE
and were instead meant for other shells, but as above, this has always taken for granted bash and expanding or repairing that constraint is out of scope here.
|
||
# if the user hasn't disabled prompt injection, | ||
# and we aren't already injecting maws_profile: | ||
if [[ -z $MAWS_PROMPT_DISABLE && $PS1 != *'$(maws_profile)' ]]; then |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Best to quote this variable in the conditional test
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Quoting the variable on the left is unnecessary (see above); quoting the variable on the right will break the string-prefix comparison, as the wildcard needs to remain unquoted to activate that functionality inside [[
... ]]
.
if [[ $PS1 == *'\$ ' ]]; then | ||
# prompt ends with dynamic '\$ ' | ||
# if the original prompt surrounds the final '\$' with whitespace, | ||
# we surround the substitution with whitespace to maintain that. | ||
[[ $PS1 == *' \$ ' ]] && MAWS_PROMPT_PREFIX="" MAWS_PROMPT_SUFFIX=" " | ||
# inject our substitution before the original '$ ' | ||
PS1="${PS1%\\$ }\$(maws_profile)\\$ " | ||
elif [[ $PS1 == *'$ ' ]]; then | ||
# prompt ends with hard-coded '$ ' | ||
# if the original prompt surrounds the final '$' with whitespace, | ||
# we surround the substitution with whitespace to maintain that. | ||
[[ $PS1 == *' $ ' ]] && MAWS_PROMPT_PREFIX="" MAWS_PROMPT_SUFFIX=" " | ||
# inject our substitution before the original '$ ' | ||
PS1="${PS1%\$ }\$(maws_profile)\$ " | ||
elif [ "${PS1% }" != "${PS1}" ]; then | ||
PS1="${PS1% }\$(maws_profile) " | ||
elif [[ $PS1 == *'%# ' ]]; then | ||
# prompt ends with dynamic '%# ' | ||
# if the original prompt surrounds the final '$' with whitespace, | ||
# we only suffix bot not prefix with whitespace to maintain that. | ||
[[ $PS1 == *' %# ' ]] && MAWS_PROMPT_PREFIX="" MAWS_PROMPT_SUFFIX=" " | ||
# inject our substitution before the original '%# ' | ||
PS1="${PS1%\%# }\$(maws_profile)%# " | ||
else | ||
# we're the last entry in the prompt, so we don't need extra whitespace. | ||
# if the original prompt ends with whitespace, | ||
# we don't need to prefix whitespace ourselves. | ||
[[ $PS1 == *' ' ]] && MAWS_PROMPT_PREFIX="" | ||
# inject our substitution before the original '%# ' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is it about how git does this for bash and ZSH that differs from how we're doing it such that they don't encounter this whitespace challenge?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Git's default instructions in 3a) only support the default bash prompt case, which does not have whitespace between the CWD
and the $
/#
character terminator; however, the macOS default zsh prompt has the extra whitespace by default, and so in that scenario the git 3a) instructions will encounter the same problem; the instructions provided in 3b) would require significant rewriting beyond just offering whitespace tuneable variables, and given their pre/post model, I'm not certain it would solve the problem, as they're using the parameters in a string-join manner rather than a "do you wish to prepend/append a space". So I went for the low-hanging fruit of "make it work the same for everyone who never cares about this, while making it possible to fix this if you do", without taking the full 3b) path.
I've been having some issues with the prompts set by maws on my macOS install, and so today I worked out what they are and improved prompt handling in the script. I've done limited testing of this on zsh and will be collecting additional reviews and testing now that I've reached a stable point. The changelog additions for this pull request are:
Fixed
Changed
Added
MAWS_PROMPT_DISABLE=1
. (This also lets users implement their own custom prompts without forking, as long as they definefunction maws_profile () { }
in bashrc/zshrc.)