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

Distinguish "<c-i> and <tab>", "<c-j> and <ret>" #2209

Open
maximbaz opened this issue Jul 12, 2018 · 21 comments
Open

Distinguish "<c-i> and <tab>", "<c-j> and <ret>" #2209

maximbaz opened this issue Jul 12, 2018 · 21 comments

Comments

@maximbaz
Copy link
Contributor

Kitty has implemented a xterm protocol extension to improve keyboard handling. Most notably, it doesn't suffer from the homonyms issue and can easily distinguish e.g. "<c-j> and <ret>".

These extensions are slowly being adopted by terminal apps, and a wider usage will force other terminals to also implement these modern features. For example, ranger has implemented the support for the graphics rendering protocol that was designed in kitty.

I'm proposing to make use of this new "full mode" if it is available.

@Delapouite
Copy link
Contributor

Related discussion about libtermkey #1012

@maximbaz
Copy link
Contributor Author

So before this or native multiple cursors (#2194) could be implemented, we must see kakoune switch from ncurses to direct terminal output?

I hope by filing these feature requests I at least help pointing out the importance and benefits of making the switch, the things that kakoune is missing out because of relying on ncurses instead of reading terminfo and using latest and greatest features in modern terminals.

@mawww
Copy link
Owner

mawww commented Jul 14, 2018

There is a chicken and egg problem here, AFAIK this keyboard mode is exclusively implemented by kitty, which remains a pretty confidential terminal emulator. In order to parse those, we would need to ditch ncurses input and replace it with our own parser supporting this. On those subjects, Kakoune has been relatively conservative, trying to be widely compatible with established practice (which is why we try to stick close to Posix in various scripts).

That said, I'd be happy to help terminal progress towards a common way to get robust input, is there other terminal emulator that work with kitty's proposed extended input protocol ?

@maximbaz
Copy link
Contributor Author

Ditching ncurses seems to be bringing enough of good benefits 🙂 I'm personally not aware of other apps using this protocols, but my point is that by using it you (1) get cool features that competitors don't have and (2) you put pressure on other terminal editors to also support this protocol, and improve it as needed. Kakoune doesn't have to break existing compatibility and exclusively support kitty, but it could use this protocol if a terminal claims a support for it — I believe this protocol was actually designed with backwards compatibility in mind.

I simply think it's depressing that in 2018 a modern text editor still cannot distinguish <c-j> and <ret> and has to simulate cursors with background colors, when modern terminals actually have this already solved.

@mawww
Copy link
Owner

mawww commented Jul 14, 2018

This is a problem I'd like to see solved, however I am not sure about that direction:

  • It could make much more sense to lobby ncurses, which is used in many apps, to support extended input. IIRC Thomas Dickey, who maintains xterm, is pretty involved in ncurses.

  • There already exists an alternate input mechanism able to distinguish those keys, it has been proposed by @leonerd and is implemented in libtermkey (and libtickit). neovim uses it, but, although they are arguably much bigger and influencial than Kakoune, I have not heard of any terminal emulator implementing this alternate input protocol.

  • Just parsing one protocol is easy enough, but in order to stay portable, we need to be able to parse variations depending on whats in the terminfo for the current terminal, that is what makes terminal input complex to implement, we need to parse terminfo (so either roll our own or use libtinfo from ncurses).

The current state of terminal input is sad, and I'd be happy to participate in fixing it, but from those example, I remain dubious just implementing the kitty protocol is going to have an impact, it is useful for Kakoune users using kitty, but thats about it.

@maximbaz
Copy link
Contributor Author

I see. I'm curious to hear your thoughts on the native multiple cursors proposal too, do you see it also as something that should be adopted by ncurses or many other apps first before it can be considered for kakoune?

@mawww
Copy link
Owner

mawww commented Jul 15, 2018

Regarding the multiple native cursor, I think what would be the easiest to work with in Kakoune, and most flexible, would be to have a 'cursor' attribute, the same way we have bold, itallic or color attributes, which would tell the terminal "display those cells as-if you would display a cursor".

I suspect that would be relatively simple for terminals to implement as well, and would avoid the complexity that a new cursor protocol would require, in particular it does not touch on cursor positionning (once you have multiple cursors, terminal will require a notion of primary cursor in order to know where to display cursor based "widgets" such as an emoji picker or chinese character input window... If we keep it as a strictly display thing with attributes, we avoid all that)

@maximbaz
Copy link
Contributor Author

@mawww I think that's more or less what I proposed in #2194 and kovidgoyal/kitty#720, I agree there is no need to make the multiple cursors a "real thing", rendering "cursor-like" cells in the correct places is all we need. It is called "protocol" only because it needs to have a collaboration with editor (e.g. kakoune) in order to decide what exactly is expected from the terminal, and it needs a documentation that other terminals might choose to follow if they also want to support multiple cursors. I see this as some kind of a new escape code that is ignored by older terminals, but is recognized by moder ones and makes them render cursors in the defined cells.

Is it possible to have this "cursor" attribute without switching away from ncurses? And would you be willing to describe in kovidgoyal/kitty#720 what your editor would ideally need from the terminal to support multiple cursors feature?

@Screwtapello
Copy link
Contributor

Is it possible to have this "cursor" attribute without switching away from ncurses?

Very unlikely. ncurses likes to redraw the screen with whatever attributes it thinks should be in effect, so if you try to draw to the screen behind its back, ncurses is likely to occasionally scribble over what you've drawn without noticing.

@leonerd
Copy link

leonerd commented Jul 20, 2018

I see mention of libtickit here already - I'd like to open that discussion if I may. With respect to this particular bug, it already uses libtermkey under the hood, so it can distinguish all the specially-encoded keys provided the terminal will coöperate.

I'm aware that a wholesale rewrite of internals to switch to a different terminal IO system is a big undertaking, so I'm not expecting that it would necessarily be done - or at least, done easily. But if nothing else I would like to hear some thoughts on what your opinion of the current offering from libtickit provides, and if there are particular "sticking points"; particular missing features or shortcomings of the current set of features, that I could take a look at improving.

And yes, I'm aware that with relatively few projects actually using it, it's an uncommon dependency to add, which just contributes to the problem. It's a situation I'd like to be able to address sometime with some "headline" projects starting to make use of it, to help bootstrap the ecosystem around it.

http://www.leonerd.org.uk/code/libtickit/

@maximbaz
Copy link
Contributor Author

I guess the main downside of using a library instead of working directly with terminal is that it is yet another layer that stands between an application and a modern terminal. For the sake of example, let's say we were to implement a native terminal support for multiple cursors. Not only kakoune has to convince terminals to implement this feature, it has to also convince the library to support it. I'm not saying this specifically about libtickit, I'm just painting a generic example 🙂

@maximbaz maximbaz changed the title Use new xterm protocol extension to better handle keyboard shortcuts in modern terminals (will solve distinguishing "<c-i> and <tab>" or "<c-j> and <ret>") Distinguish "<c-i> and <tab>", "<c-j> and <ret>" Jul 22, 2018
@lenormf
Copy link
Contributor

lenormf commented Sep 1, 2020

Has this issue be impacted by the custom escape sequence parser? Is anything to be implemented on the builtin-terminal-ui branch?

@greneholt
Copy link
Contributor

FYI kitty has released a new version of it's keyboard handling that is far more comprehensive and more backwards compatible: kovidgoyal/kitty#3248

@mawww
Copy link
Owner

mawww commented Jan 29, 2021

It looks like this new version is based off @leonerd fixterms, which is already supported by the Kakoune parser, so maybe new kitty will work out-of-the-box (as we dont need most of the advanced features such as game mode).

@maximbaz
Copy link
Contributor Author

Just tested kitty's master against kakoune's master and builtin-terminal-ui, sadly in both cases it's not working out of the box.

I tested by adding the config below, and then pressing Ctrl+i and Ctrl+j expecting to see :ci and :cj appear

map global normal '<c-i>' :ci
map global normal '<tab>' :tab
map global normal '<c-j>' :cj
map global normal '<ret>' :ret

@Screwtapello
Copy link
Contributor

According to the linked specification document, Kitty sends legacy-compatible sequences by default (at least for all the keystrokes that have legacy-compatible sequences), but you can opt-in to sending disambiguating sequences with a custom control sequence (which Kakoune would need to be patched to do, and clear the custom mode on exit, like it currently does for mouse-event and focus-event modes).

I don't know if emitting that sequence unconditionally would break other terminals; there might be a thread about it on the terminal-wg issue tracker, but I haven't gotten back to that in months. :/

@vbauerster
Copy link
Contributor

but you can opt-in to sending disambiguating sequences with a custom control sequence (which Kakoune would need to be patched to do, and clear the custom mode on exit, like it currently does for mouse-event and focus-event modes).

It is implemented in 47c0d20.
I can confirm kakoune distinguishes <c-i> and <tab>, <c-j> and <ret> in kitty 0.20.3 out of the box.
As for tmux it's not clear if it will ever be supported.

@mohkale
Copy link

mohkale commented Jun 15, 2021

@vbauerster

As for tmux it's not clear if it will ever be supported.

Technically it was supported by tmux but recently (< 3 months) changed due to tmux internally translating keys. I do intend to fix this (for my personal emacs use) and nicm seems receptive to that (see tmux#2705). In the meantime I've shared a patch that basically undoes the internal translation for C-i to TAB (etc.).

@jtrees
Copy link

jtrees commented Nov 16, 2021

Is this fixed with #4415?

@mawww
Copy link
Owner

mawww commented Nov 17, 2021

@jtrees Not really, we still have to support legacy terminals that will send the same byte when we hit the Tab key or Ctrl+i, we now can distinguish them on modern terminals that support CSI u but we still need the compatibility code that treats Tab as Ctrl+i until we decide to break old terminals and require users to map in their config.

@JosefLitos
Copy link

JosefLitos commented Jul 19, 2023

Is anything older than xterm even being used nowadays? I mean, I know it is (tty...) but who uses a more advanced text editor like this in such environments? Not sure if you're only using CSI u or also the xterm way, but if not so, xterm offers a solution too, using \033[>4;2m. Considering that xterm was almost the standard for a while, quite a few terminals understand it, even though they may not support the kitty's keyboard protocol. That should fix #4019 for most sensible terminals.

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