Capabilities

Jinxed provides a lightweight virtual capabilities database derived from the gnu ncurses file terminfo.src without the requirement of any system libraries.

Singleton-free

Python has something of an undocumented singleton in curses.setupterm(): it allows only a single terminal type to be initialized for the lifetime of the process, and may not be changed:

>>> import curses
>>> curses.setupterm('xterm')
>>> curses.tigetstr('sgr')
b'%?%p9%t\x1b(0%e\x1b(B%;\x1b[0%?%p6%t;1%;%?%p5%t;2%;%?%p2%t;4%;%?%p1%p3%|%t;7%;%?%p4%t;5%;%?%p7%t;8%;m'
>>> curses.setupterm('vt100')
# bug: curses return capabilities 'xterm' after call setupterm('vt100')
>>> curses.tigetstr('sgr')
b'%?%p9%t\x1b(0%e\x1b(B%;\x1b[0%?%p6%t;1%;%?%p5%t;2%;%?%p2%t;4%;%?%p1%p3%|%t;7%;%?%p4%t;5%;%?%p7%t;8%;m'

This is especially a problem for writing telnet or ssh network services like MUDs or BBSs, where thread-safe support for multiple terminal capabilities in a single process session is required. Jinxed has no such limitation, offering a class-first variant of the global C functions, the jinxed.Terminal class can be instantiated for many terminal types per process:

>>> import jinxed
>>> jinxed.Terminal('xterm').tigetstr('sgr')
b'\x1b[0%?%p6%t;1%;%?%p5%t;2%;%?%p2%t;4%;%?%p1%p3%|%t;7%;%?%p4%t;5%;%?%p7%t;8%;m'
# fixed: jinxed correctly returns for 'vt100'
>>> jinxed.Terminal('vt100').tigetstr('sgr')
b'\x1b[0%?%p1%p6%|%t;1%;%?%p2%t;4%;%?%p1%p3%|%t;7%;%?%p4%t;5%;m'

Database

Jinxed ships a virtual terminfo database as Python code distributed in its terminfo/ folder, and uses no system terminfo, termcap or ncurses C Library code. This is important for some distributions of Python, such as the Windows release, though containing the curses module, its capability database is empty. Many Python distributions may also be missing support for curses entirely (raising ImportError).

If you request an unsupported $TERM, jinxed raises jinxed.error. Catch it and fall back to a common terminal type, like xterm-256color.

An example using the Singleton-free jinxed.Terminal:

import jinxed, os

try:
    term = jinxed.Terminal(os.environ.get('TERM', 'xterm-256color'))
except jinxed.error:
    term = jinxed.Terminal('xterm-256color')
print(term.tigetstr('sgr'))

Terminals

To ensure a small packaging size, only a subset of the 1,000+ historically known termcap entries are provided by Jinxed. The following are generated from the ncurses terminfo.src source file by the script found in Jinxed source repository, codegen_terminfo.py.

Hand-maintained (not generated by codegen):

If you find any entry missing, please open an issue on GitHub or create a pull request for jinxed/terminals.toml

Missing Legacy Codes

Three kinds of Control Codes are removed from the virtual database:

  • $<N> delay markers (e.g. $<50> meaning “pad 50ms”) are removed, these are required for real hardware terminals with poor flow control that may need a bit of rest after some sequences.

    Jinxed provides no functions to interpret these codes and so they are removed.

  • All \x1b(B, \x1b(0, \x1b(A, \x1b(U, \x1b(K G0/G1 Set Graphic Set designations and their related \x0e and \x0f Shift-Out and Shift-In control codes are removed. These legacy sequences no longer apply to unicode/utf-8 terminals, and mainly only cause confusion.

    Historically, when a curses program used an sgr sequence the final parameter could be used to enable line drawing mode, tparm(sgr, 0,0,0,0,0,0,0,0,1), and the sgr string was yielded with \x1b(0, and calling with param 9=0 (default) yields with \x1b(B to switch back.

    Jinxed provides no functions to manage historic character sets and so they are removed.

  • The smacs, rmacs, enacs, s0ds, and s1ds capabilities are dropped entirely.

    These enter/exit alternate character set operations switch between ASCII and line-drawing mode via G0/G1 designation or Shift-Out/Shift-In.

    Jinxed provides no functions to manage historic character sets and so they are removed.