Echo asterisks when inputting the password

This commit is contained in:
Kovid Goyal 2022-03-11 16:43:46 +05:30
parent 76de99a5a8
commit 14e0b01b40
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
2 changed files with 58 additions and 7 deletions

View File

@ -145,6 +145,54 @@ def extra_for(width: int, screen_width: int) -> int:
return max(0, screen_width - width) // 2 + 1
class Password(Handler):
def __init__(self, cli_opts: AskCLIOptions, prompt: str) -> None:
self.cli_opts = cli_opts
self.prompt = prompt
from kittens.tui.line_edit import LineEdit
self.line_edit = LineEdit(is_password=True)
def initialize(self) -> None:
self.draw_screen()
@Handler.atomic_update
def draw_screen(self) -> None:
self.cmd.clear_screen()
if self.cli_opts.message:
for line in self.cli_opts.message.splitlines():
self.print(line)
self.print()
self.line_edit.write(self.write, self.prompt)
def on_text(self, text: str, in_bracketed_paste: bool = False) -> None:
self.line_edit.on_text(text, in_bracketed_paste)
self.draw_screen()
def on_key(self, key_event: KeyEventType) -> None:
if self.line_edit.on_key(key_event):
self.draw_screen()
return
if key_event.matches('enter'):
self.quit_loop(0)
if key_event.matches('esc'):
self.quit_loop(1)
def on_resize(self, screen_size: ScreenSize) -> None:
self.screen_size = screen_size
self.draw_screen()
def on_interrupt(self) -> None:
self.quit_loop(1)
on_eot = on_interrupt
@property
def response(self) -> str:
if self._tui_loop.return_code == 0:
return self.line_edit.current_input
return ''
class Choose(Handler):
mouse_tracking = MouseTracking.buttons_only
@ -370,11 +418,10 @@ def main(args: List[str]) -> Response:
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(prompt)
return {'items': items, 'response': q or ''}
loop = Loop()
phandler = Password(cli_opts, prompt)
loop.loop(phandler)
return {'items': items, 'response': phandler.response}
import readline as rl
readline = rl

View File

@ -13,8 +13,9 @@ from .operations import (
class LineEdit:
def __init__(self) -> None:
def __init__(self, is_password: bool = False) -> None:
self.clear()
self.is_password = is_password
def clear(self) -> None:
self.current_input = ''
@ -31,7 +32,10 @@ class LineEdit:
if self.pending_bell:
write('\a')
self.pending_bell = False
text = prompt + self.current_input
ci = self.current_input
if self.is_password:
ci = '*' * wcswidth(ci)
text = prompt + ci
cursor_pos = self.cursor_pos + wcswidth(prompt)
if screen_cols:
write(SAVE_CURSOR + text + RESTORE_CURSOR)