-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
Console.ReadKey returns incomplete information for some key sequences on Linux #802
Comments
In general we don't have a good way to do better than this. They're is no API similar to what Windows has for getting detailed information on the keys that were typed; we simply do our best to infer it from the escape sequences sent to the terminal. |
There are key bindings that work fine in bash but not with PSReadline, e.g. C-] is character search (a little like F3 on Windows). C-@ is also used in bash to set a mark, then C-x,C-x to exchange the point and mark. GNU readline understands these escape sequences, so presumably .Net core can as well. |
If you can make it work, we'd welcome a PR. This is a known limitation we shipped with (mono has a similar limitation), and this is not something we plan to revisit soon. |
ps I should clarify. I haven't checked the exact combinations you're talking about. If those combinations result in a unique sequence of escape codes we can reliably recognize, then fixing it should be relatively easy. My concern is they don't, and an entirely different mechanism would be needed. |
Assuming I can attempt to see the sequences easily via Console.In.Read, the keys I'm concerned about don't actually generate anything, so some investigation is necessary. I'm not sure if it's something At any rate, I'll try and investigate further at some point, I expect some PowerShell users will want |
The affected key bindings aren't too critical, so I haven't found time to take a look yet. |
A quick update -
After reviewing the code, I think I believe the bug is related to this method - it doesn't handle most of these characters, it returns It's not that useful to expect a valid Edit by @carlossanlop: since we moved to dotnet/runtime, the |
Below is a summary of the existing shortcomings and how they relate to how things work in the Unix world. Please note:
Context:The fundamental restrictions regarding Control-based chords and Alt-based chords - which come from most Unix-like OSs running
Shortcomings of the existing
|
Triage: |
Quick update: I debugged
If I type a key combination like Control + Left Arrow, it gets detected correctly by the native call we make here: runtime/src/libraries/System.Console/src/System/IO/StdInReader.cs Lines 318 to 328 in cf1390c
Going through the above successful code path means that we do not go into the long switch case section mentioned in this comment, which belongs to the
But if I try one of @lzybkr 's key combinations, For example, Control + ! with my keyboard layout (US), forces me to use Control + Shift + 1, but does not return anything. Interestingly, running the command Same with Control + @: My keyboard layout forces me to use Control + Shift + 2 and does not get detected. Next step: Understand what we are doing in |
Fundamentally, the issue seems to stem from the fact that the GetKeyFromCharValue method, which does not provide mappings for many common key characters such as `, ,, ., [, ], \ and =. I'm assuming this is intentional, as doing otherwise would be making assumptions about the keyboard layout. However, this seems to have the side-effect that combining Alt with any of the above keys results in the keyChar value being replaced by the escape key, so such chords are effectibly unusable. This strikes me as being overly conservative, however it's not clear how we could improve it in a reliable way. |
@eiriktsarpalis Do you say that it is impossible to use P/Invokes for keyboard layout mapping in ReadKey()? |
I'm saying I don't know how we could improve it. Can you recommend particular APIs we could make use of? |
Maybe https://linux.die.net/man/3/getch - it uses TermInfo too or/and return two-character strings like ^A for Ctrl-A and M-A for Alt-M. |
Unless I'm misunderstanding something, it is already the case that key combinations are surfaced as character strings compatible with what |
I don't see this specifically mentioned, but shift+enter is also incomplete on Linux (I'm testing on WSL2 Ubuntu). Using the following program returns different results on Windows vs Linux: class Program
{
static void Main(string[] args)
{
Console.WriteLine("Press a key:");
var key = Console.ReadKey();
Console.WriteLine("Key: " + key.Key);
Console.WriteLine("KeyChar: " + key.KeyChar);
Console.WriteLine("Modifiers: " + key.Modifiers);
}
} On Windows, when we press shift+enter we get: Key: Enter
KeyChar:
Modifiers: Shift On Linux, we get: Key: Enter
KeyChar:
Modifiers: 0 |
On Linux the Shift+Home and Shift+End isn't caught by the Console.ReadKey. |
This issue is likely to move to .NET 7.0, where we're anticipating a collection of Console-related work will be done. Leaving it in 6.0 for the time-being though. |
@waf that's normal: In |
Please, correct me if I'm wrong: Linux (NET.Core) doesn't have convenient ConsoleKeyInfo modifier describer because there are problems with particular combinations detection (20-30% of all) in OS. Is that correct? |
The |
We are going to move this out to .NET 7 with the intention of grouping this with other Console-related efforts as being discussed in #52374. |
On |
…106.6 (dotnet#802) [main] Update dependencies from dotnet/arcade
AB#1115513
Using PowerShell 6.0.0-alpha.10 on Ubuntu 14.04, I run
and type Ctrl-@. I get back
I see somewhat similar results with other key presses like Ctrl-! or Ctrl-%. In some cases,
KeyChar
has the correct key, butModifiers
is still0
, resulting in incorrectly assuming Ctrl was not down and e.g. inserting a!
instead of doing whatever actionCtrl+!
was bound to.This issue affects some of the key bindings in PSReadline.
The text was updated successfully, but these errors were encountered: