8000 KeyChar should be preserved for Ctrl+Letter (#75861) · dotnet/runtime@2728bb0 · GitHub
[go: up one dir, main page]

Skip to content

Commit 2728bb0

Browse files
KeyChar should be preserved for Ctrl+Letter (#75861)
Co-authored-by: Adam Sitnik <adam.sitnik@gmail.com>
1 parent 9b10c53 commit 2728bb0

File tree

2 files changed

+10
-6
lines changed

2 files changed

+10
-6
lines changed

src/libraries/System.Console/src/System/IO/KeyParser.cs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,7 @@ private static ConsoleKeyInfo ParseFromSingleChar(char single, bool isAlt)
333333
_ when char.IsAsciiLetterLower(single) => ConsoleKey.A + single - 'a',
334334
_ when char.IsAsciiLetterUpper(single) => UppercaseCharacter(single, out isShift),
335335
_ when char.IsAsciiDigit(single) => ConsoleKey.D0 + single - '0', // We can't distinguish DX and Ctrl+DX as they produce same values. Limitation: Ctrl+DX can't be mapped.
336-
_ when char.IsBetween(single, (char)1, (char)26) => ControlAndLetterPressed(single, out keyChar, out isCtrl),
336+
_ when char.IsBetween(single, (char)1, (char)26) => ControlAndLetterPressed(single, isAlt, out keyChar, out isCtrl),
337337
_ when char.IsBetween(single, (char)28, (char)31) => ControlAndDigitPressed(single, out keyChar, out isCtrl),
338338
'\u0000' => ControlAndDigitPressed(single, out keyChar, out isCtrl),
339339
_ => default
@@ -359,7 +359,7 @@ static ConsoleKey UppercaseCharacter(char single, out bool isShift)
359359
return ConsoleKey.A + single - 'A';
360360
}
361361

362-
static ConsoleKey ControlAndLetterPressed(char single, out char keyChar, out bool isCtrl)
362+
static ConsoleKey ControlAndLetterPressed(char single, bool isAlt, out char keyChar, out bool isCtrl)
363363
{
364364
// Ctrl+(a-z) characters are mapped to values from 1 to 26.
365365
// Ctrl+H is mapped to 8, which also maps to Ctrl+Backspace.
@@ -370,7 +370,9 @@ static ConsoleKey ControlAndLetterPressed(char single, out char keyChar, out boo
370370
Debug.Assert(single != 'b' && single != '\t' && single != '\n' && single != '\r');
371371

372372
isCtrl = true;
373-
keyChar = default; // we could use the letter here, but it's impossible to distinguish upper vs lowercase (and Windows doesn't do it as well)
373+
// Preserve the original character the same way Windows does (#75795),
374+
// but only when Alt was not pressed at the same time.
375+
keyChar = isAlt ? default : single;
374376
return ConsoleKey.A + single - 1;
375377
}
376378

src/libraries/System.Console/tests/KeyParserTests.cs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,8 @@ public void ExtendedStringCodePath()
264264
{
265265
get
266266
{
267+
// Control+C
268+
yield return (new string((char)3, 1), new[] { new ConsoleKeyInfo((char)3, ConsoleKey.C, false, false, true) });
267269
// Backspace
268270
yield return (new string((char)127, 1), new[] { new ConsoleKeyInfo((char)127 8000 , ConsoleKey.Backspace, false, false, false) });
269271
// Ctrl+Backspace
@@ -448,7 +450,7 @@ public class GNOMETerminalData : TerminalData
448450
{
449451
yield return (new byte[] { 90 }, new ConsoleKeyInfo('Z', ConsoleKey.Z, true, false, false));
450452
yield return (new byte[] { 97 }, new ConsoleKeyInfo('a', ConsoleKey.A, false, false, false));
451-
yield return (new byte[] { 1 }, new ConsoleKeyInfo(default, ConsoleKey.A, false, false, true));
453+
yield return (new byte[] { 1 }, new ConsoleKeyInfo((char)1, ConsoleKey.A, false, false, true));
452454
yield return (new byte[] { 27, 97 }, new ConsoleKeyInfo('a', ConsoleKey.A, false, true, false));
453455
yield return (new byte[] { 27, 1 }, new ConsoleKeyInfo(default, ConsoleKey.A, false, true, true));
454456
yield return (new byte[] { 49 }, new ConsoleKeyInfo('1', ConsoleKey.D1, false, false, false));
@@ -613,7 +615,7 @@ public class XTermData : TerminalData
613615
{
614616
yield return (new byte[] { 90 }, new ConsoleKeyInfo('Z', ConsoleKey.Z, true, false, false));
615617
yield return (new byte[] { 97 }, new ConsoleKeyInfo('a', ConsoleKey.A, false, false, false));
616-
yield return (new byte[] { 1 }, new ConsoleKeyInfo(default, ConsoleKey.A, false, false, true));
618+
yield return (new byte[] { 1 8000 }, new ConsoleKeyInfo((char)1, ConsoleKey.A, false, false, true));
617619
yield return (new byte[] { 195, 161 }, new ConsoleKeyInfo('\u00E1', default, false, false, false));
618620
yield return (new byte[] { 194, 129 }, new ConsoleKeyInfo('\u0081', default, false, false, false));
619621
yield return (new byte[] { 49 }, new ConsoleKeyInfo('1', ConsoleKey.D1, false, false, false));
@@ -886,7 +888,7 @@ public class WindowsTerminalData : TerminalData
886888
{
887889
yield return (new byte[] { 90 }, new ConsoleKeyInfo('Z', ConsoleKey.Z, true, false, false));
888890
yield return (new byte[] { 97 }, new ConsoleKeyInfo('a', ConsoleKey.A, false, false, false));
889-
yield return (new byte[] { 1 }, new ConsoleKeyInfo(default, ConsoleKey.A, false, false, true));
891+
yield return (new byte[] { 1 }, new ConsoleKeyInfo((char)1, ConsoleKey.A, false, false, true));
890892
yield return (new byte[] { 27, 97 }, new ConsoleKeyInfo('a', ConsoleKey.A, false, true, false));
891893
yield return (new byte[] { 27, 1 }, new ConsoleKeyInfo(default, ConsoleKey.A, false, true, true));
892894
yield return (new byte[] { 49 }, new ConsoleKeyInfo('1', ConsoleKey.D1, false, false, false));

0 commit comments

Comments
 (0)
0