CsiKeyPattern.cs 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. #nullable enable
  2. using System.Text.RegularExpressions;
  3. namespace Terminal.Gui.Drivers;
  4. /// <summary>
  5. /// Detects ansi escape sequences in strings that have been read from
  6. /// the terminal (see <see cref="IAnsiResponseParser"/>).
  7. /// Handles CSI key parsing such as <c>\x1b[3;5~</c> (Delete with Ctrl)
  8. /// </summary>
  9. public class CsiKeyPattern : AnsiKeyboardParserPattern
  10. {
  11. private readonly Regex _pattern = new (@"^\u001b\[(\d+)(?:;(\d+))?~$");
  12. private readonly Dictionary<int, Key> _keyCodeMap = new ()
  13. {
  14. { 1, Key.Home }, // Home (modern variant)
  15. { 4, Key.End }, // End (modern variant)
  16. { 5, Key.PageUp },
  17. { 6, Key.PageDown },
  18. { 2, Key.InsertChar },
  19. { 3, Key.Delete },
  20. { 11, Key.F1 },
  21. { 12, Key.F2 },
  22. { 13, Key.F3 },
  23. { 14, Key.F4 },
  24. { 15, Key.F5 },
  25. { 17, Key.F6 },
  26. { 18, Key.F7 },
  27. { 19, Key.F8 },
  28. { 20, Key.F9 },
  29. { 21, Key.F10 },
  30. { 23, Key.F11 },
  31. { 24, Key.F12 }
  32. };
  33. /// <inheritdoc/>
  34. public override bool IsMatch (string? input) { return _pattern.IsMatch (input!); }
  35. /// <inheritdoc/>
  36. protected override Key? GetKeyImpl (string? input)
  37. {
  38. Match match = _pattern.Match (input!);
  39. if (!match.Success)
  40. {
  41. return null;
  42. }
  43. // Group 1: Key code (e.g. 3, 17, etc.)
  44. // Group 2: Optional modifier code (e.g. 2 = Shift, 5 = Ctrl)
  45. if (!int.TryParse (match.Groups [1].Value, out int keyCode))
  46. {
  47. return null;
  48. }
  49. if (!_keyCodeMap.TryGetValue (keyCode, out Key? key))
  50. {
  51. return null;
  52. }
  53. // If there's no modifier, just return the key.
  54. if (!int.TryParse (match.Groups [2].Value, out int modifier))
  55. {
  56. return key;
  57. }
  58. key = modifier switch
  59. {
  60. 2 => key.WithShift,
  61. 3 => key.WithAlt,
  62. 4 => key.WithAlt.WithShift,
  63. 5 => key.WithCtrl,
  64. 6 => key.WithCtrl.WithShift,
  65. 7 => key.WithCtrl.WithAlt,
  66. 8 => key.WithCtrl.WithAlt.WithShift,
  67. _ => key
  68. };
  69. return key;
  70. }
  71. }