Dotfiles
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

134 lines
2.9 KiB

#!/usr/bin/env python3
10 years ago
# (c) 2015 Taeyeon Mori
# execute a python file as if the lines were entered into an interactive prompt
import sys
import io
import code
try:
import pygments, pygments.lexers, pygments.formatters
except:
hl = None
else:
pyg_lex = pygments.lexers.PythonLexer()
pyg_fmt = pygments.formatters.Terminal256Formatter()
def hl(code):
return pygments.highlight(code, pyg_lex, pyg_fmt)
class IOIPythonPrefix:
def __init__(self, init=1):
self.count = init
self.ctx = ""
self.__enter__()
def inc(self, by=1):
self.count += by
def __call__(self, ctx):
self.ctx = ctx
return self
def __enter__(self):
self.prefix = "%s\033[0m[\033[31m%2d\033[0m] " % (self.ctx, self.count)
def __exit__(self, *a):
pass
class IOPrefixWrapper:
def __init__(self, parent, pfx):
self.parent = parent
self.prefix = pfx
self.nl = True
def write(self, text):
lines = text.splitlines(True)
if lines:
if self.nl:
self.parent.write(self.prefix.prefix)
self.parent.write(lines[0])
for line in lines[1:]:
self.parent.write(self.prefix.prefix)
self.parent.write(line)
self.nl = lines[-1].endswith("\n")
def flush(self):
return self.parent.flush()
xcount = IOIPythonPrefix()
sys.stdout = IOPrefixWrapper(sys.stdout, xcount)
interp = code.InteractiveInterpreter()
def print_in_x(cmd_lines):
with xcount("\033[34mIn "):
print(">>>", cmd_lines[0], end="")
for line in cmd_lines[1:]:
print("...", line, end="")
def print_in_hl(cmd_lines):
print_in_x(hl("".join(cmd_lines)).splitlines(True))
if hl:
print_in = print_in_hl
else:
print_in = print_in_x
def compile_lines(lines):
return code.compile_command("".join(lines))
def isindent(c):
return c in " \t"
with open(sys.argv[1]) as f:
ln = 0
peekbuf = []
def readline():
global ln, peekbuf
ln += 1
if peekbuf:
l = peekbuf.pop(0)
else:
l = f.readline()
if not l:
raise SystemExit()
return l
def peekline(n=0):
global peekbuf
while len(peekbuf) <= n:
peekbuf.append(f.readline())
return peekbuf[n]
def peekindent():
i = 0
while not peekline(i).strip():
i += 1
return isindent(peekline(i)[0])
while True:
cmd_lines = [readline()]
c = compile_lines(cmd_lines)
if not c:
while not c:
cmd_lines.append(readline())
while peekindent():
cmd_lines.append(readline())
c = compile_lines(cmd_lines)
print_in(cmd_lines)
with xcount("\033[33mOut"):
interp.runcode(c)
#sys.stdout.parent.write("\n")
xcount.inc()