ajalt/mordant

Recognize `Escape` key when not used in escape sequence

Jojo4GH opened this issue · 6 comments

Moved from comment on pull request: #192 (comment)

ESC can both mean the escape key was pressed as well as be the start of an escape sequence.
It might be possible to also use a short timeout on the second read here.
Since every ESC in escape sequences is quickly followed by other characters this would allow to distinguishing from single Escape key presses and users would not need to press escape twice.

That's a good idea, and I did look into that, but I wasn't able to find a timeout value that was reliable without being ususably long.

The main issue is that there's not actually an upper bound on timeouts for ANSI sequences: you can manually type ESC [ d and the program is supposed to interpret that as a left arrow key event.

The main issue is that there's not actually an upper bound on timeouts for ANSI sequences: you can manually type ESC [ d and the program is supposed to interpret that as a left arrow key event.

That's an unfortunate compatibility requirement but understandable. Maybe this timeout could be configured/enabled manually by the programmer? Some application don't want to have use cases for manually typing those sequences and they could instead configure Mordant to have the "single escape after xxx ms" behaviour.

You already can! Pass a timeout to readEvent and it will report a single ESC as Escape if it doesn't receive anything else.

Feel free to try that, but I found that even with high timeout values I was still seeing escape sequences get split up.

Thanks! That seems to work even over network with just a 4 ms timeout set.

However, if I read the source correctly the same small timeout will apply to all read calls inside the readInputEvent function.
For some escape sequence read is used three or four times and setting a small timeout may lead to some unnecessary instability on top of the unavoidable one for the escape key case.
So if we read for instance ESC [, we know that the ESC was not the escape key but the beginning of a sequence and we could relax a bit with the following timeouts.
Maybe this could fix the splitting of escape sequences you have experienced?

This could be solved using the Kitty keyboard protocol for terminals that supports it.

I decided to go with the short timeout approach. It means you can't type in escape sequences any more, but that seems like a much less common use case than using the escape key normally.

The Kitty protocol is interesting, but most terminals don't support it yet. So it's not a high priority, but we could open a separate issue if we still think it's worth it.