Binding arrow keys in screen + PuTTY
Tags: screen, gnuscreen, linux, putty
Published: 2019-08-11 16:30:31

---
title: Binding arrow keys in screen + PuTTY
published: true
description: How to make your arrow keys behave when using GNU screen through PuTTY
tags: screen, gnu screen, linux, PuTTY
---
I've recently become a convert to the [GNU screen](https://www.gnu.org/software/screen/screen.html) 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](https://www.home-assistant.io).

![](https://thepracticaldev.s3.amazonaws.com/i/9v2hn3mlyl32ob01n0xu.png)

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:

![](https://thepracticaldev.s3.amazonaws.com/i/pg1la81ud5wh5vxby0f5.png)

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](https://www.gnu.org/software/screen/manual/html_node/Key-Binding.html#Key-Binding) 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:

```bash
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:

```bash
# 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!