Source code for plotext._kernel.terminal

# Terminal: owns the master plot, tracks the terminal size and prompt height, and clears the screen

from plotext._settings import defaults
from plotext._methods.string import write
from plotext._methods.key import is_pressed as _is_pressed
from plotext._plotter.plot import plot_class
import shutil


# Terminal container: wraps a master plot_class and tracks terminal size and prompt height
[docs] class terminal: # Initialize settings and build the master plot def __init__(self): self.clear() self._create_master() # Clean the terminal: with no lines, everything is wiped, the past rows included; with -1, only what is on screen, with no flickering; with a number, the cursor moves up that many rows, so the next writing takes their place.
[docs] def clean(self, lines = None): if lines is None: write('\033c') elif lines == -1: write('\033[H\033[2J') else: write("\033[A" * lines) return self
# Reset prompt, limit and size to defaults
[docs] def clear(self): self.prompt() self.limit() self._update_size() return self
# Set the prompt height (lines reserved below the plot)
[docs] def prompt(self, height = None): self._prompt = defaults.terminal["prompt height"] if height is None else int(height) return self
# Set whether width and height are limited to the terminal size
[docs] def limit(self, width = None, height = None): width = defaults.terminal["limit width"] if width is None else bool(width) height = defaults.terminal["limit height"] if height is None else bool(height) self._limit = [width, height] return self
# Query the total terminal size, falling back to defaults on failure def _get_total_size(self): try: size = shutil.get_terminal_size() width, height = size.columns, size.lines except: width, height = defaults.terminal["width"], defaults.terminal["height"] return width, height # Refresh cached size, subtracting the prompt height def _update_size(self): width, height = self._get_total_size() height = max(0, height - self._prompt) # the prompt cannot take away more rows than the terminal has, as when no terminal answers and the size comes back as zero self._size = self._width, self._height = [width, height] return self # Return current size, optionally updating first and optionally including the prompt height
[docs] def size(self, update = False, plottable = True): self._update_size() if update else None width, height = self._size if not plottable: height += self._prompt return width, height
# Build the master plot and attach it def _create_master(self): self._master = plot_class(parent = self) self._master._set_size(*self._size) return self # Identity check: this object is the terminal def _is_terminal(self): return True # Identity check: this object is a master def _is_master(self): return True # Identity check: this object is not a sub-master def _is_sub_master(self): return False # Build a multi-line log string including the master plot tree def _get_log(self): out = str(self) out += '\n└─' + self._master._get_log() return out # Print the terminal log
[docs] def log(self): print(self._get_log()) return self
# True when the given key was typed since the last call, answering right away without waiting; the first call asks the terminal to deliver each key as it is typed, and the answer is always False when the input is not a keyboard.
[docs] def is_pressed(self, key = 'q'): return _is_pressed(key)
# The terminal sits at the top of the plots hierarchy, above the master figure, and is its own parent at every level
[docs] def parent(self, level = 1): return self
# Short string representation def __repr__(self): width, height = self.size(update = False, plottable = True) return f'PlotextTerminal(width {width}, height {height}, prompt {self._prompt} lines, width limited {self._limit[0]}, height limited {self._limit[1]})'