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

[API Proposal]: Allow Console.ReadKey to parse VT sequences when ENABLE_VIRTUAL_TERMINAL_INPUT is set on Windows #60107

Open
Tracked by #64487
daxian-dbw opened this issue Oct 7, 2021 · 6 comments
Labels
api-suggestion Early API idea and discussion, it is NOT ready for implementation area-System.Console
Milestone

Comments

@daxian-dbw
Copy link
Contributor

daxian-dbw commented Oct 7, 2021

Background and motivation

Feature Ask

Today, when ENABLE_VIRTUAL_TERMINAL_INPUT is set to the input handler on Windows, Console.ReadKey will just pass through all the VT sequences emitted by the terminal. It would be great if a configuration is added to System.Console so that we can make Console.ReadKey parse VT sequences in this case similarly to how Console.ReadKey works on Unix platforms. Of course, this will be an opt-in functionality, maybe through a static property on System.Console, say Console.ForceParseVTSequence, which by default is false, so the existing behavior is unchanged.

Motivation

The right-clicking paste causes quite some long-standing problems in PowerShell (see PowerShell/PSReadLine#579 and #38966 for details), and we are seeking to solve it by leveraging the Bracketed Paste Mode, which Windows Terminal started to support earlier this year. To enable the bracketed paste support in Windows Terminal, the application needs to set the ENABLE_VIRTUAL_TERMINAL_INPUT mode to the console's input handler, however, that will cause Console.ReadKey to just pass through VT sequences on Windows, which would require the application itself to parse all the VT sequences.

We don't want to re-implement a VT sequence parser in PowerShell, especially given that .NET already has one that works on Unix platforms. I think it's reasonable to ask .NET to allow a similar behavior on Windows as an opt-in feature, which can benefit all applications that have the similar need.

Related Issues

#60101
PowerShell/PSReadLine#1471

API Proposal

Add a static property bool static ForceParseVTSequence to System.Console to turn on/off the feature.
Its default value is false, so that current behavior is unchanged by default.

API Usage

// Set 'ENABLE_VIRTUAL_TERMINAL_INPUT' mode to the console's input handler on Windows,
// then turn on this feature in C# code.
Console.ForceParseVTSequence = true;
// .NET will map the VT sequence emitted by the Windows Terminal to valid ConsoleKeyInfo values,
// similarly to how this behaves on Linux.
Console.ReadKey()

Risks

.NET depends on the terminfo database to map VT sequences to specific key combinations on Unix platforms, but Windows doesn't have such terminfo database. I understand this would be problem to enable a VT parser on Windows.

Would it be possible to assume VT100 as the standard on Windows? According to the doc, Windows Terminal emits sequences based on VT100:

The behavior of the following sequences is based on the VT100 and derived terminal emulator technologies, most specifically the xterm terminal emulator. More information about terminal sequences can be found at http://vt100.net and at http://invisible-island.net/xterm/ctlseqs/ctlseqs.html.

@daxian-dbw daxian-dbw added the api-suggestion Early API idea and discussion, it is NOT ready for implementation label Oct 7, 2021
@dotnet-issue-labeler dotnet-issue-labeler bot added area-System.Console untriaged New issue has not been triaged by the area owner labels Oct 7, 2021
@ghost
Copy link

ghost commented Oct 7, 2021

Tagging subscribers to this area: @dotnet/area-system-console
See info in area-owners.md if you want to be subscribed.

Issue Details

Background and motivation

Feature Ask

Today, when ENABLE_VIRTUAL_TERMINAL_INPUT is set to the input handler on Windows, Console.ReadKey will just pass through all the VT sequences emitted by the terminal. It would be great if a configuration is added to System.Console so that we can make Console.ReadKey parse VT sequences in this case similarly to how Console.ReadKey works on Unix platforms. Of course, this will be an opt-in functionality, maybe through a static property on System.Console, say Console.ForceParseVTSequence, which by default is false, so the existing behavior is unchanged.

Motivation

The right-clicking paste causes quite some long-standing problems in PowerShell (see PowerShell/PSReadLine#579 for details), and we are seeking to solve it by leveraging the Bracketed Paste Mode, which Windows Terminal started to support earlier this year. To enable the bracketed paste support in Windows Terminal, the application needs to set the ENABLE_VIRTUAL_TERMINAL_INPUT mode to the console's input handler, however, that will cause Console.ReadKey to just pass through VT sequences on Windows, which would require the application itself to parse all the VT sequences.

We don't want to re-implement a VT sequence parser in PowerShell, especially given that .NET already has one that works on Unix platforms. I think it's reasonable to ask .NET to allow a similar behavior on Windows as an opt-in feature, which can benefit all applications that have the similar need.

Related Issues

#60101
PowerShell/PSReadLine#1471

API Proposal

Add a static property bool static ForceParseVTSequence to System.Console to turn on/off the feature.
Its default value is false, so that current behavior is unchanged by default.

API Usage

// Set 'ENABLE_VIRTUAL_TERMINAL_INPUT' mode to the console's input handler on Windows,
// then turn on this feature in C# code.
Console.ForceParseVTSequence = true;
// .NET will map the VT sequence emitted by the Windows Terminal to valid ConsoleKeyInfo values,
// similarly to how this behaves on Linux.
Console.ReadKey()

Risks

.NET depends on the terminfo database to map VT sequences to specific key combinations on Unix platforms, but Windows doesn't have such terminfo database. I understand this would be problem to enable a VT parser on Windows.

Would it be possible to assume VT100 as the standard on Windows? According to the doc, Windows Terminal emits sequences based on VT100:

The behavior of the following sequences is based on the VT100 and derived terminal emulator technologies, most specifically the xterm terminal emulator. More information about terminal sequences can be found at http://vt100.net and at http://invisible-island.net/xterm/ctlseqs/ctlseqs.html.

Author: daxian-dbw
Assignees: -
Labels:

api-suggestion, area-System.Console, untriaged

Milestone: -

@daxian-dbw
Copy link
Contributor Author

daxian-dbw commented Oct 7, 2021

/cc @lzybkr, @SteveL-MSFT and @DHowett-MSFT FYI

@jeffhandley jeffhandley added needs-further-triage Issue has been initially triaged, but needs deeper consideration or reconsideration and removed untriaged New issue has not been triaged by the area owner labels Oct 9, 2021
@jeffhandley jeffhandley added this to the 7.0.0 milestone Oct 9, 2021
@adamsitnik
Copy link
Member

.NET depends on the terminfo database to map VT sequences to specific key combinations on Unix platforms, but Windows doesn't have such terminfo database. I understand this would be problem to enable a VT parser on Windows.

Not anymore. With #72193 we can parse all VT Sequences even without Terminfo. Terminfo is now treated as default source of truth, but when it does not contain mapping for given sequence, we fall back to our own mappings. This code path is very often used for PuTTy which often identifies as xterm, but uses completely different key mappings.

With #73257 we are going to get Bracketed Paste support for Unix. Implementing this issue should be way easier now, but I am afraid that we won't have the time to include it in .NET 7. Unless it's VERY important.

@adamsitnik adamsitnik modified the milestones: 7.0.0, 8.0.0 Aug 9, 2022
@adamsitnik adamsitnik removed the needs-further-triage Issue has been initially triaged, but needs deeper consideration or reconsideration label Aug 9, 2022
@daxian-dbw
Copy link
Contributor Author

Not anymore. With #72193 we can parse all VT Sequences even without Terminfo.

Sorry for my late response, but this is great! Looking forward to having this implemented in .NET 8 so that PSReadLine can enable ENABLE_VIRTUAL_TERMINAL_INPUT on Windows to get consistent behavior cross platform.

With #73257 we are going to get Bracketed Paste support for Unix.

I left a comment there to clarify my original ask. Please take a look when you get a chance.

@daxian-dbw
Copy link
Contributor Author

@adamsitnik one more ask:
What is today's behavior of Console.ReadKey when encountering escape sequences that cannot be mapped/recognized? Will it just pass the escape sequences through as is?

This is an interesting scenario in VS Code terminal with the feature "shell integration". The VS Code terminal wants to send some artificial escape sequences to the shell to trigger actions of the shell. In this particular case, triggering the shell to do a tab completion and then having the shell send the result back to the VS Code terminal. So, it requires the shell to register a mapping from some artificial escape sequences to actions, and also be able to receive those artificial escape sequences from Console.ReadKey.

Please take this scenario into consideration when addressing this issue in .NET 8. Thanks!

@adamsitnik
Copy link
Member

What is today's behavior of Console.ReadKey when encountering escape sequences that cannot be mapped/recognized? Will it just pass the escape sequences through as is?

@daxian-dbw In case Console.ReadKey does not recognize the escape sequence, it just passes it as is.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api-suggestion Early API idea and discussion, it is NOT ready for implementation area-System.Console
Projects
None yet
Development

No branches or pull requests

3 participants