| 
									
										
										
										
											2024-05-05 21:32:23 +02:00
										 |  |  | import re | 
					
						
							|  |  |  | import unicodedata | 
					
						
							| 
									
										
										
										
											2024-05-23 06:23:40 +02:00
										 |  |  | import functools | 
					
						
							| 
									
										
										
										
											2024-05-05 21:32:23 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | ANSI_ESCAPE_SEQUENCE = re.compile(r"\x1b\[[ -@]*[A-~]") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-23 06:23:40 +02:00
										 |  |  | @functools.cache | 
					
						
							| 
									
										
										
										
											2024-05-05 21:32:23 +02:00
										 |  |  | def str_width(c: str) -> int: | 
					
						
							| 
									
										
										
										
											2024-05-23 06:23:40 +02:00
										 |  |  |     if ord(c) < 128: | 
					
						
							|  |  |  |         return 1 | 
					
						
							| 
									
										
										
										
											2024-05-05 21:32:23 +02:00
										 |  |  |     w = unicodedata.east_asian_width(c) | 
					
						
							|  |  |  |     if w in ('N', 'Na', 'H', 'A'): | 
					
						
							|  |  |  |         return 1 | 
					
						
							|  |  |  |     return 2 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def wlen(s: str) -> int: | 
					
						
							|  |  |  |     length = sum(str_width(i) for i in s) | 
					
						
							|  |  |  |     # remove lengths of any escape sequences | 
					
						
							| 
									
										
										
										
											2024-05-23 06:23:40 +02:00
										 |  |  |     sequence = ANSI_ESCAPE_SEQUENCE.findall(s) | 
					
						
							|  |  |  |     return length - sum(len(i) for i in sequence) |