80

I'm currently using tmux with xterm-256color $TERM variable. When in bash under tmux, pressing home/end would insert tilde characters (~). Outside of tmux the home/end keys work fine.

Using cat and tput, I could see that there was a mismatch between the generated and expected sequences:

$ cat -v # pressing home, then end
^[[1~^[[4~
$ tput khome | cat -v; echo
^[OH
$ tput kend | cat -v; echo
^[OF

To fix this, I decided to add the following to my .bashrc:

if [[ -n "$TMUX" ]]; then
    bind '"\e[1~":"\eOH"'
    bind '"\e[4~":"\eOF"'
fi

That fixed the problem for bash, however in other readline programs, such as within a REPL such as ipython, it still inserts a tilde for home/end.

Why exactly is this a problem in the first place? Why is the generated sequence different when I'm inside tmux vs outside it? How can fix this so that it's not an issue in any programs?

Ben Davis
  • 13,112
  • 10
  • 50
  • 65
  • this is a good question for tmux config, however I would suggest you trying to get used to `ctrl-A/E/F/B/` `alt-B/F...` (emacs bind) to move cursor – Kent Sep 03 '13 at 20:00
  • btw, if this helps you? http://stackoverflow.com/questions/8604150/with-term-screen-256color-under-tmux-home-and-end-keys-dont-work-why – Kent Sep 03 '13 at 20:11
  • I currently use ctrl-a for the command-key prefix in tmux (similar to screen). I looked at that post earlier, but that seems to only apply to Vim, and it's not an issue for me in Vim. – Ben Davis Sep 03 '13 at 20:24

9 Answers9

66

It appears the main problem is with using xterm-256color for $TERM. I switched $TERM to screen-256color and the problem went away.

Ben Davis
  • 13,112
  • 10
  • 50
  • 65
  • 1
    My similar problem was solved by setting the keybindings using `.inputrc` (see `info readline`) or for zsh in `.zshrc` as in `http://zshwiki.org/home/zle/bindkeys` – here Jan 21 '14 at 07:46
  • 8
    Edit `~/.tmux.conf` and add a line `set -g default-terminal "screen-256color"` – Wernight Apr 02 '14 at 15:41
  • 2
    This answer, also works for the same issue with GNU Screen. I just added `term "screen-256color"` to my ~/.screenrc – Aleksandr Levchuk Jul 16 '15 at 18:51
  • 2
    I had to kill the tmux session, and close the terminal, then start everything again for it to take effect. – Geoffrey Sep 12 '17 at 07:12
  • 1
    `screen-256color` can mess some applications. I set manual bindings in .zshrc – elig Apr 19 '20 at 07:27
  • First tried this and it seemed okay but for me modifying the `.tmux.conf` as in @sumanta's answer turned out to work best. – TNT Mar 05 '22 at 22:03
55

Add the following to your .tmux.conf:

bind-key -n Home send Escape "OH"
bind-key -n End send Escape "OF"

And you're done!


Explanation

After attempting each one of these, and several others I saw while perusing other answers and documentation, this finally worked for me in every scenario I threw at it. I can't promise the same for you, because everyone's scenarios are different, but this is what I ended up with.

This was discovered after introducing the same trial/error and logic from a somewhat relevant article that is no longer available. The key is where the translation is occurring; in my case, this happens within my .tmux.conf, rather than .bashrc or .zshrc (mainly because my home/end worked fine outside of tmux)

Debugging

You can debug this issue by using cat -v.

Run cat -v, then press the Home and End keys. Exit using Ctrl+C.

$ cat -v

Here's what my output looked like within tmux using zsh, zsh, and bash:

tmux

➜  ~ cat -v
^[[1~^[[4~^C

zsh

➜  ~ cat -v
^[[H^[[F

bash

bash-3.2$ cat -v
^[[H^[[F

Solutioning

Compare the above examples to what we're expecting to see, by pairing tput with cat -v:

$ tput khome | cat -v; echo
^[OH
$ tput kend | cat -v; echo
^[OF

Conclusion

Because this problem exists solely within tmux, and not within the shells themselves, I opted to make the bind changes within the tmux configuration instead. By using bind-key paired with send, we can use the Escape keyword paired with the sequence we want to achieve our translation. Thus:

bind-key -n NAME_OF_KEY send Escape SEQUENCE_GOES_HERE

This debugging and solutioning process can be applied to any other key translation issues. But, don't go too crazy. Some keys are mapped to certain escape sequences for a reason. Notice how bash and zsh received the ^[[H sequence for Home instead of ^[OH; it's probably not recommended we override this in our .zshrc unless we're having major issues with this in zsh.

Swivel
  • 3,020
  • 26
  • 36
  • 2
    This problem disappeared for me with tmux 2.6 and `set-window-option -g xterm-keys on` in tmux, but this looks like a great answer that would help people with multiple terminal configurations. – zzxyz Apr 10 '19 at 19:52
  • 2
    I like this option because I wanted to use xterm-256color, as it seemed to be my only TERM that supported italics. Well, it also didn’t have a working Home/End until I added your two `bind-key` commands to my config. The `Escape` is very important, I found. Other answers omitted that and they don’t work for me. Thanks for the help! – Nate Sep 29 '19 at 08:48
  • I'm using tmux 3.1 and this started to happen after I started to used `set-window-option -g vi` so I think this is the best answer cause can work in any key modes. Nice explanation. – Arkt8 Jul 12 '21 at 11:26
  • 2
    @zzxyz would you mind making your suggestion `set-window-option -g xterm-keys on` into an answer? It fixed the problem for me too, and I almost missed it at first glance. – mgarort Jul 22 '21 at 21:49
  • I actually had `^[OH` & `^[OF` for both within the tmux and outside of the tmux. But for some unknown reason, HOME/END key doesn't work only for the terminal within the tmux. I had to manually add below to the `.zshrc` to fix this issue. bindkey "^[OH" beginning-of-line bindkey "^[OF" end-of-line – Lazy Ren Apr 19 '23 at 08:56
36

In tmux 2.0, you can just add these 2 lines in your .tmux.conf:

bind -n End send-key C-e
bind -n Home send-key C-a
Toby Speight
  • 27,591
  • 48
  • 66
  • 103
sumanta
  • 401
  • 4
  • 2
12

If you want to stay with xterm-256color in tmux for some reason - use arch solution with inputrc. I tested it in tmux with rxvt, ruby irb, python, lua and home/end keys are ok. Probably every readline app will be ok.

From the arch wiki:

First things first:

do not set $TERM manually - let the terminal do it.


Many command line applications use the Readline library to read input. So properly configuring Readline can fix Home and End in many cases.

the default /etc/inputrc file does not include a mapping for home/end keys.

To check what the emitted escape sequence for these keys is:

1. Ctrl + V
2. Home
3. Spacebar
4. Ctrl + V
5. End

this will probably print: $ ^[[1~ ^[[4~. So you have to add a mapping for these sequences to your inputrc (/etc/inputrc to be globally, or only for your user ~/.inputrc):

"\e[1~": beginning-of-line
"\e[4~": end-of-line
TryToSolveItSimple
  • 873
  • 1
  • 12
  • 23
Oleg Kr
  • 469
  • 6
  • 8
  • I was overriding TERM that was the cause of all my problems thanks for the link – Gerson Sosa Jan 30 '16 at 14:26
  • The reason most people would be running tmux under xterm-256 is because they are running a slightly old version of Ubuntu, which has an ancient tmux package. Upgrade your tmux! – zzxyz Jul 27 '18 at 22:28
  • honestly the onnly real good answer here, only you should not "just" put a link to a wiki here but also the excerpt of the wiki on how to solve the problem. I think this way many people miss out on it – TryToSolveItSimple May 06 '19 at 09:12
11

In my case it was a problem with zsh in tmux (bash in tmux was ok). None of the other anwsers here worked for me.

But adding this to .zshrc fixed it:

bindkey "\E[1~" beginning-of-line
bindkey "\E[4~" end-of-line

Besides that I also have:

bindkey "\E[H" beginning-of-line
bindkey "\E[F" end-of-line
bindkey "\E[3~" delete-char
someone
  • 449
  • 5
  • 10
  • 2
    I did something similar, as actually this had nothing to do with tmux in my case, just writing it down in case it helps someone else: ``bindkey "^[OF" end-of-line`` and ``bindkey "^[OH" beginning-of-line`` – tiho Dec 05 '19 at 20:17
5

From tmux FAQ:

PLEASE NOTE: most display problems are due to incorrect TERM! Before reporting problems make SURE that TERM settings are correct inside and outside tmux.

Inside tmux TERM must be "screen", "tmux" or similar (such as "tmux-256color"). Don't bother reporting problems where it isn't!

Outside, it should match your terminal: particularly, use "rxvt" for rxvt and derivatives.

Add the following command to your ~/.tmux.conf:

set -g default-terminal tmux-256color

PS: any solution involving binding the keys explicitly is a hack, and as such bound to fail.

André Werlang
  • 5,839
  • 1
  • 35
  • 49
  • I was actually having problems because I was using the `bind -n End`/`bind -n Home` hack in my `.tmux.conf` end then I fixed my `TERM`. So, definitely, do it right and fix your TERM. – CristianCantoro Dec 28 '20 at 10:31
2

set-window-option -g xterm-keys on

This should work in tmux 2.6 and later. (tmux -V to check) If you are using an older version than that, you're probably running an older Ubuntu and you should definitely consider pointing at a ppa with backports.

This definitely doesn't work with kitty, and is effectively "hardcoding" the terminal in terms of input, but it is better than hardcoding specific keys.

zzxyz
  • 2,953
  • 1
  • 16
  • 31
1

So I don't have enough points to comment,so I'll say it here instead. I believe the preferred solution is using set -g default-terminal "screen-256color" in your ~/.tmux.conf. I actually had this problem a while ago and decided to go with sumanta's solution :

bind -n End send-key C-e
bind -n Home send-key C-a

However I had forgotten I left this in here and ended up having a similar issue with vim (home and end were copy pasting from registers) instead of zsh. In short bind DOES affect vim.

ducklin5
  • 95
  • 1
  • 11
1

I wasted a lot of time trying all off the above. In the end I reverted to barbarism:

sudo apt purge tmux
sudo apt install tmux

fixed it for me.

Max Robbertze
  • 406
  • 4
  • 11