Home/End keys do not work in tmux
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?
Solution 1:
It appears the main problem is with using xterm-256color for $TERM. I switched $TERM to screen-256color and the problem went away.
Solution 2:
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
Solution 3:
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 this somewhat related article. The only difference 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
like referenced in the article above.
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 with 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
.
Solution 4:
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
Solution 5:
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