"""curses | |
The main package for curses support for Python. Normally used by importing | |
the package, and perhaps a particular module inside it. | |
import curses | |
from curses import textpad | |
curses.initscr() | |
... | |
""" | |
from _curses import * | |
import os as _os | |
import sys as _sys | |
# Some constants, most notably the ACS_* ones, are only added to the C | |
# _curses module's dictionary after initscr() is called. (Some | |
# versions of SGI's curses don't define values for those constants | |
# until initscr() has been called.) This wrapper function calls the | |
# underlying C initscr(), and then copies the constants from the | |
# _curses module to the curses package's dictionary. Don't do 'from | |
# curses import *' if you'll be needing the ACS_* constants. | |
def initscr(): | |
import _curses, curses | |
# we call setupterm() here because it raises an error | |
# instead of calling exit() in error cases. | |
setupterm(term=_os.environ.get("TERM", "unknown"), | |
fd=_sys.__stdout__.fileno()) | |
stdscr = _curses.initscr() | |
for key, value in _curses.__dict__.items(): | |
if key[0:4] == 'ACS_' or key in ('LINES', 'COLS'): | |
setattr(curses, key, value) | |
return stdscr | |
# This is a similar wrapper for start_color(), which adds the COLORS and | |
# COLOR_PAIRS variables which are only available after start_color() is | |
# called. | |
def start_color(): | |
import _curses, curses | |
retval = _curses.start_color() | |
if hasattr(_curses, 'COLORS'): | |
curses.COLORS = _curses.COLORS | |
if hasattr(_curses, 'COLOR_PAIRS'): | |
curses.COLOR_PAIRS = _curses.COLOR_PAIRS | |
return retval | |
# Import Python has_key() implementation if _curses doesn't contain has_key() | |
try: | |
has_key | |
except NameError: | |
from .has_key import has_key | |
# Wrapper for the entire curses-based application. Runs a function which | |
# should be the rest of your curses-based application. If the application | |
# raises an exception, wrapper() will restore the terminal to a sane state so | |
# you can read the resulting traceback. | |
def wrapper(func, /, *args, **kwds): | |
"""Wrapper function that initializes curses and calls another function, | |
restoring normal keyboard/screen behavior on error. | |
The callable object 'func' is then passed the main window 'stdscr' | |
as its first argument, followed by any other arguments passed to | |
wrapper(). | |
""" | |
try: | |
# Initialize curses | |
stdscr = initscr() | |
# Turn off echoing of keys, and enter cbreak mode, | |
# where no buffering is performed on keyboard input | |
noecho() | |
cbreak() | |
# In keypad mode, escape sequences for special keys | |
# (like the cursor keys) will be interpreted and | |
# a special value like curses.KEY_LEFT will be returned | |
stdscr.keypad(1) | |
# Start color, too. Harmless if the terminal doesn't have | |
# color; user can test with has_color() later on. The try/catch | |
# works around a minor bit of over-conscientiousness in the curses | |
# module -- the error return from C start_color() is ignorable. | |
try: | |
start_color() | |
except: | |
pass | |
return func(stdscr, *args, **kwds) | |
finally: | |
# Set everything back to normal | |
if 'stdscr' in locals(): | |
stdscr.keypad(0) | |
echo() | |
nocbreak() | |
endwin() | |