DEV Community

Mike Thomas
Mike Thomas

Posted on

Binding arrow keys in screen + PuTTY

I've recently become a convert to the GNU screen terminal window manager when working on the command line. I've been particularly pleased with it when managing the Raspberry Pi things I've been playing with, like the home automation stuff I've been getting into with Home Assistant.

I love the ability to detach and re-attach sessions, so I can happily do things like reboot my router while configuring it without losing what I was doing on the Pi. The other big thing for me is the ability to split a terminal session into multiple panes/regions, and have different terminal prompts running in each. Like this:

Here I've got a terminal doing a tail on my Z-Wave network log, my HA configuration.yaml open in vim in a terminal sudo'd to the homeassistant user, and an extra terminal down the bottom for command line stuff using the pi user. All sitting in a PuTTY session. It's sweet!

But the point of this is not to convince you to use screen (although you totally should), it's to document something that spent the day driving me nuts. I want to be able to easily switch between the regions of this session using "Ctrl-A" + arrow key. Should be easy enough, right? Just find the config and put something in there.

Well, yes, but exactly what was a bit annoying. The documentation isn't very clear about how to do this, suggesting that you need to use the bindkey command. Eventually I got something working after a fashion. My first solution looked like this, and worked pretty well:

bindkey "^A^[[OA" focus up
bindkey "^A^[[OB" focus down
bindkey "^A^[[OC" focus right
bindkey "^A^[[OD" focus left

I wasn't super happy with this though. The problem is that you have to work out exactly what the arrow keys translate to through your PuTTY session, and explicitly add the Ctrl-A keybinding at the start. That's a bit unpleasant though, for two reasons:

  • It means that if in future I use screen through some different access (e.g. not PuTTY, or an ssh session pretending to be a different terminal type) then if it sends a different key code for the arrow keys it'll stop working. You can use the -k option with bindkey to give a symbolic representation of a key (e.g. -k ku means "up arrow"), but I couldn't see an easy way to insist that the screen prefix command key had to be pressed first.

  • It hard-codes the screen prefix key as Ctrl-A, which just upsets me as a programmer. What if I want to use a different key combination in the future?

I found a much neater way, though, as there is an undocumented -k option to the
bind screen command. This allows you to specify a key by name to be used after the screen command mode has been entered.

Since bind only works for keys once we're in the screen command mode, this solves both our problems above. So now I've got the following in my ~/.screenrc, which is much neater:

# Navigating regions with prefix + arrow
bind -k kl focus left
bind -k kr focus right
bind -k ku focus up
bind -k kd focus down

Happy screening!

Discussion (1)

seanld profile image
Sean Wilkerson

Massive +1. Screen was being very stubborn with the config. The -k kX portion worked like a charm. Kudos.