Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Map keys to escape sequence #94

Closed
tbo opened this issue Jul 16, 2017 · 22 comments
Closed

Map keys to escape sequence #94

tbo opened this issue Jul 16, 2017 · 22 comments

Comments

@tbo
Copy link

tbo commented Jul 16, 2017

I want to map several shortcuts to other keys:

super+enter to ctrl+enter
super+j to ctrl+j
...

I tried the paste action, but couldn't figure out the proper format:

map super+enter paste [escape sequence]

Is there any way to achieve this?

@kovidgoyal
Copy link
Owner

There is no paste action. Only paste_from_clipboard and paste_from_selection

This should be easy to do in your OS. For example for X11: https://ubuntuforums.org/showthread.php?t=380927 if you want to rebind for only kitty. If you want to rebind globally it is even easier.

@tbo
Copy link
Author

tbo commented Jul 17, 2017

There is no paste action. Only paste_from_clipboard and paste_from_selection

paste is listed together with the other actions between # actions {{{ and # }}} in window.py. So I assumed, that it is a valid action for the configuration.

This should be easy to do in your OS. For example for X11: [...]

I'm working under MacOS. Doing this globally would be quite easy, but this would interfere with my other shortcuts. Doing it application specific is theoretically possible, but would require some coding and would be a very hacky solution.
Even if I do this in the OS, there would still be the problem, that kitty doesn't send any modifiers with enter (ctrl+enter becomes enter).
I think, that kitty would be much easier to extend with something like a "paste" action. Alacritty does this quite nicely:

https://github.com/jwilm/alacritty/blob/master/alacritty.yml#L203

@kovidgoyal
Copy link
Owner

As far as I know all terminals send only enter for ctrl+enter. Enter is itself a control code. ctrl+control code is meaningless. What are you actually trying to acheive? It seems like you want some terminal application to understand Ctrl+Enter. The only way to do that would be to remap it to something else, like Ctrl+a, at which point why not just use Ctrl+a?

Generally speaking, classic terminal programs have very limited support for keyboard handling. For example, Ctrl+Shift does not work either. What is really needed is a new keyboard handling protocol, such as kitty supports: https://github.com/kovidgoyal/kitty/blob/master/protocol-extensions.asciidoc

@kovidgoyal
Copy link
Owner

Oh and all available actions are listed in the kitty.conf file there is no need to read the source for it.

@tbo
Copy link
Author

tbo commented Jul 17, 2017

I'm using super+enter as a mapping in my neovim configuration. It works quite well if I use a UI like vimr, because all keys a simply passed on. My goal is to keep my neovim as system independent.

@kovidgoyal
Copy link
Owner

You are going to have a tough time meeting that goal. You would have to map super+enter to some other shortcut, which is likely going to conflict with an existing shortcut in vim.

Really, the proper solution is to get neovim to support the extended keyboard protocol I linked to earlier.

However, I dont mind adding something like a send_text command to kitty to cause shortcuts to send arbitrary bytes.

@justinmk
Copy link

justinmk commented Nov 5, 2017

the proper solution is to get neovim to support the extended keyboard protocol I linked to earlier.

What protocol is that? Have you seen http://www.leonerd.org.uk/hacks/fixterms/ ? We plan to support something like that.

@kovidgoyal
Copy link
Owner

I have seen fixterms and I did not like it. It tries to maintain compatibility with existing keyboard modes, without even being aware that there are already two different keyboard modes, so you literally cannot maintain compatibility with them in a single scheme. It does not have any method of detecting repeats and key release events. As far as I can tell it does not support multiple modifier keys and has no obvious way to be extended for new modifier keys in the future. It has no scheme for client programs to query the terminal emulator for what keyboard mode it is in.

@kovidgoyal
Copy link
Owner

Oh and also it does not solve the problem of differentiating between esc key presses and escape codes.

@leonerd
Copy link

leonerd commented Nov 6, 2017

It tries to maintain compatibility with existing keyboard modes,

Well it sortof has to really. At least, keys like <Ctrl-C> have to remain as the single-byte encoding they currently are, so that the termios(3) mechanisms like VINTR continue to work.

without even being aware that there are already two different keyboard modes

Which two modes? Do you mean KPAM vs. KPCM? Those are somewhat annoying but in practice don't really have much effect. They just switch between two disjoint sets of possible byte sequences that the terminal could send on some keypress. Easiest is to just accept either of them, since there's never any ambiguity, then it doesn't matter which mode the terminal is in. You'll still interpret it correctly.

It does not have any method of detecting repeats and key release events

That I'll accept. Indeed it doesn't encode repeated keys. Those are just repeats.

For key releases, I'm intending to add a mode switch to at least be aware of modifier releases, so you can do "Alt-slurring"; i.e. holding the Alt key for multiple key presses in a row. So something like Alt+12 would be different to Alt+1 Alt+2.

As far as I can tell it does not support multiple modifier keys

The modifier mask is a bitmask; so it can easily encode multiple at once. E.g. Ctrl+Alt is 4 + 2, plus the offset 1, being 7.

and has no obvious way to be extended for new modifier keys in the future.

Just invent more bits. 8, 16, 32, ... whatever. I'll accept they might not have wellknown names yet, but that's not hard to extend by adding a query mechanism to say "Hey, terminal, tell me the name of the 8th key modifier".

Oh and also it does not solve the problem of differentiating between esc key presses and escape codes.

