DEFAULT_HEIGHT = 24 module-attribute

Default screen height

DEFAULT_WIDTH = 80 module-attribute

Default screen width

Screen

Source code in pzp/screen.py
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
class Screen:
    def __init__(self, stream: TextIO = sys.stderr, fullscreen: bool = True, height: Optional[int] = None):
        """
        Initialize screen

        Args:
            stream: Output stream
            fullscreen: Full screen mode
            height: Screen height

        Attributes:
            stream: Output stream
            data: Data to be written on the stream
            fullscreen: Full screen mode
            height: Screen height
        """
        self.stream: TextIO = stream
        self.data: List[str] = []
        self.fullscreen = fullscreen
        if self.fullscreen or height is None:
            self.height: int = self.get_terminal_height()
        else:
            self.height = min(height, self.get_terminal_height())
        # Save cursor position
        self.write(f"{CURSOR_SAVE_POS}")
        self.flush()

    @classmethod
    def get_terminal_height(cls) -> int:
        """
        Get the terminal height

        Returns:
            height: terminal height
        """
        return shutil.get_terminal_size(fallback=(DEFAULT_WIDTH, DEFAULT_HEIGHT)).lines

    def write(self, line: str) -> "Screen":
        "Add data to be written on the stream"
        self.data.append(line)
        return self

    def flush(self) -> "Screen":
        "Write data to the stream and flush it"
        self.stream.write("".join(self.data))
        self.data = []
        self.stream.flush()
        return self

    def cleanup(self) -> "Screen":
        "Clean screen and restore cursor position"
        self.erase_screen()
        if self.fullscreen:
            self.write(f"{CURSOR_RESTORE_POS}")
            self.move_up(self.height - 1)
        self.flush()
        return self

    def nl(self, lines: int = 1) -> "Screen":
        """
        Add n newlines

        Args:
            lines: number of newlines to be added
        """
        self.data.append(f"{NL}" * lines)
        return self

    def space(self, num: int = 1) -> "Screen":
        """
        Add n spaces

        Args:
            num: number of spaces
        """
        self.data.append(" " * num)
        return self

    def reset(self) -> "Screen":
        "Reset style and color"
        self.write(f"{RESET}")
        return self

    def bold(self) -> "Screen":
        "Set bold mode"
        self.write(f"{BOLD}")
        return self

    def erase_screen(self) -> "Screen":
        "Erase the screen"
        lines: int = self.height - 1
        return self.erase_line().move_up(lines).erase_lines(lines)

    def erase_line(self) -> "Screen":
        "Erase the current line"
        self.write(f"{ERASE_LINE}")
        return self

    def erase_lines(self, lines: int) -> "Screen":
        """
        Erase n lines

        Args:
            lines: number of lines to be erased
        """
        self.write(f"{ERASE_LINE}{NL}" * lines)
        return self.move_up(lines)

    def move_up(self, lines: int) -> "Screen":
        """
        Move cursor up
        If the cursor is already at the edge of the screen, this has no effect.

        Args:
            lines: number of lines
        """
        return self.write(f"{ESC}[{lines}A")

    def move_down(self, lines: int) -> "Screen":
        """
        Move cursor down
        If the cursor is already at the edge of the screen, this has no effect.

        Args:
            lines: number of lines
        """
        return self.write(f"{ESC}[{lines}B")

    def move_right(self, characters: int) -> "Screen":
        """
        Move cursor right
        If the cursor is already at the edge of the screen, this has no effect.

        Args:
            characters: number of characters
        """
        if characters > 0:
            return self.write(f"{ESC}[{characters}C")
        return self

    def move_left(self, characters: int) -> "Screen":
        """
        Move cursor left
        If the cursor is already at the edge of the screen, this has no effect.

        Args:
            characters: number of characters
        """
        if characters > 0:
            return self.write(f"{ESC}[{characters}D")
        return self

__init__(stream=sys.stderr, fullscreen=True, height=None)

Initialize screen

Parameters:

Name Type Description Default
stream TextIO

Output stream

sys.stderr
fullscreen bool

Full screen mode

True
height Optional[int]

Screen height

None

Attributes:

Name Type Description
stream

Output stream

data

Data to be written on the stream

fullscreen

Full screen mode

height

Screen height

Source code in pzp/screen.py
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
def __init__(self, stream: TextIO = sys.stderr, fullscreen: bool = True, height: Optional[int] = None):
    """
    Initialize screen

    Args:
        stream: Output stream
        fullscreen: Full screen mode
        height: Screen height

    Attributes:
        stream: Output stream
        data: Data to be written on the stream
        fullscreen: Full screen mode
        height: Screen height
    """
    self.stream: TextIO = stream
    self.data: List[str] = []
    self.fullscreen = fullscreen
    if self.fullscreen or height is None:
        self.height: int = self.get_terminal_height()
    else:
        self.height = min(height, self.get_terminal_height())
    # Save cursor position
    self.write(f"{CURSOR_SAVE_POS}")
    self.flush()

bold()

Set bold mode

Source code in pzp/screen.py
116
117
118
119
def bold(self) -> "Screen":
    "Set bold mode"
    self.write(f"{BOLD}")
    return self

