mirror of
https://github.com/wassname/pyreadline.git
synced 2026-08-16 11:26:14 +08:00
Changed all strings to unicodestrings
This commit is contained in:
@@ -6,7 +6,7 @@
|
||||
# Distributed under the terms of the BSD License. The full license is in
|
||||
# the file COPYING, distributed as part of this software.
|
||||
#*****************************************************************************
|
||||
'''Cursor control and color for the Windows console.
|
||||
u'''Cursor control and color for the Windows console.
|
||||
|
||||
This was modeled after the C extension of the same name by Fredrik Lundh.
|
||||
'''
|
||||
@@ -23,7 +23,7 @@ try:
|
||||
from ctypes import *
|
||||
from _ctypes import call_function
|
||||
except ImportError:
|
||||
raise ImportError("You need ctypes to run this code")
|
||||
raise ImportError(u"You need ctypes to run this code")
|
||||
|
||||
# my code
|
||||
from pyreadline.keysyms import make_KeyPress
|
||||
@@ -168,12 +168,12 @@ def split_block(text,size=1000):
|
||||
|
||||
|
||||
class Console(object):
|
||||
'''Console driver for Windows.
|
||||
u'''Console driver for Windows.
|
||||
|
||||
'''
|
||||
|
||||
def __init__(self, newbuffer=0):
|
||||
'''Initialize the Console object.
|
||||
u'''Initialize the Console object.
|
||||
|
||||
newbuffer=1 will allocate a new buffer so the old content will be restored
|
||||
on exit.
|
||||
@@ -208,16 +208,16 @@ class Console(object):
|
||||
for escape in self.escape_to_color:
|
||||
if self.escape_to_color[escape] is not None:
|
||||
self.escape_to_color[escape] |= background
|
||||
log('initial attr=%x' % self.attr)
|
||||
log(u'initial attr=%x' % self.attr)
|
||||
self.softspace = 0 # this is for using it as a file-like object
|
||||
self.serial = 0
|
||||
|
||||
self.pythondll = CDLL('python%s%s' % (sys.version[0], sys.version[2]))
|
||||
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, 'PyMem_Malloc', self.pythondll.PyMem_Malloc)
|
||||
setattr(Console, u'PyMem_Malloc', self.pythondll.PyMem_Malloc)
|
||||
|
||||
def __del__(self):
|
||||
'''Cleanup the console when finished.'''
|
||||
u'''Cleanup the console when finished.'''
|
||||
# I don't think this ever gets called
|
||||
self.SetConsoleTextAttribute(self.hout, self.saveattr)
|
||||
self.SetConsoleMode(self.hin, self.inmode)
|
||||
@@ -232,7 +232,7 @@ class Console(object):
|
||||
return top,bot
|
||||
|
||||
def fixcoord(self, x, y):
|
||||
'''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))
|
||||
@@ -245,7 +245,7 @@ class Console(object):
|
||||
return c_int(y << 16 | x)
|
||||
|
||||
def pos(self, x=None, y=None):
|
||||
'''Move or query the window cursor.'''
|
||||
u'''Move or query the window cursor.'''
|
||||
if x is None:
|
||||
info = CONSOLE_SCREEN_BUFFER_INFO()
|
||||
self.GetConsoleScreenBufferInfo(self.hout, byref(info))
|
||||
@@ -254,38 +254,38 @@ class Console(object):
|
||||
return self.SetConsoleCursorPosition(self.hout, self.fixcoord(x, y))
|
||||
|
||||
def home(self):
|
||||
'''Move to home.'''
|
||||
u'''Move to home.'''
|
||||
self.pos(0,0)
|
||||
|
||||
# Map ANSI color escape sequences into Windows Console Attributes
|
||||
|
||||
terminal_escape = re.compile('(\001?\033\\[[0-9;]+m\002?)')
|
||||
escape_parts = re.compile('\001?\033\\[([0-9;]+)m\002?')
|
||||
escape_to_color = { '0;30': 0x0, #black
|
||||
'0;31': 0x4, #red
|
||||
'0;32': 0x2, #green
|
||||
'0;33': 0x4+0x2, #brown?
|
||||
'0;34': 0x1, #blue
|
||||
'0;35': 0x1+0x4, #purple
|
||||
'0;36': 0x2+0x4, #cyan
|
||||
'0;37': 0x1+0x2+0x4, #grey
|
||||
'1;30': 0x1+0x2+0x4, #dark gray
|
||||
'1;31': 0x4+0x8, #red
|
||||
'1;32': 0x2+0x8, #light green
|
||||
'1;33': 0x4+0x2+0x8, #yellow
|
||||
'1;34': 0x1+0x8, #light blue
|
||||
'1;35': 0x1+0x4+0x8, #light purple
|
||||
'1;36': 0x1+0x2+0x8, #light cyan
|
||||
'1;37': 0x1+0x2+0x4+0x8, #white
|
||||
'0': None,
|
||||
terminal_escape = re.compile(u'(\001?\033\\[[0-9;]+m\002?)')
|
||||
escape_parts = re.compile(u'\001?\033\\[([0-9;]+)m\002?')
|
||||
escape_to_color = { u'0;30': 0x0, #black
|
||||
u'0;31': 0x4, #red
|
||||
u'0;32': 0x2, #green
|
||||
u'0;33': 0x4+0x2, #brown?
|
||||
u'0;34': 0x1, #blue
|
||||
u'0;35': 0x1+0x4, #purple
|
||||
u'0;36': 0x2+0x4, #cyan
|
||||
u'0;37': 0x1+0x2+0x4, #grey
|
||||
u'1;30': 0x1+0x2+0x4, #dark gray
|
||||
u'1;31': 0x4+0x8, #red
|
||||
u'1;32': 0x2+0x8, #light green
|
||||
u'1;33': 0x4+0x2+0x8, #yellow
|
||||
u'1;34': 0x1+0x8, #light blue
|
||||
u'1;35': 0x1+0x4+0x8, #light purple
|
||||
u'1;36': 0x1+0x2+0x8, #light cyan
|
||||
u'1;37': 0x1+0x2+0x4+0x8, #white
|
||||
u'0': None,
|
||||
}
|
||||
|
||||
# This pattern should match all characters that change the cursor position differently
|
||||
# than a normal character.
|
||||
motion_char_re = re.compile('([\n\r\t\010\007])')
|
||||
motion_char_re = re.compile(u'([\n\r\t\010\007])')
|
||||
|
||||
def write_scrolling(self, text, attr=None):
|
||||
'''write text at current cursor position while watching for scrolling.
|
||||
u'''write text at current cursor position while watching for scrolling.
|
||||
|
||||
If the window scrolls because you are at the bottom of the screen
|
||||
buffer, all positions that you are storing will be shifted by the
|
||||
@@ -306,19 +306,19 @@ class Console(object):
|
||||
for chunk in chunks:
|
||||
n = self.write_color(chunk, attr)
|
||||
if len(chunk) == 1: # the funny characters will be alone
|
||||
if chunk[0] == '\n': # newline
|
||||
if chunk[0] == u'\n': # newline
|
||||
x = 0
|
||||
y += 1
|
||||
elif chunk[0] == '\r': # carriage return
|
||||
elif chunk[0] == u'\r': # carriage return
|
||||
x = 0
|
||||
elif chunk[0] == '\t': # tab
|
||||
elif chunk[0] == u'\t': # tab
|
||||
x = 8*(int(x/8)+1)
|
||||
if x > w: # newline
|
||||
x -= w
|
||||
y += 1
|
||||
elif chunk[0] == '\007': # bell
|
||||
elif chunk[0] == u'\007': # bell
|
||||
pass
|
||||
elif chunk[0] == '\010':
|
||||
elif chunk[0] == u'\010':
|
||||
x -= 1
|
||||
if x < 0:
|
||||
y -= 1 # backed up 1 line
|
||||
@@ -353,8 +353,8 @@ class Console(object):
|
||||
return n
|
||||
|
||||
def write_plain(self, text, attr=None):
|
||||
'''write text at current cursor position.'''
|
||||
log('write("%s", %s)' %(text,attr))
|
||||
u'''write text at current cursor position.'''
|
||||
log(u'write("%s", %s)' %(text,attr))
|
||||
if attr is None:
|
||||
attr = self.attr
|
||||
n = c_int(0)
|
||||
@@ -365,7 +365,7 @@ class Console(object):
|
||||
|
||||
#This function must be used to ensure functioning with EMACS
|
||||
#Emacs sets the EMACS environment variable
|
||||
if os.environ.has_key("EMACS"):
|
||||
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)
|
||||
@@ -374,7 +374,7 @@ class Console(object):
|
||||
|
||||
# make this class look like a file object
|
||||
def write(self, text):
|
||||
log('write("%s")' % text)
|
||||
log(u'write("%s")' % text)
|
||||
return self.write_color(text)
|
||||
|
||||
#write = write_scrolling
|
||||
@@ -385,8 +385,8 @@ class Console(object):
|
||||
def flush(self):
|
||||
pass
|
||||
|
||||
def page(self, attr=None, fill=' '):
|
||||
'''Fill the entire screen.'''
|
||||
def page(self, attr=None, fill=u' '):
|
||||
u'''Fill the entire screen.'''
|
||||
if attr is None:
|
||||
attr = self.attr
|
||||
if len(fill) != 1:
|
||||
@@ -405,7 +405,7 @@ class Console(object):
|
||||
self.attr = attr
|
||||
|
||||
def text(self, x, y, text, attr=None):
|
||||
'''Write text at the given position.'''
|
||||
u'''Write text at the given position.'''
|
||||
if attr is None:
|
||||
attr = self.attr
|
||||
|
||||
@@ -422,8 +422,8 @@ class Console(object):
|
||||
if pos[1]<bot:
|
||||
self.rectangle((0,pos[1]+1,w,bot+1))
|
||||
|
||||
def rectangle(self, rect, attr=None, fill=' '):
|
||||
'''Fill Rectangle.'''
|
||||
def rectangle(self, rect, attr=None, fill=u' '):
|
||||
u'''Fill Rectangle.'''
|
||||
x0, y0, x1, y1 = rect
|
||||
n = c_int(0)
|
||||
if attr is None:
|
||||
@@ -434,7 +434,7 @@ class Console(object):
|
||||
self.FillConsoleOutputCharacterW(self.hout, ord(fill[0]), x1-x0, pos, byref(n))
|
||||
|
||||
def scroll(self, rect, dx, dy, attr=None, fill=' '):
|
||||
'''Scroll a rectangle.'''
|
||||
u'''Scroll a rectangle.'''
|
||||
if attr is None:
|
||||
attr = self.attr
|
||||
|
||||
@@ -442,18 +442,18 @@ class Console(object):
|
||||
source = SMALL_RECT(x0, y0, x1-1, y1-1)
|
||||
dest = self.fixcoord(x0+dx, y0+dy)
|
||||
style = CHAR_INFO()
|
||||
style.Char.AsciiChar = fill[0]
|
||||
style.Char.AsciiChar = ensure_str(fill[0])
|
||||
style.Attributes = attr
|
||||
|
||||
return self.ScrollConsoleScreenBufferW(self.hout, byref(source), byref(source),
|
||||
dest, byref(style))
|
||||
|
||||
def scroll_window(self, lines):
|
||||
'''Scroll the window by the indicated number of lines.'''
|
||||
u'''Scroll the window by the indicated number of lines.'''
|
||||
info = CONSOLE_SCREEN_BUFFER_INFO()
|
||||
self.GetConsoleScreenBufferInfo(self.hout, byref(info))
|
||||
rect = info.srWindow
|
||||
log('sw: rtop=%d rbot=%d' % (rect.Top, rect.Bottom))
|
||||
log(u'sw: rtop=%d rbot=%d' % (rect.Top, rect.Bottom))
|
||||
top = rect.Top + lines
|
||||
bot = rect.Bottom + lines
|
||||
h = bot - top
|
||||
@@ -470,12 +470,12 @@ class Console(object):
|
||||
nrect.Bottom = bot
|
||||
nrect.Left = rect.Left
|
||||
nrect.Right = rect.Right
|
||||
log('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('r=%d' % r)
|
||||
log(u'r=%d' % r)
|
||||
|
||||
def get(self):
|
||||
'''Get next event from queue.'''
|
||||
u'''Get next event from queue.'''
|
||||
inputHookFunc = c_int.from_address(self.inputHookPtr).value
|
||||
|
||||
Cevent = INPUT_RECORD()
|
||||
@@ -490,23 +490,23 @@ class Console(object):
|
||||
return e
|
||||
|
||||
def getkeypress(self):
|
||||
'''Return next key press event from the queue, ignoring others.'''
|
||||
u'''Return next key press event from the queue, ignoring others.'''
|
||||
while 1:
|
||||
e = self.get()
|
||||
if e.type == 'KeyPress' and e.keycode not in key_modifiers:
|
||||
log("console.getleypress %s"%e)
|
||||
if e.type == u'KeyPress' and e.keycode not in key_modifiers:
|
||||
log(u"console.getleypress %s"%e)
|
||||
if e.keyinfo.keyname == 'next':
|
||||
self.scroll_window(12)
|
||||
elif e.keyinfo.keyname == 'prior':
|
||||
self.scroll_window(-12)
|
||||
else:
|
||||
return e
|
||||
elif e.type == 'KeyRelease' and e.keyinfo==(True, False, False, 83):
|
||||
log("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):
|
||||
'''Get next character from queue.'''
|
||||
u'''Get next character from queue.'''
|
||||
|
||||
Cevent = INPUT_RECORD()
|
||||
count = c_int(0)
|
||||
@@ -520,7 +520,7 @@ class Console(object):
|
||||
return sym
|
||||
|
||||
def peek(self):
|
||||
'''Check event queue.'''
|
||||
u'''Check event queue.'''
|
||||
Cevent = INPUT_RECORD()
|
||||
count = c_int(0)
|
||||
status = self.PeekConsoleInputW(self.hin, byref(Cevent), 1, byref(count))
|
||||
@@ -528,7 +528,7 @@ class Console(object):
|
||||
return event(self, Cevent)
|
||||
|
||||
def title(self, txt=None):
|
||||
'''Set/get title.'''
|
||||
u'''Set/get title.'''
|
||||
if txt:
|
||||
self.SetConsoleTitleW(txt)
|
||||
else:
|
||||
@@ -538,7 +538,7 @@ class Console(object):
|
||||
return buffer.value[:n]
|
||||
|
||||
def size(self, width=None, height=None):
|
||||
'''Set/get window size.'''
|
||||
u'''Set/get window size.'''
|
||||
info = CONSOLE_SCREEN_BUFFER_INFO()
|
||||
status = self.GetConsoleScreenBufferInfo(self.hout, byref(info))
|
||||
if not status:
|
||||
@@ -555,7 +555,7 @@ class Console(object):
|
||||
return (info.dwSize.X, info.dwSize.Y)
|
||||
|
||||
def cursor(self, visible=None, size=None):
|
||||
'''Set cursor on or off.'''
|
||||
u'''Set cursor on or off.'''
|
||||
info = CONSOLE_CURSOR_INFO()
|
||||
if self.GetConsoleCursorInfo(self.hout, byref(info)):
|
||||
if visible is not None:
|
||||
@@ -565,10 +565,10 @@ class Console(object):
|
||||
self.SetConsoleCursorInfo(self.hout, byref(info))
|
||||
|
||||
def bell(self):
|
||||
self.write('\007')
|
||||
self.write(u'\007')
|
||||
|
||||
def next_serial(self):
|
||||
'''Get next event serial number.'''
|
||||
u'''Get next event serial number.'''
|
||||
self.serial += 1
|
||||
return self.serial
|
||||
|
||||
@@ -584,26 +584,26 @@ VkKeyScan = windll.user32.VkKeyScanA
|
||||
|
||||
|
||||
class event(Event):
|
||||
'''Represent events from the console.'''
|
||||
u'''Represent events from the console.'''
|
||||
def __init__(self, console, input):
|
||||
'''Initialize an event from the Windows input structure.'''
|
||||
self.type = '??'
|
||||
self.type = u'??'
|
||||
self.serial = console.next_serial()
|
||||
self.width = 0
|
||||
self.height = 0
|
||||
self.x = 0
|
||||
self.y = 0
|
||||
self.char = ''
|
||||
self.char = u''
|
||||
self.keycode = 0
|
||||
self.keysym = '??'
|
||||
self.keysym = u'??'
|
||||
self.keyinfo = None # a tuple with (control, meta, shift, keycode) for dispatch
|
||||
self.width = None
|
||||
|
||||
if input.EventType == KEY_EVENT:
|
||||
if input.Event.KeyEvent.bKeyDown:
|
||||
self.type = "KeyPress"
|
||||
self.type = u"KeyPress"
|
||||
else:
|
||||
self.type = "KeyRelease"
|
||||
self.type = u"KeyRelease"
|
||||
self.char = input.Event.KeyEvent.uChar.UnicodeChar
|
||||
self.keycode = input.Event.KeyEvent.wVirtualKeyCode
|
||||
self.state = input.Event.KeyEvent.dwControlKeyState
|
||||
@@ -611,23 +611,23 @@ class event(Event):
|
||||
|
||||
elif input.EventType == MOUSE_EVENT:
|
||||
if input.Event.MouseEvent.dwEventFlags & MOUSE_MOVED:
|
||||
self.type = "Motion"
|
||||
self.type = u"Motion"
|
||||
else:
|
||||
self.type = "Button"
|
||||
self.type = u"Button"
|
||||
self.x = input.Event.MouseEvent.dwMousePosition.X
|
||||
self.y = input.Event.MouseEvent.dwMousePosition.Y
|
||||
self.state = input.Event.MouseEvent.dwButtonState
|
||||
elif input.EventType == WINDOW_BUFFER_SIZE_EVENT:
|
||||
self.type = "Configure"
|
||||
self.type = u"Configure"
|
||||
self.width = input.Event.WindowBufferSizeEvent.dwSize.X
|
||||
self.height = input.Event.WindowBufferSizeEvent.dwSize.Y
|
||||
elif input.EventType == FOCUS_EVENT:
|
||||
if input.Event.FocusEvent.bSetFocus:
|
||||
self.type = "FocusIn"
|
||||
self.type = u"FocusIn"
|
||||
else:
|
||||
self.type = "FocusOut"
|
||||
self.type = u"FocusOut"
|
||||
elif input.EventType == MENU_EVENT:
|
||||
self.type = "Menu"
|
||||
self.type = u"Menu"
|
||||
self.state = input.Event.MenuEvent.dwCommandId
|
||||
|
||||
def getconsole(buffer=1):
|
||||
@@ -664,23 +664,23 @@ readline_hook = None # the python hook goes here
|
||||
readline_ref = None # this holds a reference to the c-callable to keep it alive
|
||||
|
||||
def hook_wrapper_23(stdin, stdout, prompt):
|
||||
'''Wrap a Python readline so it behaves like GNU readline.'''
|
||||
u'''Wrap a Python readline so it behaves like GNU readline.'''
|
||||
try:
|
||||
# call the Python hook
|
||||
res = ensure_str(readline_hook(prompt))
|
||||
# make sure it returned the right sort of thing
|
||||
if res and not isinstance(res, str):
|
||||
raise TypeError, 'readline must return a string.'
|
||||
raise TypeError, u'readline must return a string.'
|
||||
except KeyboardInterrupt:
|
||||
# GNU readline returns 0 on keyboard interrupt
|
||||
return 0
|
||||
except EOFError:
|
||||
# It returns an empty string on EOF
|
||||
res = ''
|
||||
res = u''
|
||||
except:
|
||||
print >>sys.stderr, 'Readline internal error'
|
||||
print >>sys.stderr, u'Readline internal error'
|
||||
traceback.print_exc()
|
||||
res = '\n'
|
||||
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)
|
||||
@@ -688,23 +688,23 @@ def hook_wrapper_23(stdin, stdout, prompt):
|
||||
return p
|
||||
|
||||
def hook_wrapper(prompt):
|
||||
'''Wrap a Python readline so it behaves like GNU readline.'''
|
||||
u'''Wrap a Python readline so it behaves like GNU readline.'''
|
||||
try:
|
||||
# call the Python hook
|
||||
res = ensure_str(readline_hook(prompt))
|
||||
# make sure it returned the right sort of thing
|
||||
if res and not isinstance(res, str):
|
||||
raise TypeError, 'readline must return a string.'
|
||||
raise TypeError, u'readline must return a string.'
|
||||
except KeyboardInterrupt:
|
||||
# GNU readline returns 0 on keyboard interrupt
|
||||
return 0
|
||||
except EOFError:
|
||||
# It returns an empty string on EOF
|
||||
res = ''
|
||||
res = u''
|
||||
except:
|
||||
print >>sys.stderr, 'Readline internal error'
|
||||
print >>sys.stderr, u'Readline internal error'
|
||||
traceback.print_exc()
|
||||
res = '\n'
|
||||
res = u'\n'
|
||||
# we have to make a copy because the caller expects to free the result
|
||||
p = cdll.msvcrt._strdup(res)
|
||||
return p
|
||||
|
||||
Reference in New Issue
Block a user