Currently, my zshrc
looks like this
setopt prompt_subst # real time reevaluation of prompt zmodload zsh/mathfunc # int function function widthHelper() { echo $(( int(${COLUMNS:-80}) * ${1}/100)) } # calc $1% of prompt outWidth='$(widthHelper 40)' inWidth='$(widthHelper 90)' export PROMPT="%F{cyan}%${outWidth}<◀︎<%f" # truncation based on terminal width PROMPT+="%(l." # inner truncation group PROMPT+="%F{cyan}%8>‣>%n%>>%f" # username truncated PROMPT+="%-${inWidth}(l. %F{blue}%5>‣>%m%>>%f.) " # hostname truncated PROMPT+=".)" # end truncation PROMPT+="%F{magenta}%1~%f%<< " # pwd 1 depth PROMPT+="%# " # privilege group
influenced by this question and my other question
what is currently working as expected
- it truncates the hostname and the username to constant values
- it dynamically truncates the entire PROMPT based on
widthHelper()
which allows me to resize my terminal and dynamically truncate the PROMPT
Currently, I have this line working but not in the desired way
PROMPT+="%-${inWidth}(l. %F{blue}%5>‣>%m%>>%f.) " # hostname truncated
what I want
I want to have the displaying of the hostname depend on the length of the entire PROMPT
and not just rely on the width of the current terminal COLUMNS
.
i.e. I want the hostname to dissapear if I enter a directory with a very long name before I begin to truncate the entire prompt. But I do want both to happen in this order
- the hostname would dissapear (this happens but is not dependent on the
PROMPT
length but on the width of the entire terminal,COLUMNS
) - the entire prompt would begin to truncate on the left (this currently works)
example
If I am in a directory ~
then move into a directory with a long name ~/abcdefghijklmnopqrstuvwxyzabcd
I want the hostname to dissapear, but what is happening is that my prompt is being truncated first.
william‣ wmbp‣ ~ % william‣ wmbp‣ ~ % cd abcdefghijklmnopqrstuvwxyzabcd ◀︎m‣ wmbp‣ abcdefghijklmnopqrstuvwxyzabcd %
what I want
william‣ wmbp‣ ~ % william‣ wmbp‣ ~ % cd abcdefghijklmnopqrstuvwxyzabcd william‣ abcdefghijklmnopqrstuvwxyzabcd %
If I could make the # hostname truncated
line depend on the PROMPT
length then I could solve this issue.
tldr
How can I remove part of my PROMPT
based on how long my current PROMPT
is.
Advertisement
Answer
Ok so I solved my own problem but first I have to say the question was flawed because I am holding the length of the prompt to a solid percentage of the terminal window. So, I can not expect the prompt to do this
william‣ wmbp‣ ~ % william‣ wmbp‣ ~ % cd abcdefghijklmnopqrstuvwxyzabcd william‣ abcdefghijklmnopqrstuvwxyzabcd %
but what I can do is expect the terminal to do this
william‣ wmbp‣ Desktop % william‣ wmbp‣ Desktop % cd abcdefghijk william‣ abcdefghijk %
because the %
is aligned from one line to the next.
The way I got to this solution was to use this in my zshrc
LENGTH_OF_USERNAME=8 LENGTH_OF_HOSTNAME=5 # calc $1% of prompt function termWidthPercentHelper() { echo $(( int(${COLUMNS:-80}) * ${1}/100)) } function hostNameInPromptHelper() { # if you are in the home directory or if you are in a directory with a name # that has a length which is less than $1% of the terminal's width if [[ ${PWD##*/} == ${HOME##*/} ]] || [[ ${#PWD##*/} -lt $(termWidthPercentHelper $1) ]] then echo "%F{blue}%${LENGTH_OF_HOSTNAME}>‣>%m%>>%f " fi } PROMPT_PERCENTAGE='$(termWidthPercentHelper 30)' HOST_NAME_IN_PROMPT='$(hostNameInPromptHelper 9)' # left prompt export PROMPT="%F{cyan}%${PROMPT_PERCENTAGE}<◀︎<%f" # truncation based on terminal width PROMPT+='%(l.' # inner truncation group PROMPT+="%F{cyan}%${LENGTH_OF_USERNAME}>‣>%n%>>%f " # username truncated PROMPT+="${HOST_NAME_IN_PROMPT}" PROMPT+='.)' # end truncation PROMPT+='%F{magenta}%1~%f%<< ' # pwd 1 depth PROMPT+='%# ' # privilege group
I replaced the old line PROMPT+="%-${inWidth}(l. %F{blue}%5>‣>%m%>>%f.) " # hostname truncated
with a function call PROMPT+="${HOST_NAME_IN_PROMPT}"
. This is so that I can check the length of the current directory, and then either display the hostname or if the current directory is too long then not display the hostname.
things which helped me come to this solution
[[ ${PWD##*/} == ${HOME##*/} ]]
returns true if you are in your home directory${#PWD##*/}
gives the length of the present working directory without calling a subprocess
conclusion
What I wanted to do was not possible if I wanted to keep the entire prompt to a certain percentage of my terminal screen as seen in the previously named widthHelper
function call.
I was able to get to a point where my terminal would not display a portion of my PROMPT
if I entered a directory with a long name (See definition for hostNameInPromptHelper
above). I also tweaked the values for the percentage of my screen that is the prompt (i.e. PROMPT_PERCENTAGE='$(termWidthPercentHelper 30)'
) and the value set for the percentage of my screen that the length of the directory name can take up before I don’t display the hostname (i.e. HOST_NAME_IN_PROMPT='$(hostNameInPromptHelper 9)'
). These values work for me but if you might want to tweak these until you like your prompt.