Let's suppose you want your prompt to look something like this:
left text----------------------------------------------------------right text
prompt$
This is pretty straight-forward provided that right text
has a known size. (For example, it might be the current date and time.) What we do is to print the right number of dashes (or, for utf-8 terminals, the prettier \u2500
), followed by right text
, then a carriage return (\r
, not a newline) and the left text, which will overwrite the dashes. The only tricky bit is "the right number of dashes", but we can use $(tput cols)
to see how wide the terminal is, and fortunately bash
will command-expand PS1
. So, for example:
PS1='\[$(printf "%*s" $(($(tput cols)-20)) "" | sed "s/ /-/g") \d \t\r\u@\h:\w \]\n\$ '
Here, $(($(tput cols)-20))
is the width of the terminal minus 20, which is based on \d \t
being exactly 20 characters wide (including the initial space).
PS1
does not understand utf-8 escapes (\uxxxx
), and inserting the appropriate substitution into the sed
command involves an annoying embedded quote issue, although it's possible. However, printf
does understand utf-8 escapes, so it is easier to produce the sequence of dashes in a different way:
PS1='\[$(printf "\\u2500%.0s" $(seq 21 $(tput cols))) \d \t\r\u@\h:\w \]\n\$ '
Yet another way to do this involves turning off the terminal's autowrap, which is possible if you are using xterm
or a terminal emulator which implements the same control codes (or the linux console itself). To disable autowrap, output the sequence ESC[?7l. To turn it back on, use ESC[?7h. With autowrap disabled, once output reaches the end of a line, the last character will just get overwritten with the next character instead of starting a new line. With this technique, it's not really necessary to compute the exact length of the dash sequence; we just need a string of dashes which is longer than any console will be wide, say the following:
DASHES="$(printf '\u2500%0.s' {1..1000})"
PS1='\[\e[?7l\u@\h:\w $DASHES \e[19D \d \t\e[?7h\]\n\$ '
Here, \e[19D
is the terminal-emulator code for "move cursor backwards 19 characters". I could have used $(tput cub 19)
instead. (There might be a tput
parameter for turning autowrap on and off, but I don't know what it would be.)
The example in the video also involves inserting a right-aligned string in the actual command line. I don't know any clean way of doing this with bash
; the console in the video is almost certainly using zsh
with the RPROMPT
feature. Of course, you can output right-aligned prompts in bash
, using the same technique as above, but readline
won't know anything about them, so as soon as you do something to edit the line, the right prompt will vanish.