Source code

Revision control

Copy as Markdown

Other Tools

# -*- coding: utf-8 -*-
# Copyright 2019 Avram Lubkin, All Rights Reserved
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
"""
Provides a terminal class primarily for accessing functions that depend on
a terminal which has been previously setup as well as those functions
"""
import importlib
import io
import platform
import sys
from jinxed.terminfo import BOOL_CAPS, NUM_CAPS
from jinxed._util import BASESTRING, error, raise_from_none
if platform.system() == 'Windows': # pragma: no branch
from jinxed.win32 import get_term # pragma: no cover
else:
from jinxed._util import get_term
TERM = None
class Terminal(object):
"""
Persistent terminal object for functions that require a previously configured state
"""
def __init__(self, term=None, fd=-1): # pylint: disable=invalid-name
# Type check for term
if term is not None and not isinstance(term, BASESTRING):
raise TypeError('term must be a string or None, not %s' % type(term).__name__)
# Type check and default handling for fd
if fd == -1:
try:
self.stream_fd = sys.stdout.fileno()
except (AttributeError, TypeError, io.UnsupportedOperation):
self.stream_fd = None
elif not isinstance(fd, int):
raise TypeError('fd must be an integer, not %s' % type(fd).__name__)
else:
self.stream_fd = fd
# Try to dynamically determine terminal type
if term is None:
term = get_term(self.stream_fd)
try:
self.terminfo = importlib.import_module('jinxed.terminfo.%s' % term.replace('-', '_'))
except ImportError:
raise_from_none(error('Could not find terminal %s' % term))
def tigetstr(self, capname):
"""
Reimplementation of curses.tigetstr()
"""
return self.terminfo.STR_CAPS.get(capname, None)
def tigetnum(self, capname):
"""
Reimplementation of curses.tigetnum()
"""
return self.terminfo.NUM_CAPS.get(capname, -1 if capname in NUM_CAPS else -2)
def tigetflag(self, capname):
"""
Reimplementation of curses.tigetflag()
"""
if capname in self.terminfo.BOOL_CAPS:
return 1
if capname in BOOL_CAPS:
return 0
return -1
def setupterm(term=None, fd=-1): # pylint: disable=invalid-name
"""
Reimplementation of :py:func:`curses.setupterm`
"""
global TERM # pylint: disable=global-statement
TERM = Terminal(term, fd)
def tigetflag(capname):
"""
Reimplementation of :py:func:`curses.tigetflag`
"""
if TERM is None:
raise error('Must call setupterm() first')
return TERM.tigetflag(capname)
def tigetnum(capname):
"""
Reimplementation of :py:func:`curses.tigetnum`
"""
if TERM is None:
raise error('Must call setupterm() first')
return TERM.tigetnum(capname)
def tigetstr(capname):
"""
Reimplementation of :py:func:`curses.tigetstr`
"""
if TERM is None:
raise error('Must call setupterm() first')
return TERM.tigetstr(capname)