| 96 | self.stdout.write("This value is required.\n") |
| 97 | |
| 98 | def _choose_numbered( |
| 99 | self, |
| 100 | prompt: str, |
| 101 | options: list[MenuOption], |
| 102 | *, |
| 103 | default: int = 0, |
| 104 | ) -> MenuOption: |
| 105 | self.stdout.write(f"{prompt}\n") |
| 106 | for index, option in enumerate(options, start=1): |
| 107 | default_tag = " (default)" if index - 1 == default else "" |
| 108 | hint = f" — {option.hint}" if option.hint else "" |
| 109 | self.stdout.write(f" {index}. {option.label}{default_tag}{hint}\n") |
| 110 | self.stdout.flush() |
| 111 | |
| 112 | while True: |
| 113 | self.stdout.write(f"Select an option [{default + 1}]: ") |
| 114 | self.stdout.flush() |
| 115 | answer = self.stdin.readline() |
| 116 | if answer == "": |
| 117 | return options[default] |
| 118 | clean = answer.strip() |
| 119 | if not clean: |
| 120 | return options[default] |
| 121 | if clean.isdigit(): |
| 122 | index = int(clean) - 1 |
| 123 | if 0 <= index < len(options): |
| 124 | return options[index] |
| 125 | self.stdout.write("Enter one of the numbers above.\n") |
| 126 | |
| 127 | def _choose_tty( |
| 128 | self, |