Skip to content

Commit 3d65f2b

Browse files
authored
Merge pull request Textualize#5154 from Textualize/text-area-crop-fix
fix infinite loop in cropping
2 parents e3b1948 + dd9b2bc commit 3d65f2b

File tree

9 files changed

+971
-622
lines changed

9 files changed

+971
-622
lines changed

CHANGELOG.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,12 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](http://keepachangelog.com/)
66
and this project adheres to [Semantic Versioning](http://semver.org/).
77

8-
## Unreleased
8+
## [0.84.0] - 2024-10-22
99

1010
### Fixed
1111

1212
- Fixed `RadioSet` not being scrollable https://github.com/Textualize/textual/issues/5100
13+
- Fixed infinite loop in TextArea https://github.com/Textualize/textual/pull/5154
1314

1415
### Added
1516

@@ -2453,6 +2454,7 @@ https://textual.textualize.io/blog/2022/11/08/version-040/#version-040
24532454
- New handler system for messages that doesn't require inheritance
24542455
- Improved traceback handling
24552456

2457+
[0.84.0]: https://github.com/Textualize/textual/compare/v0.83.0...v0.84.0
24562458
[0.83.0]: https://github.com/Textualize/textual/compare/v0.82.0...v0.83.0
24572459
[0.82.0]: https://github.com/Textualize/textual/compare/v0.81.0...v0.82.0
24582460
[0.81.0]: https://github.com/Textualize/textual/compare/v0.80.1...v0.81.0

poetry.lock

Lines changed: 785 additions & 616 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tool.poetry]
22
name = "textual"
3-
version = "0.83.0"
3+
version = "0.84.0"
44
homepage = "https://github.com/Textualize/textual"
55
repository = "https://github.com/Textualize/textual"
66
documentation = "https://textual.textualize.io/"

src/textual/strip.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -372,10 +372,13 @@ def crop(self, start: int, end: int | None = None) -> Strip:
372372
Returns:
373373
A new Strip.
374374
"""
375+
375376
start = max(0, start)
376377
end = self.cell_length if end is None else min(self.cell_length, end)
377378
if start == 0 and end == self.cell_length:
378379
return self
380+
if end <= start:
381+
return Strip([], 0)
379382
cache_key = (start, end)
380383
cached = self._crop_cache.get(cache_key)
381384
if cached is not None:

src/textual/widgets/_text_area.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1236,9 +1236,7 @@ def render_line(self, y: int) -> Strip:
12361236

12371237
# Crop the line to show only the visible part (some may be scrolled out of view)
12381238
if not self.soft_wrap:
1239-
text_strip = text_strip.crop(
1240-
scroll_x, scroll_x + virtual_width - gutter_width
1241-
)
1239+
text_strip = text_strip.crop(scroll_x, scroll_x + virtual_width)
12421240

12431241
# Stylize the line the cursor is currently on.
12441242
if cursor_row == line_index:

tests/snapshot_tests/__snapshots__/test_snapshots/test_split_segments_infinite_loop.svg

Lines changed: 154 additions & 0 deletions
Loading
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
from textual.app import App, ComposeResult
2+
from textual.widgets import TextArea
3+
4+
FAIL_TEXT = "x"
5+
6+
7+
class CodeApp(App):
8+
def compose(self) -> ComposeResult:
9+
yield TextArea(FAIL_TEXT, soft_wrap=False, show_line_numbers=True)
10+
11+
12+
if __name__ == "__main__":
13+
app = CodeApp()
14+
app.run()

tests/snapshot_tests/test_snapshots.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2417,3 +2417,12 @@ def on_mount(self) -> None:
24172417
self.mount(Label("HELLO"))
24182418

24192419
assert snap_compare(PSApp())
2420+
2421+
2422+
def test_split_segments_infinite_loop(snap_compare):
2423+
"""Regression test for https://github.com/Textualize/textual/issues/5151
2424+
2425+
Should be a bare-bones text editor containing "x"
2426+
2427+
"""
2428+
assert snap_compare(SNAPSHOT_APPS_DIR / "split_segments.py")

tests/test_strip.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ def test_crop():
131131

132132
assert Strip([Segment("foo")]).crop(1, 3) == Strip([Segment("oo")])
133133
assert Strip([Segment("foo")]).crop(1, 2) == Strip([Segment("o")])
134-
assert Strip([Segment("foo")]).crop(1, 1) == Strip([Segment("")])
134+
assert Strip([Segment("foo")]).crop(1, 1) == Strip([])
135135

136136
assert Strip([Segment("foo💩"), Segment("b💩ar"), Segment("ba💩z")]).crop(
137137
1, 6

0 commit comments

Comments
 (0)