1""" 
    2Mappings from VT100 (ANSI) escape sequences to the corresponding prompt_toolkit 
    3keys. 
    4 
    5We are not using the terminfo/termcap databases to detect the ANSI escape 
    6sequences for the input. Instead, we recognize 99% of the most common 
    7sequences. This works well, because in practice, every modern terminal is 
    8mostly Xterm compatible. 
    9 
    10Some useful docs: 
    11- Mintty: https://github.com/mintty/mintty/blob/master/wiki/Keycodes.md 
    12""" 
    13 
    14from __future__ import annotations 
    15 
    16from ..keys import Keys 
    17 
    18__all__ = [ 
    19    "ANSI_SEQUENCES", 
    20    "REVERSE_ANSI_SEQUENCES", 
    21] 
    22 
    23# Mapping of vt100 escape codes to Keys. 
    24ANSI_SEQUENCES: dict[str, Keys | tuple[Keys, ...]] = { 
    25    # Control keys. 
    26    "\x00": Keys.ControlAt,  # Control-At (Also for Ctrl-Space) 
    27    "\x01": Keys.ControlA,  # Control-A (home) 
    28    "\x02": Keys.ControlB,  # Control-B (emacs cursor left) 
    29    "\x03": Keys.ControlC,  # Control-C (interrupt) 
    30    "\x04": Keys.ControlD,  # Control-D (exit) 
    31    "\x05": Keys.ControlE,  # Control-E (end) 
    32    "\x06": Keys.ControlF,  # Control-F (cursor forward) 
    33    "\x07": Keys.ControlG,  # Control-G 
    34    "\x08": Keys.ControlH,  # Control-H (8) (Identical to '\b') 
    35    "\x09": Keys.ControlI,  # Control-I (9) (Identical to '\t') 
    36    "\x0a": Keys.ControlJ,  # Control-J (10) (Identical to '\n') 
    37    "\x0b": Keys.ControlK,  # Control-K (delete until end of line; vertical tab) 
    38    "\x0c": Keys.ControlL,  # Control-L (clear; form feed) 
    39    "\x0d": Keys.ControlM,  # Control-M (13) (Identical to '\r') 
    40    "\x0e": Keys.ControlN,  # Control-N (14) (history forward) 
    41    "\x0f": Keys.ControlO,  # Control-O (15) 
    42    "\x10": Keys.ControlP,  # Control-P (16) (history back) 
    43    "\x11": Keys.ControlQ,  # Control-Q 
    44    "\x12": Keys.ControlR,  # Control-R (18) (reverse search) 
    45    "\x13": Keys.ControlS,  # Control-S (19) (forward search) 
    46    "\x14": Keys.ControlT,  # Control-T 
    47    "\x15": Keys.ControlU,  # Control-U 
    48    "\x16": Keys.ControlV,  # Control-V 
    49    "\x17": Keys.ControlW,  # Control-W 
    50    "\x18": Keys.ControlX,  # Control-X 
    51    "\x19": Keys.ControlY,  # Control-Y (25) 
    52    "\x1a": Keys.ControlZ,  # Control-Z 
    53    "\x1b": Keys.Escape,  # Also Control-[ 
    54    "\x9b": Keys.ShiftEscape, 
    55    "\x1c": Keys.ControlBackslash,  # Both Control-\ (also Ctrl-| ) 
    56    "\x1d": Keys.ControlSquareClose,  # Control-] 
    57    "\x1e": Keys.ControlCircumflex,  # Control-^ 
    58    "\x1f": Keys.ControlUnderscore,  # Control-underscore (Also for Ctrl-hyphen.) 
    59    # ASCII Delete (0x7f) 
    60    # Vt220 (and Linux terminal) send this when pressing backspace. We map this 
    61    # to ControlH, because that will make it easier to create key bindings that 
    62    # work everywhere, with the trade-off that it's no longer possible to 
    63    # handle backspace and control-h individually for the few terminals that 
    64    # support it. (Most terminals send ControlH when backspace is pressed.) 
    65    # See: http://www.ibb.net/~anne/keyboard.html 
    66    "\x7f": Keys.ControlH, 
    67    # -- 
    68    # Various 
    69    "\x1b[1~": Keys.Home,  # tmux 
    70    "\x1b[2~": Keys.Insert, 
    71    "\x1b[3~": Keys.Delete, 
    72    "\x1b[4~": Keys.End,  # tmux 
    73    "\x1b[5~": Keys.PageUp, 
    74    "\x1b[6~": Keys.PageDown, 
    75    "\x1b[7~": Keys.Home,  # xrvt 
    76    "\x1b[8~": Keys.End,  # xrvt 
    77    "\x1b[Z": Keys.BackTab,  # shift + tab 
    78    "\x1b\x09": Keys.BackTab,  # Linux console 
    79    "\x1b[~": Keys.BackTab,  # Windows console 
    80    # -- 
    81    # Function keys. 
    82    "\x1bOP": Keys.F1, 
    83    "\x1bOQ": Keys.F2, 
    84    "\x1bOR": Keys.F3, 
    85    "\x1bOS": Keys.F4, 
    86    "\x1b[[A": Keys.F1,  # Linux console. 
    87    "\x1b[[B": Keys.F2,  # Linux console. 
    88    "\x1b[[C": Keys.F3,  # Linux console. 
    89    "\x1b[[D": Keys.F4,  # Linux console. 
    90    "\x1b[[E": Keys.F5,  # Linux console. 
    91    "\x1b[11~": Keys.F1,  # rxvt-unicode 
    92    "\x1b[12~": Keys.F2,  # rxvt-unicode 
    93    "\x1b[13~": Keys.F3,  # rxvt-unicode 
    94    "\x1b[14~": Keys.F4,  # rxvt-unicode 
    95    "\x1b[15~": Keys.F5, 
    96    "\x1b[17~": Keys.F6, 
    97    "\x1b[18~": Keys.F7, 
    98    "\x1b[19~": Keys.F8, 
    99    "\x1b[20~": Keys.F9, 
    100    "\x1b[21~": Keys.F10, 
    101    "\x1b[23~": Keys.F11, 
    102    "\x1b[24~": Keys.F12, 
    103    "\x1b[25~": Keys.F13, 
    104    "\x1b[26~": Keys.F14, 
    105    "\x1b[28~": Keys.F15, 
    106    "\x1b[29~": Keys.F16, 
    107    "\x1b[31~": Keys.F17, 
    108    "\x1b[32~": Keys.F18, 
    109    "\x1b[33~": Keys.F19, 
    110    "\x1b[34~": Keys.F20, 
    111    # Xterm 
    112    "\x1b[1;2P": Keys.F13, 
    113    "\x1b[1;2Q": Keys.F14, 
    114    # '\x1b[1;2R': Keys.F15,  # Conflicts with CPR response. 
    115    "\x1b[1;2S": Keys.F16, 
    116    "\x1b[15;2~": Keys.F17, 
    117    "\x1b[17;2~": Keys.F18, 
    118    "\x1b[18;2~": Keys.F19, 
    119    "\x1b[19;2~": Keys.F20, 
    120    "\x1b[20;2~": Keys.F21, 
    121    "\x1b[21;2~": Keys.F22, 
    122    "\x1b[23;2~": Keys.F23, 
    123    "\x1b[24;2~": Keys.F24, 
    124    # -- 
    125    # CSI 27 disambiguated modified "other" keys (xterm) 
    126    # Ref: https://invisible-island.net/xterm/modified-keys.html 
    127    # These are currently unsupported, so just re-map some common ones to the 
    128    # unmodified versions 
    129    "\x1b[27;2;13~": Keys.ControlM,  # Shift + Enter 
    130    "\x1b[27;5;13~": Keys.ControlM,  # Ctrl + Enter 
    131    "\x1b[27;6;13~": Keys.ControlM,  # Ctrl + Shift + Enter 
    132    # -- 
    133    # Control + function keys. 
    134    "\x1b[1;5P": Keys.ControlF1, 
    135    "\x1b[1;5Q": Keys.ControlF2, 
    136    # "\x1b[1;5R": Keys.ControlF3,  # Conflicts with CPR response. 
    137    "\x1b[1;5S": Keys.ControlF4, 
    138    "\x1b[15;5~": Keys.ControlF5, 
    139    "\x1b[17;5~": Keys.ControlF6, 
    140    "\x1b[18;5~": Keys.ControlF7, 
    141    "\x1b[19;5~": Keys.ControlF8, 
    142    "\x1b[20;5~": Keys.ControlF9, 
    143    "\x1b[21;5~": Keys.ControlF10, 
    144    "\x1b[23;5~": Keys.ControlF11, 
    145    "\x1b[24;5~": Keys.ControlF12, 
    146    "\x1b[1;6P": Keys.ControlF13, 
    147    "\x1b[1;6Q": Keys.ControlF14, 
    148    # "\x1b[1;6R": Keys.ControlF15,  # Conflicts with CPR response. 
    149    "\x1b[1;6S": Keys.ControlF16, 
    150    "\x1b[15;6~": Keys.ControlF17, 
    151    "\x1b[17;6~": Keys.ControlF18, 
    152    "\x1b[18;6~": Keys.ControlF19, 
    153    "\x1b[19;6~": Keys.ControlF20, 
    154    "\x1b[20;6~": Keys.ControlF21, 
    155    "\x1b[21;6~": Keys.ControlF22, 
    156    "\x1b[23;6~": Keys.ControlF23, 
    157    "\x1b[24;6~": Keys.ControlF24, 
    158    # -- 
    159    # Tmux (Win32 subsystem) sends the following scroll events. 
    160    "\x1b[62~": Keys.ScrollUp, 
    161    "\x1b[63~": Keys.ScrollDown, 
    162    "\x1b[200~": Keys.BracketedPaste,  # Start of bracketed paste. 
    163    # -- 
    164    # Sequences generated by numpad 5. Not sure what it means. (It doesn't 
    165    # appear in 'infocmp'. Just ignore. 
    166    "\x1b[E": Keys.Ignore,  # Xterm. 
    167    "\x1b[G": Keys.Ignore,  # Linux console. 
    168    # -- 
    169    # Meta/control/escape + pageup/pagedown/insert/delete. 
    170    "\x1b[3;2~": Keys.ShiftDelete,  # xterm, gnome-terminal. 
    171    "\x1b[5;2~": Keys.ShiftPageUp, 
    172    "\x1b[6;2~": Keys.ShiftPageDown, 
    173    "\x1b[2;3~": (Keys.Escape, Keys.Insert), 
    174    "\x1b[3;3~": (Keys.Escape, Keys.Delete), 
    175    "\x1b[5;3~": (Keys.Escape, Keys.PageUp), 
    176    "\x1b[6;3~": (Keys.Escape, Keys.PageDown), 
    177    "\x1b[2;4~": (Keys.Escape, Keys.ShiftInsert), 
    178    "\x1b[3;4~": (Keys.Escape, Keys.ShiftDelete), 
    179    "\x1b[5;4~": (Keys.Escape, Keys.ShiftPageUp), 
    180    "\x1b[6;4~": (Keys.Escape, Keys.ShiftPageDown), 
    181    "\x1b[3;5~": Keys.ControlDelete,  # xterm, gnome-terminal. 
    182    "\x1b[5;5~": Keys.ControlPageUp, 
    183    "\x1b[6;5~": Keys.ControlPageDown, 
    184    "\x1b[3;6~": Keys.ControlShiftDelete, 
    185    "\x1b[5;6~": Keys.ControlShiftPageUp, 
    186    "\x1b[6;6~": Keys.ControlShiftPageDown, 
    187    "\x1b[2;7~": (Keys.Escape, Keys.ControlInsert), 
    188    "\x1b[5;7~": (Keys.Escape, Keys.ControlPageDown), 
    189    "\x1b[6;7~": (Keys.Escape, Keys.ControlPageDown), 
    190    "\x1b[2;8~": (Keys.Escape, Keys.ControlShiftInsert), 
    191    "\x1b[5;8~": (Keys.Escape, Keys.ControlShiftPageDown), 
    192    "\x1b[6;8~": (Keys.Escape, Keys.ControlShiftPageDown), 
    193    # -- 
    194    # Arrows. 
    195    # (Normal cursor mode). 
    196    "\x1b[A": Keys.Up, 
    197    "\x1b[B": Keys.Down, 
    198    "\x1b[C": Keys.Right, 
    199    "\x1b[D": Keys.Left, 
    200    "\x1b[H": Keys.Home, 
    201    "\x1b[F": Keys.End, 
    202    # Tmux sends following keystrokes when control+arrow is pressed, but for 
    203    # Emacs ansi-term sends the same sequences for normal arrow keys. Consider 
    204    # it a normal arrow press, because that's more important. 
    205    # (Application cursor mode). 
    206    "\x1bOA": Keys.Up, 
    207    "\x1bOB": Keys.Down, 
    208    "\x1bOC": Keys.Right, 
    209    "\x1bOD": Keys.Left, 
    210    "\x1bOF": Keys.End, 
    211    "\x1bOH": Keys.Home, 
    212    # Shift + arrows. 
    213    "\x1b[1;2A": Keys.ShiftUp, 
    214    "\x1b[1;2B": Keys.ShiftDown, 
    215    "\x1b[1;2C": Keys.ShiftRight, 
    216    "\x1b[1;2D": Keys.ShiftLeft, 
    217    "\x1b[1;2F": Keys.ShiftEnd, 
    218    "\x1b[1;2H": Keys.ShiftHome, 
    219    # Meta + arrow keys. Several terminals handle this differently. 
    220    # The following sequences are for xterm and gnome-terminal. 
    221    #     (Iterm sends ESC followed by the normal arrow_up/down/left/right 
    222    #     sequences, and the OSX Terminal sends ESCb and ESCf for "alt 
    223    #     arrow_left" and "alt arrow_right." We don't handle these 
    224    #     explicitly, in here, because would could not distinguish between 
    225    #     pressing ESC (to go to Vi navigation mode), followed by just the 
    226    #     'b' or 'f' key. These combinations are handled in 
    227    #     the input processor.) 
    228    "\x1b[1;3A": (Keys.Escape, Keys.Up), 
    229    "\x1b[1;3B": (Keys.Escape, Keys.Down), 
    230    "\x1b[1;3C": (Keys.Escape, Keys.Right), 
    231    "\x1b[1;3D": (Keys.Escape, Keys.Left), 
    232    "\x1b[1;3F": (Keys.Escape, Keys.End), 
    233    "\x1b[1;3H": (Keys.Escape, Keys.Home), 
    234    # Alt+shift+number. 
    235    "\x1b[1;4A": (Keys.Escape, Keys.ShiftDown), 
    236    "\x1b[1;4B": (Keys.Escape, Keys.ShiftUp), 
    237    "\x1b[1;4C": (Keys.Escape, Keys.ShiftRight), 
    238    "\x1b[1;4D": (Keys.Escape, Keys.ShiftLeft), 
    239    "\x1b[1;4F": (Keys.Escape, Keys.ShiftEnd), 
    240    "\x1b[1;4H": (Keys.Escape, Keys.ShiftHome), 
    241    # Control + arrows. 
    242    "\x1b[1;5A": Keys.ControlUp,  # Cursor Mode 
    243    "\x1b[1;5B": Keys.ControlDown,  # Cursor Mode 
    244    "\x1b[1;5C": Keys.ControlRight,  # Cursor Mode 
    245    "\x1b[1;5D": Keys.ControlLeft,  # Cursor Mode 
    246    "\x1b[1;5F": Keys.ControlEnd, 
    247    "\x1b[1;5H": Keys.ControlHome, 
    248    # Tmux sends following keystrokes when control+arrow is pressed, but for 
    249    # Emacs ansi-term sends the same sequences for normal arrow keys. Consider 
    250    # it a normal arrow press, because that's more important. 
    251    "\x1b[5A": Keys.ControlUp, 
    252    "\x1b[5B": Keys.ControlDown, 
    253    "\x1b[5C": Keys.ControlRight, 
    254    "\x1b[5D": Keys.ControlLeft, 
    255    "\x1bOc": Keys.ControlRight,  # rxvt 
    256    "\x1bOd": Keys.ControlLeft,  # rxvt 
    257    # Control + shift + arrows. 
    258    "\x1b[1;6A": Keys.ControlShiftDown, 
    259    "\x1b[1;6B": Keys.ControlShiftUp, 
    260    "\x1b[1;6C": Keys.ControlShiftRight, 
    261    "\x1b[1;6D": Keys.ControlShiftLeft, 
    262    "\x1b[1;6F": Keys.ControlShiftEnd, 
    263    "\x1b[1;6H": Keys.ControlShiftHome, 
    264    # Control + Meta + arrows. 
    265    "\x1b[1;7A": (Keys.Escape, Keys.ControlDown), 
    266    "\x1b[1;7B": (Keys.Escape, Keys.ControlUp), 
    267    "\x1b[1;7C": (Keys.Escape, Keys.ControlRight), 
    268    "\x1b[1;7D": (Keys.Escape, Keys.ControlLeft), 
    269    "\x1b[1;7F": (Keys.Escape, Keys.ControlEnd), 
    270    "\x1b[1;7H": (Keys.Escape, Keys.ControlHome), 
    271    # Meta + Shift + arrows. 
    272    "\x1b[1;8A": (Keys.Escape, Keys.ControlShiftDown), 
    273    "\x1b[1;8B": (Keys.Escape, Keys.ControlShiftUp), 
    274    "\x1b[1;8C": (Keys.Escape, Keys.ControlShiftRight), 
    275    "\x1b[1;8D": (Keys.Escape, Keys.ControlShiftLeft), 
    276    "\x1b[1;8F": (Keys.Escape, Keys.ControlShiftEnd), 
    277    "\x1b[1;8H": (Keys.Escape, Keys.ControlShiftHome), 
    278    # Meta + arrow on (some?) Macs when using iTerm defaults (see issue #483). 
    279    "\x1b[1;9A": (Keys.Escape, Keys.Up), 
    280    "\x1b[1;9B": (Keys.Escape, Keys.Down), 
    281    "\x1b[1;9C": (Keys.Escape, Keys.Right), 
    282    "\x1b[1;9D": (Keys.Escape, Keys.Left), 
    283    # -- 
    284    # Control/shift/meta + number in mintty. 
    285    # (c-2 will actually send c-@ and c-6 will send c-^.) 
    286    "\x1b[1;5p": Keys.Control0, 
    287    "\x1b[1;5q": Keys.Control1, 
    288    "\x1b[1;5r": Keys.Control2, 
    289    "\x1b[1;5s": Keys.Control3, 
    290    "\x1b[1;5t": Keys.Control4, 
    291    "\x1b[1;5u": Keys.Control5, 
    292    "\x1b[1;5v": Keys.Control6, 
    293    "\x1b[1;5w": Keys.Control7, 
    294    "\x1b[1;5x": Keys.Control8, 
    295    "\x1b[1;5y": Keys.Control9, 
    296    "\x1b[1;6p": Keys.ControlShift0, 
    297    "\x1b[1;6q": Keys.ControlShift1, 
    298    "\x1b[1;6r": Keys.ControlShift2, 
    299    "\x1b[1;6s": Keys.ControlShift3, 
    300    "\x1b[1;6t": Keys.ControlShift4, 
    301    "\x1b[1;6u": Keys.ControlShift5, 
    302    "\x1b[1;6v": Keys.ControlShift6, 
    303    "\x1b[1;6w": Keys.ControlShift7, 
    304    "\x1b[1;6x": Keys.ControlShift8, 
    305    "\x1b[1;6y": Keys.ControlShift9, 
    306    "\x1b[1;7p": (Keys.Escape, Keys.Control0), 
    307    "\x1b[1;7q": (Keys.Escape, Keys.Control1), 
    308    "\x1b[1;7r": (Keys.Escape, Keys.Control2), 
    309    "\x1b[1;7s": (Keys.Escape, Keys.Control3), 
    310    "\x1b[1;7t": (Keys.Escape, Keys.Control4), 
    311    "\x1b[1;7u": (Keys.Escape, Keys.Control5), 
    312    "\x1b[1;7v": (Keys.Escape, Keys.Control6), 
    313    "\x1b[1;7w": (Keys.Escape, Keys.Control7), 
    314    "\x1b[1;7x": (Keys.Escape, Keys.Control8), 
    315    "\x1b[1;7y": (Keys.Escape, Keys.Control9), 
    316    "\x1b[1;8p": (Keys.Escape, Keys.ControlShift0), 
    317    "\x1b[1;8q": (Keys.Escape, Keys.ControlShift1), 
    318    "\x1b[1;8r": (Keys.Escape, Keys.ControlShift2), 
    319    "\x1b[1;8s": (Keys.Escape, Keys.ControlShift3), 
    320    "\x1b[1;8t": (Keys.Escape, Keys.ControlShift4), 
    321    "\x1b[1;8u": (Keys.Escape, Keys.ControlShift5), 
    322    "\x1b[1;8v": (Keys.Escape, Keys.ControlShift6), 
    323    "\x1b[1;8w": (Keys.Escape, Keys.ControlShift7), 
    324    "\x1b[1;8x": (Keys.Escape, Keys.ControlShift8), 
    325    "\x1b[1;8y": (Keys.Escape, Keys.ControlShift9), 
    326} 
    327 
    328 
    329def _get_reverse_ansi_sequences() -> dict[Keys, str]: 
    330    """ 
    331    Create a dictionary that maps prompt_toolkit keys back to the VT100 escape 
    332    sequences. 
    333    """ 
    334    result: dict[Keys, str] = {} 
    335 
    336    for sequence, key in ANSI_SEQUENCES.items(): 
    337        if not isinstance(key, tuple): 
    338            if key not in result: 
    339                result[key] = sequence 
    340 
    341    return result 
    342 
    343 
    344REVERSE_ANSI_SEQUENCES = _get_reverse_ansi_sequences()