For that, you switch the terminal into S8C1T mode. In this mode, all CSI sequences coming from the terminal arrive in 8bit encoding starting with the real 0x9b CSI byte. Now, the only time you'll ever see a true 0x1b ESC byte from the terminal is when the user really pressed the actual <Escape> key. It's now entirely unambiguous based purely on the bytes received, without needing timing information.

@kovidgoyal
Copy link
Owner

kovidgoyal commented Nov 6, 2017 via email

@leonerd
Copy link

leonerd commented Nov 6, 2017

It tries to maintain compatibility with existing keyboard modes,

Well it sortof has to really. At least, keys like "" have to remain as the single-byte encoding they currently are, so that the termios(3) mechanisms like VINTR continue to work.

without even being aware that there are already two different keyboard modes

Which two modes? Do you mean KPAM vs. KPCM? Those are somewhat annoying but in practice don't really have much effect. They just switch between two disjoint sets of possible byte sequences that the terminal could send on some keypress. Easiest is to just accept either of them, since there's never any ambiguity, then it doesn't matter which mode the terminal is in. You'll still interpret it correctly.

It does not have any method of detecting repeats and key release events

That I'll accept. Indeed it doesn't encode repeated keys. Those are just repeats.

For key releases, I'm intending to add a mode switch to at least be aware of modifier releases, so you can do "Alt-slurring"; i.e. holding the Alt key for multiple key presses in a row. So something like "Alt+12" would be different to "Alt+1 Alt+2"

As far as I can tell it does not support multiple modifier keys

The modifier mask is a bitmask; so it can easily encode multiple at once. E.g. Ctrl+Alt is 4 + 2, plus the offset 1, being 7.

and has no obvious way to be extended for new modifier keys in the future.

Just invent more bits. 8, 16, 32, ... whatever. I'll accept they might not have wellknown names yet, but that's not hard to extend by adding a query mechanism to say "Hey, terminal, tell me the name of the 8th key modifier".

Oh and also it does not solve the problem of differentiating between esc key presses and escape codes.

For that, you switch the terminal into S8C1T mode. In this mode, all CSI sequences coming from the terminal arrive in 8bit encoding starting with the real 0x9b CSI byte. Now, the only time you'll ever see a true 0x1b ESC byte from the terminal is when the user really pressed the actual "" key. It's now entirely unambiguous based purely on the bytes received, without needing timing information.

@leonerd
Copy link

leonerd commented Nov 6, 2017

That mode has terrible semantics. It overlaps with UTF-8, which means you have to write a custom utf-8 decoder just to decode the byte stream correctly. I strongly urge against using it. Applications will get it wrong.

It doesn't overlap with well-formed UTF-8 though. Wellformed UTF-8 never starts a multibyte sequence with a C1 control byte; any of the C1 byte range (0x80 to 0x9F) UTF-8 considers to be in the continuation range. So a little bit of heuristic detection in the parser and unambiguously split a stream of UTF-8 encoded Unicode characters from C1 control sequences. I do that all the time in both libvterm on the input-to-terminal end and libtermkey/libtickit on the input-to-application end, and it works absolutely fine.

Of course, it will still get confused on malformed UTF-8, but that's true in general - if you send junk bytes in who knows what will happen?

@kovidgoyal
Copy link
Owner

I'm not saying it doesn't work, I'm saying it is easy to get wrong. I think it behooves us to come up with a protocol that is easy to implement and does not require doing things like writing a custom utf-8 parser. One of my goals is to simplify the art of writing correctly behaving terminal emulators and programs running in the terminal as well.

@leonerd
Copy link

leonerd commented Nov 6, 2017

Well alternatively if you'd prefer not to use S8C1T, just use CSIu encoding of the real Escape key. That does start to affect or break programs that weren't expecting it, but it avoids needing the combined C1+UTF8 parser.

Ofcourse, my actual answer to making things easy to implement, would be to point out to people that my libtermkey+libtickit already answers that and they should just use that already :) But maybe alternatives are also good.

@kovidgoyal
Copy link
Owner

kovidgoyal commented Nov 6, 2017 via email

@leonerd
Copy link

leonerd commented Nov 6, 2017

@kovidgoyal - small comment on your kitty protocol:

You document:

Shift — 0x1, Control — 0x2, Alt — 0x4

If you simply swapped Ctrl to be 0x4 and Alt to be 0x2, that then makes the modifiers use the same numbering sequence as xterm/et.al's CSIu encoding.

@kovidgoyal
Copy link
Owner

@leonerd thanks, comments are welcome. Since the protocol is currently only in kitty, it can be changed based on feedback.

@kovidgoyal
Copy link
Owner

@leonerd Modifier encoding changed as requested: 1f9acf9

@xparq
Copy link

xparq commented Sep 8, 2019

Wow, guys, @leonerd, @kovidgoyal, thanks, this was fun to follow! :)

Any important update to this nice debate, or in general, the "state of the art" of overcoming the disgusting, neglected, dusty mess of legacy keyboard handling in *n*x terminals?

(I'm on the verge of losing hope and abandoning the whole notion of bare ssh sessions in favor of something over WASM, just to make decent keyboard mappings possible. Even the horrid keyboard abstraction in JavaScript seems to provide a more usable platform for this.)

@kovidgoyal
Copy link
Owner

Nothing has happened. No one could agree on a new protocol and the effort died at the design stage https://gitlab.freedesktop.org/terminal-wg/specifications/issues/1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants