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
Add option to insert newline when prompt is long #617
base: master
Are you sure you want to change the base?
Add option to insert newline when prompt is long #617
Conversation
0530580
to
e74fc50
Compare
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.
Thanks for the PR! As I'm sure you saw on the feature request, I agree this is a needed feature.
A few things to note:
Even with this check, there a quite a few scenarios where this will not work right or make it worse. This ignores how wide your terminal is, and could add a newline where it doesn't make sense at all. A better implementation would decide to wrap based on how many columns are left, not how many have been taken. This is obviously harder. Imagine a scenario where the prompt is 60 characters, but the terminal is 55 characters. Should you add a newline? Probably not.
I wasn't planning on adding this feature until v2.1, as I wanted other reworking of stuff to happen first. Not saying that I can't merge this before then, only that I want this to look pretty close to the final form, not some partial thing that adds more work for v2.0.
Anyway, let's start with these changes and see if we can't come up with a solution for my above hypothetical scenarios.
liquidprompt
Outdated
@@ -1849,6 +1850,14 @@ _lp_set_prompt() | |||
# is set. | |||
PS1+="${LP_VCS}" | |||
|
|||
if [[ "$LP_MINIMUM_CMD_LENGTH" -ne 0 ]]; then | |||
if [[ $(_remaining_space) -lt "$LP_MINIMUM_CMD_LENGTH" ]]; then | |||
LP_MARK_PREFIX=$'\n' |
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.
Technically, even though it isn't documented as such, $LP_MARK_PREFIX
is a valid configuration variable:
https://github.com/nojhan/liquidprompt/blob/deff598f30f097279d6f6959ba49441923dec041/liquidprompt#L347
Overriding it here would break the config of anyone who configures this. I'm not sure what the right way to do it would be (maybe add another var??), but this isn't it.
liquidprompt
Outdated
@@ -1849,6 +1850,14 @@ _lp_set_prompt() | |||
# is set. | |||
PS1+="${LP_VCS}" | |||
|
|||
if [[ "$LP_MINIMUM_CMD_LENGTH" -ne 0 ]]; then | |||
if [[ $(_remaining_space) -lt "$LP_MINIMUM_CMD_LENGTH" ]]; 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.
No need for a new function: _lp_as_text()
does the stripping already:
if [[ $(_remaining_space) -lt "$LP_MINIMUM_CMD_LENGTH" ]]; then | |
local printable_ps1=$(_lp_as_text "$PS1") | |
if [[ ${#printable_ps1} -lt "$LP_MINIMUM_CMD_LENGTH" ]]; then |
Add new setting LP_MINIMUM_SPACE_AFTER_PROMPT. A new line is added when the prompt would leave less space than this in the terminal. See feature request liquidprompt#599.
8e55fe6
to
50234ed
Compare
Thanks for the quick response.
I actually used $COLUMNS to take into account the terminal width and handled the edge cases in the
So for a prompt length of 60 and terminal 55, remaining space would be 50 However, I admit it wasn't clear from the variable names or documentation that this what I was doing, so I've hopefully made that clearer. I've taken perl out and used I also added an I'm a bash user, but I've tested it with zsh and it seems to be working as I expect. |
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.
Thanks for updating this PR. Unfortunately there is no way to merge this without first a rebase onto the current master
. There have been too many changes since then.
I'm happy to help if you run into issues with rebasing, just let me know. You will want to look at the new docs/
folder to add documentation, and if you still need to add a new function like _remaining_space()
, you should add tests for it in tests/test_utils.sh
.
_lp_length() | ||
{ | ||
typeset len evaluated_ps1 | ||
typeset printable_ps1=$(_lp_as_text "$1") |
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.
This (typeset and assignment on the same line) is unsafe in zsh < 5.1:
% func() {
typeset var=$(echo foo bar)
echo "$var"
}
% func
foo
Either wrap in quotes or break into two lines:
typeset printable_ps1=$(_lp_as_text "$1") | |
typeset printable_ps1="$(_lp_as_text "$1")" |
Check for other issues like this, I see a few other instances.
typeset printable_ps1=$(_lp_as_text "$1") | ||
|
||
if $_LP_SHELL_bash; then | ||
evaluated_ps1=$(printf '%s' "${printable_ps1@P}") |
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.
This is a Bash-4.4+ feature:
https://github.com/bminor/bash/blob/76404c85d492c001f59f2644074333ffb7608532/CHANGES#L2400-L2401
Liquidprompt supports Bash-3.2+, so this is a no-go.
How to evaluate escape codes is a known problem in Liquidprompt. See:
- Terminal title: Make title bar work out-of-the-box with Gnome Terminal #609 (comment)
- Ksh support: Ksh compatibility #608 (comment)
On the surface it is simple, and should not be hard to fix, but I think there could be issues that spring up when we try to replace all escape codes with strings.
Anyway, that is on the top of my to-do list for v2.1. I don't see a way to make this PR work without that first, so you might need to wait...
len=${#evaluated_ps1} | ||
|
||
echo $len |
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.
Post-rework Liquidprompt avoids using stdout to return values. Use a variable, named after the function:
len=${#evaluated_ps1} | |
echo $len | |
lp_prompt_length=${#evaluated_ps1} |
Oh and name the function __lp_prompt_length()
. The name is too generic, and lies about what it does.
# add return code | ||
PS1+="${LP_RUNTIME}${LP_ERR}" | ||
|
||
# determine if we need to add new line before prompt mark | ||
if (( LP_MINIMUM_SPACE_AFTER_PROMPT )); then | ||
if [[ $(_remaining_space) -lt "$LP_MINIMUM_SPACE_AFTER_PROMPT" ]]; then | ||
PS1+=$'\n' | ||
fi | ||
fi | ||
|
||
# add prompt mark | ||
PS1+="${LP_MARK_PREFIX}${LP_COLOR_MARK}${LP_MARK}${LP_PS1_POSTFIX}" |
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.
This part is elegant.
The problem is that this section is possibly in the user's control. If the user has a template file ($LP_PS1_FILE
), this block will never be run.
If we are going to advertise this as a feature, it needs to work no matter what template or theme the user is running. I'm not sure at the moment how to fix that, something to worry about later after the other issues are fixed maybe.
If I can help (by testing, basically) this feature on |
Add new setting
LP_MINIMUM_CMD_LENGTH
, which controls when a newline is added. Setting defaults to 0 (disabled).See feature request #599.
I had to use perl for removing the non-printable characters from the prompt. It doesn't feel like the nicest solution, but I couldn't remove them with bash pattern matching or sed. This was due to the requirement to match the 2 characters at the end of each block:
\]
.Let me know if there's anything you'd like changed, I'm keen to do all I can to get this merged. I only discovered this project recently and it's almost perfect - this is the missing piece of the puzzle for me!