This module can move the cursor around in the terminal, change the text color, highlighting color, et cetera, bold, underlined, flashing (if supported). It also has a word wrap function, and can center text.
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 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 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 | #!/usr/bin/python
import sys,os
hist=[]
def actually_write():
global hist
sys.stdout.write("\x1b[%sm"%(";".join(hist)))
def o(msg):
global hist
msg="%02i"%msg
hist.append(msg)
actually_write()
def undo():
global hist
hist.pop()
actually_write()
def reset():
global hist
hist=[]
sys.stdout.write("\x1bc\x1b[!p\x1b[?3;4l\x1b[4l\x1b>")
default()
def default():
o(10) # in case someone called o(12) by mistake :P
o(0)
def clear():
sys.stdout.write("\x1b[H\x1b[2J")
def move(y,x):
sys.stdout.write("\x1b[%i;%iH"%(y+1,x+1))
def up():
sys.stdout.write("\x1b[A")
def down():
sys.stdout.write("\x1b[B")
def right():
sys.stdout.write("\x1b[C")
def left():
sys.stdout.write("\x1b[D")
def endline():
sys.stdout.write("\x1b[K")
def cursorinvisible():
sys.stdout.write("\x1b[?25l")
def cursornormal():
sys.stdout.write("\x1b[?12l\x1b[?25h")
def cursorveryvisible():
sys.stdout.write("\x1b[?12;25h")
def deletelines(lines=1):
sys.stdout.write("'\x1b[%iM"%lines)
def scrolldown():
sys.stdout.write("\x1bM")
def cols():
return int(os.popen("tput cols").read().strip())
def lines():
return int(os.popen("tput lines").read().strip())
def savecursor():
sys.stdout.write("\x1b7")
def restorecursor():
sys.stdout.write("\x1b8")
def bold():
o(1)
def hidden():
o(2)
def underline():
o(4)
def blink():
o(5)
def reverse():
o(7)
def formatting():
o(12)
def black():
o(30)
def red():
o(31)
def green():
o(32)
def orange():
o(33)
def blue():
o(34)
def magenta():
o(35)
def cyan():
o(36)
def white():
o(37)
def bgred():
o(41)
def bggreen():
o(42)
def bgorange():
o(43)
def bgblue():
o(44)
def bgmagenta():
o(45)
def bgcyan():
o(46)
def bgwhite():
o(47)
def put(line,indent,msg):
move(line,indent)
sys.stdout.write(msg)
def center(line,msg):
columns=cols()
indent=(columns-len(msg))/2
put(line,indent,msg)
return line,indent+len(msg)
def wrap(*args):
"wrap(line, [[lmargin,] rmargin,] msg)"
if len(args)==4:
line,lmargin,rmargin,msg=args
elif len(args)==3:
line,rmargin,msg=args
lmargin=0
elif len(args)==2:
line,msg=args
lmargin,rmargin=0,0
elif len(args)<2:
raise TypeError,"wrap() takes at least two arguments"
else:
raise TypeError,"wrap() takes at most four arguments"
line_length=cols()-lmargin-rmargin
msg=list(msg)
curr_indent=0
curr_line=line
char=msg.pop(0)
while 1:
if line_length-curr_indent<1:
put(curr_line,lmargin+curr_indent,'\n')
curr_line+=1
curr_indent=0
put(curr_line,lmargin,char)
else:
put(curr_line,lmargin+curr_indent,char)
curr_indent+=1
if len(msg)==0:
break
char=msg.pop(0)
return curr_line,lmargin+curr_indent
def wordwrap(*args):
"wordwrap(line, [[lmargin,] rmargin,] msg)"
if len(args)==4:
line,lmargin,rmargin,msg=args
elif len(args)==3:
line,rmargin,msg=args
lmargin=0
elif len(args)==2:
line,msg=args
lmargin,rmargin=0,0
elif len(args)<2:
raise TypeError,"wordwrap() takes at least two arguments"
else:
raise TypeError,"wordwrap() takes at most four arguments"
line_length=cols()-lmargin-rmargin
msg=msg.split()
curr_indent=0
curr_line=line
word=msg.pop(0)
while 1:
if line_length<len(word): # word is longer than allowed line
put(curr_line,lmargin,word[:line_length]) # wrap by letter
word=word[line_length:]
put(curr_line,lmargin+curr_indent,'\n')
curr_line+=1
curr_indent=0
elif line_length-curr_indent<len(word): # word cannot fit on remainder
put(curr_line,lmargin+curr_indent,'\n') # of line -- wrap by word
curr_line+=1
curr_indent=0
put(curr_line,lmargin,word)
else: # word fits on line
put(curr_line,lmargin+curr_indent,word)
curr_indent+=len(word)+1
if len(msg)==0:
break
word=msg.pop(0)
return curr_line,lmargin+curr_indent
def main():
reset()
bgblue()
white()
bold()
clear()
reverse()
center(5,' Windows ')
undo()
line,col=wordwrap(7,7,8,"Windows crashed again. I am the Blue Screen of Death. No one hears your screams.")
print
put(line+2,11,"*")
line,col=wordwrap(line+2,14,8,"Press any key to terminate the application.")
put(line+1,11,"*")
line,col=wordwrap(line+1,14,8,"Press CTRL+ALT+DEL again to restart your computer. You will lose any unsaved data in all applications.")
line,col=center(line+3,"Press any key to continue")
move(line,col+1)
endline()
raw_input()
reset()
if __name__=="__main__":
main()
|
I wrote this program a while ago just for fun. It has the ability to change text and background color in the terminal, move the cursor, word-wrap, center text, et cetera. Also, if you run it in a virtual terminal as the main application, you get a rather convincing (and comical, if you read the text) rendition of the BSOD with a nice haiku at the beginning of it. Oh, and it also has an "undo()" function, so you don't have to keep track of the stack of things that you've done that messed up the screen :-P
Enjoy :)
Nice. And seems to run nicely on OS X, too. The code would be more reusable as a class, though.
Thanks :)
Feel free to change it and email me the edited code at [my first name][my last name] at gmail dot com.
The stack is a nice feature.
Use the curses module, it handles a lot more terminal types.
Yeah, I wrote this because I actually needed a quick and dirty hack to do something with terminal colors and I couldn't be bothered learning how to use curses. It was actually more of a learning experience related to how the linux terminal works behind the scenes. I couldn't be bothered turning it into a class, either, because in my case there was only one terminal that it could print to.
I know that what I did was equivalent as far as good form goes to writing raw X code to create my windows where I should be using a cross-platform library. So be it. I learned how the terminal works.
I expect that others can learn the same from this code, since it is simple enough to understand without knowing too much Python.