Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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?

share|improve this question
I actually found the answer this myself but StackExchange won't let me officially answer my own question for another 7 hours as I don't have enough reputation yet. Anyway if anyone is interested, doing set-window-option xterm-keys on seems to fix it. I set this as a global option by putting this in my .tmux.conf and I seem to be back in business: set-window-option -g xterm-keys on – triangle_man Nov 11 '11 at 18:21
Try to vote to close question if you really can't – Eir Nym Nov 19 '11 at 15:05

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.

share|improve this answer
This is exactly what I needed to use textadept in tmux. – William Hilton Jul 9 '15 at 2:58

First you must enable xterm-keys in your tmux config. So put the following in ~/.tmux.conf

setw -g xterm-keys on

But, this will break other key combinations. To fix them, put the following in your~/.emacs or ~/.emacs.d/init.el config

;; handle tmux's xterm-keys
;; put the following line in your ~/.tmux.conf:
;;   setw -g xterm-keys on
(if (getenv "TMUX")
      (let ((x 2) (tkey ""))
    (while (<= x 8)
      ;; shift
      (if (= x 2)
          (setq tkey "S-"))
      ;; alt
      (if (= x 3)
          (setq tkey "M-"))
      ;; alt + shift
      (if (= x 4)
          (setq tkey "M-S-"))
      ;; ctrl
      (if (= x 5)
          (setq tkey "C-"))
      ;; ctrl + shift
      (if (= x 6)
          (setq tkey "C-S-"))
      ;; ctrl + alt
      (if (= x 7)
          (setq tkey "C-M-"))
      ;; ctrl + alt + shift
      (if (= x 8)
          (setq tkey "C-M-S-"))

      ;; arrows
      (define-key key-translation-map (kbd (format "M-[ 1 ; %d A" x)) (kbd (format "%s<up>" tkey)))
      (define-key key-translation-map (kbd (format "M-[ 1 ; %d B" x)) (kbd (format "%s<down>" tkey)))
      (define-key key-translation-map (kbd (format "M-[ 1 ; %d C" x)) (kbd (format "%s<right>" tkey)))
      (define-key key-translation-map (kbd (format "M-[ 1 ; %d D" x)) (kbd (format "%s<left>" tkey)))
      ;; home
      (define-key key-translation-map (kbd (format "M-[ 1 ; %d H" x)) (kbd (format "%s<home>" tkey)))
      ;; end
      (define-key key-translation-map (kbd (format "M-[ 1 ; %d F" x)) (kbd (format "%s<end>" tkey)))
      ;; page up
      (define-key key-translation-map (kbd (format "M-[ 5 ; %d ~" x)) (kbd (format "%s<prior>" tkey)))
      ;; page down
      (define-key key-translation-map (kbd (format "M-[ 6 ; %d ~" x)) (kbd (format "%s<next>" tkey)))
      ;; insert
      (define-key key-translation-map (kbd (format "M-[ 2 ; %d ~" x)) (kbd (format "%s<delete>" tkey)))
      ;; delete
      (define-key key-translation-map (kbd (format "M-[ 3 ; %d ~" x)) (kbd (format "%s<delete>" tkey)))
      ;; f1
      (define-key key-translation-map (kbd (format "M-[ 1 ; %d P" x)) (kbd (format "%s<f1>" tkey)))
      ;; f2
      (define-key key-translation-map (kbd (format "M-[ 1 ; %d Q" x)) (kbd (format "%s<f2>" tkey)))
      ;; f3
      (define-key key-translation-map (kbd (format "M-[ 1 ; %d R" x)) (kbd (format "%s<f3>" tkey)))
      ;; f4
      (define-key key-translation-map (kbd (format "M-[ 1 ; %d S" x)) (kbd (format "%s<f4>" tkey)))
      ;; f5
      (define-key key-translation-map (kbd (format "M-[ 15 ; %d ~" x)) (kbd (format "%s<f5>" tkey)))
      ;; f6
      (define-key key-translation-map (kbd (format "M-[ 17 ; %d ~" x)) (kbd (format "%s<f6>" tkey)))
      ;; f7
      (define-key key-translation-map (kbd (format "M-[ 18 ; %d ~" x)) (kbd (format "%s<f7>" tkey)))
      ;; f8
      (define-key key-translation-map (kbd (format "M-[ 19 ; %d ~" x)) (kbd (format "%s<f8>" tkey)))
      ;; f9
      (define-key key-translation-map (kbd (format "M-[ 20 ; %d ~" x)) (kbd (format "%s<f9>" tkey)))
      ;; f10
      (define-key key-translation-map (kbd (format "M-[ 21 ; %d ~" x)) (kbd (format "%s<f10>" tkey)))
      ;; f11
      (define-key key-translation-map (kbd (format "M-[ 23 ; %d ~" x)) (kbd (format "%s<f11>" tkey)))
      ;; f12
      (define-key key-translation-map (kbd (format "M-[ 24 ; %d ~" x)) (kbd (format "%s<f12>" tkey)))
      ;; f13
      (define-key key-translation-map (kbd (format "M-[ 25 ; %d ~" x)) (kbd (format "%s<f13>" tkey)))
      ;; f14
      (define-key key-translation-map (kbd (format "M-[ 26 ; %d ~" x)) (kbd (format "%s<f14>" tkey)))
      ;; f15
      (define-key key-translation-map (kbd (format "M-[ 28 ; %d ~" x)) (kbd (format "%s<f15>" tkey)))
      ;; f16
      (define-key key-translation-map (kbd (format "M-[ 29 ; %d ~" x)) (kbd (format "%s<f16>" tkey)))
      ;; f17
      (define-key key-translation-map (kbd (format "M-[ 31 ; %d ~" x)) (kbd (format "%s<f17>" tkey)))
      ;; f18
      (define-key key-translation-map (kbd (format "M-[ 32 ; %d ~" x)) (kbd (format "%s<f18>" tkey)))
      ;; f19
      (define-key key-translation-map (kbd (format "M-[ 33 ; %d ~" x)) (kbd (format "%s<f19>" tkey)))
      ;; f20
      (define-key key-translation-map (kbd (format "M-[ 34 ; %d ~" x)) (kbd (format "%s<f20>" tkey)))

      (setq x (+ x 1))

Also I have my solution in archlinux wiki

share|improve this answer
comment left by @JeffKlukas: "oblique's answer is just what I needed to get this working through PuTTY on Windows as well (I don't have the reputation to add this as a comment, so making an answer instead). When I turned on the xterm-keys option in tmux, Shift-arrow would produce text like 2C in emacs. By adding the above elisp code to my init.el, I get the expected functionality (especially useful in org mode)." – slm Jun 4 '14 at 14:23

In general case, problems like this happen because of mistmatch between what the terminal emulator sends and what the client application expects.

Different terminal emulators have different degree of customizability, so familiarizing oneself with emulation tunables of a particular one is necessary.

Client applications depend on value of $TERM which is used to lookup terminal (emulator)'s capabilities in the terminfo (or termcap) database.

In your case, your emacs bindings use explicit sequences thus $TERM and terminfo are irrelevant: a specific terminal emulator is expected - as you already figured out, a xterm-compatible one.

share|improve this answer
See Fix Terminals - Please for a proposal to standardize some of these differences/deficiencies in terminal input. It's been raised on iterm2-discuss but I don't think anybody's implemented it yet. – ephemient Mar 18 '12 at 22:19

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.