@@ -1784,7 +1784,9 @@ def _write_to_screen_at_index(
1784
1784
ui_content , write_position .width - total_margin_width , write_position .height
1785
1785
)
1786
1786
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
1788
1790
)
1789
1791
1790
1792
# Erase background and fill with `char`.
@@ -1967,13 +1969,13 @@ def _whitespace_wrap_finder(
1967
1969
cont_width = fragment_list_width (continuation )
1968
1970
1969
1971
def wrap_finder (
1970
- lineno : int , start : int , end : int
1972
+ lineno : int , wrap_count : int , start : int , end : int
1971
1973
) -> tuple [int , int , AnyFormattedText ]:
1972
1974
line = explode_text_fragments (get_line (lineno ))
1973
1975
cont_reserved = 0
1974
1976
while cont_reserved < cont_width :
1975
1977
style , char , * _ = line [end - 1 ]
1976
- cont_reserved += _CHAR_CACHE [ style , char ]. width
1978
+ cont_reserved += get_cwidth ( char )
1977
1979
end -= 1
1978
1980
1979
1981
segment = to_plain_text (line [start :end ])
@@ -2002,8 +2004,7 @@ def _copy_body(
2002
2004
has_focus : bool = False ,
2003
2005
align : WindowAlign = WindowAlign .LEFT ,
2004
2006
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 ,
2007
2008
) -> tuple [dict [int , tuple [int , int ]], dict [tuple [int , int ], tuple [int , int ]]]:
2008
2009
"""
2009
2010
Copy the UIContent into the output screen.
@@ -2029,6 +2030,7 @@ def find_next_wrap(
2029
2030
remaining_width : int ,
2030
2031
is_input : bool ,
2031
2032
lineno : int ,
2033
+ wrap_count : int ,
2032
2034
fragment : int = 0 ,
2033
2035
char_pos : int = 0 ,
2034
2036
) -> tuple [int , int , AnyFormattedText ]:
@@ -2060,14 +2062,14 @@ def find_next_wrap(
2060
2062
return sys .maxsize , 0 , []
2061
2063
2062
2064
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 ):
2064
2066
if remaining_width < char_width :
2065
2067
break
2066
2068
remaining_width -= char_width
2067
2069
max_wrap_pos += 1
2068
2070
2069
2071
return (
2070
- wrap_finder (lineno , min_wrap_pos , max_wrap_pos )
2072
+ wrap_finder (lineno , wrap_count , min_wrap_pos , max_wrap_pos )
2071
2073
if is_input and wrap_finder
2072
2074
else None
2073
2075
) or (
@@ -2124,7 +2126,7 @@ def copy_line(
2124
2126
2125
2127
new_buffer_row = new_buffer [y + ypos ]
2126
2128
wrap_start , wrap_replaced , continuation = find_next_wrap (
2127
- width - x , is_input , lineno
2129
+ width - x , is_input , lineno , 0
2128
2130
)
2129
2131
continuation = to_formatted_text (continuation )
2130
2132
@@ -2148,7 +2150,7 @@ def copy_line(
2148
2150
# Wrap when the line width is exceeded.
2149
2151
if wrap_lines and char_count == wrap_start :
2150
2152
skipped_width = sum (
2151
- _CHAR_CACHE [ char , style ]. width
2153
+ get_cwidth ( char )
2152
2154
for char in text [wrap_start - text_start :][:wrap_replaced ]
2153
2155
)
2154
2156
col += wrap_replaced
@@ -2163,8 +2165,11 @@ def copy_line(
2163
2165
# Make sure to erase rest of the line
2164
2166
for i in range (x , width ):
2165
2167
new_buffer_row [i + xpos ] = empty_char
2166
- wrap_skip = wrap_replaced
2167
2168
2169
+ if wrap_replaced < 0 :
2170
+ return x , y
2171
+
2172
+ wrap_skip = wrap_replaced
2168
2173
y += 1
2169
2174
wrap_count += 1
2170
2175
x = 0
@@ -2181,6 +2186,7 @@ def copy_line(
2181
2186
width - x ,
2182
2187
is_input ,
2183
2188
lineno ,
2189
+ wrap_count ,
2184
2190
fragment_count ,
2185
2191
wrap_start + wrap_replaced ,
2186
2192
)
0 commit comments