@@ -694,24 +694,41 @@ class _DialogList(Generic[_T]):
694694    Common code for `RadioList` and `CheckboxList`. 
695695    """ 
696696
697-     open_character : str  =  "" 
698-     close_character : str  =  "" 
699-     container_style : str  =  "" 
700-     default_style : str  =  "" 
701-     selected_style : str  =  "" 
702-     checked_style : str  =  "" 
703-     multiple_selection : bool  =  False 
704-     show_scrollbar : bool  =  True 
705- 
706697    def  __init__ (
707698        self ,
708699        values : Sequence [tuple [_T , AnyFormattedText ]],
709700        default_values : Sequence [_T ] |  None  =  None ,
701+         select_on_focus : bool  =  False ,
702+         open_character : str  =  "" ,
703+         select_character : str  =  "*" ,
704+         close_character : str  =  "" ,
705+         container_style : str  =  "" ,
706+         default_style : str  =  "" ,
707+         number_style : str  =  "" ,
708+         selected_style : str  =  "" ,
709+         checked_style : str  =  "" ,
710+         multiple_selection : bool  =  False ,
711+         show_scrollbar : bool  =  True ,
712+         show_cursor : bool  =  True ,
713+         show_numbers : bool  =  False ,
710714    ) ->  None :
711715        assert  len (values ) >  0 
712716        default_values  =  default_values  or  []
713717
714718        self .values  =  values 
719+         self .show_numbers  =  show_numbers 
720+ 
721+         self .open_character  =  open_character 
722+         self .select_character  =  select_character 
723+         self .close_character  =  close_character 
724+         self .container_style  =  container_style 
725+         self .default_style  =  default_style 
726+         self .number_style  =  number_style 
727+         self .selected_style  =  selected_style 
728+         self .checked_style  =  checked_style 
729+         self .multiple_selection  =  multiple_selection 
730+         self .show_scrollbar  =  show_scrollbar 
731+ 
715732        # current_values will be used in multiple_selection, 
716733        # current_value will be used otherwise. 
717734        keys : list [_T ] =  [value  for  (value , _ ) in  values ]
@@ -734,12 +751,18 @@ def __init__(
734751        kb  =  KeyBindings ()
735752
736753        @kb .add ("up" ) 
754+         @kb .add ("k" )  # Vi-like.  
737755        def  _up (event : E ) ->  None :
738756            self ._selected_index  =  max (0 , self ._selected_index  -  1 )
757+             if  select_on_focus :
758+                 self ._handle_enter ()
739759
740760        @kb .add ("down" ) 
761+         @kb .add ("j" )  # Vi-like.  
741762        def  _down (event : E ) ->  None :
742763            self ._selected_index  =  min (len (self .values ) -  1 , self ._selected_index  +  1 )
764+             if  select_on_focus :
765+                 self ._handle_enter ()
743766
744767        @kb .add ("pageup" ) 
745768        def  _pageup (event : E ) ->  None :
@@ -774,9 +797,22 @@ def _find(event: E) -> None:
774797                    self ._selected_index  =  self .values .index (value )
775798                    return 
776799
800+         numbers_visible  =  Condition (lambda : self .show_numbers )
801+ 
802+         for  i  in  range (1 , 10 ):
803+ 
804+             @kb .add (str (i ), filter = numbers_visible ) 
805+             def  _select_i (event : E , index : int  =  i ) ->  None :
806+                 self ._selected_index  =  min (len (self .values ) -  1 , index  -  1 )
807+                 if  select_on_focus :
808+                     self ._handle_enter ()
809+ 
777810        # Control and window. 
778811        self .control  =  FormattedTextControl (
779-             self ._get_text_fragments , key_bindings = kb , focusable = True 
812+             self ._get_text_fragments ,
813+             key_bindings = kb ,
814+             focusable = True ,
815+             show_cursor = show_cursor ,
780816        )
781817
782818        self .window  =  Window (
@@ -831,13 +867,19 @@ def mouse_handler(mouse_event: MouseEvent) -> None:
831867                result .append (("[SetCursorPosition]" , "" ))
832868
833869            if  checked :
834-                 result .append ((style , "*" ))
870+                 result .append ((style , self . select_character ))
835871            else :
836872                result .append ((style , " " ))
837873
838874            result .append ((style , self .close_character ))
839-             result .append ((self .default_style , " " ))
840-             result .extend (to_formatted_text (value [1 ], style = self .default_style ))
875+             result .append ((f"{ style }   { self .default_style }  " , " " ))
876+ 
877+             if  self .show_numbers :
878+                 result .append ((f"{ style }   { self .number_style }  " , f"{ i  +  1 :2d}  . " ))
879+ 
880+             result .extend (
881+                 to_formatted_text (value [1 ], style = f"{ style }   { self .default_style }  " )
882+             )
841883            result .append (("" , "\n " ))
842884
843885        # Add mouse handler to all fragments. 
@@ -858,25 +900,44 @@ class RadioList(_DialogList[_T]):
858900    :param values: List of (value, label) tuples. 
859901    """ 
860902
861-     open_character  =  "(" 
862-     close_character  =  ")" 
863-     container_style  =  "class:radio-list" 
864-     default_style  =  "class:radio" 
865-     selected_style  =  "class:radio-selected" 
866-     checked_style  =  "class:radio-checked" 
867-     multiple_selection  =  False 
868- 
869903    def  __init__ (
870904        self ,
871905        values : Sequence [tuple [_T , AnyFormattedText ]],
872906        default : _T  |  None  =  None ,
907+         show_numbers : bool  =  False ,
908+         select_on_focus : bool  =  False ,
909+         open_character : str  =  "(" ,
910+         select_character : str  =  "*" ,
911+         close_character : str  =  ")" ,
912+         container_style : str  =  "class:radio-list" ,
913+         default_style : str  =  "class:radio" ,
914+         selected_style : str  =  "class:radio-selected" ,
915+         checked_style : str  =  "class:radio-checked" ,
916+         number_style : str  =  "class:radio-number" ,
917+         multiple_selection : bool  =  False ,
918+         show_cursor : bool  =  True ,
873919    ) ->  None :
874920        if  default  is  None :
875921            default_values  =  None 
876922        else :
877923            default_values  =  [default ]
878924
879-         super ().__init__ (values , default_values = default_values )
925+         super ().__init__ (
926+             values ,
927+             default_values = default_values ,
928+             select_on_focus = select_on_focus ,
929+             show_numbers = show_numbers ,
930+             open_character = open_character ,
931+             select_character = select_character ,
932+             close_character = close_character ,
933+             container_style = container_style ,
934+             default_style = default_style ,
935+             selected_style = selected_style ,
936+             checked_style = checked_style ,
937+             number_style = number_style ,
938+             multiple_selection = False ,
939+             show_cursor = show_cursor ,
940+         )
880941
881942
882943class  CheckboxList (_DialogList [_T ]):
@@ -886,13 +947,30 @@ class CheckboxList(_DialogList[_T]):
886947    :param values: List of (value, label) tuples. 
887948    """ 
888949
889-     open_character  =  "[" 
890-     close_character  =  "]" 
891-     container_style  =  "class:checkbox-list" 
892-     default_style  =  "class:checkbox" 
893-     selected_style  =  "class:checkbox-selected" 
894-     checked_style  =  "class:checkbox-checked" 
895-     multiple_selection  =  True 
950+     def  __init__ (
951+         self ,
952+         values : Sequence [tuple [_T , AnyFormattedText ]],
953+         default_values : Sequence [_T ] |  None  =  None ,
954+         open_character : str  =  "[" ,
955+         select_character : str  =  "*" ,
956+         close_character : str  =  "]" ,
957+         container_style : str  =  "class:checkbox-list" ,
958+         default_style : str  =  "class:checkbox" ,
959+         selected_style : str  =  "class:checkbox-selected" ,
960+         checked_style : str  =  "class:checkbox-checked" ,
961+     ) ->  None :
962+         super ().__init__ (
963+             values ,
964+             default_values = default_values ,
965+             open_character = open_character ,
966+             select_character = select_character ,
967+             close_character = close_character ,
968+             container_style = container_style ,
969+             default_style = default_style ,
970+             selected_style = selected_style ,
971+             checked_style = checked_style ,
972+             multiple_selection = True ,
973+         )
896974
897975
898976class  Checkbox (CheckboxList [str ]):
0 commit comments