1

Suppose, for example, that PS1 has the value shown below:

'\w (\[\e[32m\]${__git_ps1_branch_name}\[\e[0m\] \[\e[31m\]*\[\e[31m\]%\[\e[0m\]>)\$ '

...where __git_ps1_branch_name is some string, like master or feature123.

Q: I am looking for a way to compute the on-screen width (in number of characters) of the prompt that bash will generate from a PS1 like the one shown above.


Recent versions of bash expand the expression ${PS1@P} to the string obtained by replacing the elements of the prompt specification above by their final display values. (Thus \w will be replaced by the path to the current directory, for example, and ${__git_ps1_branch_name} will be replaced by the string contained in the __git_ps1_branch_name variable, etc.) This however is not enough to solve the problem.

More specifically, if we set:

EXPANDED_PS1="${PS1@P}"

...the expression ${#EXPANDED_PS1} (i.e. the number of characters in $EXPANDED_PS1) yields a number that is significantly greater than the on-screen width of the prompt that bash would generate from $PS1. The excess comes from the escape sequences that confer color to the displayed prompt.

In any case, I am also interested in solutions that will work with versions of bash that do not support @P.

1

1 Answer 1

1

Without support for @P it is difficult. The thing is, you need to expand PS1, but that function is private, so you cannot use it directly. Still, there are some very nice tries in this question.

If you do have support for @P then this might work for you:

$ echo -ne "\n${PS1@P}\033[6n";read -e -s -d R cnt;cnt=$((${cnt#;} - 1));echo $cnt

First a new line and the expanded PS1 string are sent. That means that the cursor will now be at the column length_of_PS1 + 1.

Then the ANSI escape code Device Status Report (CSI6n) is sent. The terminal answers back with:

Reports the cursor position (CPR) by transmitting ESC[n;mR, where n is the row and m is the column.)

The value is read from the standard input and placed into cnt.

It' hackish, just for ANSI terminals, but it seems to work. Note that if the expansion is longer than the width of the terminal, the column will not show the length of PS1. Output from other processes could also be a problem.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .