ZSH Shell Prompt Horizontal Line

Issue

When scrolling thru your terminal’s history it can be difficult to see where each command begins and ends.

Solution

The Z shell has two features that makes it possible to draw a horizontal line the full width of the terminal window.

ZSH Prompt Horizontal Divider

The first feature is the variable $COLUMNS which contains the current number of characters displayed in each line of the terminal window. This means the value changes if you resize the window.

The second feature is string expansion. The man page is a bit terse in defining functionality so I’ve added an example demonstrating how the string feature works.

FeatureMan Page DefinitionExample
l:expr::string1::string2

: is the argument delimiter
l means pad left
expr is the width of the column
string1 is the characters to use for padding
string2 is the value to display
Pad the resulting words on the left. Each word will be truncated if required and placed in a field expr characters wide.
The arguments :string1: and :string2: are optional; neither, the first, or both may be given. Note that the same pairs of delimiters must be used for each of the three arguments. The space to the left will be filled with string1 (concatenated as often as needed) or spaces if string1 is not given. If both string1 and string2 are given, string2 is inserted once directly to the left of each word, truncated if necessary, before string1 is used to produce any remaining padding.
This feature lets you print out data in a column expr characters wide. This is useful when displaying numerical data in a table format.

For example to right justify a number and pad with asterisks on the left.
» echo ${(l:10::*::67890:)}
results in
*****67890
r:expr::string1::string2

: is the argument delimiter
r means pad right
expr is the width of the column
string1 is the characters to use for padding
string2 is the value to display
[Same] As l, but pad the words on the right and insert string2 on the right.For example to left justify a number and pad with asterisks on the right.
» echo ${(r:10::*::12345:)}
results in
12345*****

If you want to display a character n times you can by not providing string2
» echo ${(r:10::*:)}
results in
**********

Therefore, knowing the number of columns, we can draw a line the width of the terminal window.


# Set prompt substitution on so that ${} are evaluated. 
set -o PROMPT_SUBST

# Add new line to the prompt.
PS1=$'\n'

# Set the text to green.
PS1=$PS1'%F{%(#.white.green)}'

# Add a horizontal line to the prompt.
PS1=$PS1'${(r:$COLUMNS::—:)}'

# Add UserName@HostName and pwd to the prompt.
PS1=$PS1'%n@%m %~ » '

# Change the text after the prompt to orange.
PS1=$PS1'%F{%(#.white.orange)}'

Conclusion

Visually separating terminal commands with horizontal lines makes it easier to find previously ran commands.