Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

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.

share|improve this question
    
How about screen + buobu?: launchpad.net/byobu, and maybe kmandla.wordpress.com/2010/01/03/… for screenshots –  Janus Jan 14 '11 at 8:44
add comment

2 Answers

up vote 16 down vote accepted

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.

share|improve this answer
add comment

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 http://superuser.com/questions/175799/ for more info.

EDIT: Improved script based on Gilles' comments.

share|improve this answer
    
@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 '11 at 0:12
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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