Norma Stitz
Norma Stitz

Reputation: 89

bash: line wrapping with fancy PS1 that does positional echo'ing

I have something like this in my login script that keeps $foo in the top right of my terminal. It works, but with a caveat. If I type a really long command it doesn't wrap. (Well, it'll wrap if it's more than two lines long, but the 2nd line overwrites the 1st line, if that makes sense.)

Anyone know how I can make bash wrap (i.e. insert newline) at $POS? Or even at $COLUMNS?

trunc_pwd () { # See http://www.tldp.org/HOWTO/Bash-Prompt-HOWTO/x783.html
   local pwdmaxlen=50 # Number of $PWD chars to keep
   local trunc_symbol="<" # Prepend to truncated $PWD
   if (( ${#PWD} > $pwdmaxlen )); then
      local pwdoffset=$(( ${#PWD} - $pwdmaxlen ))
      echo "${trunc_symbol}${PWD:$pwdoffset:$pwdmaxlen}"
   else
      echo ${PWD} | sed "s%^${HOME}%~%g"
   fi
}

foo="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

get_pos ()
{
   POS=$((COLUMNS-(${#foo}+4)))
}

if [[ ${PS1} ]]; then
   PROMPT_COMMAND='get_pos ; echo -ne "\033]0;${USER}@${HOSTNAME%%.*}:$(trunc_pwd)"; echo -ne "\007"'
   export PS1="\u@\h \W \$ \[\e[s\]\[\e[1;\$(echo -n \${POS})H\]$foo\[\e[u\]"
fi

Upvotes: 2

Views: 2111

Answers (1)

evil otto
evil otto

Reputation: 10582

Bash uses the \[ and \] escapes in the prompt to determine the line length and where to wrap. If you enclose anything that shouldn't affect the line length (the escape sequences, the $foo, etc) with those you should be ok.

I'm not sure why your prompt isn't working (and I don't recognize some of the escape sequences like \e[s, could be you're on something other than a vt100), my attempt works just fine:

PS1='\[\e7\e[0;$((COLUMNS-(${#foo})))H$foo\e8\][\u@\h \W]\$ '

actually re-looking at yours, it might work if you change your PS1 to

PS1="\u@\h \W \$ \[\e[s\e[1;\$(echo -n \${POS})H$foo\e[u\]"

i.e., wrapping \[ ... \] around all the out-of-line stuff.

Upvotes: 3

Related Questions