Skip to content
Open
Show file tree
Hide file tree
Changes from all 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

- shift+backspace is now an alias for backspace in Input and TextArea https://github.com/Textualize/textual/pull/6611

## [8.2.8] - 2026-06-30

### Fixed
Expand Down
9 changes: 7 additions & 2 deletions src/textual/widgets/_input.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,12 @@ class Input(ScrollView):
"Move cursor right a word and select",
show=False,
),
Binding("backspace", "delete_left", "Delete character left", show=False),
Binding(
"backspace,shift+backspace",
"delete_left",
"Delete character left",
show=False,
),
Binding("ctrl+shift+a", "select_all", "Select all", show=False),
Binding("home,ctrl+a", "home", "Go to start", show=False),
Binding("end,ctrl+e", "end", "Go to end", show=False),
Expand Down Expand Up @@ -149,7 +154,7 @@ class Input(ScrollView):
| ctrl+shift+left | Move cursor left a word and select. |
| shift+right | Move cursor right and select. |
| ctrl+right | Move the cursor one word to the right. |
| backspace | Delete the character to the left of the cursor. |
| backspace,shift+backspace | Delete the character to the left of the cursor. |
| ctrl+backspace,alt+backspace | Delete right to start of word. |
| ctrl+shift+right | Move cursor right a word and select. |
| ctrl+shift+a | Select all text in the input. |
Expand Down
2 changes: 1 addition & 1 deletion src/textual/widgets/_text_area.py
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,7 @@ class TextArea(ScrollView):
),
# Deletion
Binding(
"backspace",
"backspace,shift+backspace",
"delete_left",
"Delete character left",
show=False,
Expand Down
16 changes: 16 additions & 0 deletions tests/input/test_input_key_modification_actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,3 +179,19 @@ async def test_delete_right_all_from_end() -> None:
input.action_delete_right_all()
assert input.cursor_position == len(input.value)
assert input.value == TEST_INPUTS[input.id]


async def test_shift_backspace_deletes_left() -> None:
"""shift+backspace should behave the same as backspace."""

class SingleInputApp(App[None]):
def compose(self) -> ComposeResult:
yield Input()

async with SingleInputApp().run_test() as pilot:
input = pilot.app.query_one(Input)
await pilot.click(input)
await pilot.press(*"Hello")
await pilot.press("shift+backspace")
assert input.value == "Hell"
assert input.cursor_position == 4
16 changes: 12 additions & 4 deletions tests/text_area/test_edit_via_bindings.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,17 @@ async def test_delete_left_end():
assert text_area.selection == Selection.cursor((0, 12))


async def test_delete_left_shift_backspace_alias():
app = TextAreaApp()
async with app.run_test() as pilot:
text_area = app.query_one(TextArea)
text_area.load_text("Hello, world!")
text_area.move_cursor((0, 6))
await pilot.press("shift+backspace")
assert text_area.text == "Hello world!"
assert text_area.selection == Selection.cursor((0, 5))


@pytest.mark.parametrize(
"key,selection",
[
Expand All @@ -132,14 +143,11 @@ async def test_deletion_with_non_empty_selection(key, selection):
text_area.selection = selection
await pilot.press(key)
assert text_area.selection == Selection.cursor((1, 2))
assert (
text_area.text
== """\
assert text_area.text == """\
ABCDE
FGT
UVWXY
Z"""
)


async def test_delete_right():
Expand Down