Describe-key

Is it possible to tell what kakoune is interpreting a keypress as?

For me, when I press Fn-Right on my Macbook, I expect it to generate an <end> but it isn’t. I get the message “no selections remaining” from kakoune, which is not a big enough clue for what it means.

I ran Emacs in the same terminal and did M-x describe-key and got <select> but mapping that to something in kakoune fails.

I have the same problem with Fn-Left, emacs says <home> but kakoune says “no selections remaining” and when I try to map it something else (like gh) it is ineffective.

These suggest to me that kakoune is interpreting the keys differently, but I don’t know how.

I attempted to use <c-v> to directly input the character into the map call, but in both cases “~” gets printed.

Although it would be nice to get this particular problem fixed (i.e. correct my iTerm2/tmux config), I think it is more important to get something like describe-key so this problem can be solved. So, is there such a thing already that I just can’t find?

seems like your key codes were eaten by text form.

Thanks, fixed, it was < and >

This might not about solving your issue but why use arrow keys? Especially with Fn, it looks to me like an inefficient way of moving around. Both Kakoune, and Emacs define shortcuts for it. In Emacs it is Ctrl+a Ctrl+e, for Home and End respectively, which I think is more accessible compared to fn+left/right, and Kakoune has gh and gl for that, which in my opinion is even more accessible.

As for the actual issue, it might be not supported by terminal emulators, but supported by Emacs and other GUI apps. Try the same Fn+Arrow shortcuts in terminal version of Emacs and see if it works or not.

My Fn+Arrow tests in Emacs were in the terminal version (inside the same tmux and all)

As for why I want this… muscle memory is the biggest reason for me and second is that my laptop doesn’t have Home and End keys at all, but in general “Kakoune doesn’t support X, therefore you should not want X” is lame, especially when it is as simple as “make keybindings what you want.”

I’ve never said that you shouldn’t want X. I just said that maybe you’re could try the approach and decide for yourself if it is better. Home and End keys are usable keys in some scenarios, but this generally means that you leave home row, and modal editing is in general about not leaving the homerow.

As for not handling keys, I think you can keep track of this issue on Kakoune’s github, as I believe that that’s the core of problem here: https://github.com/mawww/kakoune/issues/2554

Generally Fn-Left and Fn-Right on a Macbook will produce the same keycodes as the standalone “Home” and “End” keys would on a full-sized keyboard, so they shouldn’t need to be mapped separately.

On the other hand, inside a terminal the “Home” and “End” keys produce a sequence of bytes rather than a single code (just like every special key), so a “describe key” function wouldn’t be much help: if Kakoune doesn’t recognise the special sequence, it would just tell you that you’d pressed the key corresponding to the first byte of the sequence (probably Esc) and then subsequent bytes would dismiss the message. I know, that’s a dumb way to handle key-codes, but terminal input is kinda dumb.

Basically, there’s two parts of the configuration that need to agree: iTerm needs to know what bytes to send, and Kakoune needs to know what bytes to expect for each key.

I believe iTerm lets you configure what bytes to send for each special key, but I’m going to assume it has sensible defaults. If you want to see for yourself what bytes a key sends and can’t find it in the configuration, the easiest way is to open a new terminal and run the cat command with no arguments, and just press the key you’re interested in. For example, on the Linux computer I’m using now, when I run cat and press Home:

