I am trying to bind the key sequence control-h (ch
in fish) to the right arrow key. I know how to bind it to backward-char
with bind
the normal way, but that poses an issue in my config, since I have b
bound to backward-kill-word
, such that fish interprets my control-h as a b
since the control key is held down and deletes the word.
bind cl forward-char
bind ch backward-char
bind ck history-search-backward
bind cj history-search-forward
bind b backward-kill-word # this picks up control-h which I don't want
So I am wondering if I can just rebind ch
to do the same thing as the left arrow key, since that doesn’t seem to get picked up by b
.
Fish has no function to rebind a key to another key.
You need to figure out what function it is bound to and bind that.
However, that’s not your problem. Your problem is that ctrl-h is backspace.
The way terminal emulators work is by sending byte sequences when you press keys. And the default encoding is that:
- Normal characters like “h” appear as themselves
- Control clears the top 3 bits of the character
And when you look in an ASCII table, you’ll find that “h” is 0x68, “H” is 0x48 and backspace (b
) is 0x08.
That means ctrl-h and ctrl-H encode as the backspace codepoint[0]. Other keys are also indistinguishable, for example ctrl-i and ctrl-I are tab.
There is no way for any program running in your terminal to tell these sequences apart because they are literally the same. See also https://fishshell.com/docs/3.7/interactive.html#key-sequences.
The way around this is something like the kitty keyboard protocol, which fish will support in the next release. That tells the terminal to send newer, less ambiguous sequences for key chords.
[0]: Note that that’s not necessarily the same as backspace-the-key – there’s historical confusion there, in a lot of terminals pressing the backspace-key sends delete (0x7f) instead of 0x08 (and control-backspace then typically sends 0x08).