cspotcode
cspotcode

Reputation: 1892

How do Linux utilities avoid accidentally splitting ANSI key sequences in stdin stream?

Terminal emulators encode keyboard input as ANSI escape sequences.

Escape key is a single byte: \x1b
Delete key is 4 bytes: \x1b '[' '3' '~'

What differentiates between a user pressing the Delete key and the sequence of keys "Escape", "[", "3", "~"?

How do interactive programs like vim tell the difference?

How do terminal emulators and utilities like SSH send key sequences in a way that ensures the receiving program makes the right interpretation?

Upvotes: 1

Views: 139

Answers (1)

user2404501
user2404501

Reputation:

Timing.

If the characters arrive in a short enough time span, it's unlikely that they were typed individually.

In vim, the options esckeys, ttimeout, and ttimeoutlen determine whether and how long to wait for an escape sequence to complete. These are not traditional vi options; in traditional vi an escape is just an escape and arrow keys are useless.

You can test this by typing Esc O A or Esc [ A really fast in vim. If you're fast enough, and your terminal settings aren't too exotic, one of them will act like the up arrow key. Type the same thing slowly, and it will do something different. Do :set noesckeys and it will never act like the arrow key (even when you actually press the arrow key) - this is the price you must pay if you want the response to the escape key to be instant.

The experiment could be done with other sequences like your ^[[3~ but a 3-character one is easier to type.

The curses library also uses timeouts when interpreting terminal input. Here's a related question about that: How can I know that the user hit the ESC key in a console with ncurses (Linux)?

Upvotes: 1

Related Questions