1r"""
2Terminal escape sequence patterns.
3
4This module provides regex patterns for matching terminal escape sequences. All patterns match
5sequences that begin with ESC (``\x1b``). Before calling re.match with these patterns, callers
6should first check that the character at the current position is ESC for optimal performance.
7"""
8# std imports
9import re
10
11# Zero-width escape sequences (SGR, OSC, CSI, etc.). This table, like INDETERMINATE_EFFECT_SEQUENCE,
12# originated from the 'blessed' library.
13ZERO_WIDTH_PATTERN = re.compile(
14 # CSI sequences
15 r'\x1b\[[\x30-\x3f]*[\x20-\x2f]*[\x40-\x7e]|'
16 # OSC sequences
17 r'\x1b\][^\x07\x1b]*(?:\x07|\x1b\\)|'
18 # APC sequences
19 r'\x1b_[^\x1b\x07]*(?:\x07|\x1b\\)|'
20 # DCS sequences
21 r'\x1bP[^\x1b\x07]*(?:\x07|\x1b\\)|'
22 # PM sequences
23 r'\x1b\^[^\x1b\x07]*(?:\x07|\x1b\\)|'
24 # Character set designation
25 r'\x1b[()].|'
26 # Fe sequences
27 r'\x1b[\x40-\x5f]|'
28 # Fp sequences
29 r'\x1b[78=>g]'
30)
31
32# Cursor right movement: CSI [n] C, parameter may be parsed by width()
33CURSOR_RIGHT_SEQUENCE = re.compile(r'\x1b\[(\d*)C')
34
35# Cursor left movement: CSI [n] D, parameter may be parsed by width()
36CURSOR_LEFT_SEQUENCE = re.compile(r'\x1b\[(\d*)D')
37
38# Indeterminate effect sequences - raise ValueError in 'strict' mode. The effects of these sequences
39# are likely to be undesirable, moving the cursor vertically or to any unknown position, and
40# otherwise not managed by the 'width' method of this library.
41#
42# This table was created initially with code generation by extraction of termcap library with
43# techniques used at 'blessed' library runtime for 'xterm', 'alacritty', 'kitty', ghostty',
44# 'screen', 'tmux', and others. Then, these common capabilities were merged into the list below.
45INDETERMINATE_EFFECT_SEQUENCE = re.compile(
46 '|'.join(f'(?:{_pattern})' for _pattern in (
47 r'\x1b\[\d+;\d+r', # change_scroll_region
48 r'\x1b\[\d*K', # erase_in_line (clr_eol, clr_bol)
49 r'\x1b\[\d*J', # erase_in_display (clr_eos, erase_display)
50 r'\x1b\[\d*G', # column_address
51 r'\x1b\[\d+;\d+H', # cursor_address
52 r'\x1b\[\d*H', # cursor_home
53 r'\x1b\[\d*A', # cursor_up
54 r'\x1b\[\d*B', # cursor_down
55 r'\x1b\[\d*P', # delete_character
56 r'\x1b\[\d*M', # delete_line
57 r'\x1b\[\d*L', # insert_line
58 r'\x1b\[\d*@', # insert_character
59 r'\x1b\[\d+X', # erase_chars
60 r'\x1b\[\d*S', # scroll_up (parm_index)
61 r'\x1b\[\d*T', # scroll_down (parm_rindex)
62 r'\x1b\[\d*d', # row_address
63 r'\x1b\[\?1049[hl]', # alternate screen buffer
64 r'\x1b\[\?47[hl]', # alternate screen (legacy)
65 r'\x1b8', # restore_cursor
66 r'\x1bD', # scroll_forward (index)
67 r'\x1bM', # scroll_reverse (reverse index)
68 ))
69)