Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/library/pippy/console.py
blob: c185ce96efb456db703a9771150b186c3ff2155c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
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
"""Console helpers for pippy."""
# Copyright (C) 2007 One Laptop Per Child Association, Inc.
# Licensed under the terms of the GNU GPL v2 or later; see
# /usr/share/licenses/common-licenses/GPLv2+ for details.
# Written by C. Scott Ananian <cscott@laptop.org>
import sys
def clear():
    """Clear screen on console."""
    # magic escape sequence
    sys.stdout.write('\x1B[H\x1B[J')

def size():
    """Return the number of rows/columns in the current terminal widget."""
    # xterm magic! see http://rtfm.etla.org/xterm/ctlseq.html
    import os, tty, termios
    fd = os.open('/dev/tty', os.O_RDWR|os.O_APPEND)
    def read_to_delimit(delimit):
        buf = []
        while True:
            c = os.read(fd, 1)
            if c==delimit: break
            buf.append(c)
        return ''.join(buf)
    oldattr = termios.tcgetattr(fd) # make sure we can restore tty state
    tty.setraw(fd, termios.TCSANOW) # set to raw mode.
    os.write(fd, '\x1B[18t')        # write the 'query screen size' command
    read_to_delimit('\x1b')         # parse response.
    read_to_delimit('[')
    size = read_to_delimit('t')
    # Output can be '8;rows;cols' or 'rows;cols' depending on vte version.
    # (SL #843)
    values = size.split(';')
    if len(values) == 3:
        rows = int(values[1])
        cols = int(values[2])
    else:
        rows = int(values[0])
        cols = int(values[1])
    termios.tcsetattr(fd, termios.TCSANOW, oldattr) # reset tty
    return cols, rows

def getpos():
    """Return the current x, y position of the cursor on the screen.

    The top-left corner is 1,1."""
    # xterm magic! see http://rtfm.etla.org/xterm/ctlseq.html
    sys.stdout.flush() # ensure that writes to the terminal have finished
    import os, tty, termios
    fd = os.open('/dev/tty', os.O_RDWR|os.O_APPEND)
    def read_to_delimit(delimit):
        buf = []
        while True:
            c = os.read(fd, 1)
            if c==delimit: break
            buf.append(c)
        return ''.join(buf)
    oldattr = termios.tcgetattr(fd) # make sure we can restore tty state
    tty.setraw(fd, termios.TCSANOW) # set to raw mode.
    os.write(fd, '\x1B[6n')         # Report Cursor Position
    read_to_delimit('\x1b')         # parse response.
    read_to_delimit('[')
    row = int(read_to_delimit(';'))
    col = int(read_to_delimit('R'))
    termios.tcsetattr(fd, termios.TCSANOW, oldattr) # reset tty
    return col, row

def setpos(column, row):
    """Move to the given position on the screen.

    The top-left corner is 1,1"""
    # xterm magic! see http://rtfm.etla.org/xterm/ctlseq.html
    sys.stdout.write('\x1B[%d;%dH' % (row, column))

def up(count=1):
    """Move the cursor up the given number of rows."""
    sys.stdout.write('\x1B[%dA' % count)

def down(count=1):
    """Move the cursor down the given number of rows."""
    sys.stdout.write('\x1B[%dB' % count)

def forward(count=1):
    """Move the cursor forward the given number of columns."""
    sys.stdout.write('\x1B[%dC' % count)

def backward(count=1):
    """Move the cursor backward the given number of columns."""
    sys.stdout.write('\x1B[%dD' % count)

def normal():
    """Switch to normal text."""
    sys.stdout.write('\x1B[0m')

def bold():
    """Switch to bold text."""
    sys.stdout.write('\x1B[1m')

def underlined():
    """Switch to underlined text."""
    sys.stdout.write('\x1B[4m')

def inverse():
    """Switch to inverse text."""
    sys.stdout.write('\x1B[7m')

def black():
    """Change text color to black."""
    # magic escape sequence.
    sys.stdout.write('\x1B[30m')

def red():
    """Change text color to red."""
    # magic escape sequence.
    sys.stdout.write('\x1B[31m')

def green():
    """Change text color to green."""
    # magic escape sequence.
    sys.stdout.write('\x1B[32m')

def yellow():
    """Change text color to yellow."""
    # magic escape sequence.
    sys.stdout.write('\x1B[33m')

def blue():
    """Change text color to blue."""
    # magic escape sequence.
    sys.stdout.write('\x1B[34m')

def magenta():
    """Change text color to magenta."""
    # magic escape sequence.
    sys.stdout.write('\x1B[35m')

def cyan():
    """Change text color to cyan."""
    # magic escape sequence.
    sys.stdout.write('\x1B[36m')

def white():
    """Change text color to white."""
    # magic escape sequence.
    sys.stdout.write('\x1B[37m')

def hide_cursor():
    """Hide the cursor."""
    sys.stdout.write('\x1B[?25l')

def show_cursor():
    """Show the cursor."""
    sys.stdout.write('\x1B[?25h')

def reset():
    """Clear screen and reset text color."""
    clear()
    show_cursor()
    sys.stdout.write('\x1B[0;39m')