Skip to content

Commit

Permalink
Improve WrappedPaginator performance on large text
Browse files Browse the repository at this point in the history
  • Loading branch information
scarletcafe committed Apr 1, 2022
1 parent 1da71e9 commit 2addc54
Showing 1 changed file with 39 additions and 30 deletions.
69 changes: 39 additions & 30 deletions jishaku/paginators.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class WrappedPaginator(commands.Paginator):
wrap_on: tuple
A tuple of wrapping delimiters.
include_wrapped: bool
Whether to include the delimiter at the start of the new wrapped line.
Whether to include the delimiter at the end of a wrapped line.
force_wrap: bool
If this is True, lines will be split at their maximum points should trimming not be possible
with any provided delimiter.
Expand All @@ -55,39 +55,48 @@ def __init__(self, *args, wrap_on=('\n', ' '), include_wrapped=True, force_wrap=
self.force_wrap = force_wrap

def add_line(self, line='', *, empty=False):
true_max_size = self.max_size - self._prefix_len - self._suffix_len - 2
original_length = len(line)
if not empty:
true_max_size = self.max_size - self._prefix_len - self._suffix_len - 2
start = 0
needle = 0
last_delimiter = -1
last_space = -1

while needle < len(line):
if needle - start >= true_max_size:
if last_delimiter != -1:
if self.include_wrapped and line[last_delimiter] != '\n':
super().add_line(line[start:last_delimiter + 1])
needle = last_delimiter + 1
start = last_delimiter + 1
else:
super().add_line(line[start:last_delimiter])
needle = last_delimiter + 1
start = last_delimiter + 1
elif last_space != -1:
super().add_line(line[start:last_space])
needle = last_space + 1
start = last_space
else:
super().add_line(line[start:needle])
start = needle

while len(line) > true_max_size:
search_string = line[0:true_max_size - 1]
wrapped = False
last_delimiter = -1
last_space = -1

for delimiter in self.wrap_on:
position = search_string.rfind(delimiter)
if line[needle] in self.wrap_on:
last_delimiter = needle
elif line[needle] == ' ':
last_space = needle

if position > 0:
super().add_line(line[0:position], empty=empty)
wrapped = True
needle += 1

if self.include_wrapped:
line = line[position:]
else:
line = line[position + len(delimiter):]

break

if not wrapped:
if self.force_wrap:
super().add_line(line[0:true_max_size - 1])
line = line[true_max_size - 1:]
else:
raise ValueError(
f"Line of length {original_length} had sequence of {len(line)} characters"
f" (max is {true_max_size}) that WrappedPaginator could not wrap with"
f" delimiters: {self.wrap_on}"
)

super().add_line(line, empty=empty)
last_line = line[start:needle]
if last_line:
super().add_line(last_line)

else:
super().add_line(empty=empty)


class FilePaginator(commands.Paginator):
Expand Down

0 comments on commit 2addc54

Please sign in to comment.