100 lines
3.1 KiB
Python
100 lines
3.1 KiB
Python
|
from __future__ import generators
|
||
|
import sys
|
||
|
import os
|
||
|
import py
|
||
|
from py.__.misc import terminal_helper
|
||
|
|
||
|
class Out(object):
|
||
|
tty = False
|
||
|
fullwidth = terminal_helper.terminal_width
|
||
|
def __init__(self, file):
|
||
|
self.file = py.io.dupfile(file)
|
||
|
|
||
|
def sep(self, sepchar, title=None):
|
||
|
fullwidth = self.fullwidth
|
||
|
# the goal is to have the line be as long as possible
|
||
|
# under the condition that len(line) <= fullwidth
|
||
|
if title is not None:
|
||
|
# we want 2 + 2*len(fill) + len(title) <= fullwidth
|
||
|
# i.e. 2 + 2*len(sepchar)*N + len(title) <= fullwidth
|
||
|
# 2*len(sepchar)*N <= fullwidth - len(title) - 2
|
||
|
# N <= (fullwidth - len(title) - 2) // (2*len(sepchar))
|
||
|
N = (fullwidth - len(title) - 2) // (2*len(sepchar))
|
||
|
fill = sepchar * N
|
||
|
line = "%s %s %s" % (fill, title, fill)
|
||
|
else:
|
||
|
# we want len(sepchar)*N <= fullwidth
|
||
|
# i.e. N <= fullwidth // len(sepchar)
|
||
|
line = sepchar * (fullwidth // len(sepchar))
|
||
|
# in some situations there is room for an extra sepchar at the right,
|
||
|
# in particular if we consider that with a sepchar like "_ " the
|
||
|
# trailing space is not important at the end of the line
|
||
|
if len(line) + len(sepchar.rstrip()) <= fullwidth:
|
||
|
line += sepchar.rstrip()
|
||
|
self.line(line)
|
||
|
|
||
|
class TerminalOut(Out):
|
||
|
tty = True
|
||
|
def __init__(self, file):
|
||
|
super(TerminalOut, self).__init__(file)
|
||
|
try:
|
||
|
import termios,fcntl,struct
|
||
|
call = fcntl.ioctl(0,termios.TIOCGWINSZ,"\000"*8)
|
||
|
height,width = struct.unpack( "hhhh", call ) [:2]
|
||
|
self.fullwidth = width
|
||
|
except (SystemExit, KeyboardInterrupt), e:
|
||
|
raise
|
||
|
except:
|
||
|
pass
|
||
|
|
||
|
def write(self, s):
|
||
|
self.file.write(str(s))
|
||
|
self.file.flush()
|
||
|
|
||
|
def line(self, s=''):
|
||
|
if s:
|
||
|
self.file.write(s + '\n')
|
||
|
else:
|
||
|
self.file.write('\n')
|
||
|
self.file.flush()
|
||
|
|
||
|
def rewrite(self, s=''):
|
||
|
#self.write('\x1b[u%s' % s) - this escape sequence does
|
||
|
# strange things, or nothing at all, on various terminals.
|
||
|
# XXX what is it supposed to do in the first place??
|
||
|
self.write(s)
|
||
|
|
||
|
class FileOut(Out):
|
||
|
def write(self, s):
|
||
|
self.file.write(str(s))
|
||
|
self.file.flush()
|
||
|
|
||
|
def line(self, s=''):
|
||
|
if s:
|
||
|
self.file.write(str(s) + '\n')
|
||
|
else:
|
||
|
self.file.write('\n')
|
||
|
self.file.flush()
|
||
|
|
||
|
def rewrite(self, s=''):
|
||
|
self.write(s)
|
||
|
|
||
|
def getout(file):
|
||
|
# XXX investigate further into terminal output, this is not enough
|
||
|
#
|
||
|
if file is None:
|
||
|
file = py.std.sys.stdout
|
||
|
elif hasattr(file, 'send'): # likely a channel like thing
|
||
|
file = WriteFile(file.send)
|
||
|
if hasattr(file, 'isatty') and file.isatty():
|
||
|
return TerminalOut(file)
|
||
|
else:
|
||
|
return FileOut(file)
|
||
|
|
||
|
class WriteFile(object):
|
||
|
def __init__(self, writemethod):
|
||
|
self.write = writemethod
|
||
|
def flush(self):
|
||
|
return
|
||
|
|