Skip to content

Commit 334cffb

Browse files
Optimization to the removal of trailing spaces in the render code.
1 parent 0585d11 commit 334cffb

File tree

1 file changed

+38
-3
lines changed

1 file changed

+38
-3
lines changed

prompt_toolkit/renderer.py

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
from prompt_toolkit.output import ColorDepth, Output
1818
from prompt_toolkit.styles import (
1919
Attrs,
20-
DEFAULT_ATTRS,
2120
BaseStyle,
2221
DummyStyleTransformation,
2322
StyleTransformation,
@@ -46,6 +45,7 @@ def _output_screen_diff(
4645
is_done: bool, # XXX: drop is_done
4746
full_screen: bool,
4847
attrs_for_style_string: "_StyleStringToAttrsCache",
48+
style_string_has_style: "_StyleStringHasStyleCache",
4949
size: Size,
5050
previous_width: int,
5151
) -> Tuple[Point, Optional[str]]:
@@ -156,7 +156,7 @@ def get_max_column_index(row: Dict[int, Char]) -> int:
156156
numbers = [
157157
index
158158
for index, cell in row.items()
159-
if cell.char != " " or attrs_for_style_string[cell.style] != DEFAULT_ATTRS
159+
if cell.char != " " or style_string_has_style[cell.style]
160160
]
161161
numbers.append(0)
162162
return max(numbers)
@@ -202,7 +202,7 @@ def get_max_column_index(row: Dict[int, Char]) -> int:
202202

203203
# Loop over the columns.
204204
c = 0
205-
while c < new_max_line_len + 1:
205+
while c <= new_max_line_len:
206206
new_char = new_row[c]
207207
old_char = previous_row[c]
208208
char_width = new_char.width or 1
@@ -290,6 +290,34 @@ def __missing__(self, style_str: str) -> Attrs:
290290
return attrs
291291

292292

293+
class _StyleStringHasStyleCache(Dict[str, bool]):
294+
"""
295+
Cache for remember which style strings don't render the default output
296+
style (default fg/bg, no underline and no reverse and no blink). That way
297+
we know that we should render these cells, even when they're empty (when
298+
they contain a space).
299+
300+
Note: we don't consider bold/italic/hidden because they don't change the
301+
output if there's no text in the cell.
302+
"""
303+
304+
def __init__(self, style_string_to_attrs: Dict[str, Attrs]) -> None:
305+
self.style_string_to_attrs = style_string_to_attrs
306+
307+
def __missing__(self, style_str: str) -> bool:
308+
attrs = self.style_string_to_attrs[style_str]
309+
is_default = bool(
310+
attrs.color
311+
or attrs.bgcolor
312+
or attrs.underline
313+
or attrs.blink
314+
or attrs.reverse
315+
)
316+
317+
self[style_str] = is_default
318+
return is_default
319+
320+
293321
class CPR_Support(Enum):
294322
" Enum: whether or not CPR is supported. "
295323
SUPPORTED = "SUPPORTED"
@@ -339,6 +367,7 @@ def __init__(
339367

340368
# Cache for the style.
341369
self._attrs_for_style: Optional[_StyleStringToAttrsCache] = None
370+
self._style_string_has_style: Optional[_StyleStringHasStyleCache] = None
342371
self._last_style_hash: Optional[Hashable] = None
343372
self._last_transformation_hash: Optional[Hashable] = None
344373
self._last_color_depth: Optional[ColorDepth] = None
@@ -605,11 +634,16 @@ def render(
605634
):
606635
self._last_screen = None
607636
self._attrs_for_style = None
637+
self._style_string_has_style = None
608638

609639
if self._attrs_for_style is None:
610640
self._attrs_for_style = _StyleStringToAttrsCache(
611641
self.style.get_attrs_for_style_str, app.style_transformation
612642
)
643+
if self._style_string_has_style is None:
644+
self._style_string_has_style = _StyleStringHasStyleCache(
645+
self._attrs_for_style
646+
)
613647

614648
self._last_style_hash = self.style.invalidation_hash()
615649
self._last_transformation_hash = app.style_transformation.invalidation_hash()
@@ -641,6 +675,7 @@ def render(
641675
is_done,
642676
full_screen=self.full_screen,
643677
attrs_for_style_string=self._attrs_for_style,
678+
style_string_has_style=self._style_string_has_style,
644679
size=size,
645680
previous_width=(self._last_size.columns if self._last_size else 0),
646681
)

0 commit comments

Comments
 (0)