Skip to content

Instantly share code, notes, and snippets.

@ashelly
Last active January 5, 2023 20:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save ashelly/e24de5e9cdd268f9d16a to your computer and use it in GitHub Desktop.
Save ashelly/e24de5e9cdd268f9d16a to your computer and use it in GitHub Desktop.
interactive single-char input in Python (no newline needed)
import sys,os
import termios
import tty
from contextlib import contextmanager
import signal
""" Allow single-key keyboard input (no <enter> needed)
Sample Usage:
with interactive.raw_read() as raw:
while not exit_flag:
keypress = raw.getch()
exit_flag = handle_key(keypress)
"""
@contextmanager
def raw_read():
"""Enable Non-blocking single character read"""
class RawReadCtrlChar(Exception): pass
class RawReader():
def getch(self):
termios.tcflush(sys.stdin, termios.TCIOFLUSH)
c = sys.stdin.read(1)
if c in ("\03", "\04", "\1a"): # break on ctrl-c, d or z
raise RawReadCtrlChar(c)
return c
fd = sys.stdin.fileno()
old_settings = termios.tcgetattr(fd)
try:
tty.setraw(fd)
yield RawReader()
except RawReadCtrlChar as ex:
if str(ex) == "\1a": raise signal.SIGSTP
finally:
termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment