Skip to content

Commit

Permalink
Don’t assume we’re wrapping a content line
Browse files Browse the repository at this point in the history
Though it should be the most common case, maybe we may have to wrap some
is_input=False content.
  • Loading branch information
Cimbali committed Jul 12, 2024
1 parent 42b48d1 commit aa25eb9
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 23 deletions.
12 changes: 5 additions & 7 deletions examples/full-screen/simple-demos/word-wrapping.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,7 @@ def get_line_prefix(lineno, wrap_count):
BufferControl(buffer=buff),
wrap_lines=True,
wrap_finder=Window._whitespace_wrap_finder(
lambda n: [] if n else to_formatted_text(LIPSUM),
continuation=to_formatted_text(" ⮠"),
continuation=to_formatted_text(" ⮠")
),
get_line_prefix=lambda lineno, wrap_count: to_formatted_text(" ⭢ ")
if wrap_count
Expand All @@ -92,15 +91,14 @@ def get_line_prefix(lineno, wrap_count):
Window(
BufferControl(buffer=buff),
wrap_lines=True,
wrap_finder=lambda lineno,
wrap_finder=lambda line,
lineno,
wrap_count,
start,
end,
fallback=Window._whitespace_wrap_finder(
lambda n: [] if n else to_formatted_text(LIPSUM),
): (end - 3, -1, "...")
fallback=Window._whitespace_wrap_finder(): (end - 3, -1, "...")
if wrap_count > 0
else fallback(lineno, wrap_count, start, end),
else fallback(line, lineno, wrap_count, start, end),
),
]
),
Expand Down
20 changes: 11 additions & 9 deletions src/prompt_toolkit/layout/containers.py
Original file line number Diff line number Diff line change
Expand Up @@ -1784,9 +1784,7 @@ def _write_to_screen_at_index(
ui_content, write_position.width - total_margin_width, write_position.height
)
wrap_finder = self.wrap_finder or (
self._whitespace_wrap_finder(ui_content.get_line)
if self.word_wrap()
else None
self._whitespace_wrap_finder() if self.word_wrap() else None
)

# Erase background and fill with `char`.
Expand Down Expand Up @@ -1946,7 +1944,6 @@ def render_margin(m: Margin, width: int) -> UIContent:
@classmethod
def _whitespace_wrap_finder(
cls,
get_line: Callable[[int], StyleAndTextTuples],
sep: str | re.Pattern[str] = r"[ \t]", # Don’t include \xA0 by default (in \s)
split: str = "remove",
continuation: StyleAndTextTuples = [],
Expand All @@ -1969,9 +1966,9 @@ def _whitespace_wrap_finder(
cont_width = fragment_list_width(continuation)

def wrap_finder(
lineno: int, wrap_count: int, start: int, end: int
line: AnyFormattedText, lineno: int, wrap_count: int, start: int, end: int
) -> tuple[int, int, AnyFormattedText]:
line = explode_text_fragments(get_line(lineno))
line = explode_text_fragments(to_formatted_text(line))
cont_reserved = 0
while cont_reserved < cont_width:
style, char, *_ = line[end - 1]
Expand Down Expand Up @@ -2027,6 +2024,7 @@ def _copy_body(
rowcol_to_yx: dict[tuple[int, int], tuple[int, int]] = {}

def find_next_wrap(
line: StyleAndTextTuples,
remaining_width: int,
is_input: bool,
lineno: int,
Expand All @@ -2037,7 +2035,6 @@ def find_next_wrap(
if not wrap_lines:
return sys.maxsize, 0, []

line = ui_content.get_line(lineno)
try:
style0, text0, *more = line[fragment]
except IndexError:
Expand Down Expand Up @@ -2069,7 +2066,7 @@ def find_next_wrap(
max_wrap_pos += 1

return (
wrap_finder(lineno, wrap_count, min_wrap_pos, max_wrap_pos)
wrap_finder(line, lineno, wrap_count, min_wrap_pos, max_wrap_pos)
if is_input and wrap_finder
else None
) or (
Expand Down Expand Up @@ -2126,7 +2123,11 @@ def copy_line(

new_buffer_row = new_buffer[y + ypos]
wrap_start, wrap_replaced, continuation = find_next_wrap(
width - x, is_input, lineno, 0
line,
width - x,
is_input,
lineno,
0,
)
continuation = to_formatted_text(continuation)

Expand Down Expand Up @@ -2183,6 +2184,7 @@ def copy_line(

new_buffer_row = new_buffer[y + ypos]
wrap_start, wrap_replaced, continuation = find_next_wrap(
line,
width - x,
is_input,
lineno,
Expand Down
17 changes: 10 additions & 7 deletions src/prompt_toolkit/layout/controls.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,9 @@
]

GetLinePrefixCallable = Callable[[int, int], AnyFormattedText]
WrapFinderCallable = Callable[[int, int, int, int], Tuple[int, int, AnyFormattedText]]
WrapFinderCallable = Callable[
[AnyFormattedText, int, int, int, int], Tuple[int, int, AnyFormattedText]
]


class UIControl(metaclass=ABCMeta):
Expand Down Expand Up @@ -206,9 +208,10 @@ def get_height_for_line(
height = 10**8
else:
# Calculate line width first.
line = fragment_list_to_text(self.get_line(lineno))[:slice_stop]
line = self.get_line(lineno)
line_text = fragment_list_to_text(line)[:slice_stop]
start = 0
text_width = get_cwidth(line[start:])
text_width = get_cwidth(line_text[start:])

if get_line_prefix or wrap_finder:
# Add prefix width.
Expand All @@ -229,17 +232,17 @@ def get_height_for_line(
if wrap_finder:
# Decent guess for max breakpoint place?
end = start + width - prefix_width
start_end_width = get_cwidth(line[start:end])
start_end_width = get_cwidth(line_text[start:end])
while start_end_width >= width - prefix_width:
start_end_width -= get_cwidth(line[end - 1])
start_end_width -= get_cwidth(line_text[end - 1])
end -= 1
wrap, skip, cont = wrap_finder(
lineno, height - 1, start, end
line, lineno, height - 1, start, end
)
if skip < 0:
break # Truncate line
start = wrap + skip
text_width = get_cwidth(line[start:])
text_width = get_cwidth(line_text[start:])
else:
text_width -= width

Expand Down

0 comments on commit aa25eb9

Please sign in to comment.