@@ -680,12 +680,12 @@ def output_line(lineno):
680680 colorized_line_parts = []
681681 colorized_carets_parts = []
682682
683- for color , group in itertools .groupby (itertools . zip_longest (line , carets , fillvalue = "" ), key = lambda x : x [1 ]):
683+ for color , group in itertools .groupby (_zip_display_width (line , carets ), key = lambda x : x [1 ]):
684684 caret_group = list (group )
685- if color == "^" :
685+ if "^" in color :
686686 colorized_line_parts .append (theme .error_highlight + "" .join (char for char , _ in caret_group ) + theme .reset )
687687 colorized_carets_parts .append (theme .error_highlight + "" .join (caret for _ , caret in caret_group ) + theme .reset )
688- elif color == "~" :
688+ elif "~" in color :
689689 colorized_line_parts .append (theme .error_range + "" .join (char for char , _ in caret_group ) + theme .reset )
690690 colorized_carets_parts .append (theme .error_range + "" .join (caret for _ , caret in caret_group ) + theme .reset )
691691 else :
@@ -967,7 +967,24 @@ def setup_positions(expr, force_valid=True):
967967
968968 return None
969969
970- _WIDE_CHAR_SPECIFIERS = "WF"
970+
971+ def _lookahead (iterator , default ):
972+ forked = itertools .tee (iterator , 1 )[0 ]
973+ return next (forked , default )
974+
975+
976+ def _zip_display_width (line , carets ):
977+ line = itertools .tee (line , 1 )[0 ]
978+ carets = iter (carets )
979+ for char in line :
980+ char_width = _display_width (char )
981+ next_char = _lookahead (line , "" )
982+ if next_char and char_width == _display_width (char + next_char ):
983+ next (line )
984+ yield char + next_char , "" .join (itertools .islice (carets , char_width ))
985+ else :
986+ yield char , "" .join (itertools .islice (carets , char_width ))
987+
971988
972989def _display_width (line , offset = None ):
973990 """Calculate the extra amount of width space the given source
@@ -981,13 +998,9 @@ def _display_width(line, offset=None):
981998 if line .isascii ():
982999 return offset
9831000
984- import unicodedata
985-
986- return sum (
987- 2 if unicodedata .east_asian_width (char ) in _WIDE_CHAR_SPECIFIERS else 1
988- for char in line [:offset ]
989- )
1001+ from _pyrepl .utils import wlen
9901002
1003+ return wlen (line [:offset ])
9911004
9921005
9931006class _ExceptionPrintContext :
0 commit comments