diff --git a/kittens/ask/main.py b/kittens/ask/main.py index b8776f441..eee75db41 100644 --- a/kittens/ask/main.py +++ b/kittens/ask/main.py @@ -103,6 +103,11 @@ For example: y:Yes and n;red:No A default choice or text. If unspecified, it is "y" for :code:`yesno`, the first choice for :code:`choices` and empty for others. The default choice is selected when the user presses the Enter key. + + +--prompt -p +default="> " +The prompt to use when inputting a line of text or a password. ''' @@ -361,11 +366,14 @@ def main(args: List[str]) -> Response: loop.loop(handler) return {'items': items, 'response': handler.response} + prompt = cli_opts.prompt + if prompt[0] == prompt[-1] and prompt[0] in '\'"': + prompt = prompt[1:-1] if cli_opts.type == 'password': import getpass if cli_opts.message: print(styled(cli_opts.message, bold=True)) - q = getpass.getpass() + q = getpass.getpass(prompt) return {'items': items, 'response': q or ''} import readline as rl @@ -378,7 +386,6 @@ def main(args: List[str]) -> Response: if cli_opts.message: print(styled(cli_opts.message, bold=True)) - prompt = '> ' with suppress(KeyboardInterrupt, EOFError): if cli_opts.default: def prefill_text() -> None: diff --git a/kitty/boss.py b/kitty/boss.py index a43e10643..74a6f8ed7 100644 --- a/kitty/boss.py +++ b/kitty/boss.py @@ -705,11 +705,12 @@ class Boss: self, msg: str, # can contain newlines and ANSI formatting callback: Callable[..., None], # called with the answer or empty string when aborted window: Optional[Window] = None, # the window associated with the confirmation + prompt: str = '> ', is_password: bool = False ) -> None: def callback_(res: Dict[str, Any], x: int, boss: Boss) -> None: callback(res.get('response') or '') - cmd = ['--type', 'password' if is_password else 'line', '--message', msg] + cmd = ['--type', 'password' if is_password else 'line', '--message', msg, '--prompt', prompt] self._run_kitten('ask', cmd, window=window, custom_callback=callback_, default_data={'response': ''}) def confirm_tab_close(self, tab: Tab) -> None: diff --git a/kitty/window.py b/kitty/window.py index ec9d48591..3b9c0876a 100644 --- a/kitty/window.py +++ b/kitty/window.py @@ -900,17 +900,17 @@ class Window: shm.seek(0) shm.write(b'\x01') - prompt: str = data['prompt'] + message: str = data['message'] if data['type'] == 'confirm': get_boss().confirm( - prompt, callback, window=self, confirm_on_cancel=bool(data.get('confirm_on_cancel')), + message, callback, window=self, confirm_on_cancel=bool(data.get('confirm_on_cancel')), confirm_on_accept=bool(data.get('confirm_on_accept'))) elif data['type'] == 'choose': get_boss().choose( - prompt, callback, *data['choices'], window=self, default=data.get('default', '')) + message, callback, *data['choices'], window=self, default=data.get('default', '')) elif data['type'] == 'get_line': get_boss().get_line( - prompt, callback, window=self, is_password=bool(data.get('is_password'))) + message, callback, window=self, is_password=bool(data.get('is_password')), prompt=data.get('prompt', '> ')) else: log_error(f'Ignoring ask request with unknown type: {data["type"]}') diff --git a/shell-integration/ssh/askpass.py b/shell-integration/ssh/askpass.py index e0dea9e9d..909a0068a 100755 --- a/shell-integration/ssh/askpass.py +++ b/shell-integration/ssh/askpass.py @@ -10,16 +10,17 @@ from kitty.shm import SharedMemory msg = sys.argv[-1] prompt = os.environ.get('SSH_ASKPASS_PROMPT', '') -is_confirm = prompt == 'confirm' +is_confirm = prompt == 'confirm' or 'continue connecting' in msg q = { - 'prompt': msg, + 'message': msg, 'type': 'confirm' if is_confirm else 'get_line', 'is_password': True, } data = json.dumps(q) -with SharedMemory(size=len(data) + 1 + SharedMemory.num_bytes_for_size, unlink_on_exit=True, prefix=f'askpass-{os.getpid()}-' - ) as shm, open(os.ctermid(), 'wb') as tty: +with SharedMemory( + size=len(data) + 1 + SharedMemory.num_bytes_for_size, unlink_on_exit=True, prefix=f'askpass-{os.getpid()}-') as shm, \ + open(os.ctermid(), 'wb') as tty: shm.write(b'\0') shm.write_data_with_size(data) shm.flush()