diff --git a/CHANGELOG.md b/CHANGELOG.md index f300262eba..14864e433c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -46,6 +46,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - BREAKING: `AppFocus` and `AppBlur` are now posted when the terminal window gains or loses focus, if the terminal supports this https://github.com/Textualize/textual/pull/4265 - When the terminal window loses focus, the currently-focused widget will also lose focus. - When the terminal window regains focus, the previously-focused widget will regain focus. +- TextArea binding for ctrl+k will now delete the line if the line is empty https://github.com/Textualize/textual/issues/4277 ## [0.52.1] - 2024-02-20 diff --git a/src/textual/widgets/_text_area.py b/src/textual/widgets/_text_area.py index 61042474fd..dc2ea49d44 100644 --- a/src/textual/widgets/_text_area.py +++ b/src/textual/widgets/_text_area.py @@ -219,7 +219,12 @@ class TextArea(ScrollView): Binding( "ctrl+u", "delete_to_start_of_line", "delete to line start", show=False ), - Binding("ctrl+k", "delete_to_end_of_line", "delete to line end", show=False), + Binding( + "ctrl+k", + "delete_to_end_of_line_or_delete_line", + "delete to line end", + show=False, + ), Binding("ctrl+z", "undo", "Undo", show=False), Binding("ctrl+y", "redo", "Redo", show=False), ] @@ -2112,6 +2117,26 @@ def action_delete_to_end_of_line(self) -> None: to_location = self.get_cursor_line_end_location() self._delete_via_keyboard(from_location, to_location) + async def action_delete_to_end_of_line_or_delete_line(self) -> None: + """Deletes from the cursor location to the end of the line, or deletes the line. + + The line will be deleted if the line is empty. + """ + # Assume we're just going to delete to the end of the line. + action = "delete_to_end_of_line" + if self.get_cursor_line_start_location() == self.get_cursor_line_end_location(): + # The line is empty, so we'll simply remove the line itself. + action = "delete_line" + elif ( + self.selection.start + == self.selection.end + == self.get_cursor_line_end_location() + ): + # We're at the end of the line, so the kill delete operation + # should join the next line to this. + action = "delete_right" + await self.run_action(action) + def action_delete_word_left(self) -> None: """Deletes the word to the left of the cursor and updates the cursor location.""" if self.cursor_at_start_of_text: