Terminal: <ESC> comes through as <ESC><ESC>

Created on 17 Jun 2019  路  9Comments  路  Source: microsoft/terminal

Environment

Windows 1903 18917.1000
terminal master 315abf6fa6e096f0ad8ba7db68fa8a3fd9a591b1

Steps to reproduce

Run CascadiaPackage
Select new Ubuntu package.
run some command (e.g. ls /usr/bin)
now attempt to paste the last command to the previous shell command using <ESC> . (e.g. type cd <ESC> . .

Expected behavior

the last command to the previous shell command should be pasted (e.g. cd /usr/bin)

Actual behavior

cd . Escape appears to be ignored / not passed to WSL.

In WSL <ESC> . works as expected.
I note that <ALT> + and <ALT> . work. For whatever historic reason, my muscle memory is <ESC> . pastes the final argument to last command I ran.

There are other uses of that should be consider (e.g <ESC> t to swap the last two words on the line). As bash considers a control character, it should probably be sent along to the WSL command line the same as CTRL and ALT are.

Area-Input Area-TerminalControl Issue-Bug Needs-Tag-Fix Product-Terminal

All 9 comments

holy crap I never knew that keybinding existed. I guess I didn't really know about the alt+. one either, though, fundamentally they're the same keybinding, as esc+. is sending the same sequence as alt+..

This _does_ work in conhost+conpty, so this is definitely a terminal-specific bug. Thanks for the report!

Looks like WT passes ESC through as ESC ESC. That's not great.

The double escape happens because Terminal::SendKeyEvent ignores almost always TerminalInput::HandleKey's return value: https://github.com/microsoft/terminal/blob/08464648f280624023d3572346a75dee7a428de8/src/cascadia/TerminalCore/Terminal.cpp#L253-L258

ch is set to UNICODE_NULL for the escape case, hence SendKeyEvent returns false, even though the key was already handled by TerminalInput::HandleKey. That means that TermControl::_CharacterHandler will be called with the key translated as character, which will be \x1b, hence it appears as ESC ESC.

Now ignoring HandleKey's return value (in many cases) would mean that almost all keys would appear twice. And indeed that happens in theory, but not in effect because HandleKey has two cases: one for "printable" keys and one for others: https://github.com/microsoft/terminal/blob/08464648f280624023d3572346a75dee7a428de8/src/terminal/input/terminalInput.cpp#L446-L461

So for printable keys, the event's char data is used - but char data is most of the times UNICODE_NULL due to the way Terminal::SendKeyEvent constructs the event: https://github.com/microsoft/terminal/blob/08464648f280624023d3572346a75dee7a428de8/src/cascadia/TerminalCore/Terminal.cpp#L255

And ch is initialized with UNICODE_NULL: https://github.com/microsoft/terminal/blob/08464648f280624023d3572346a75dee7a428de8/src/cascadia/TerminalCore/Terminal.cpp#L226

And that means that for "printable" keys, HandleKey returns that it handled the key already, but then didn't really send an input sequence (or rather: it sends one with size 0) - which doesn't really matter because SendKeyEvent happily "ignores" the return value.

I note that + and . work. For whatever historic reason, my muscle memory is .

This is because bash (and other shells/terminals) prefix an ESC in response to the Alt key. Alt + . ends up as ESC + .

Just to add that a very common sequence is also esc-p, which in tcsh and csh executes a command search based on what has been typed so far. In other words, you type a part of a command, esc-p and you get the first possible completion, and so on. Esc-p is also used in zsh and it is also possible to enable it in .inputrc for bash. Speaking of which, esc-b (back one word) and esc-f (forward one word) and esc-d (delete word) also cannot work in bash. I'd say that correct esc behaviour is important.

Microsoft terminal version 0.2.1715.0.

Cool, thanks, we know it is a bug and it is impacting peoples' lives. It will break _all sorts_ of different things that require individual escape characters.

@Trundle you've looked at this in a good amount of depth. Would you want to take it on as a community contribution? :smile:

I can try to, but I also won't be able to do so until the end of next week - I don't mind if someone else fixes it in the meantime.

:tada:This issue was addressed in #1974, which has now been successfully released as Windows Terminal Preview v0.3.2142.0.:tada:

Handy links:

Was this page helpful?
0 / 5 - 0 ratings