reformatted pyreadline/console

This commit is contained in:
Jorgen Stenarson
2008-11-11 21:37:11 +01:00
parent 25530a8554
commit 095b86f9e6
5 changed files with 233 additions and 213 deletions
+6 -5
View File
@@ -1,21 +1,22 @@
import glob,sys
success=False
in_ironpython="IronPython" in sys.version
success = False
in_ironpython = "IronPython" in sys.version
if in_ironpython:
try:
from ironpython_console import *
success=True
success = True
except ImportError:
raise
else:
try:
from console import *
success=True
success = True
except ImportError:
pass
if not success:
raise ImportError("Could not find a console implementation for your platform")
raise ImportError(
"Could not find a console implementation for your platform")
+56 -54
View File
@@ -7,61 +7,63 @@ escape_parts = re.compile(u'\001?\033\\[([0-9;]*)m\002?')
class AnsiState(object):
def __init__(self,bold=False,inverse=False,color=u"white",background=u"black",backgroundbold=False):
self.bold=bold
self.inverse=inverse
self.color=color
self.background=background
self.backgroundbold=backgroundbold
self.bold = bold
self.inverse = inverse
self.color = color
self.background = background
self.backgroundbold = backgroundbold
trtable={u"black":0,u"red":4,u"green":2,u"yellow":6,u"blue":1,u"magenta":5,u"cyan":3,u"white":7}
revtable=dict(zip(trtable.values(),trtable.keys()))
trtable = {u"black":0, u"red":4, u"green":2, u"yellow":6,
u"blue":1, u"magenta":5, u"cyan":3, u"white":7}
revtable = dict(zip(trtable.values(),trtable.keys()))
def get_winattr(self):
attr=0
attr = 0
if self.bold:
attr|=0x0008
attr |= 0x0008
if self.backgroundbold:
attr|=0x0080
attr |= 0x0080
if self.inverse:
attr|=0x4000
attr|=self.trtable[self.color]
attr|=(self.trtable[self.background]<<4)
attr |= 0x4000
attr |= self.trtable[self.color]
attr |= (self.trtable[self.background] << 4)
return attr
def set_winattr(self,attr):
self.bold=bool(attr&0x0008)
self.backgroundbold=bool(attr&0x0080)
self.inverse=bool(attr&0x4000)
self.color=self.revtable[attr&0x0007]
self.background=self.revtable[(attr&0x0070)>>4]
def set_winattr(self, attr):
self.bold = bool(attr & 0x0008)
self.backgroundbold = bool(attr & 0x0080)
self.inverse = bool(attr & 0x4000)
self.color = self.revtable[attr & 0x0007]
self.background = self.revtable[(attr & 0x0070) >> 4]
winattr=property(get_winattr,set_winattr)
def __repr__(self):
return u'AnsiState(bold=%s,inverse=%s,color=%9s,background=%9s,backgroundbold=%s)# 0x%x'%(self.bold,
self.inverse,
'"%s"'%self.color,
'"%s"'%self.background,
self.backgroundbold,
self.winattr)
return u'AnsiState(bold=%s,inverse=%s,color=%9s,' \
u'background=%9s,backgroundbold=%s)# 0x%x'% \
(self.bold, self.inverse, '"%s"'%self.color,
'"%s"'%self.background, self.backgroundbold,
self.winattr)
def copy(self):
x=AnsiState()
x.bold=self.bold
x.inverse=self.inverse
x.color=self.color
x.background=self.background
x.backgroundbold=self.backgroundbold
x = AnsiState()
x.bold = self.bold
x.inverse = self.inverse
x.color = self.color
x.background = self.background
x.backgroundbold = self.backgroundbold
return x
defaultstate=AnsiState(False,False,u"white")
trtable={0:u"black",1:u"red",2:u"green",3:u"yellow",4:u"blue",5:u"magenta",6:u"cyan",7:u"white"}
defaultstate = AnsiState(False,False,u"white")
trtable = {0:u"black", 1:u"red", 2:u"green", 3:u"yellow",
4:u"blue", 5:u"magenta", 6:u"cyan", 7:u"white"}
class AnsiWriter(object):
def __init__(self,default=defaultstate):
if isinstance(defaultstate,AnsiState):
self.defaultstate=default
def __init__(self, default=defaultstate):
if isinstance(defaultstate, AnsiState):
self.defaultstate = default
else:
self.defaultstate=AnsiState()
self.defaultstate.winattr=defaultstate
self.defaultstate.winattr = defaultstate
def write_color(self,text, attr=None):
@@ -70,21 +72,21 @@ class AnsiWriter(object):
return the number of characters written.
'''
if isinstance(attr,AnsiState):
defaultstate=attr
defaultstate = attr
elif attr is None: #use attribute form initial console
attr = self.defaultstate.copy()
else:
defaultstate=AnsiState()
defaultstate.winattr=attr
attr=defaultstate
defaultstate = AnsiState()
defaultstate.winattr = attr
attr = defaultstate
chunks = terminal_escape.split(text)
n = 0 # count the characters we actually write, omitting the escapes
res=[]
for chunk in chunks:
m = escape_parts.match(chunk)
if m:
parts=m.group(1).split(u";")
if len(parts)==1 and parts[0]==u"0":
parts = m.group(1).split(u";")
if len(parts) == 1 and parts[0] == u"0":
attr = self.defaultstate.copy()
continue
for part in parts:
@@ -96,29 +98,29 @@ class AnsiWriter(object):
elif part == u"1": # switch on bold (i.e. intensify foreground color)
attr.bold=True
elif len(part) == 2 and u"30" <= part <= u"37": # set foreground color
attr.color = trtable[int(part)-30]
attr.color = trtable[int(part) - 30]
elif len(part) == 2 and u"40" <= part <= u"47": # set background color
attr.color = trtable[int(part)-40]
attr.color = trtable[int(part) - 40]
continue
n += len(chunk)
if True:
res.append((attr.copy(),chunk))
res.append((attr.copy(), chunk))
return n,res
def parse_color(self,text, attr=None):
n,res=self.write_color(text,attr)
return n,[attr.winattr for attr,text in res]
n,res=self.write_color(text, attr)
return n, [attr.winattr for attr, text in res]
def write_color(text,attr=None):
a=AnsiWriter(defaultstate)
return a.write_color(text,attr)
def write_color(text, attr=None):
a = AnsiWriter(defaultstate)
return a.write_color(text, attr)
def write_color_old( text, attr=None):
u'''write text at current cursor position and interpret color escapes.
return the number of characters written.
'''
res=[]
res = []
chunks = terminal_escape.split(text)
n = 0 # count the characters we actually write, omitting the escapes
if attr is None:#use attribute from initial console
@@ -138,14 +140,14 @@ def write_color_old( text, attr=None):
# we have to mirror bits
attr = (attr & ~0x07) | ((part & 0x1) << 2) | (part & 0x2) | ((part & 0x4) >> 2)
elif len(part) == 2 and u"40" <= part <= u"47": # set background color
part = int(part)-40
part = int(part) - 40
# we have to mirror bits
attr = (attr & ~0x70) | ((part & 0x1) << 6) | ((part & 0x2) << 4) | ((part & 0x4) << 2)
# ignore blink, underline and anything we don't understand
continue
n += len(chunk)
if chunk:
res.append((u"0x%x"%attr,chunk))
res.append((u"0x%x"%attr, chunk))
return res
+78 -60
View File
@@ -156,14 +156,14 @@ funcs = [
]
# I don't want events for these keys, they are just a bother for my application
key_modifiers = { VK_SHIFT:1,
VK_CONTROL:1,
VK_MENU:1, # alt key
0x5b:1, # windows key
key_modifiers = { VK_SHIFT : 1,
VK_CONTROL : 1,
VK_MENU : 1, # alt key
0x5b : 1, # windows key
}
def split_block(text,size=1000):
return [text[start:start+size] for start in range(0, len(text), size)]
def split_block(text, size=1000):
return [text[start:start + size] for start in range(0, len(text), size)]
@@ -184,8 +184,9 @@ class Console(object):
#self.AllocConsole()
if newbuffer:
self.hout = self.CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE,
0, None, 1, None)
self.hout = self.CreateConsoleScreenBuffer(
GENERIC_READ | GENERIC_WRITE,
0, None, 1, None)
self.SetConsoleActiveScreenBuffer(self.hout)
else:
self.hout = self.GetStdHandle(STD_OUTPUT_HANDLE)
@@ -199,10 +200,9 @@ class Console(object):
self.attr = info.wAttributes
self.saveattr = info.wAttributes # remember the initial colors
self.defaultstate=AnsiState()
self.defaultstate.winattr=info.wAttributes
self.ansiwriter=AnsiWriter(self.defaultstate)
# self.ansiwriter.defaultstate.bold=False
self.defaultstate = AnsiState()
self.defaultstate.winattr = info.wAttributes
self.ansiwriter = AnsiWriter(self.defaultstate)
background = self.attr & 0xf0
for escape in self.escape_to_color:
@@ -212,8 +212,10 @@ class Console(object):
self.softspace = 0 # this is for using it as a file-like object
self.serial = 0
self.pythondll = CDLL(u'python%s%s' % (sys.version[0], sys.version[2]))
self.inputHookPtr = c_int.from_address(addressof(self.pythondll.PyOS_InputHook)).value
self.pythondll = \
CDLL(u'python%s%s' % (sys.version[0], sys.version[2]))
self.inputHookPtr = \
c_int.from_address(addressof(self.pythondll.PyOS_InputHook)).value
setattr(Console, u'PyMem_Malloc', self.pythondll.PyMem_Malloc)
def __del__(self):
@@ -232,7 +234,8 @@ class Console(object):
return top,bot
def fixcoord(self, x, y):
u'''Return a long with x and y packed inside, also handle negative x and y.'''
u'''Return a long with x and y packed inside,
also handle negative x and y.'''
if x < 0 or y < 0:
info = CONSOLE_SCREEN_BUFFER_INFO()
self.GetConsoleScreenBufferInfo(self.hout, byref(info))
@@ -240,8 +243,8 @@ class Console(object):
x = info.srWindow.Right - x
y = info.srWindow.Bottom + y
# this is a hack! ctypes won't pass structures but COORD is just like a
# long, so this works.
# this is a hack! ctypes won't pass structures but COORD is
# just like a long, so this works.
return c_int(y << 16 | x)
def pos(self, x=None, y=None):
@@ -251,11 +254,12 @@ class Console(object):
self.GetConsoleScreenBufferInfo(self.hout, byref(info))
return (info.dwCursorPosition.X, info.dwCursorPosition.Y)
else:
return self.SetConsoleCursorPosition(self.hout, self.fixcoord(x, y))
return self.SetConsoleCursorPosition(self.hout,
self.fixcoord(x, y))
def home(self):
u'''Move to home.'''
self.pos(0,0)
self.pos(0, 0)
# Map ANSI color escape sequences into Windows Console Attributes
@@ -312,7 +316,7 @@ class Console(object):
elif chunk[0] == u'\r': # carriage return
x = 0
elif chunk[0] == u'\t': # tab
x = 8*(int(x/8)+1)
x = 8 * (int(x / 8) + 1)
if x > w: # newline
x -= w
y += 1
@@ -342,25 +346,27 @@ class Console(object):
def write_color(self, text, attr=None):
text = ensure_unicode(text)
n,res= self.ansiwriter.write_color(text,attr)
n, res= self.ansiwriter.write_color(text, attr)
junk = c_int(0)
for attr,chunk in res:
log(u"console.attr:%s"%unicode(attr))
log(u"console.chunk:%s"%unicode(chunk))
self.SetConsoleTextAttribute(self.hout, attr.winattr)
for short_chunk in split_block(chunk):
self.WriteConsoleW(self.hout, short_chunk, len(short_chunk), byref(junk), None)
self.WriteConsoleW(self.hout, short_chunk,
len(short_chunk), byref(junk), None)
return n
def write_plain(self, text, attr=None):
u'''write text at current cursor position.'''
log(u'write("%s", %s)' %(text,attr))
log(u'write("%s", %s)' %(text, attr))
if attr is None:
attr = self.attr
n = c_int(0)
self.SetConsoleTextAttribute(self.hout, attr)
for short_chunk in split_block(chunk):
self.WriteConsoleW(self.hout, ensure_unicode(short_chunk), len(short_chunk), byref(junk), None)
self.WriteConsoleW(self.hout, ensure_unicode(short_chunk),
len(short_chunk), byref(junk), None)
return len(text)
#This function must be used to ensure functioning with EMACS
@@ -368,7 +374,7 @@ class Console(object):
if os.environ.has_key(u"EMACS"):
def write_color(self, text, attr=None):
junk = c_int(0)
self.WriteFile(self.hout, text, len(text), byref(junk),None)
self.WriteFile(self.hout, text, len(text), byref(junk), None)
return len(text)
write_plain = write_color
@@ -399,8 +405,10 @@ class Console(object):
w = info.dwSize.X
n = c_int(0)
for y in range(info.dwSize.Y):
self.FillConsoleOutputAttribute(self.hout, attr, w, self.fixcoord(0, y), byref(n))
self.FillConsoleOutputCharacterW(self.hout, ord(fill[0]), w, self.fixcoord(0, y), byref(n))
self.FillConsoleOutputAttribute(self.hout, attr,
w, self.fixcoord(0, y), byref(n))
self.FillConsoleOutputCharacterW(self.hout, ord(fill[0]),
w, self.fixcoord(0, y), byref(n))
self.attr = attr
@@ -411,16 +419,17 @@ class Console(object):
pos = self.fixcoord(x, y)
n = c_int(0)
self.WriteConsoleOutputCharacterW(self.hout, text, len(text), pos, byref(n))
self.WriteConsoleOutputCharacterW(self.hout, text,
len(text), pos, byref(n))
self.FillConsoleOutputAttribute(self.hout, attr, n, pos, byref(n))
def clear_to_end_of_window(self):
top,bot=self._get_top_bot()
pos=self.pos()
w,h=self.size()
self.rectangle( (pos[0],pos[1],w,pos[1]+1))
if pos[1]<bot:
self.rectangle((0,pos[1]+1,w,bot+1))
top, bot = self._get_top_bot()
pos = self.pos()
w, h = self.size()
self.rectangle( (pos[0], pos[1], w, pos[1] + 1))
if pos[1] < bot:
self.rectangle((0, pos[1] + 1, w, bot + 1))
def rectangle(self, rect, attr=None, fill=u' '):
u'''Fill Rectangle.'''
@@ -430,23 +439,24 @@ class Console(object):
attr = self.attr
for y in range(y0, y1):
pos = self.fixcoord(x0, y)
self.FillConsoleOutputAttribute(self.hout, attr, x1-x0, pos, byref(n))
self.FillConsoleOutputCharacterW(self.hout, ord(fill[0]), x1-x0, pos, byref(n))
self.FillConsoleOutputAttribute(self.hout, attr, x1 - x0,
pos, byref(n))
self.FillConsoleOutputCharacterW(self.hout, ord(fill[0]), x1 - x0,
pos, byref(n))
def scroll(self, rect, dx, dy, attr=None, fill=' '):
u'''Scroll a rectangle.'''
if attr is None:
attr = self.attr
x0, y0, x1, y1 = rect
source = SMALL_RECT(x0, y0, x1-1, y1-1)
dest = self.fixcoord(x0+dx, y0+dy)
source = SMALL_RECT(x0, y0, x1 - 1, y1 - 1)
dest = self.fixcoord(x0 + dx, y0 + dy)
style = CHAR_INFO()
style.Char.AsciiChar = ensure_str(fill[0])
style.Attributes = attr
return self.ScrollConsoleScreenBufferW(self.hout, byref(source), byref(source),
dest, byref(style))
return self.ScrollConsoleScreenBufferW(self.hout, byref(source),
byref(source), dest, byref(style))
def scroll_window(self, lines):
u'''Scroll the window by the indicated number of lines.'''
@@ -470,7 +480,7 @@ class Console(object):
nrect.Bottom = bot
nrect.Left = rect.Left
nrect.Right = rect.Right
log(u'sn: top=%d bot=%d' % (top,bot))
log(u'sn: top=%d bot=%d' % (top, bot))
r=self.SetConsoleWindowInfo(self.hout, True, byref(nrect))
log(u'r=%d' % r)
@@ -483,7 +493,8 @@ class Console(object):
while 1:
if inputHookFunc:
call_function(inputHookFunc, ())
status = self.ReadConsoleInputW(self.hin, byref(Cevent), 1, byref(count))
status = self.ReadConsoleInputW(self.hin,
byref(Cevent), 1, byref(count))
if status and count.value == 1:
e = event(self, Cevent)
log(u"console.get %s"%ensure_unicode(e.keyinfo))
@@ -501,8 +512,9 @@ class Console(object):
self.scroll_window(-12)
else:
return e
elif e.type == u'KeyRelease' and e.keyinfo==(True, False, False, 83):
log(u"getKeypress:%s,%s,%s"%(e.keyinfo,e.keycode,e.type))
elif ((e.type == u'KeyRelease') and
(e.keyinfo == (True, False, False, 83))):
log(u"getKeypress:%s,%s,%s"%(e.keyinfo, e.keycode, e.type))
return e
def getchar(self):
@@ -511,9 +523,12 @@ class Console(object):
Cevent = INPUT_RECORD()
count = c_int(0)
while 1:
status = self.ReadConsoleInputW(self.hin, byref(Cevent), 1, byref(count))
if (status and count.value==1 and Cevent.EventType == 1 and
Cevent.Event.KeyEvent.bKeyDown):
status = self.ReadConsoleInputW(self.hin,
byref(Cevent), 1, byref(count))
if (status and
(count.value == 1) and
(Cevent.EventType == 1) and
Cevent.Event.KeyEvent.bKeyDown):
sym = keysym(Cevent.Event.KeyEvent.wVirtualKeyCode)
if len(sym) == 0:
sym = Cevent.Event.KeyEvent.uChar.AsciiChar
@@ -523,7 +538,8 @@ class Console(object):
u'''Check event queue.'''
Cevent = INPUT_RECORD()
count = c_int(0)
status = self.PeekConsoleInputW(self.hin, byref(Cevent), 1, byref(count))
status = self.PeekConsoleInputW(self.hin,
byref(Cevent), 1, byref(count))
if status and count == 1:
return event(self, Cevent)
@@ -550,7 +566,8 @@ class Console(object):
width = max(width, wmin)
height = max(height, hmin)
#print width, height
self.SetConsoleScreenBufferSize(self.hout, self.fixcoord(width, height))
self.SetConsoleScreenBufferSize(self.hout,
self.fixcoord(width, height))
else:
return (info.dwSize.X, info.dwSize.Y)
@@ -575,8 +592,8 @@ class Console(object):
# add the functions from the dll to the class
for func in funcs:
setattr(Console, func, getattr(windll.kernel32, func))
windll.kernel32.SetConsoleTitleW.argtypes=[c_wchar_p]
windll.kernel32.GetConsoleTitleW.argtypes=[c_wchar_p,c_short]
windll.kernel32.SetConsoleTitleW.argtypes = [c_wchar_p]
windll.kernel32.GetConsoleTitleW.argtypes = [c_wchar_p,c_short]
from event import Event
@@ -607,7 +624,7 @@ class event(Event):
self.char = input.Event.KeyEvent.uChar.UnicodeChar
self.keycode = input.Event.KeyEvent.wVirtualKeyCode
self.state = input.Event.KeyEvent.dwControlKeyState
self.keyinfo=make_KeyPress(self.char,self.state,self.keycode)
self.keyinfo = make_KeyPress(self.char,self.state,self.keycode)
elif input.EventType == MOUSE_EVENT:
if input.Event.MouseEvent.dwEventFlags & MOUSE_MOVED:
@@ -661,7 +678,7 @@ HOOKFUNC22 = CFUNCTYPE(c_char_p, c_char_p)
HOOKFUNC23 = CFUNCTYPE(c_char_p, c_void_p, c_void_p, c_char_p)
readline_hook = None # the python hook goes here
readline_ref = None # this holds a reference to the c-callable to keep it alive
readline_ref = None # reference to the c-callable to keep it alive
def hook_wrapper_23(stdin, stdout, prompt):
u'''Wrap a Python readline so it behaves like GNU readline.'''
@@ -683,8 +700,8 @@ def hook_wrapper_23(stdin, stdout, prompt):
res = u'\n'
# we have to make a copy because the caller expects to free the result
n = len(res)
p = Console.PyMem_Malloc(n+1)
cdll.msvcrt.strncpy(p, res, n+1)
p = Console.PyMem_Malloc(n + 1)
cdll.msvcrt.strncpy(p, res, n + 1)
return p
def hook_wrapper(prompt):
@@ -710,13 +727,14 @@ def hook_wrapper(prompt):
return p
def install_readline(hook):
'''Set up things for the interpreter to call our function like GNU readline.'''
'''Set up things for the interpreter to call
our function like GNU readline.'''
global readline_hook, readline_ref
# save the hook so the wrapper can call it
readline_hook = hook
# get the address of PyOS_ReadlineFunctionPointer so we can update it
PyOS_RFP = c_int.from_address(Console.GetProcAddress(sys.dllhandle,
"PyOS_ReadlineFunctionPointer"))
"PyOS_ReadlineFunctionPointer"))
# save a reference to the generated C-callable so it doesn't go away
if sys.version < '2.3':
readline_ref = HOOKFUNC22(hook_wrapper)
@@ -738,11 +756,11 @@ if __name__ == '__main__':
sys.stdout = c
sys.stderr = c
c.page()
print p("d"),p("D")
print p("d"), p("D")
c.pos(5, 10)
c.write('hi there')
print 'some printed output'
for i in range(10):
q=c.getkeypress()
q = c.getkeypress()
print q
del c
+3 -2
View File
@@ -2,12 +2,13 @@ class Event(object):
u'''Represent events from the console.'''
def __init__(self, console, input):
pass
def __repr__(self):
u'''Display an event for debugging.'''
if self.type in [u'KeyPress', u'KeyRelease']:
chr=self.char
chr = self.char
if ord(chr)<ord(u"A"):
chr=u"?"
chr = u"?"
s = u"%s char='%s'%d keysym='%s' keycode=%d:%x state=%x keyinfo=%s" % \
(self.type, chr, ord(self.char), self.keysym, self.keycode, self.keycode,
self.state, self.keyinfo)
+90 -92
View File
@@ -37,10 +37,10 @@ import System
from event import Event
from pyreadline.logger import log
#print "Codepage",System.Console.InputEncoding.CodePage
from pyreadline.keysyms import make_keysym, make_keyinfo,make_KeyPress,make_KeyPress_from_keydescr
from pyreadline.keysyms import \
make_keysym, make_keyinfo, make_KeyPress, make_KeyPress_from_keydescr
from pyreadline.console.ansi import AnsiState
color=System.ConsoleColor
color = System.ConsoleColor
ansicolor={u"0;30": color.Black,
u"0;31": color.DarkRed,
@@ -60,14 +60,14 @@ ansicolor={u"0;30": color.Black,
u"1;37": color.White
}
winattr={u"black":0,u"darkgray":0+8,
u"darkred":4,u"red":4+8,
u"darkgreen":2,u"green":2+8,
u"darkyellow":6,u"yellow":6+8,
u"darkblue":1,u"blue":1+8,
u"darkmagenta":5, u"magenta":5+8,
u"darkcyan":3,u"cyan":3+8,
u"gray":7,u"white":7+8}
winattr = {u"black" : 0, u"darkgray" : 0+8,
u"darkred" : 4, u"red" : 4+8,
u"darkgreen" : 2, u"green" : 2+8,
u"darkyellow" : 6, u"yellow" : 6+8,
u"darkblue" : 1, u"blue" : 1+8,
u"darkmagenta" : 5, u"magenta" : 5+8,
u"darkcyan" : 3, u"cyan" : 3+8,
u"gray" : 7, u"white" : 7+8}
class Console(object):
u'''Console driver for Windows.
@@ -80,21 +80,23 @@ class Console(object):
newbuffer=1 will allocate a new buffer so the old content will be restored
on exit.
'''
self.serial=0
self.serial = 0
self.attr = System.Console.ForegroundColor
self.saveattr = winattr[str(System.Console.ForegroundColor).lower()]
self.savebg=System.Console.BackgroundColor
self.savebg = System.Console.BackgroundColor
log(u'initial attr=%s' % self.attr)
def _get(self):
top=System.Console.WindowTop
top = System.Console.WindowTop
log(u"WindowTop:%s"%top)
return top
def _set(self,value):
top=System.Console.WindowTop
log(u"Set WindowTop:old:%s,new:%s"%(top,value))
WindowTop=property(_get,_set)
del _get,_set
def _set(self, value):
top = System.Console.WindowTop
log(u"Set WindowTop:old:%s,new:%s"%(top, value))
WindowTop = property(_get, _set)
del _get, _set
def __del__(self):
u'''Cleanup the console when finished.'''
@@ -106,16 +108,16 @@ class Console(object):
if x is not None:
System.Console.CursorLeft=x
else:
x=System.Console.CursorLeft
x = System.Console.CursorLeft
if y is not None:
System.Console.CursorTop=y
else:
y=System.Console.CursorTop
return x,y
y = System.Console.CursorTop
return x, y
def home(self):
u'''Move to home.'''
self.pos(0,0)
self.pos(0, 0)
# Map ANSI color escape sequences into Windows Console Attributes
@@ -155,7 +157,7 @@ class Console(object):
elif chunk[0] == u'\r': # carriage return
x = 0
elif chunk[0] == u'\t': # tab
x = 8*(int(x/8)+1)
x = 8 * (int(x / 8) + 1)
if x > w: # newline
x -= w
y += 1
@@ -183,10 +185,12 @@ class Console(object):
y = h - 1
return scroll
trtable={0:color.Black,4:color.DarkRed,2:color.DarkGreen,6:color.DarkYellow,
1:color.DarkBlue,5:color.DarkMagenta,3:color.DarkCyan,7:color.Gray,
8:color.DarkGray,4+8:color.Red,2+8:color.Green,6+8:color.Yellow,
1+8:color.Blue,5+8:color.Magenta,3+8:color.Cyan,7+8:color.White}
trtable = {0 : color.Black, 4 : color.DarkRed, 2 : color.DarkGreen,
6 : color.DarkYellow, 1 : color.DarkBlue, 5 : color.DarkMagenta,
3 : color.DarkCyan, 7 : color.Gray, 8 : color.DarkGray,
4+8 : color.Red, 2+8 : color.Green, 6+8 : color.Yellow,
1+8 : color.Blue, 5+8 : color.Magenta,3+8 : color.Cyan,
7+8 : color.White}
def write_color(self, text, attr=None):
'''write text at current cursor position and interpret color escapes.
@@ -196,31 +200,30 @@ class Console(object):
log(u'write_color("%s", %s)' % (text, attr))
chunks = self.terminal_escape.split(text)
log(u'chunks=%s' % repr(chunks))
bg=self.savebg
bg = self.savebg
n = 0 # count the characters we actually write, omitting the escapes
if attr is None:#use attribute from initial console
attr = self.attr
try:
fg=self.trtable[(0x000f&attr)]
bg=self.trtable[(0x00f0&attr)>>4]
fg = self.trtable[(0x000f&attr)]
bg = self.trtable[(0x00f0&attr)>>4]
except TypeError:
fg=attr
fg = attr
for chunk in chunks:
m = self.escape_parts.match(chunk)
if m:
log(m.group(1))
attr=ansicolor.get(m.group(1),self.attr)
attr = ansicolor.get(m.group(1), self.attr)
n += len(chunk)
System.Console.ForegroundColor=fg
System.Console.BackgroundColor=bg
#self.WriteConsoleA(self.hout, chunk, len(chunk), byref(junk), None)
System.Console.ForegroundColor = fg
System.Console.BackgroundColor = bg
System.Console.Write(chunk)
return n
def write_plain(self, text, attr=None):
u'''write text at current cursor position.'''
log(u'write("%s", %s)' %(text,attr))
log(u'write("%s", %s)' %(text, attr))
if attr is None:
attr = self.attr
n = c_int(0)
@@ -254,92 +257,87 @@ class Console(object):
def text(self, x, y, text, attr=None):
u'''Write text at the given position.'''
self.pos(x,y)
self.write_color(text,attr)
self.pos(x, y)
self.write_color(text, attr)
def clear_to_end_of_window(self):
oldtop=self.WindowTop
lastline=self.WindowTop+System.Console.WindowHeight
pos=self.pos()
w,h=self.size()
length=w-pos[0]+min((lastline-pos[1]-1),5)*w-1
self.write_color(length*u" ")
oldtop = self.WindowTop
lastline = self.WindowTop+System.Console.WindowHeight
pos = self.pos()
w, h = self.size()
length = w - pos[0] + min((lastline - pos[1] - 1), 5) * w - 1
self.write_color(length * u" ")
self.pos(*pos)
self.WindowTop=oldtop
self.WindowTop = oldtop
def rectangle(self, rect, attr=None, fill=u' '):
u'''Fill Rectangle.'''
pass
oldtop=self.WindowTop
oldpos=self.pos()
oldtop = self.WindowTop
oldpos = self.pos()
#raise NotImplementedError
x0, y0, x1, y1 = rect
if attr is None:
attr = self.attr
if fill:
rowfill=fill[:1]*abs(x1-x0)
rowfill = fill[:1] * abs(x1 - x0)
else:
rowfill=u' '*abs(x1-x0)
rowfill = u' ' * abs(x1 - x0)
for y in range(y0, y1):
System.Console.SetCursorPosition(x0,y)
self.write_color(rowfill,attr)
System.Console.SetCursorPosition(x0, y)
self.write_color(rowfill, attr)
self.pos(*oldpos)
def scroll(self, rect, dx, dy, attr=None, fill=' '):
u'''Scroll a rectangle.'''
pass
raise NotImplementedError
def scroll_window(self, lines):
u'''Scroll the window by the indicated number of lines.'''
top=self.WindowTop+lines
if top<0:
top=0
if top+System.Console.WindowHeight>System.Console.BufferHeight:
top=System.Console.BufferHeight
self.WindowTop=top
top = self.WindowTop + lines
if top < 0:
top = 0
if top + System.Console.WindowHeight > System.Console.BufferHeight:
top = System.Console.BufferHeight
self.WindowTop = top
def getkeypress(self):
u'''Return next key press event from the queue, ignoring others.'''
ck=System.ConsoleKey
ck = System.ConsoleKey
while 1:
e = System.Console.ReadKey(True)
if e.Key == System.ConsoleKey.PageDown: #PageDown
self.scroll_window(12)
elif e.Key == System.ConsoleKey.PageUp:#PageUp
self.scroll_window(-12)
elif str(e.KeyChar)==u"\000":#Drop deadkeys
elif str(e.KeyChar) == u"\000":#Drop deadkeys
log(u"Deadkey: %s"%e)
return event(self,e)
pass
return event(self, e)
else:
return event(self,e)
return event(self, e)
def title(self, txt=None):
u'''Set/get title.'''
if txt:
System.Console.Title=txt
System.Console.Title = txt
else:
return System.Console.Title
def size(self, width=None, height=None):
u'''Set/get window size.'''
sc=System.Console
sc = System.Console
if width is not None and height is not None:
sc.BufferWidth,sc.BufferHeight=width,height
sc.BufferWidth, sc.BufferHeight = width,height
else:
return sc.BufferWidth,sc.BufferHeight
return sc.BufferWidth, sc.BufferHeight
if width is not None and height is not None:
sc.WindowWidth,sc.WindowHeight=width,height
sc.WindowWidth, sc.WindowHeight = width,height
else:
return sc.WindowWidth-1,sc.WindowHeight-1
return sc.WindowWidth - 1, sc.WindowHeight - 1
def cursor(self, visible=True, size=None):
u'''Set cursor on or off.'''
System.Console.CursorVisible=visible
System.Console.CursorVisible = visible
def bell(self):
System.Console.Beep()
@@ -362,22 +360,22 @@ class event(Event):
self.char = str(input.KeyChar)
self.keycode = input.Key
self.state = input.Modifiers
log(u"%s,%s,%s"%(input.Modifiers,input.Key,input.KeyChar))
self.type="KeyRelease"
log(u"%s,%s,%s"%(input.Modifiers, input.Key, input.KeyChar))
self.type = "KeyRelease"
self.keysym = make_keysym(self.keycode)
self.keyinfo = make_KeyPress(self.char, self.state, self.keycode)
def make_event_from_keydescr(keydescr):
def input():
return 1
input.KeyChar=u"a"
input.Key=System.ConsoleKey.A
input.Modifiers=System.ConsoleModifiers.Shift
input.next_serial=input
e=event(input,input)
input.KeyChar = u"a"
input.Key = System.ConsoleKey.A
input.Modifiers = System.ConsoleModifiers.Shift
input.next_serial = input
e = event(input,input)
del input.next_serial
keyinfo=make_KeyPress_from_keydescr(keydescr)
e.keyinfo=keyinfo
keyinfo = make_KeyPress_from_keydescr(keydescr)
e.keyinfo = keyinfo
return e
CTRL_C_EVENT=make_event_from_keydescr(u"Control-c")
@@ -385,21 +383,21 @@ CTRL_C_EVENT=make_event_from_keydescr(u"Control-c")
def install_readline(hook):
def hook_wrap():
try:
res=hook()
res = hook()
except KeyboardInterrupt,x: #this exception does not seem to be caught
res=u""
res = u""
except EOFError:
return None
if res[-1:]==u"\n":
if res[-1:] == u"\n":
return res[:-1]
else:
return res
class IronPythonWrapper(IronPythonConsole.IConsole):
def ReadLine(self,autoIndentSize):
def ReadLine(self, autoIndentSize):
return hook_wrap()
def Write(self,text, style):
def Write(self, text, style):
System.Console.Write(text)
def WriteLine(self,text, style):
def WriteLine(self, text, style):
System.Console.WriteLine(text)
IronPythonConsole.PythonCommandLine.MyConsole = IronPythonWrapper()
@@ -416,11 +414,11 @@ if __name__ == u'__main__':
c.title(u"Testing console")
# c.bell()
print
print u"size",c.size()
print u"size", c.size()
print u' some printed output'
for i in range(10):
e=c.getkeypress()
print e.Key,chr(e.KeyChar),ord(e.KeyChar),e.Modifiers
e = c.getkeypress()
print e.Key, chr(e.KeyChar), ord(e.KeyChar), e.Modifiers
del c
System.Console.Clear()