Understanding GNU Screen’s hardstatus strings

My cur­rent devel­op­ment set­up revolves main­ly around Vim and GNU Screen. I use Screen only to keep ses­sions run­ning between work days or in case I get dis­con­nect­ed, but late­ly I’ve been tempt­ed to try using dif­fer­ent win­dows inside Screen. In order to make this eas­i­er, I want­ed one of those sta­tus lines that shows you all your win­dows as “tabs”.

Con­fig­ur­ing this sta­tus line (the “hard­ware sta­tus line” or, as I’ll call it, “hard­sta­tus”) is done with a sin­gle, often long string of char­ac­ters in ~/.screenrc that at first can look entire­ly baf­fling:

hardstatus string "%{= KW} %H [%`] %{= Kw}|%{-} %-Lw%{= bW}%n%f %t%{-}%+Lw %=%C%a %Y-%M-%d"

Exact­ly.

To my dis­may, almost every­thing I can find about hard­sta­tus through Google are just dumps of oth­er people’s strings, with lit­tle to no expla­na­tion about why they do what they do – it’s easy to imag­ine that the peo­ple who post them hard­ly know why they do what they do, either. GNU’s offi­cial doc­u­men­ta­tion isn’t ter­ri­bly help­ful.

After final­ly deci­pher­ing a lot of what goes on in these strings, I want­ed to spell it out to any­body else who might be hunt­ing around for half a clue about this voodoo. There are (more than?) a few things I haven’t cov­ered here, of course – trun­ca­tion and con­di­tion­als, name­ly – but this should be enough to get you start­ed.

Below is my cur­rent hard­sta­tus string, with com­ments on each lit­tle unit inside it.

hardstatus string "%{= KW} %H [%`] %{= Kw}|%{-} %-Lw%{= bW}%n%f %t%{-}%+Lw %=%C%a %Y-%M-%d"
#
# http://www.gnu.org/software/screen/manual/html_node/String-Escapes.html
#
# %{= wK} : set colors to bright white (W) on bright black (K) and keep current text styles (=)
# %H      : hostname
# [       : opening bracket character
# %`      : print output of 'backtick' command (defined elsewhere in .screenrc)
# ]       : closing bracket character
# %{= wW} : set colors to white (w) on bright black (K) and keep current text styles (=)
# |       : bar character
# ${-}    : restore colors to previous colors / undo last color change
# %-Lw    : list windows before current window (L [optional] = "include flags")
# %{= bW} : set colors to bright white (W) on blue (b) and keep current text styles (=)
# %f      : window flags
# %t      : window title
# %{-}    : restore colors to previous colors / undo last color change
# %+Lw    : list windows after current window (L [optional] = "include flags")
# %=      : expand to fill all space (used here to make remaining content flush right)
# %C      : current time (12-hr; 24-hr is %c)
# %a      : am/pm (lowercase; uppercase is %A)
# %Y      : current year
# -       : hyphen character
# %m      : current month (0-padded; %M for "Jan" etc.)
# -       : hyphen character
# %d      : current date (0-padded)

This results in some­thing like this:

hardstatus

Let’s take a clos­er look at the types of things that these units are doing.

Text Styles

Any­thing inside {curly braces} changes the way the text in hard­sta­tus looks, and noth­ing more. I’ll get to this lat­er, so for now, let’s just strip out these strings, mak­ing the rest of the code some­what eas­i­er to under­stand. I rec­om­mend you do the same when study­ing any­body else’s hard­sta­tus strings.

 %H [%`] | %-Lw%n%f %t%+Lw %=%C%a %Y-%M-%d

Win­dows

Any­thing with a w (or W) in it deals with dis­play­ing the Screen win­dow titles them­selves. Some­where in the mid­dle of most hard­sta­tus strings will be some­thing like this:

%-Lw%n%f %t%+Lw

Book­end­ing this line are the strings %-Lw and %+Lw. These mean, sim­ply, “Print the (previous/next) win­dows”: %-w for the pre­vi­ous ones, %+w for the next ones, and L to indi­cate that we want those win­dows’ flags to appear as well (although this is option­al).

If we take these away, we’re left with this:

%n%f %t

This is the for­mat­ting of the title for our active win­dow: Num­ber, Flags, (space,) and Title. Sim­ple!

Sys­tem Info

Doing away with our win­dow list­ing, we’re left with this:

 %H [%`] | %=%C%a %Y-%M-%d

Let’s get rid of the last half of it right away, the stuff that was to the right of the win­dow list. %C%a %Y-%M-%d is just the time and date, and %= just tells Screen to shove every­thing after it to the right edge of the ter­mi­nal (more or less: this string “push­es” text away until it meets the screen edge or anoth­er %=).

Now all that remains is what was to the left of the win­dow list:

 %H [%`] |

%H is the host­name of the serv­er that we’re con­nect­ed to; the square brack­ets are lit­er­al­ly square brack­ets that get print­ed onto the screen, as is the ver­ti­cal bar. (Any­thing that isn’t pre­ced­ed by % will be print­ed out as-is.)

The back­tick char­ac­ter, %`, prints the out­put of what­ev­er you’ve assigned to the back­tick com­mand. In my case (in ~/.screenrc):

backtick 0 30 30 sh -c 'screen -ls | grep --color=no -o "$PPID[^[:space:]]*"'

This prints the name of my cur­rent Screen ses­sion. I have no idea why this does what it does; I con­fess I nicked it from Super User. My under­stand­ing is that lat­er ver­sions of Screen can or will be able to do this with a sim­ple escape char­ac­ter sim­i­lar to those above.

Text Styles (Again)

As I said, any­thing inside {curly braces} affects the way the text looks – this includes for­mat­ting (like bold, under­line, etc) and col­or. Here’s an exam­ple:

%{+bu wW}

The first half of the string inside the braces (+bu) tells hard­sta­tus to dis­play the fol­low­ing text as bold and under­lined. More styling codes are avail­able and are list­ed in GNU’s doc­u­men­ta­tion. The + indi­cates that we want to add this prop­er­ty; if we sub­se­quent­ly want­ed to unbold text, we would do some­thing like this: %{-b}.

The sec­ond half of the string (wW) tells hard­sta­tus which col­ors to use, the first char­ac­ter being the back­ground col­or and the sec­ond being the fore­ground col­or. In this case, we’re print­ing “bright white” on “white” (which is real­ly more of a light gray). Again, more codes are avail­able in GNU’s doc­u­men­ta­tion.

To reset text styles to their pre­vi­ous state (before the most recent change), all you need is %{-}.

Hope­ful­ly this will suf­fice to have you build­ing your own hard­sta­tus with­out blind­ly copy­ing oth­er people’s code from GitHub. If I’ve left any­thing out or got­ten any­thing wrong, please let me know in the com­ments.

Addi­tion­al help came from this com­ment on Stack Over­flow.