| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283 |
- #nullable enable
- using System.Text.RegularExpressions;
- namespace Terminal.Gui.Drivers;
- /// <summary>
- /// Detects ansi escape sequences in strings that have been read from
- /// the terminal (see <see cref="IAnsiResponseParser"/>).
- /// Handles CSI key parsing such as <c>\x1b[3;5~</c> (Delete with Ctrl)
- /// </summary>
- public class CsiKeyPattern : AnsiKeyboardParserPattern
- {
- private readonly Regex _pattern = new (@"^\u001b\[(\d+)(?:;(\d+))?~$");
- private readonly Dictionary<int, Key> _keyCodeMap = new ()
- {
- { 1, Key.Home }, // Home (modern variant)
- { 4, Key.End }, // End (modern variant)
- { 5, Key.PageUp },
- { 6, Key.PageDown },
- { 2, Key.InsertChar },
- { 3, Key.Delete },
- { 11, Key.F1 },
- { 12, Key.F2 },
- { 13, Key.F3 },
- { 14, Key.F4 },
- { 15, Key.F5 },
- { 17, Key.F6 },
- { 18, Key.F7 },
- { 19, Key.F8 },
- { 20, Key.F9 },
- { 21, Key.F10 },
- { 23, Key.F11 },
- { 24, Key.F12 }
- };
- /// <inheritdoc/>
- public override bool IsMatch (string? input) { return _pattern.IsMatch (input!); }
- /// <inheritdoc/>
- protected override Key? GetKeyImpl (string? input)
- {
- Match match = _pattern.Match (input!);
- if (!match.Success)
- {
- return null;
- }
- // Group 1: Key code (e.g. 3, 17, etc.)
- // Group 2: Optional modifier code (e.g. 2 = Shift, 5 = Ctrl)
- if (!int.TryParse (match.Groups [1].Value, out int keyCode))
- {
- return null;
- }
- if (!_keyCodeMap.TryGetValue (keyCode, out Key? key))
- {
- return null;
- }
- // If there's no modifier, just return the key.
- if (!int.TryParse (match.Groups [2].Value, out int modifier))
- {
- return key;
- }
- key = modifier switch
- {
- 2 => key.WithShift,
- 3 => key.WithAlt,
- 4 => key.WithAlt.WithShift,
- 5 => key.WithCtrl,
- 6 => key.WithCtrl.WithShift,
- 7 => key.WithCtrl.WithAlt,
- 8 => key.WithCtrl.WithAlt.WithShift,
- _ => key
- };
- return key;
- }
- }
|