#!/usr/bin/env python

import os , sys , code , ctypes , readline , signal , threading , subprocess # Core stuff

import pygments , pygments.formatters , pygments.lexers , blessings # Drawing stuff

def slight_delay ():

threading . Timer ( 0.001 , draw ) . start ()

return 0

def draw ():

with lock :

lines = console . buffer + [ readline . get_line_buffer ()]

prompts = [ sys . ps1 ] + [ sys . ps2 ] * ( len ( lines ) - 1 )

highlighted = pygments . highlight ( '

' . join ( lines ), lexer , formatter )[: - 1 ]

highlighted = [ p + l for p , l in zip ( prompts , highlighted . split ( '

' ))]

with terminal . location ( x = 0 ):

print ( len ( lines ) - 1 ) * terminal . move_up + '

' . join ( highlighted ),

readline . redisplay ()

return 0

def my_interrupt ( n , frame ):

set_hooks ( True )

threading . Timer ( 0.05 , lambda : subprocess . call ([ 'kill' , '-2' , str ( os . getpid ())])) . start ()

def set_hooks ( to_defaults ):

global default_interrupt , callback

hook_ptr = ctypes . c_void_p . in_dll ( ctypes . pythonapi , "PyOS_InputHook" )

if to_defaults :

signal . signal ( signal . SIGINT , default_interrupt )

hook_ptr . value = ctypes . c_void_p ( None ) . value

else :

signal . signal ( signal . SIGINT , my_interrupt )

hook_ptr . value = ctypes . cast ( callback , ctypes . c_void_p ) . value

default_interrupt = signal . getsignal ( signal . SIGINT )

callback = ctypes . PYFUNCTYPE ( ctypes . c_int )( slight_delay )

terminal = blessings . Terminal ()

lexer = pygments . lexers . PythonLexer ()

formatter = pygments . formatters . TerminalFormatter ()

console = code . InteractiveConsole ()

lock = threading . Lock ()

set_hooks ( False )

sys . ps1 = sys . ps1 if 'ps1' in dir ( sys ) else '>>> '

sys . ps2 = sys . ps2 if 'ps2' in dir ( sys ) else '... '

more = False

while True :

try :

try :

line = console . raw_input ( sys . ps2 if more else sys . ps1 )

encoding = getattr ( sys . stdin , "encoding" , None )

if encoding and not isinstance ( line , unicode ):

line = line . decode ( encoding )

except EOFError :

console . write ( "

" )

break

else :

more = console . push ( line )

except KeyboardInterrupt :

console . write ( "

KeyboardInterrupt

" )

console . resetbuffer ()

more = False