Create and return the main PromptSession for the application. Builds an interactive session if self.stdin and self.stdout are TTYs. Otherwise, uses dummy drivers to support non-interactive streams like pipes or files.
(self, auto_suggest: bool, completekey: str)
| 717 | return False |
| 718 | |
| 719 | def _create_main_session(self, auto_suggest: bool, completekey: str) -> PromptSession[str]: |
| 720 | """Create and return the main PromptSession for the application. |
| 721 | |
| 722 | Builds an interactive session if self.stdin and self.stdout are TTYs. |
| 723 | Otherwise, uses dummy drivers to support non-interactive streams like |
| 724 | pipes or files. |
| 725 | """ |
| 726 | # Configure custom key bindings |
| 727 | key_bindings = KeyBindings() |
| 728 | |
| 729 | # Add a binding for 'enter' that triggers only when a completion is selected. |
| 730 | # This allows accepting a completion without submitting the command. |
| 731 | @key_bindings.add("enter", filter=filters.completion_is_selected) |
| 732 | def _(event: Any) -> None: # pragma: no cover |
| 733 | event.current_buffer.complete_state = None |
| 734 | |
| 735 | if completekey != self.DEFAULT_COMPLETEKEY: |
| 736 | # Configure prompt_toolkit `KeyBindings` with the custom key for completion |
| 737 | @key_bindings.add(completekey) |
| 738 | def _(event: Any) -> None: # pragma: no cover |
| 739 | """Trigger completion.""" |
| 740 | b = event.current_buffer |
| 741 | if b.complete_state: |
| 742 | b.complete_next() |
| 743 | else: |
| 744 | b.start_completion(select_first=False) |
| 745 | |
| 746 | # Base configuration |
| 747 | kwargs: dict[str, Any] = { |
| 748 | "auto_suggest": AutoSuggestFromHistory() if auto_suggest else None, |
| 749 | "bottom_toolbar": self.get_bottom_toolbar if self.bottom_toolbar else None, |
| 750 | "complete_style": CompleteStyle.MULTI_COLUMN, |
| 751 | "complete_in_thread": True, |
| 752 | "complete_while_typing": False, |
| 753 | "completer": Cmd2Completer(self), |
| 754 | "history": Cmd2History(item.raw for item in self.history), |
| 755 | "key_bindings": key_bindings, |
| 756 | "lexer": Cmd2Lexer(self), |
| 757 | "multiline": filters.Condition(self._should_continue_multiline), |
| 758 | "prompt_continuation": self.continuation_prompt, |
| 759 | "rprompt": self.get_rprompt, |
| 760 | } |
| 761 | |
| 762 | if self.stdin.isatty() and self.stdout.isatty(): |
| 763 | try: |
| 764 | if self.stdin != sys.stdin: |
| 765 | kwargs["input"] = create_input(stdin=self.stdin) |
| 766 | if self.stdout != sys.stdout: |
| 767 | kwargs["output"] = create_output(stdout=self.stdout) |
| 768 | return PromptSession(**kwargs) |
| 769 | |
| 770 | except (NoConsoleScreenBufferError, AttributeError, ValueError): |
| 771 | # Fallback to dummy input/output if PromptSession initialization fails. |
| 772 | # This can happen in some CI environments (like GitHub Actions on Windows) |
| 773 | # where isatty() is True but there is no real console. |
| 774 | pass |
| 775 | |
| 776 | # Fallback to dummy drivers for non-interactive environments. |