diff --git a/bin/nn b/bin/nn index 21bd53b..044b559 100755 --- a/bin/nn +++ b/bin/nn @@ -6,6 +6,8 @@ import re import shutil import subprocess import sys +import termios +import tty from datetime import datetime from pathlib import Path @@ -273,13 +275,23 @@ def apply_renames(plan): def confirm(prompt='Apply renames? [y/n] '): - """Ask the user for confirmation.""" - while True: - answer = input(prompt).strip().lower() - if answer == 'y': - return True - if answer == 'n': - return False + """Ask the user for confirmation, reacting to a single keypress.""" + print(prompt, end='', flush=True) + if not sys.stdin.isatty(): + return sys.stdin.read(1).strip().lower() == 'y' + + fd = sys.stdin.fileno() + old_settings = termios.tcgetattr(fd) + try: + # cbreak (not raw) keeps Ctrl-C as SIGINT and newlines well behaved. + tty.setcbreak(fd) + while (key := sys.stdin.read(1).lower()) not in ('y', 'n', ''): + pass + finally: + termios.tcsetattr(fd, termios.TCSADRAIN, old_settings) + + print(key) + return key == 'y' def main(): @@ -337,4 +349,8 @@ def main(): if __name__ == '__main__': - main() + try: + main() + except KeyboardInterrupt: + print('\nAborted.') + sys.exit(1)