CsiKeyPattern.cs 2.2 KB

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