| 1 | n/a | """curses |
|---|
| 2 | n/a | |
|---|
| 3 | n/a | The main package for curses support for Python. Normally used by importing |
|---|
| 4 | n/a | the package, and perhaps a particular module inside it. |
|---|
| 5 | n/a | |
|---|
| 6 | n/a | import curses |
|---|
| 7 | n/a | from curses import textpad |
|---|
| 8 | n/a | curses.initscr() |
|---|
| 9 | n/a | ... |
|---|
| 10 | n/a | |
|---|
| 11 | n/a | """ |
|---|
| 12 | n/a | |
|---|
| 13 | n/a | from _curses import * |
|---|
| 14 | n/a | import os as _os |
|---|
| 15 | n/a | import sys as _sys |
|---|
| 16 | n/a | |
|---|
| 17 | n/a | # Some constants, most notably the ACS_* ones, are only added to the C |
|---|
| 18 | n/a | # _curses module's dictionary after initscr() is called. (Some |
|---|
| 19 | n/a | # versions of SGI's curses don't define values for those constants |
|---|
| 20 | n/a | # until initscr() has been called.) This wrapper function calls the |
|---|
| 21 | n/a | # underlying C initscr(), and then copies the constants from the |
|---|
| 22 | n/a | # _curses module to the curses package's dictionary. Don't do 'from |
|---|
| 23 | n/a | # curses import *' if you'll be needing the ACS_* constants. |
|---|
| 24 | n/a | |
|---|
| 25 | n/a | def initscr(): |
|---|
| 26 | n/a | import _curses, curses |
|---|
| 27 | n/a | # we call setupterm() here because it raises an error |
|---|
| 28 | n/a | # instead of calling exit() in error cases. |
|---|
| 29 | n/a | setupterm(term=_os.environ.get("TERM", "unknown"), |
|---|
| 30 | n/a | fd=_sys.__stdout__.fileno()) |
|---|
| 31 | n/a | stdscr = _curses.initscr() |
|---|
| 32 | n/a | for key, value in _curses.__dict__.items(): |
|---|
| 33 | n/a | if key[0:4] == 'ACS_' or key in ('LINES', 'COLS'): |
|---|
| 34 | n/a | setattr(curses, key, value) |
|---|
| 35 | n/a | |
|---|
| 36 | n/a | return stdscr |
|---|
| 37 | n/a | |
|---|
| 38 | n/a | # This is a similar wrapper for start_color(), which adds the COLORS and |
|---|
| 39 | n/a | # COLOR_PAIRS variables which are only available after start_color() is |
|---|
| 40 | n/a | # called. |
|---|
| 41 | n/a | |
|---|
| 42 | n/a | def start_color(): |
|---|
| 43 | n/a | import _curses, curses |
|---|
| 44 | n/a | retval = _curses.start_color() |
|---|
| 45 | n/a | if hasattr(_curses, 'COLORS'): |
|---|
| 46 | n/a | curses.COLORS = _curses.COLORS |
|---|
| 47 | n/a | if hasattr(_curses, 'COLOR_PAIRS'): |
|---|
| 48 | n/a | curses.COLOR_PAIRS = _curses.COLOR_PAIRS |
|---|
| 49 | n/a | return retval |
|---|
| 50 | n/a | |
|---|
| 51 | n/a | # Import Python has_key() implementation if _curses doesn't contain has_key() |
|---|
| 52 | n/a | |
|---|
| 53 | n/a | try: |
|---|
| 54 | n/a | has_key |
|---|
| 55 | n/a | except NameError: |
|---|
| 56 | n/a | from .has_key import has_key |
|---|
| 57 | n/a | |
|---|
| 58 | n/a | # Wrapper for the entire curses-based application. Runs a function which |
|---|
| 59 | n/a | # should be the rest of your curses-based application. If the application |
|---|
| 60 | n/a | # raises an exception, wrapper() will restore the terminal to a sane state so |
|---|
| 61 | n/a | # you can read the resulting traceback. |
|---|
| 62 | n/a | |
|---|
| 63 | n/a | def wrapper(func, *args, **kwds): |
|---|
| 64 | n/a | """Wrapper function that initializes curses and calls another function, |
|---|
| 65 | n/a | restoring normal keyboard/screen behavior on error. |
|---|
| 66 | n/a | The callable object 'func' is then passed the main window 'stdscr' |
|---|
| 67 | n/a | as its first argument, followed by any other arguments passed to |
|---|
| 68 | n/a | wrapper(). |
|---|
| 69 | n/a | """ |
|---|
| 70 | n/a | |
|---|
| 71 | n/a | try: |
|---|
| 72 | n/a | # Initialize curses |
|---|
| 73 | n/a | stdscr = initscr() |
|---|
| 74 | n/a | |
|---|
| 75 | n/a | # Turn off echoing of keys, and enter cbreak mode, |
|---|
| 76 | n/a | # where no buffering is performed on keyboard input |
|---|
| 77 | n/a | noecho() |
|---|
| 78 | n/a | cbreak() |
|---|
| 79 | n/a | |
|---|
| 80 | n/a | # In keypad mode, escape sequences for special keys |
|---|
| 81 | n/a | # (like the cursor keys) will be interpreted and |
|---|
| 82 | n/a | # a special value like curses.KEY_LEFT will be returned |
|---|
| 83 | n/a | stdscr.keypad(1) |
|---|
| 84 | n/a | |
|---|
| 85 | n/a | # Start color, too. Harmless if the terminal doesn't have |
|---|
| 86 | n/a | # color; user can test with has_color() later on. The try/catch |
|---|
| 87 | n/a | # works around a minor bit of over-conscientiousness in the curses |
|---|
| 88 | n/a | # module -- the error return from C start_color() is ignorable. |
|---|
| 89 | n/a | try: |
|---|
| 90 | n/a | start_color() |
|---|
| 91 | n/a | except: |
|---|
| 92 | n/a | pass |
|---|
| 93 | n/a | |
|---|
| 94 | n/a | return func(stdscr, *args, **kwds) |
|---|
| 95 | n/a | finally: |
|---|
| 96 | n/a | # Set everything back to normal |
|---|
| 97 | n/a | if 'stdscr' in locals(): |
|---|
| 98 | n/a | stdscr.keypad(0) |
|---|
| 99 | n/a | echo() |
|---|
| 100 | n/a | nocbreak() |
|---|
| 101 | n/a | endwin() |
|---|