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.
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It only takes a minute to sign up.
Sign up to join this communityLets'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.
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.
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.