cleanup()

Clean screen and restore cursor position

Source code in pzp/screen.py
82
83
84
85
86
87
88
89
def cleanup(self) -> "Screen":
    "Clean screen and restore cursor position"
    self.erase_screen()
    if self.fullscreen:
        self.write(f"{CURSOR_RESTORE_POS}")
        self.move_up(self.height - 1)
    self.flush()
    return self

erase_line()

Erase the current line

Source code in pzp/screen.py
126
127
128
129
def erase_line(self) -> "Screen":
    "Erase the current line"
    self.write(f"{ERASE_LINE}")
    return self

erase_lines(lines)

Erase n lines

Parameters:

Name Type Description Default
lines int

number of lines to be erased

required
Source code in pzp/screen.py
131
132
133
134
135
136
137
138
139
def erase_lines(self, lines: int) -> "Screen":
    """
    Erase n lines

    Args:
        lines: number of lines to be erased
    """
    self.write(f"{ERASE_LINE}{NL}" * lines)
    return self.move_up(lines)

erase_screen()

Erase the screen

Source code in pzp/screen.py
121
122
123
124
def erase_screen(self) -> "Screen":
    "Erase the screen"
    lines: int = self.height - 1
    return self.erase_line().move_up(lines).erase_lines(lines)

flush()

Write data to the stream and flush it

Source code in pzp/screen.py
75
76
77
78
79
80
def flush(self) -> "Screen":
    "Write data to the stream and flush it"
    self.stream.write("".join(self.data))
    self.data = []
    self.stream.flush()
    return self

get_terminal_height() classmethod

Get the terminal height

Returns:

Name Type Description
height int

terminal height

Source code in pzp/screen.py
60
61
62
63
64
65
66
67
68
@classmethod
def get_terminal_height(cls) -> int:
    """
    Get the terminal height

    Returns:
        height: terminal height
    """
    return shutil.get_terminal_size(fallback=(DEFAULT_WIDTH, DEFAULT_HEIGHT)).lines

move_down(lines)

Move cursor down If the cursor is already at the edge of the screen, this has no effect.

Parameters:

Name Type Description Default
lines int

number of lines

required
Source code in pzp/screen.py
151
152
153
154
155
156
157
158
159
def move_down(self, lines: int) -> "Screen":
    """
    Move cursor down
    If the cursor is already at the edge of the screen, this has no effect.

    Args:
        lines: number of lines
    """
    return self.write(f"{ESC}[{lines}B")

move_left(characters)

Move cursor left If the cursor is already at the edge of the screen, this has no effect.

Parameters:

Name Type Description Default
characters int

number of characters

required
Source code in pzp/screen.py
173
174
175
176
177
178
179
180
181
182
183
def move_left(self, characters: int) -> "Screen":
    """
    Move cursor left
    If the cursor is already at the edge of the screen, this has no effect.

    Args:
        characters: number of characters
    """
    if characters > 0:
        return self.write(f"{ESC}[{characters}D")
    return self

move_right(characters)

Move cursor right If the cursor is already at the edge of the screen, this has no effect.

Parameters:

Name Type Description Default
characters int

number of characters

required
Source code in pzp/screen.py
161
162
163
164
165
166
167
168
169
170
171
def move_right(self, characters: int) -> "Screen":
    """
    Move cursor right
    If the cursor is already at the edge of the screen, this has no effect.

    Args:
        characters: number of characters
    """
    if characters > 0:
        return self.write(f"{ESC}[{characters}C")
    return self

move_up(lines)

Move cursor up If the cursor is already at the edge of the screen, this has no effect.

Parameters:

Name Type Description Default
lines int

number of lines

required
Source code in pzp/screen.py
141
142
143
144
145
146
147
148
149
def move_up(self, lines: int) -> "Screen":
    """
    Move cursor up
    If the cursor is already at the edge of the screen, this has no effect.

    Args:
        lines: number of lines
    """
    return self.write(f"{ESC}[{lines}A")

nl(lines=1)

Add n newlines

Parameters:

Name Type Description Default
lines int

number of newlines to be added

1
Source code in pzp/screen.py
91
92
93
94
95
96
97
98
99
def nl(self, lines: int = 1) -> "Screen":
    """
    Add n newlines

    Args:
        lines: number of newlines to be added
    """
    self.data.append(f"{NL}" * lines)
    return self

reset()

Reset style and color

Source code in pzp/screen.py
111
112
113
114
def reset(self) -> "Screen":
    "Reset style and color"
    self.write(f"{RESET}")
    return self

space(num=1)

Add n spaces

Parameters:

Name Type Description Default
num int

number of spaces

1
Source code in pzp/screen.py
101
102
103
104
105
106
107
108
109
def space(self, num: int = 1) -> "Screen":
    """
    Add n spaces

    Args:
        num: number of spaces
    """
    self.data.append(" " * num)
    return self

write(line)

Add data to be written on the stream

Source code in pzp/screen.py
70
71
72
73
def write(self, line: str) -> "Screen":
    "Add data to be written on the stream"
    self.data.append(line)
    return self