mawww / kakoune

mawww's experiment for a better code editor
http://kakoune.org
The Unlicense
9.85k stars 711 forks source link

[BUG] Delay while getting out of insert mode? #4987

Closed Ashvith10 closed 8 months ago

Ashvith10 commented 11 months ago

Version of Kakoune

v2023.08.05

Reproducer

  1. Press i to enter insert mode and note the delay
  2. Press esc to exit insert mode and note the delay

Outcome

You will quickly toggle to insert mode, but there is a good amount of delay while exiting.

Expectations

Toggle should not have any delay

Additional information

krobelus commented 11 months ago

I haven't managed to reproduce. We could try to create a reproducer script that inputs key strokes (perhaps using tmux send-keys).

Making use of tmux makes it even more worse.

that is probably due to tmux' high default escape time, see :help faq why-does-leaving-insert-mode-take-more-than-half-a-second-in-tmux?

Ashvith10 commented 11 months ago

@krobelus I tried reading the manual, and the Alt-; key seems to perform the same action (just an assumption), but faster. I'm not really sure what's happening?

Edit: No, it isn't the same as toggling i, my bad.

Screwtapello commented 11 months ago

Do you mean "press <esc> to exit insert mode"? Pressing i shouldn`t exit insert mode, after any delay.

Tilix and Blackbox are both UI wrappers for the libvte terminal emulator library. Does the same thing happen in a different terminal emulator, like xterm or rxvt or QTerminal?

Ashvith10 commented 11 months ago

@Screwtapello thank you for pointing that out. I'll correct it right away.

I haven't used a non-VTE emulator yet, so I can't be sure.

Screwtapello commented 11 months ago

For background information:

If you press Escape, the terminal sends byte 0x1B. If you press I, the terminal sends byte 0x49. If you press Alt+I, the terminal sends... 0x1B 0x49, but without any delay caused by your fingers moving from one key to the next. As a result, tools designed for long-distance serial connections (where error-recovery can delay messages by a surprising amount) tend to have a timeout - when they receive 0x1B, they start a timer, and if another character arrives before the timer expires, it's a Alt modifier, otherwise it's a standalone Esc. tmux is one such application, by default adding a 500ms delay after Esc.

Kakoune is not designed for long-distance serial connections, it's designed with the assumption it's talking to the terminal through a kernel psuedo-TTY rather than actual serial or even networking hardware. When it receives Esc, it only treats it as an Alt modifier if another character occurs within the same packet. As a result, there should be no perceptible delay when running Kakoune on a local machine, in a local terminal emulator.

If there is a perceptible delay in that situation, it's hard to imagine where it might come from.

Ashvith10 commented 11 months ago

@Screwtapello From my experience with zellij, there's no such problem. It's just that zellij is quite new, so I want to be able to use tmux. The recommended solution, at least from what I was able to gather, was to add this to the tmux config file:

 set -sg escape-time 20

But since you're talking about long-distance serial connection, now I'm a little concerned about how I should handle cases where I would have to use ssh to edit stuff on a far-away machine. Will Kakoune struggle there?

Screwtapello commented 11 months ago

zellij runs inside a terminal, so it still has to deal with the many ills to which the terminal is heir, including Esc/Alt ambiguity.

That tmux config change should make Kakoune-inside-tmux much more pleasant to work with, yes.

The issue with a long-distance connection is that packets can get fragmented and may not arrive at the destination with the exact timing they left the source computer, which can lead to Esc and Alt being unreliable. One way around this might be to run the remote Kakoune inside tmux with a larger escape-time delay (avoiding accidental fragmentation issues) and typing more slowly (avoiding accidental combining issues). Alternatively, you might be able to use a client like mosh instead of ssh, which parses keypresses locally and sends a less-brittle encoding over the network (I think).

arachsys commented 11 months ago

I use Kakoune a lot over higher latency ssh connections. I live in the middle of nowhere and often work on remote hosts over a 4G modem.

In practice, esc sequences don't seem to get 'torn apart' over ssh despite Kakoune's assumption that it can get them in a single read(). This is presumably because the user -> server direction of an interactive session is nearly idle anyway: pretty much one nearly-empty packet per keypress, which will always have space for the entire sequence.

However, sometimes a standalone esc will get sent in the same packet as the next key I hit and might result in an unintended effect. I've apparently developed a habit of briefly pausing after I hit esc (but no other key) on connections that feel particularly laggy to avoid this, or hitting esc twice. (It affects pretty much anything that uses esc, not just kakoune. I think I originally learned the habit on nvi or vim years ago, when 100ms latency wasn't unusual.)

I think I may have seen tearing over slow serial links, but even there, it's surprisingly rare. As @Screwtapello says, it would probably help to wrap with tmux/screen there and set the escape timeout to some multiple of the reciprocal baudrate. I don't do this often enough to have investigated much though. Presumably setting it too high is bad news because you'll become more and more susceptible to unwanted combining with subsequent characters after a real esc...