1818
1919from textual .reactive import Reactive , var
2020from textual .validation import ValidationResult , Validator
21- from textual .widgets ._input import Input
21+ from textual .widgets ._input import Input , Selection
2222
2323InputValidationOn = Literal ["blur" , "changed" , "submitted" ]
2424"""Possible messages that trigger input validation."""
@@ -703,17 +703,31 @@ def action_cursor_left(self, select: bool = False) -> None:
703703 Args:
704704 select: If `True`, select the text to the left of the cursor.
705705 """
706+ start , end = self .selection
706707 cursor_position = self ._template .move_cursor (- 1 )
707- self .cursor_position = cursor_position
708+ if select :
709+ self .selection = Selection (start , cursor_position )
710+ else :
711+ if self .selection .is_empty :
712+ self .cursor_position = cursor_position
713+ else :
714+ self .cursor_position = min (start , end )
708715
709716 def action_cursor_right (self , select : bool = False ) -> None :
710717 """Move the cursor one position to the right; separators are skipped.
711718
712719 Args:
713720 select: If `True`, select the text to the right of the cursor.
714721 """
722+ start , end = self .selection
715723 cursor_position = self ._template .move_cursor (1 )
716- self .cursor_position = cursor_position
724+ if select :
725+ self .selection = Selection (start , cursor_position )
726+ else :
727+ if self .selection .is_empty :
728+ self .cursor_position = cursor_position
729+ else :
730+ self .cursor_position = max (start , end )
717731
718732 def action_home (self , select : bool = False ) -> None :
719733 """Move the cursor to the start of the input.
@@ -722,7 +736,10 @@ def action_home(self, select: bool = False) -> None:
722736 select: If `True`, select the text between the old and new cursor positions.
723737 """
724738 cursor_position = self ._template .move_cursor (- len (self .template ))
725- self .cursor_position = cursor_position
739+ if select :
740+ self .selection = Selection (self .cursor_position , cursor_position )
741+ else :
742+ self .cursor_position = cursor_position
726743
727744 def action_cursor_left_word (self , select : bool = False ) -> None :
728745 """Move the cursor left next to the previous separator. If no previous
@@ -732,12 +749,22 @@ def action_cursor_left_word(self, select: bool = False) -> None:
732749 select: If `True`, select the text between the old and new cursor positions.
733750 """
734751 if self ._template .at_separator (self .cursor_position - 1 ):
735- position = self ._template .prev_separator_position (self .cursor_position - 1 )
752+ separator_position = self ._template .prev_separator_position (
753+ self .cursor_position - 1
754+ )
736755 else :
737- position = self ._template .prev_separator_position ()
738- if position :
739- position += 1
740- self .cursor_position = position or 0
756+ separator_position = self ._template .prev_separator_position ()
757+
758+ if separator_position is None :
759+ cursor_position = 0
760+ else :
761+ cursor_position = separator_position + 1
762+
763+ if select :
764+ start , _ = self .selection
765+ self .selection = Selection (start , cursor_position )
766+ else :
767+ self .cursor_position = cursor_position
741768
742769 def action_cursor_right_word (self , select : bool = False ) -> None :
743770 """Move the cursor right next to the next separator. If no next
@@ -746,11 +773,17 @@ def action_cursor_right_word(self, select: bool = False) -> None:
746773 Args:
747774 select: If `True`, select the text between the old and new cursor positions.
748775 """
749- position = self ._template .next_separator_position ()
750- if position is None :
751- self . cursor_position = len (self ._template .mask )
776+ separator_position = self ._template .next_separator_position ()
777+ if separator_position is None :
778+ cursor_position = len (self ._template .mask )
752779 else :
753- self .cursor_position = position + 1
780+ cursor_position = separator_position + 1
781+
782+ if select :
783+ start , _ = self .selection
784+ self .selection = Selection (start , cursor_position )
785+ else :
786+ self .cursor_position = cursor_position
754787
755788 def action_delete_right (self ) -> None :
756789 """Delete one character at the current cursor position."""
0 commit comments