7878from prompt_toolkit .output import DummyOutput , create_output
7979from prompt_toolkit .patch_stdout import patch_stdout
8080from prompt_toolkit .shortcuts import CompleteStyle , PromptSession , choice , set_title
81+ from prompt_toolkit .styles import DynamicStyle
82+ from prompt_toolkit .styles import Style as PtStyle
8183from rich .console import (
8284 Group ,
8385 JustifyMethod ,
@@ -714,6 +716,46 @@ def _should_continue_multiline(self) -> bool:
714716 # No macro found or already processed. The statement is complete.
715717 return False
716718
719+ def _get_pt_style (self ) -> "PtStyle" :
720+ """Return the prompt_toolkit style for the completion menu."""
721+
722+ def to_pt_style (rich_style : Style | None ) -> str :
723+ """Convert a rich Style object to a prompt_toolkit style string."""
724+ if not rich_style :
725+ return ""
726+ parts = ["noreverse" ]
727+ if rich_style .color :
728+ c = rich_style .color .get_truecolor ()
729+ parts .append (f"fg:#{ c .red :02x} { c .green :02x} { c .blue :02x} " )
730+ else :
731+ parts .append ("fg:default" )
732+
733+ if rich_style .bgcolor :
734+ c = rich_style .bgcolor .get_truecolor ()
735+ parts .append (f"bg:#{ c .red :02x} { c .green :02x} { c .blue :02x} " )
736+ else :
737+ parts .append ("bg:default" )
738+
739+ if rich_style .bold is not None :
740+ parts .append ("bold" if rich_style .bold else "nobold" )
741+ if rich_style .italic is not None :
742+ parts .append ("italic" if rich_style .italic else "noitalic" )
743+ if rich_style .underline is not None :
744+ parts .append ("underline" if rich_style .underline else "nounderline" )
745+ return " " .join (parts )
746+
747+ theme = ru .get_theme ()
748+ item_style = to_pt_style (theme .styles .get (Cmd2Style .COMPLETION_MENU_ITEM ))
749+ meta_style = to_pt_style (theme .styles .get (Cmd2Style .COMPLETION_MENU_META ))
750+
751+ return PtStyle .from_dict (
752+ {
753+ "completion-menu.completion.current" : item_style ,
754+ "completion-menu.meta.completion.current" : meta_style ,
755+ "completion-menu.multi-column-meta" : meta_style ,
756+ }
757+ )
758+
717759 def _create_main_session (self , auto_suggest : bool , completekey : str ) -> PromptSession [str ]:
718760 """Create and return the main PromptSession for the application.
719761
@@ -755,6 +797,7 @@ def _(event: Any) -> None: # pragma: no cover
755797 "multiline" : filters .Condition (self ._should_continue_multiline ),
756798 "prompt_continuation" : self .continuation_prompt ,
757799 "rprompt" : self .get_rprompt ,
800+ "style" : DynamicStyle (self ._get_pt_style ),
758801 }
759802
760803 if self .stdin .isatty () and self .stdout .isatty ():
@@ -3578,6 +3621,7 @@ def read_input(
35783621 key_bindings = self .main_session .key_bindings ,
35793622 input = self .main_session .input ,
35803623 output = self .main_session .output ,
3624+ style = DynamicStyle (self ._get_pt_style ),
35813625 )
35823626
35833627 return self ._read_raw_input (prompt , temp_session )
@@ -3596,6 +3640,7 @@ def read_secret(
35963640 temp_session : PromptSession [str ] = PromptSession (
35973641 input = self .main_session .input ,
35983642 output = self .main_session .output ,
3643+ style = DynamicStyle (self ._get_pt_style ),
35993644 )
36003645
36013646 return self ._read_raw_input (prompt , temp_session , is_password = True )
0 commit comments