22

Lets's say my prompt looks like this (the _ represents my cursor)

~ % _

Is there any way I could make it look like this

~ % _
[some status]

The question was originally about zsh, but now has other answers.

1

2 Answers 2

17

The following settings seem to work. The text on the second line disappears if the command line overflows the first line. The preexec function erases the second line before running the command; if you want to keep it, change to preexec () { echo; }.

terminfo_down_sc=$terminfo[cud1]$terminfo[cuu1]$terminfo[sc]$terminfo[cud1]
PS1_2='[some status]'
PS1="%{$terminfo_down_sc$PS1_2$terminfo[rc]%}%~ %# "
preexec () { print -rn -- $terminfo[el]; }

% escapes are documented in the zsh manual (man zshmisc).

Terminfo is a terminal access API. Zsh has a terminfo module that gives access to the terminal description database: $terminfo[$cap] is the sequence of characters to send to exercise the terminal's capability $cap, i.e., to run its $cap command. See man 5 terminfo (on Linux, the section number may vary on other unices) for more information.

The sequence of actions is: move the cursor down one line (cud1), then back up (cuu1); save the cursor position (sc); move the cursor down one line; print [some status]; restore the cursor position. The down-and-up bit at the beginning is only necessary in case the prompt is on the bottom line of the screen. The preexec line erases the second line (el) so that it doesn't get mixed up with output from the command.

If the text on the second line is wider than the terminal, the display may be garbled. Use Ctrl+L in a pinch to repair.

0
5

Here is a bash equivalent of Gilles' zsh solution. Bash doesn't have a native terminfo module, but the tput command (bundled with terminfo) does much the same thing.

PS1_line1='\w \$ '
PS1_line2='[some status]'

if (tput cuu1 && tput sc && tput rc && tput el) >/dev/null 2>&1
then
    PS1="
\[$(tput cuu1; tput sc)\]
\[${PS1_line2}$(tput rc)\]${PS1_line1}"
    PS2="\[$(tput el)\]> "
    trap 'tput el' DEBUG
else
    PS1="$PS1_line2 :: $PS1_line1"
fi

If the terminal doesn't support one of the capabilities, it will fall back to a one-line prompt.

The trap line is a hacky way to emulate zsh's preexec function. See https://superuser.com/questions/175799/ for more info.

EDIT: Improved script based on Gilles' comments.

1
  • @Gilles: Thanks for the input! I think I've got it working better now. Tried bash 4.1.5 in gnome-terminal and xterm, and bash 3.2.48 in OSX Terminal.
    – Jander
    Jan 14, 2011 at 0:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.