Shift-arrow not working in emacs within tmux

emacstmux

I recently started using tmux (was a screen user before) and I'm loving it, except for one small problem. I use emacs within my tmux session and I am used to using Shift-arrow keys to move between emacs windows (not tmux windows). When running within tmux, these bindings seem to stop working entirely (it's like they don't register to emacs at all). If I exit tmux and just run emacs in my shell, they work fine.

I'm using iTerm2, ssh'd into a Linux box, running tmux/emacs there. I have the Shift-arrow key bindings set up as follows in my .emacs:

(global-set-key "\M-[1;2A" 'windmove-up)
(global-set-key "\M-[1;2B" 'windmove-down)
(global-set-key "\M-[1;2C" 'windmove-right)
(global-set-key "\M-[1;2D" 'windmove-left)

When not running in tmux, I can confirm those are the right character sequences for the shift-arrow key combinations by doing C-q in emacs and then pressing the key sequence. Within tmux, even that doesn't work because it doesn't seem to see any input from the shift-arrow keypress (it just sits at the C-q prompt).

Looking at the key bindings for tmux, I don't think anything is bound to Shift-arrow keys and even if it was, they would only register after entering the prefix (which is bound to C-o in my case).

Any idea on how to make the shift-arrow keys work again within tmux?

Best Answer

First, make sure your TERM is correct at each location:

  • xterm-something (e.g. xterm-256color) inside your local shell running in your iTerm2 window
  • xterm-something inside your shell after SSHing to the Linux system
    This should be the same as whatever you are using locally in iTerm2, since SSH should be passing it along to the remote side (and, importantly, the remote side should not be blindly overriding the value in a shell initialization file).
  • screen-something (e.g. screen-256color) inside your shell running under tmux on the Linux system
    You should always use a screen-based TERM inside tmux.

Having an xterm TERM immediately outside tmux will allow tmux to recognize the modified arrow keys, but it will not pass them through unless you also have its xterm-keys window option turned on. Put this in your ~/.tmux.conf on the Linux system:

set-window-option -g xterm-keys on

The sequences for the shifted keys should now make it through to Emacs, running inside tmux, across an SSH connection, inside an iTerm2 window.

Related Question