@@ -1784,7 +1784,9 @@ def _write_to_screen_at_index(
17841784 ui_content , write_position .width - total_margin_width , write_position .height
17851785 )
17861786 wrap_finder = self .wrap_finder or (
1787- self ._whitespace_wrap_finder (ui_content .get_line ) if self .word_wrap () else None
1787+ self ._whitespace_wrap_finder (ui_content .get_line )
1788+ if self .word_wrap ()
1789+ else None
17881790 )
17891791
17901792 # Erase background and fill with `char`.
@@ -1967,13 +1969,13 @@ def _whitespace_wrap_finder(
19671969 cont_width = fragment_list_width (continuation )
19681970
19691971 def wrap_finder (
1970- lineno : int , start : int , end : int
1972+ lineno : int , wrap_count : int , start : int , end : int
19711973 ) -> tuple [int , int , AnyFormattedText ]:
19721974 line = explode_text_fragments (get_line (lineno ))
19731975 cont_reserved = 0
19741976 while cont_reserved < cont_width :
19751977 style , char , * _ = line [end - 1 ]
1976- cont_reserved += _CHAR_CACHE [ style , char ]. width
1978+ cont_reserved += get_cwidth ( char )
19771979 end -= 1
19781980
19791981 segment = to_plain_text (line [start :end ])
@@ -2002,8 +2004,7 @@ def _copy_body(
20022004 has_focus : bool = False ,
20032005 align : WindowAlign = WindowAlign .LEFT ,
20042006 get_line_prefix : Callable [[int , int ], AnyFormattedText ] | None = None ,
2005- wrap_finder : Callable [[int , int , int ], tuple [int , int , AnyFormattedText ] | None ]
2006- | None = None ,
2007+ wrap_finder : WrapFinderCallable | None = None ,
20072008 ) -> tuple [dict [int , tuple [int , int ]], dict [tuple [int , int ], tuple [int , int ]]]:
20082009 """
20092010 Copy the UIContent into the output screen.
@@ -2029,6 +2030,7 @@ def find_next_wrap(
20292030 remaining_width : int ,
20302031 is_input : bool ,
20312032 lineno : int ,
2033+ wrap_count : int ,
20322034 fragment : int = 0 ,
20332035 char_pos : int = 0 ,
20342036 ) -> tuple [int , int , AnyFormattedText ]:
@@ -2060,14 +2062,14 @@ def find_next_wrap(
20602062 return sys .maxsize , 0 , []
20612063
20622064 style , text , * _ = next_fragment
2063- for char_width in (_CHAR_CACHE [ char , style ]. width for char in text ):
2065+ for char_width in (get_cwidth ( char ) for char in text ):
20642066 if remaining_width < char_width :
20652067 break
20662068 remaining_width -= char_width
20672069 max_wrap_pos += 1
20682070
20692071 return (
2070- wrap_finder (lineno , min_wrap_pos , max_wrap_pos )
2072+ wrap_finder (lineno , wrap_count , min_wrap_pos , max_wrap_pos )
20712073 if is_input and wrap_finder
20722074 else None
20732075 ) or (
@@ -2124,7 +2126,7 @@ def copy_line(
21242126
21252127 new_buffer_row = new_buffer [y + ypos ]
21262128 wrap_start , wrap_replaced , continuation = find_next_wrap (
2127- width - x , is_input , lineno
2129+ width - x , is_input , lineno , 0
21282130 )
21292131 continuation = to_formatted_text (continuation )
21302132
@@ -2148,7 +2150,7 @@ def copy_line(
21482150 # Wrap when the line width is exceeded.
21492151 if wrap_lines and char_count == wrap_start :
21502152 skipped_width = sum (
2151- _CHAR_CACHE [ char , style ]. width
2153+ get_cwidth ( char )
21522154 for char in text [wrap_start - text_start :][:wrap_replaced ]
21532155 )
21542156 col += wrap_replaced
@@ -2163,8 +2165,11 @@ def copy_line(
21632165 # Make sure to erase rest of the line
21642166 for i in range (x , width ):
21652167 new_buffer_row [i + xpos ] = empty_char
2166- wrap_skip = wrap_replaced
21672168
2169+ if wrap_replaced < 0 :
2170+ return x , y
2171+
2172+ wrap_skip = wrap_replaced
21682173 y += 1
21692174 wrap_count += 1
21702175 x = 0
@@ -2181,6 +2186,7 @@ def copy_line(
21812186 width - x ,
21822187 is_input ,
21832188 lineno ,
2189+ wrap_count ,
21842190 fragment_count ,
21852191 wrap_start + wrap_replaced ,
21862192 )
0 commit comments