Skip to content

Commit 925cb42

Browse files
committed
Actually implement truncation mentioned in PR
Also small fixes to character width computation
1 parent 75a1128 commit 925cb42

File tree

2 files changed

+22
-12
lines changed

2 files changed

+22
-12
lines changed

Diff for: src/prompt_toolkit/layout/containers.py

+16-10
Original file line numberDiff line numberDiff line change
@@ -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
)

Diff for: src/prompt_toolkit/layout/controls.py

+6-2
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@
5858
]
5959

6060
GetLinePrefixCallable = Callable[[int, int], AnyFormattedText]
61-
WrapFinderCallable = Callable[[int, int, int], Tuple[int, int, AnyFormattedText]]
61+
WrapFinderCallable = Callable[[int, int, int, int], Tuple[int, int, AnyFormattedText]]
6262

6363

6464
class UIControl(metaclass=ABCMeta):
@@ -233,7 +233,11 @@ def get_height_for_line(
233233
while start_end_width >= width - prefix_width:
234234
start_end_width -= get_cwidth(line[end - 1])
235235
end -= 1
236-
wrap, skip, cont = wrap_finder(lineno, start, end)
236+
wrap, skip, cont = wrap_finder(
237+
lineno, height - 1, start, end
238+
)
239+
if skip < 0:
240+
break # Truncate line
237241
start = wrap + skip
238242
text_width = get_cwidth(line[start:])
239243
else:

0 commit comments

Comments
 (0)