Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Selection behaviour update #5400

Merged
merged 7 commits into from
Dec 18, 2024
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).

## Unreleased

### Changed

- Updated `TextArea` and `Input` behavior when there is a selection and the user presses left or right https://github.com/Textualize/textual/pull/5400

## [1.0.0] - 2024-12-12

### Added
Expand Down
14 changes: 10 additions & 4 deletions src/textual/widgets/_input.py
Original file line number Diff line number Diff line change
Expand Up @@ -761,27 +761,33 @@ def action_cursor_left(self, select: bool = False) -> None:
Args:
select: If `True`, select the text to the left of the cursor.
"""
start, end = self.selection
if select:
start, end = self.selection
self.selection = Selection(start, end - 1)
else:
self.cursor_position -= 1
if self.selection.is_empty:
self.cursor_position -= 1
else:
self.cursor_position = min(start, end)

def action_cursor_right(self, select: bool = False) -> None:
"""Accept an auto-completion or move the cursor one position to the right.

Args:
select: If `True`, select the text to the right of the cursor.
"""
start, end = self.selection
if select:
start, end = self.selection
self.selection = Selection(start, end + 1)
else:
if self._cursor_at_end and self._suggestion:
self.value = self._suggestion
self.cursor_position = len(self.value)
else:
self.cursor_position += 1
if self.selection.is_empty:
self.cursor_position += 1
else:
self.cursor_position = max(start, end)

def action_home(self, select: bool = False) -> None:
"""Move the cursor to the start of the input.
Expand Down
16 changes: 14 additions & 2 deletions src/textual/widgets/_text_area.py
Original file line number Diff line number Diff line change
Expand Up @@ -1835,10 +1835,16 @@ def action_cursor_left(self, select: bool = False) -> None:
If the cursor is at the left edge of the document, try to move it to
the end of the previous line.

If text is selected, move the cursor to the start of the selection.

Args:
select: If True, select the text while moving.
"""
target = self.get_cursor_left_location()
target = (
self.get_cursor_left_location()
if select or self.selection.is_empty
else min(*self.selection)
)
self.move_cursor(target, select=select)

def get_cursor_left_location(self) -> Location:
Expand All @@ -1854,10 +1860,16 @@ def action_cursor_right(self, select: bool = False) -> None:

If the cursor is at the end of a line, attempt to go to the start of the next line.

If text is selected, move the cursor to the end of the selection.

Args:
select: If True, select the text while moving.
"""
target = self.get_cursor_right_location()
target = (
self.get_cursor_right_location()
if select or self.selection.is_empty
else max(*self.selection)
)
self.move_cursor(target, select=select)

def get_cursor_right_location(self) -> Location:
Expand Down
4 changes: 3 additions & 1 deletion tests/input/test_input_terminal_cursor.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ class InputApp(App):
CSS = "Input { padding: 4 8 }"

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


async def test_initial_terminal_cursor_position():
Expand Down
Loading