Allow controlling the prompt used to input the password

This commit is contained in:
Kovid Goyal 2022-03-11 15:34:23 +05:30
parent 61558d518e
commit 5bb6b29ca3
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
4 changed files with 20 additions and 11 deletions

View File

@ -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:

View File

@ -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:

View File

@ -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"]}')

View File

@ -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()