I noticed that shift+backspace didn't result in a character being deleted. I made a PR for that one specifically but seems like more might be affected. See quote below.
I used Claude code for investigation and it surfaced this:
In terminals that report the shift modifier as a separate key event (e.g. via the Kitty keyboard protocol, support for which was added in 8.2.7), pressing shift+backspace in an Input or TextArea does nothing. Both widgets only bind plain backspace, so the shift+backspace event matches no binding and is silently dropped.
On terminals that don't report separate modifiers, shift+backspace sends the same bytes as backspace and deletes as expected — so this only affects Kitty-protocol-capable terminals (Kitty, Ghostty, recent WezTerm, Warp). Shift has no distinct meaning for deletion, so the expectation is that it behaves the same as plain backspace, consistent with the alt+backspace (#6593) and super+backspace (#6594) aliases.
The same root cause affects other keys pressed with shift held: shift+delete doesn't forward-delete (Input and TextArea), shift+enter doesn't insert a newline in TextArea (or submit in an Input), and shift+space doesn't insert a space in TextArea — while plain delete, enter, and space all work. shift+delete can be aliased the same way as backspace (add it to the delete,ctrl+d binding). shift+enter and shift+space go through the key-insert path rather than BINDINGS, and shift+enter has the added question of whether it should mean newline or submit.
Confirmed against Textual 8.2.8.
Repro
This headless test fails on main: shift+backspace leaves the text untouched, while plain backspace deletes.
import asyncio
from textual.app import App, ComposeResult
from textual.widgets import TextArea
class A(App):
def compose(self) -> ComposeResult:
yield TextArea("Hello")
async def main():
async with A().run_test() as pilot:
ta = pilot.app.query_one(TextArea)
ta.move_cursor((0, 5))
await pilot.press("shift+backspace")
print("after shift+backspace:", repr(ta.text)) # -> 'Hello' (unchanged)
await pilot.press("backspace")
print("after backspace:", repr(ta.text)) # -> 'Hell'
asyncio.run(main())
Interactively, the same thing happens: on a Kitty-protocol terminal, holding Shift while pressing Backspace in a focused Input/TextArea deletes nothing.
Fix
Bind shift+backspace alongside backspace to delete_left in both widgets. PR: #6611 (scoped to shift+backspace for now; shift+delete would be a small follow-on if wanted).
I noticed that
shift+backspacedidn't result in a character being deleted. I made a PR for that one specifically but seems like more might be affected. See quote below.I used Claude code for investigation and it surfaced this:
Repro
This headless test fails on
main:shift+backspaceleaves the text untouched, while plainbackspacedeletes.Interactively, the same thing happens: on a Kitty-protocol terminal, holding Shift while pressing Backspace in a focused
Input/TextAreadeletes nothing.Fix
Bind
shift+backspacealongsidebackspacetodelete_leftin both widgets. PR: #6611 (scoped toshift+backspacefor now;shift+deletewould be a small follow-on if wanted).