$ cat
^[[H

…so for me, Home is the same as pressing Esc[H. Note that Esc is written as ^[ for historical reasons.

Kakoune sets its expectations from the $TERM environment variable, which names what terminal variant you’re using. Again, on my computer:

$ echo $TERM
vte-256color

That terminal name is looked up in a database that describes what bytes are sent for the various keys the terminal supports. You can look up that database yourself with the tput command. Because it prints the raw output to the terminal, we’ll need to pipe it through cat -v to turn control-characters into visible ones.

$ tput home | cat -v
^[[H

Unsurprisingly, the “home” field for my terminal contains the bytes my terminal sends when I press “Home”. If you’re interested, infocmp -1x should list all the fields for your terminal, and man 5 terminfo should explain what all the cryptic names mean.

If tput home | cat -v produces different output than typing Fn-Left into cat directly, you probably need to change $TERM to something appropriate for your terminal. I believe iTerm has a config option for what $TERM is set to for each new terminal. In your case, you probably want the first one from this list that works:

  • iterm2
  • xterm-256color
  • xterm

Thanks @Scretapello

My Fn-Left and Fn-Right are generating what tput produces on khome and kend (not Home and End). key.cc:61 doesn’t support those two names, but also I’m finding that when I change the bindings in iTerm2 to produce different bytes, tmux is switching them back to khome/kend.

I feel like I should patch Kakoune to support these keys, because they are real keys. Shorter term, I could figure out how to get tmux to stop doing this translation.

I did some experimenting with Kitty and screen and learned that I could get it working if tmux’s default-terminal to screen-256color (rather than tmux-256color or xterm-256color)

Ah, right, I forgot about tmux. Also, I forgot about “keypad mode”; a key like Home can send different bytes depending on keypad mode, but tput khome assumes keypad mode is enabled.

It’s worth pointing out that tmux is double-ended: as an application that runs inside a terminal emulator, it checks $TERM to interpret keys sent by the outer terminal; as a terminal emulator itself, it sets its own, different $TERM and sends its own key encodings to the applications running inside it.

To trace how Fn+Left gets processed:

  • directly inside iTerm2, run tput smkx to enable keypad mode, then run cat, and press Fn+Left to see what bytes iTerm2 sends
  • directly inside iTerm2, run tput khome | cat -v to check what bytes applications are looking for, and verify that the output matches what iTerm2 sends
  • if that’s true, then tmux should correctly interpret Fn+Left as Home.
  • inside tmux, run tput smkx to enable keypad mode, then run cat and press Fn-Left to see what bytes tmux sends (it’s probably different from what iTerm2 sends directly, and that’s OK)
  • inside tmux, run tput khome | cat -v to check what bytes applications are looking for, and verify that the output matches what tmux sends
  • if that’s true, then applications inside Kakoune should correctly handle Home too

key.cc:61 doesn’t support those two names

I assume you mean Kakoune’s keys.cc file. That’s OK, the names in that file are made up by Kakoune, and are different from the terminfo names. Keys from the terminal are interpreted in ncurses_ui.cc at around line 586, but those names are from ncurses, which has different conventions again.

I feel like I should patch Kakoune to support these keys, because they are real keys. Shorter term, I could figure out how to get tmux to stop doing this translation.

You shouldn’t have to do either of those things. Once you have $TERM set correctly (probably iterm2 or kitty for the outer terminal, depending on which one you’re using, and tmux-256color for the inner terminal), everything should Just Work.

Thank you! Very useful!

If anyone finds this thread in the future, it was all about tmux.

I had to turn on “xterm-keys” in tmux. But then some keys would work with TERM=screen-256color and others would work with TERM=xterm-256color but no matter which I used something was broken. I had to follow the advice in the ArchWiki [1] but I had to add the kind and kri capabilities which kak uses for the up and down arrows [2].

  1. https://wiki.archlinux.org/index.php/tmux#xterm-keys
  2. https://github.com/jeapostrophe/exp/blob/master/xterm-screen-256color.terminfo
1 Like

Hmm… I would have expected the up and down arrows to be kcuu1 and kcud1 (“Key CUrsor Up 1” and “Key CUrsor Down 1” respectively). I see you’ve got kri and kind set to the traditional codes for Shift+Up and Shift+Down respectively. Looking at the unmodified “tmux-256color” entry in my terminal database, I see those codes are assigned to kUP and kDOWN which is what I’d expect the shifted arrow keys to look like… but they’re also assigned to kri and kind, so I guess that’s a legacy thing.

Out of curiosity, why did you have to turn on “xterm-keys” in tmux? My tmux manpage says “If this option is set, tmux will generate xterm(1) -style function key sequences; these have a number included to indicate modifiers such as Shift, Alt or Ctrl.” but that seems to be true even without “xterm-keys” set. When I run cat inside tmux and press Shift+F1, I get xterm-style ^[[1;2P instead of unmodified ^[[OP.

I meant the shifted up/down arrows. I thought they’d be kUP and KDN as well, but kakoune is looking for KEY_SR and KEY_SF [1] which man 5 terminfo lists as kind and kri

Your experience with tmux without xterm-keys it different than mine.

  1. https://github.com/mawww/kakoune/blob/2a4d3eb13b325f1633441c6501c1df556b6096ae/src/ncurses_ui.cc#L588