(
self,
prompt: str,
options: list[MenuOption],
*,
default: int = 0,
)
| 125 | self.stdout.write("Enter one of the numbers above.\n") |
| 126 | |
| 127 | def _choose_tty( |
| 128 | self, |
| 129 | prompt: str, |
| 130 | options: list[MenuOption], |
| 131 | *, |
| 132 | default: int = 0, |
| 133 | ) -> MenuOption: |
| 134 | index = max(0, min(default, len(options) - 1)) |
| 135 | lines = self._menu_lines(prompt, options, index) |
| 136 | block_height = len(lines) |
| 137 | self.stdout.write("\x1b[?25l") |
| 138 | self.stdout.write("\n".join(lines)) |
| 139 | self.stdout.write("\n") |
| 140 | self.stdout.flush() |
| 141 | |
| 142 | try: |
| 143 | while True: |
| 144 | key = self._read_key() |
| 145 | if key == "up": |
| 146 | index = (index - 1) % len(options) |
| 147 | elif key == "down": |
| 148 | index = (index + 1) % len(options) |
| 149 | elif key == "enter": |
| 150 | self.stdout.write("\x1b[?25h") |
| 151 | self.stdout.flush() |
| 152 | return options[index] |
| 153 | elif key == "interrupt": |
| 154 | raise KeyboardInterrupt |
| 155 | else: |
| 156 | continue |
| 157 | |
| 158 | lines = self._menu_lines(prompt, options, index) |
| 159 | self.stdout.write(f"\x1b[{block_height}F") |
| 160 | for line in lines: |
| 161 | self.stdout.write("\x1b[2K") |
| 162 | self.stdout.write(line) |
| 163 | self.stdout.write("\n") |
| 164 | self.stdout.flush() |
| 165 | finally: |
| 166 | self.stdout.write("\x1b[?25h") |
| 167 | self.stdout.flush() |
| 168 | |
| 169 | def _menu_lines( |
| 170 | self, |
no test coverage detected