I noticed in this video, that the terminal prompt extends the entire width of the terminal before breaking down to a new line. How can I set my PS1
variable to fill the remaining terminal space with some character, like the way this user did?
The issue is, I don't know how to update the PS1
variable per command. It seems to me, that the string value for PS1
is only read in once just as the .bashrc
file is only read in once. Do I have to write some kind of hook after each command or something?
I should also point out, that the PS1
variable will be evaluated to a different length based on the escape characters that make up it. For example, \w
print the path.
I know I can get the terminal width using $(COLUMNS)
, and the width of the current PS1
variable with ${#PS1}
, do the math, and print the right amount of buffer characters, but how do I get it to update everytime. Is there a preferred way?
Quick tip: You can also use the Ctrl + Shift , (comma) keyboard shortcut to open the settings page. Click on Startup. Under the “Launch size” section, use the Columns option to adjust the width of the Windows Terminal. Under the “Launch size” section, use the Rows option to adjust the height of the Windows Terminal.
You should go to Edit->Profile Preferences, General page and check Use custom default terminal size, and then set your preferred horizontal and vertical dimensions.
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.
Use PROMPT_COMMAND
to reset the value of PS1
before each command.
PROMPT_COMMAND=set_prompt
set_prompt () {
PS1=...
}
Although some system script (or you yourself) may already use PROMPT_COMMAND
for something, in which case you can simply add to it.
PROMPT_COMMAND="$PROMPT_COMMAND; set_prompt"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With