Understanding GNU Screen’s hardstatus strings

My current development setup revolves mainly around Vim and GNU Screen. I use Screen only to keep sessions running between work days or in case I get disconnected, but lately I’ve been tempted to try using different windows inside Screen. In order to make this easier, I wanted one of those status lines that shows you all your windows as “tabs”.

Configuring this status line (the “hardware status line” or, as I’ll call it, “hardstatus”) is done with a single, often long string of characters in ~/.screenrc that at first can look entirely baffling:

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

Exactly.

To my dismay, almost everything I can find about hardstatus through Google are just dumps of other people’s strings, with little to no explanation about why they do what they do – it’s easy to imagine that the people who post them hardly know why they do what they do, either. GNU’s official documentation isn’t terribly helpful.

After finally deciphering a lot of what goes on in these strings, I wanted to spell it out to anybody else who might be hunting around for half a clue about this voodoo. There are (more than?) a few things I haven’t covered here, of course – truncation and conditionals, namely – but this should be enough to get you started.

Below is my current hardstatus string, with comments on each little 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 something like this:

hardstatus

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

Text Styles

Anything inside {curly braces} changes the way the text in hardstatus looks, and nothing more. I’ll get to this later, so for now, let’s just strip out these strings, making the rest of the code somewhat easier to understand. I recommend you do the same when studying anybody else’s hardstatus strings.

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

Windows

Anything with a w (or W) in it deals with displaying the Screen window titles themselves. Somewhere in the middle of most hardstatus strings will be something like this:

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

Bookending this line are the strings %-Lw and %+Lw. These mean, simply, “Print the (previous/next) windows”: %-w for the previous ones, %+w for the next ones, and L to indicate that we want those windows’ flags to appear as well (although this is optional).

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

%n%f %t

This is the formatting of the title for our active window: Number, Flags, (space,) and Title. Simple!

System Info

Doing away with our window listing, 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 window list. %C%a %Y-%M-%d is just the time and date, and %= just tells Screen to shove everything after it to the right edge of the terminal (more or less: this string “pushes” text away until it meets the screen edge or another %=).

Now all that remains is what was to the left of the window list:

%H [%`] |

%H is the hostname of the server that we’re connected to; the square brackets are literally square brackets that get printed onto the screen, as is the vertical bar. (Anything that isn’t preceded by % will be printed out as-is.)

The backtick character, %`, prints the output of whatever you’ve assigned to the backtick command. 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 current Screen session. I have no idea why this does what it does; I confess I nicked it from Super User. My understanding is that later versions of Screen can or will be able to do this with a simple escape character similar to those above.

Text Styles (Again)

As I said, anything inside {curly braces} affects the way the text looks – this includes formatting (like bold, underline, etc) and color. Here’s an example:

%{+bu wW}

The first half of the string inside the braces (+bu) tells hardstatus to display the following text as bold and underlined. More styling codes are available and are listed in GNU’s documentation. The + indicates that we want to add this property; if we subsequently wanted to unbold text, we would do something like this: %{-b}.

The second half of the string (wW) tells hardstatus which colors to use, the first character being the background color and the second being the foreground color. In this case, we’re printing “bright white” on “white” (which is really more of a light gray). Again, more codes are available in GNU’s documentation.

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


Hopefully this will suffice to have you building your own hardstatus without blindly copying other people’s code from GitHub. If I’ve left anything out or gotten anything wrong, please let me know in the comments.

Additional help came from this comment on Stack Overflow.

17 Responses to “Understanding GNU Screen’s hardstatus strings”

  1. OneGrain says:

    > There are (more than?) a few things I haven’t cov­ered here, of course – trun­ca­tion and con­di­tion­als, namely

    This would have been the real added value. :)
    Just kidding, it is already far FAR far better than what we can find on the topic.

  2. Tommy Stanton says:

    I was able to play with hardstatus settings very quickly by editing the screenrc in Vim (inside of a running GNU Screen session), then running this command while my cursor was on the “hardstatus …” line in the file:

    :call system(‘screen -X ‘ . getline(‘.’))

  3. David T says:

    This really helped me, thanks!
    This also: http://aperiodic.net/screen/man:string_escapes

  4. gestos says:

    Having experienced the same “almost every­thing I can find about hard­sta­tus through Google are just dumps of other people’s strings” thing, luckily I came to this post.
    Nice overview for quick modifications. Helped me a lot! Thanks.

  5. Rensa says:

    *bursts into tears* Thank you :’)

  6. Anthony K says:

    Can you clear a little contradiction please:
    At the top where you explain the meanings of the hardstatus line, you have:

    # %{= wK} : set colors to bright white (W) on bright black (K) and keep current text styles (=)

    (there’s really no bright white here unless I’m missing the point completely)

    Then later on, you state:

    (wW) tells hardstatus which colors to use, the first character being the background color and the second being the foreground color. In this case, we’re printing “bright white” on “white”

    So, which is it? Should the first line then be:

    ( wK ) bright black (K) on white (w)

    OR

    ( Kw ) bright black (K) on white (w)

    Thanks,
    ak.

  7. Anthony K says:

    How uncouth less of me???

    Thanks for a wonderful article. Like you and others have stated, the last time I tried to understand all this, all I could were dumps of .screenrc files with hardly any explanation and all I could do was copy paste into my .screenrc until I found one that suited me.

    This article has given me sight where I previously was blind.

    Keep ’em articles coming,
    ak.

  8. jonathan says:

    htanks. What they ^^^ said.

  9. Alan D. Salewski says:

    Nice article. I know this is an older post, but for the benefit of others that find it in the future I want to note that (since screen 4.2.0, from 2014-04-17) the screen ‘sessionname’ can be included directly by using the ‘%S’ string escape; there’s no need to use a configured ‘backtick’ command to obtain it.

    Thanks,
    -Al

  10. Gabriel Sobrinho says:

    Hi! Any idea why HEAD screen is not printing the colors on hardstatus? No color at all, all just white :(

  11. Malli says:

    finally stopped copying the others hard status strings

    Outstanding post

  12. Malli says:

    finally stopped copying the others hard status strings, have experimented many ,successfully on my own after this post.

    Outstanding information.

  13. Brilliant! Thanks for sharing this. Still relevant for running a headless Raspberry Pi server at home. 

    Cheers!

  14. Balazs Meszaros says:

    Thanks you very much!

  15. jg says:

    I have wondered this for twenty years. Probably a dozen times I have begun this exploration until my phone rang. Today I found this post and I expect it will be good enough for me for the next twenty years. Thank you.

Pings

Leave a Reply