Skip to content

Commit f57d501

Browse files
authored
Merge pull request #5400 from Textualize/selection-fix
Selection behaviour update
2 parents d9f8e39 + 0884282 commit f57d501

File tree

4 files changed

+29
-7
lines changed

4 files changed

+29
-7
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
77

88
## Unreleased
99

10+
1011
### Fixed
1112

1213
- Fixed `Pilot.click` not working with `times` parameter https://github.com/Textualize/textual/pull/5398
@@ -18,6 +19,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
1819
### Changed
1920

2021
- The content of an `Input` will now only be automatically selected when the widget is focused by the user, not when the app itself has regained focus (similar to web browsers). https://github.com/Textualize/textual/pull/5379
22+
- Updated `TextArea` and `Input` behavior when there is a selection and the user presses left or right https://github.com/Textualize/textual/pull/5400
2123

2224

2325
## [1.0.0] - 2024-12-12

src/textual/widgets/_input.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -761,27 +761,33 @@ def action_cursor_left(self, select: bool = False) -> None:
761761
Args:
762762
select: If `True`, select the text to the left of the cursor.
763763
"""
764+
start, end = self.selection
764765
if select:
765-
start, end = self.selection
766766
self.selection = Selection(start, end - 1)
767767
else:
768-
self.cursor_position -= 1
768+
if self.selection.is_empty:
769+
self.cursor_position -= 1
770+
else:
771+
self.cursor_position = min(start, end)
769772

770773
def action_cursor_right(self, select: bool = False) -> None:
771774
"""Accept an auto-completion or move the cursor one position to the right.
772775
773776
Args:
774777
select: If `True`, select the text to the right of the cursor.
775778
"""
779+
start, end = self.selection
776780
if select:
777-
start, end = self.selection
778781
self.selection = Selection(start, end + 1)
779782
else:
780783
if self._cursor_at_end and self._suggestion:
781784
self.value = self._suggestion
782785
self.cursor_position = len(self.value)
783786
else:
784-
self.cursor_position += 1
787+
if self.selection.is_empty:
788+
self.cursor_position += 1
789+
else:
790+
self.cursor_position = max(start, end)
785791

786792
def action_home(self, select: bool = False) -> None:
787793
"""Move the cursor to the start of the input.

src/textual/widgets/_text_area.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1835,10 +1835,16 @@ def action_cursor_left(self, select: bool = False) -> None:
18351835
If the cursor is at the left edge of the document, try to move it to
18361836
the end of the previous line.
18371837
1838+
If text is selected, move the cursor to the start of the selection.
1839+
18381840
Args:
18391841
select: If True, select the text while moving.
18401842
"""
1841-
target = self.get_cursor_left_location()
1843+
target = (
1844+
self.get_cursor_left_location()
1845+
if select or self.selection.is_empty
1846+
else min(*self.selection)
1847+
)
18421848
self.move_cursor(target, select=select)
18431849

18441850
def get_cursor_left_location(self) -> Location:
@@ -1854,10 +1860,16 @@ def action_cursor_right(self, select: bool = False) -> None:
18541860
18551861
If the cursor is at the end of a line, attempt to go to the start of the next line.
18561862
1863+
If text is selected, move the cursor to the end of the selection.
1864+
18571865
Args:
18581866
select: If True, select the text while moving.
18591867
"""
1860-
target = self.get_cursor_right_location()
1868+
target = (
1869+
self.get_cursor_right_location()
1870+
if select or self.selection.is_empty
1871+
else max(*self.selection)
1872+
)
18611873
self.move_cursor(target, select=select)
18621874

18631875
def get_cursor_right_location(self) -> Location:

tests/input/test_input_terminal_cursor.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@ class InputApp(App):
88
CSS = "Input { padding: 4 8 }"
99

1010
def compose(self) -> ComposeResult:
11-
yield Input("こんにちは!")
11+
# We don't want to select the text on focus, as selected text
12+
# has different interactions with the cursor_left action.
13+
yield Input("こんにちは!", select_on_focus=False)
1214

1315

1416
async def test_initial_terminal_cursor_position():

0 commit comments

Comments
 (0)