mirror of
https://github.com/wassname/pyreadline.git
synced 2026-06-27 16:10:38 +08:00
Merging refactoring branch
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.
|
||||
#*****************************************************************************
|
||||
import unicode_helper,logger,clipboard,lineeditor,modes
|
||||
import unicode_helper, logger, clipboard, lineeditor, modes
|
||||
from rlmain import *
|
||||
import rlmain
|
||||
__all__ = [ 'parse_and_bind',
|
||||
@@ -27,6 +27,9 @@ __all__ = [ 'parse_and_bind',
|
||||
'set_completer_delims',
|
||||
'get_completer_delims',
|
||||
'add_history',
|
||||
'callback_handler_install',
|
||||
'callback_handler_remove',
|
||||
'callback_read_char',
|
||||
'GetOutputFile',
|
||||
'rl',
|
||||
'rlmain']
|
||||
|
||||
@@ -1,18 +1,17 @@
|
||||
import sys
|
||||
success=False
|
||||
in_ironpython="IronPython" in sys.version
|
||||
success = True
|
||||
in_ironpython = u"IronPython" in sys.version
|
||||
if in_ironpython:
|
||||
try:
|
||||
from ironpython_clipboard import GetClipboardText,SetClipboardText
|
||||
success=True
|
||||
from ironpython_clipboard import GetClipboardText, SetClipboardText
|
||||
except ImportError:
|
||||
pass
|
||||
from no_clipboard import GetClipboardText, SetClipboardText
|
||||
|
||||
else:
|
||||
try:
|
||||
from win32_clipboard import GetClipboardText,SetClipboardText
|
||||
success=True
|
||||
from win32_clipboard import GetClipboardText, SetClipboardText
|
||||
except ImportError:
|
||||
raise
|
||||
from no_clipboard import GetClipboardText, SetClipboardText
|
||||
|
||||
|
||||
def send_data(lists):
|
||||
@@ -23,15 +22,15 @@ def set_clipboard_text(toclipboard):
|
||||
SetClipboardText(str(toclipboard))
|
||||
|
||||
def make_tab(lists):
|
||||
if hasattr(lists,"tolist"):
|
||||
lists=lists.tolist()
|
||||
ut=[]
|
||||
if hasattr(lists, u"tolist"):
|
||||
lists = lists.tolist()
|
||||
ut = []
|
||||
for rad in lists:
|
||||
if type(rad) in [list,tuple]:
|
||||
ut.append("\t".join(["%s"%x for x in rad]))
|
||||
if type(rad) in [list, tuple]:
|
||||
ut.append(u"\t".join([u"%s"%x for x in rad]))
|
||||
else:
|
||||
ut.append("%s"%rad)
|
||||
return "\n".join(ut)
|
||||
ut.append(u"%s"%rad)
|
||||
return u"\n".join(ut)
|
||||
|
||||
def make_list_of_list(txt):
|
||||
def make_num(x):
|
||||
@@ -46,28 +45,28 @@ def make_list_of_list(txt):
|
||||
except ValueError:
|
||||
return x
|
||||
return x
|
||||
ut=[]
|
||||
flag=False
|
||||
for rad in [x for x in txt.split("\r\n") if x!=""]:
|
||||
raden=[make_num(x) for x in rad.split("\t")]
|
||||
ut = []
|
||||
flag = False
|
||||
for rad in [x for x in txt.split(u"\r\n") if x != u""]:
|
||||
raden=[make_num(x) for x in rad.split(u"\t")]
|
||||
if str in map(type,raden):
|
||||
flag=True
|
||||
flag = True
|
||||
ut.append(raden)
|
||||
return ut,flag
|
||||
return ut, flag
|
||||
|
||||
|
||||
def get_clipboard_text_and_convert(paste_list=False):
|
||||
"""Get txt from clipboard. if paste_list==True the convert tab separated
|
||||
u"""Get txt from clipboard. if paste_list==True the convert tab separated
|
||||
data to list of lists. Enclose list of list in array() if all elements are
|
||||
numeric"""
|
||||
txt=GetClipboardText()
|
||||
txt = GetClipboardText()
|
||||
if txt:
|
||||
if paste_list and "\t" in txt:
|
||||
array,flag=make_list_of_list(txt)
|
||||
if paste_list and u"\t" in txt:
|
||||
array, flag = make_list_of_list(txt)
|
||||
if flag:
|
||||
txt=repr(array)
|
||||
txt = repr(array)
|
||||
else:
|
||||
txt="array(%s)"%repr(array)
|
||||
txt="".join([c for c in txt if c not in " \t\r\n"])
|
||||
txt = u"array(%s)"%repr(array)
|
||||
txt = u"".join([c for c in txt if c not in u" \t\r\n"])
|
||||
return txt
|
||||
|
||||
|
||||
@@ -6,21 +6,21 @@
|
||||
# the file COPYING, distributed as part of this software.
|
||||
#*****************************************************************************
|
||||
import clr
|
||||
clr.AddReferenceByPartialName("System.Windows.Forms")
|
||||
clr.AddReferenceByPartialName(u"System.Windows.Forms")
|
||||
import System.Windows.Forms.Clipboard as cb
|
||||
|
||||
def GetClipboardText():
|
||||
text=""
|
||||
text = ""
|
||||
if cb.ContainsText():
|
||||
text=cb.GetText()
|
||||
text = cb.GetText()
|
||||
|
||||
return text
|
||||
|
||||
def SetClipboardText(text):
|
||||
cb.SetText(text)
|
||||
|
||||
if __name__ == '__main__':
|
||||
txt=GetClipboardText() # display last text clipped
|
||||
if __name__ == u'__main__':
|
||||
txt = GetClipboardText() # display last text clipped
|
||||
print txt
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#*****************************************************************************
|
||||
# Copyright (C) 2006 Jorgen Stenarson. <jorgen.stenarson@bostream.nu>
|
||||
#
|
||||
# Distributed under the terms of the BSD License. The full license is in
|
||||
# the file COPYING, distributed as part of this software.
|
||||
#*****************************************************************************
|
||||
|
||||
|
||||
mybuffer = u""
|
||||
|
||||
def GetClipboardText():
|
||||
return mybuffer
|
||||
|
||||
def SetClipboardText(text):
|
||||
global mybuffer
|
||||
mybuffer = text
|
||||
|
||||
@@ -37,44 +37,50 @@ from pyreadline.keysyms.winconstants import CF_TEXT, GHND
|
||||
from pyreadline.unicode_helper import ensure_unicode,ensure_str
|
||||
|
||||
OpenClipboard = windll.user32.OpenClipboard
|
||||
EmptyClipboard = windll.user32.EmptyClipboard
|
||||
GetClipboardData = windll.user32.GetClipboardData
|
||||
GetClipboardFormatName = windll.user32.GetClipboardFormatNameA
|
||||
SetClipboardData = windll.user32.SetClipboardData
|
||||
EnumClipboardFormats = windll.user32.EnumClipboardFormats
|
||||
CloseClipboard = windll.user32.CloseClipboard
|
||||
OpenClipboard.argtypes=[c_int]
|
||||
EnumClipboardFormats.argtypes=[c_int]
|
||||
CloseClipboard.argtypes=[]
|
||||
GetClipboardFormatName.argtypes=[c_uint,c_char_p,c_int]
|
||||
GetClipboardData.argtypes=[c_int]
|
||||
SetClipboardData.argtypes=[c_int,c_int]
|
||||
OpenClipboard.argtypes = [c_int]
|
||||
|
||||
EmptyClipboard = windll.user32.EmptyClipboard
|
||||
|
||||
GetClipboardData = windll.user32.GetClipboardData
|
||||
GetClipboardData.argtypes = [c_int]
|
||||
|
||||
GetClipboardFormatName = windll.user32.GetClipboardFormatNameA
|
||||
GetClipboardFormatName.argtypes = [c_uint,c_char_p,c_int]
|
||||
|
||||
SetClipboardData = windll.user32.SetClipboardData
|
||||
SetClipboardData.argtypes = [c_int,c_int]
|
||||
|
||||
EnumClipboardFormats = windll.user32.EnumClipboardFormats
|
||||
EnumClipboardFormats.argtypes = [c_int]
|
||||
|
||||
CloseClipboard = windll.user32.CloseClipboard
|
||||
CloseClipboard.argtypes = []
|
||||
|
||||
|
||||
GlobalLock = windll.kernel32.GlobalLock
|
||||
GlobalAlloc = windll.kernel32.GlobalAlloc
|
||||
GlobalLock = windll.kernel32.GlobalLock
|
||||
GlobalLock.argtypes = [c_int]
|
||||
GlobalUnlock = windll.kernel32.GlobalUnlock
|
||||
GlobalLock.argtypes=[c_int]
|
||||
GlobalUnlock.argtypes=[c_int]
|
||||
GlobalUnlock.argtypes = [c_int]
|
||||
memcpy = cdll.msvcrt.memcpy
|
||||
|
||||
def enum():
|
||||
OpenClipboard(0)
|
||||
q=EnumClipboardFormats(0)
|
||||
q = EnumClipboardFormats(0)
|
||||
while q:
|
||||
print q,
|
||||
q=EnumClipboardFormats(q)
|
||||
q = EnumClipboardFormats(q)
|
||||
CloseClipboard()
|
||||
|
||||
def getformatname(format):
|
||||
buffer = c_buffer(" "*100)
|
||||
bufferSize = sizeof(buffer)
|
||||
OpenClipboard(0)
|
||||
GetClipboardFormatName(format,buffer,bufferSize)
|
||||
GetClipboardFormatName(format, buffer, bufferSize)
|
||||
CloseClipboard()
|
||||
return buffer.value
|
||||
|
||||
def GetClipboardText():
|
||||
text = ""
|
||||
text = u""
|
||||
if OpenClipboard(0):
|
||||
hClipMem = GetClipboardData(CF_TEXT)
|
||||
if hClipMem:
|
||||
@@ -97,6 +103,6 @@ def SetClipboardText(text):
|
||||
SetClipboardData(c_int(CF_TEXT), c_int(hGlobalMem))
|
||||
CloseClipboard()
|
||||
|
||||
if __name__ == '__main__':
|
||||
txt=GetClipboardText() # display last text clipped
|
||||
if __name__ == u'__main__':
|
||||
txt = GetClipboardText() # display last text clipped
|
||||
print txt
|
||||
|
||||
@@ -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")
|
||||
|
||||
+88
-79
@@ -1,124 +1,126 @@
|
||||
# -*- coding: ISO-8859-1 -*-
|
||||
import re,sys,os
|
||||
|
||||
terminal_escape = re.compile('(\001?\033\\[[0-9;]*m\002?)')
|
||||
escape_parts = re.compile('\001?\033\\[([0-9;]*)m\002?')
|
||||
terminal_escape = re.compile(u'(\001?\033\\[[0-9;]*m\002?)')
|
||||
escape_parts = re.compile(u'\001?\033\\[([0-9;]*)m\002?')
|
||||
|
||||
|
||||
class AnsiState(object):
|
||||
def __init__(self,bold=False,inverse=False,color="white",background="black",backgroundbold=False):
|
||||
self.bold=bold
|
||||
self.inverse=inverse
|
||||
self.color=color
|
||||
self.background=background
|
||||
self.backgroundbold=backgroundbold
|
||||
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
|
||||
|
||||
trtable={"black":0,"red":4,"green":2,"yellow":6,"blue":1,"magenta":5,"cyan":3,"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 '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,"white")
|
||||
|
||||
trtable={0:"black",1:"red",2:"green",3:"yellow",4:"blue",5:"magenta",6:"cyan",7:"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):
|
||||
'''write text at current cursor position and interpret color escapes.
|
||||
u'''write text at current cursor position and interpret color escapes.
|
||||
|
||||
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(";")
|
||||
if len(parts)==1 and parts[0]=="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:
|
||||
if part == "0": # No text attribute
|
||||
if part == u"0": # No text attribute
|
||||
attr = self.defaultstate.copy()
|
||||
attr.bold=False
|
||||
elif part == "7": # switch on reverse
|
||||
elif part == u"7": # switch on reverse
|
||||
attr.inverse=True
|
||||
elif part == "1": # switch on bold (i.e. intensify foreground color)
|
||||
elif part == u"1": # switch on bold (i.e. intensify foreground color)
|
||||
attr.bold=True
|
||||
elif len(part) == 2 and "30" <= part <= "37": # set foreground color
|
||||
attr.color = trtable[int(part)-30]
|
||||
elif len(part) == 2 and "40" <= part <= "47": # set background color
|
||||
attr.backgroundcolor = trtable[int(part)-40]
|
||||
elif len(part) == 2 and u"30" <= part <= u"37": # set foreground color
|
||||
attr.color = trtable[int(part) - 30]
|
||||
elif len(part) == 2 and u"40" <= part <= u"47": # set background color
|
||||
attr.backgroundcolor = 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):
|
||||
'''write text at current cursor position and interpret color escapes.
|
||||
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
|
||||
@@ -126,56 +128,63 @@ def write_color_old( text, attr=None):
|
||||
for chunk in chunks:
|
||||
m = escape_parts.match(chunk)
|
||||
if m:
|
||||
for part in m.group(1).split(";"):
|
||||
if part == "0": # No text attribute
|
||||
for part in m.group(1).split(u";"):
|
||||
if part == u"0": # No text attribute
|
||||
attr = 0
|
||||
elif part == "7": # switch on reverse
|
||||
elif part == u"7": # switch on reverse
|
||||
attr |= 0x4000
|
||||
if part == "1": # switch on bold (i.e. intensify foreground color)
|
||||
if part == u"1": # switch on bold (i.e. intensify foreground color)
|
||||
attr |= 0x08
|
||||
elif len(part) == 2 and "30" <= part <= "37": # set foreground color
|
||||
elif len(part) == 2 and u"30" <= part <= u"37": # set foreground color
|
||||
part = int(part)-30
|
||||
# we have to mirror bits
|
||||
attr = (attr & ~0x07) | ((part & 0x1) << 2) | (part & 0x2) | ((part & 0x4) >> 2)
|
||||
elif len(part) == 2 and "40" <= part <= "47": # set background color
|
||||
part = int(part)-40
|
||||
elif len(part) == 2 and u"40" <= part <= u"47": # set background color
|
||||
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(("0x%x"%attr,chunk))
|
||||
res.append((u"0x%x"%attr, chunk))
|
||||
return res
|
||||
|
||||
|
||||
#trtable={0:"black",1:"red",2:"green",3:"yellow",4:"blue",5:"magenta",6:"cyan",7:"white"}
|
||||
|
||||
if __name__=="__main__":
|
||||
if __name__==u"__main__x":
|
||||
import pprint
|
||||
pprint=pprint.pprint
|
||||
|
||||
s="\033[0;31mred\033[0;32mgreen\033[0;33myellow\033[0;34mblue\033[0;35mmagenta\033[0;36mcyan\033[0;37mwhite\033[0m"
|
||||
s=u"\033[0;31mred\033[0;32mgreen\033[0;33myellow\033[0;34mblue\033[0;35mmagenta\033[0;36mcyan\033[0;37mwhite\033[0m"
|
||||
pprint (write_color(s))
|
||||
pprint (write_color_old(s))
|
||||
s="\033[1;31mred\033[1;32mgreen\033[1;33myellow\033[1;34mblue\033[1;35mmagenta\033[1;36mcyan\033[1;37mwhite\033[0m"
|
||||
s=u"\033[1;31mred\033[1;32mgreen\033[1;33myellow\033[1;34mblue\033[1;35mmagenta\033[1;36mcyan\033[1;37mwhite\033[0m"
|
||||
pprint (write_color(s))
|
||||
pprint (write_color_old(s))
|
||||
|
||||
s="\033[0;7;31mred\033[0;7;32mgreen\033[0;7;33myellow\033[0;7;34mblue\033[0;7;35mmagenta\033[0;7;36mcyan\033[0;7;37mwhite\033[0m"
|
||||
s=u"\033[0;7;31mred\033[0;7;32mgreen\033[0;7;33myellow\033[0;7;34mblue\033[0;7;35mmagenta\033[0;7;36mcyan\033[0;7;37mwhite\033[0m"
|
||||
pprint (write_color(s))
|
||||
pprint (write_color_old(s))
|
||||
s="\033[1;7;31mred\033[1;7;32mgreen\033[1;7;33myellow\033[1;7;34mblue\033[1;7;35mmagenta\033[1;7;36mcyan\033[1;7;37mwhite\033[0m"
|
||||
s=u"\033[1;7;31mred\033[1;7;32mgreen\033[1;7;33myellow\033[1;7;34mblue\033[1;7;35mmagenta\033[1;7;36mcyan\033[1;7;37mwhite\033[0m"
|
||||
pprint (write_color(s))
|
||||
pprint (write_color_old(s))
|
||||
|
||||
|
||||
if __name__=="__main__":
|
||||
if __name__==u"__main__":
|
||||
import console
|
||||
import pprint
|
||||
pprint=pprint.pprint
|
||||
|
||||
c=console.Console()
|
||||
c.write_color("dhsjdhs")
|
||||
c.write_color("\033[0;32mIn [\033[1;32m1\033[0;32m]:")
|
||||
c.write_color(u"dhsjdhs")
|
||||
c.write_color(u"\033[0;32mIn [\033[1;32m1\033[0;32m]:")
|
||||
print
|
||||
pprint (write_color("\033[0;32mIn [\033[1;32m1\033[0;32m]:"))
|
||||
pprint (write_color(u"\033[0;32mIn [\033[1;32m1\033[0;32m]:"))
|
||||
|
||||
if __name__==u"__main__x":
|
||||
import pprint
|
||||
pprint=pprint.pprint
|
||||
s=u"\033[0;31mred\033[0;32mgreen\033[0;33myellow\033[0;34mblue\033[0;35mmagenta\033[0;36mcyan\033[0;37mwhite\033[0m"
|
||||
pprint (write_color(s))
|
||||
|
||||
+180
-152
@@ -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.
|
||||
'''
|
||||
@@ -16,18 +16,25 @@ This was modeled after the C extension of the same name by Fredrik Lundh.
|
||||
import sys,os
|
||||
import traceback
|
||||
import re
|
||||
from pyreadline.logger import log,log_sock
|
||||
from pyreadline.unicode_helper import ensure_unicode,ensure_str
|
||||
|
||||
import pyreadline.unicode_helper as unicode_helper
|
||||
|
||||
from pyreadline.logger import log
|
||||
from pyreadline.unicode_helper import ensure_unicode, ensure_str
|
||||
from pyreadline.keysyms import make_KeyPress, KeyPress
|
||||
from pyreadline.console.ansi import AnsiState,AnsiWriter
|
||||
|
||||
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")
|
||||
|
||||
def nolog(string):
|
||||
pass
|
||||
|
||||
log = nolog
|
||||
|
||||
# my code
|
||||
from pyreadline.keysyms import make_KeyPress
|
||||
from pyreadline.console.ansi import AnsiState,AnsiWriter
|
||||
|
||||
# some constants we need
|
||||
STD_INPUT_HANDLE = -10
|
||||
@@ -149,24 +156,24 @@ 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)]
|
||||
|
||||
|
||||
|
||||
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.
|
||||
@@ -177,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)
|
||||
@@ -192,25 +200,26 @@ 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:
|
||||
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.inputHookPtr = c_int.from_address(addressof(self.pythondll.PyOS_InputHook)).value
|
||||
setattr(Console, 'PyMem_Malloc', self.pythondll.PyMem_Malloc)
|
||||
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):
|
||||
'''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)
|
||||
@@ -225,7 +234,8 @@ 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))
|
||||
@@ -233,52 +243,53 @@ 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):
|
||||
'''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))
|
||||
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):
|
||||
'''Move to home.'''
|
||||
self.pos(0,0)
|
||||
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
|
||||
@@ -297,22 +308,21 @@ class Console(object):
|
||||
# split the string into ordinary characters and funny characters
|
||||
chunks = self.motion_char_re.split(text)
|
||||
for chunk in chunks:
|
||||
log('C:'+chunk)
|
||||
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
|
||||
x = 8*(int(x/8)+1)
|
||||
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
|
||||
@@ -336,39 +346,44 @@ 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(unicode(attr))
|
||||
log(unicode(chunk))
|
||||
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):
|
||||
'''write text at current cursor position.'''
|
||||
log('write("%s", %s)' %(text,attr))
|
||||
u'''write text at current cursor position.'''
|
||||
text = ensure_unicode(text)
|
||||
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
|
||||
#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):
|
||||
text = ensure_str(text)
|
||||
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
|
||||
|
||||
# make this class look like a file object
|
||||
def write(self, text):
|
||||
log('write("%s")' % text)
|
||||
text = ensure_unicode(text)
|
||||
log(u'write("%s")' % text)
|
||||
return self.write_color(text)
|
||||
|
||||
#write = write_scrolling
|
||||
@@ -379,8 +394,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:
|
||||
@@ -393,61 +408,65 @@ 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
|
||||
|
||||
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
|
||||
|
||||
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=' '):
|
||||
'''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:
|
||||
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=' '):
|
||||
'''Scroll a rectangle.'''
|
||||
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 = fill[0]
|
||||
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):
|
||||
'''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
|
||||
@@ -464,12 +483,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()
|
||||
@@ -477,52 +496,58 @@ 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_sock(ensure_unicode(e.keyinfo),"keypress")
|
||||
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(e)
|
||||
if e.keyinfo.keyname == 'next':
|
||||
if e.type == u'KeyPress' and e.keycode not in key_modifiers:
|
||||
log(u"console.getkeypress %s"%e)
|
||||
if e.keyinfo.keyname == u'next':
|
||||
self.scroll_window(12)
|
||||
elif e.keyinfo.keyname == 'prior':
|
||||
elif e.keyinfo.keyname == u'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 == KeyPress('S', False, True, False, 'S'))):
|
||||
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)
|
||||
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
|
||||
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))
|
||||
status = self.PeekConsoleInputW(self.hin,
|
||||
byref(Cevent), 1, byref(count))
|
||||
if status and count == 1:
|
||||
return event(self, Cevent)
|
||||
|
||||
def title(self, txt=None):
|
||||
'''Set/get title.'''
|
||||
u'''Set/get title.'''
|
||||
if txt:
|
||||
self.SetConsoleTitleW(txt)
|
||||
else:
|
||||
@@ -532,7 +557,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:
|
||||
@@ -544,12 +569,13 @@ 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)
|
||||
|
||||
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:
|
||||
@@ -559,18 +585,18 @@ 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
|
||||
|
||||
# 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
|
||||
|
||||
@@ -578,52 +604,53 @@ 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
|
||||
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:
|
||||
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):
|
||||
"""Get a console handle.
|
||||
|
||||
@@ -655,62 +682,63 @@ 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):
|
||||
'''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)
|
||||
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):
|
||||
'''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
|
||||
|
||||
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)
|
||||
@@ -732,11 +760,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
|
||||
|
||||
@@ -6,18 +6,18 @@ class baseconsole:
|
||||
raise NotImplementedError
|
||||
|
||||
def pos(self, x=None, y=None):
|
||||
'''Move or query the window cursor.'''
|
||||
u'''Move or query the window cursor.'''
|
||||
raise NotImplementedError
|
||||
|
||||
def size(self):
|
||||
raise NotImplementedError
|
||||
|
||||
def rectangle(self, rect, attr=None, fill=' '):
|
||||
'''Fill Rectangle.'''
|
||||
def rectangle(self, rect, attr=None, fill=u' '):
|
||||
u'''Fill Rectangle.'''
|
||||
raise NotImplementedError
|
||||
|
||||
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
|
||||
@@ -33,14 +33,14 @@ class baseconsole:
|
||||
raise NotImplementedError
|
||||
|
||||
def getkeypress(self):
|
||||
'''Return next key press event from the queue, ignoring others.'''
|
||||
u'''Return next key press event from the queue, ignoring others.'''
|
||||
raise NotImplementedError
|
||||
|
||||
def write(self, text):
|
||||
raise NotImplementedError
|
||||
|
||||
def page(self, attr=None, fill=' '):
|
||||
'''Fill the entire screen.'''
|
||||
u'''Fill the entire screen.'''
|
||||
raise NotImplementedError
|
||||
|
||||
def isatty(self):
|
||||
|
||||
+11
-10
@@ -1,23 +1,24 @@
|
||||
class Event(object):
|
||||
'''Represent events from the console.'''
|
||||
u'''Represent events from the console.'''
|
||||
def __init__(self, console, input):
|
||||
pass
|
||||
|
||||
def __repr__(self):
|
||||
'''Display an event for debugging.'''
|
||||
if self.type in ['KeyPress', 'KeyRelease']:
|
||||
chr=self.char
|
||||
if ord(chr)<ord("A"):
|
||||
chr="?"
|
||||
u'''Display an event for debugging.'''
|
||||
if self.type in [u'KeyPress', u'KeyRelease']:
|
||||
chr = self.char
|
||||
if ord(chr)<ord(u"A"):
|
||||
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)
|
||||
elif self.type in ['Motion', 'Button']:
|
||||
elif self.type in [u'Motion', u'Button']:
|
||||
s = u'%s x=%d y=%d state=%x' % (self.type, self.x, self.y, self.state)
|
||||
elif self.type == 'Configure':
|
||||
elif self.type == u'Configure':
|
||||
s = u'%s w=%d h=%d' % (self.type, self.width, self.height)
|
||||
elif self.type in ['FocusIn', 'FocusOut']:
|
||||
elif self.type in [u'FocusIn', u'FocusOut']:
|
||||
s = self.type
|
||||
elif self.type == 'Menu':
|
||||
elif self.type == u'Menu':
|
||||
s = u'%s state=%x' % (self.type, self.state)
|
||||
else:
|
||||
s = u'unknown event type'
|
||||
|
||||
@@ -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 .NET console.
|
||||
u'''Cursor control and color for the .NET console.
|
||||
'''
|
||||
|
||||
#
|
||||
@@ -35,100 +35,101 @@ import os
|
||||
import System
|
||||
|
||||
from event import Event
|
||||
from pyreadline.logger import log,log_sock
|
||||
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={"0;30": color.Black,
|
||||
"0;31": color.DarkRed,
|
||||
"0;32": color.DarkGreen,
|
||||
"0;33": color.DarkYellow,
|
||||
"0;34": color.DarkBlue,
|
||||
"0;35": color.DarkMagenta,
|
||||
"0;36": color.DarkCyan,
|
||||
"0;37": color.DarkGray,
|
||||
"1;30": color.Gray,
|
||||
"1;31": color.Red,
|
||||
"1;32": color.Green,
|
||||
"1;33": color.Yellow,
|
||||
"1;34": color.Blue,
|
||||
"1;35": color.Magenta,
|
||||
"1;36": color.Cyan,
|
||||
"1;37": color.White
|
||||
ansicolor={u"0;30": color.Black,
|
||||
u"0;31": color.DarkRed,
|
||||
u"0;32": color.DarkGreen,
|
||||
u"0;33": color.DarkYellow,
|
||||
u"0;34": color.DarkBlue,
|
||||
u"0;35": color.DarkMagenta,
|
||||
u"0;36": color.DarkCyan,
|
||||
u"0;37": color.DarkGray,
|
||||
u"1;30": color.Gray,
|
||||
u"1;31": color.Red,
|
||||
u"1;32": color.Green,
|
||||
u"1;33": color.Yellow,
|
||||
u"1;34": color.Blue,
|
||||
u"1;35": color.Magenta,
|
||||
u"1;36": color.Cyan,
|
||||
u"1;37": color.White
|
||||
}
|
||||
|
||||
winattr={"black":0,"darkgray":0+8,
|
||||
"darkred":4,"red":4+8,
|
||||
"darkgreen":2,"green":2+8,
|
||||
"darkyellow":6,"yellow":6+8,
|
||||
"darkblue":1,"blue":1+8,
|
||||
"darkmagenta":5, "magenta":5+8,
|
||||
"darkcyan":3,"cyan":3+8,
|
||||
"gray":7,"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):
|
||||
'''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.
|
||||
'''
|
||||
self.serial=0
|
||||
self.serial = 0
|
||||
self.attr = System.Console.ForegroundColor
|
||||
self.saveattr = winattr[str(System.Console.ForegroundColor).lower()]
|
||||
self.savebg=System.Console.BackgroundColor
|
||||
log('initial attr=%s' % self.attr)
|
||||
log_sock("%s"%self.saveattr)
|
||||
self.savebg = System.Console.BackgroundColor
|
||||
log(u'initial attr=%s' % self.attr)
|
||||
|
||||
def _get(self):
|
||||
top=System.Console.WindowTop
|
||||
log_sock("WindowTop:%s"%top,"console")
|
||||
top = System.Console.WindowTop
|
||||
log(u"WindowTop:%s"%top)
|
||||
return top
|
||||
def _set(self,value):
|
||||
top=System.Console.WindowTop
|
||||
log_sock("Set WindowTop:old:%s,new:%s"%(top,value),"console")
|
||||
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):
|
||||
'''Cleanup the console when finished.'''
|
||||
u'''Cleanup the console when finished.'''
|
||||
# I don't think this ever gets called
|
||||
pass
|
||||
|
||||
def pos(self, x=None, y=None):
|
||||
'''Move or query the window cursor.'''
|
||||
u'''Move or query the window cursor.'''
|
||||
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):
|
||||
'''Move to home.'''
|
||||
self.pos(0,0)
|
||||
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?')
|
||||
terminal_escape = re.compile(u'(\001?\033\\[[0-9;]*m\002?)')
|
||||
escape_parts = re.compile(u'\001?\033\\[([0-9;]*)m\002?')
|
||||
|
||||
# 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
|
||||
@@ -148,22 +149,21 @@ class Console(object):
|
||||
# split the string into ordinary characters and funny characters
|
||||
chunks = self.motion_char_re.split(text)
|
||||
for chunk in chunks:
|
||||
log('C:'+chunk)
|
||||
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
|
||||
x = 8*(int(x/8)+1)
|
||||
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
|
||||
@@ -185,44 +185,45 @@ 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.
|
||||
|
||||
return the number of characters written.
|
||||
'''
|
||||
log('write_color("%s", %s)' % (text, attr))
|
||||
log(u'write_color("%s", %s)' % (text, attr))
|
||||
chunks = self.terminal_escape.split(text)
|
||||
log('chunks=%s' % repr(chunks))
|
||||
bg=self.savebg
|
||||
log(u'chunks=%s' % repr(chunks))
|
||||
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):
|
||||
'''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)
|
||||
@@ -230,7 +231,7 @@ class Console(object):
|
||||
self.WriteConsoleA(self.hout, text, len(text), byref(n), None)
|
||||
return len(text)
|
||||
|
||||
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)
|
||||
@@ -239,7 +240,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
|
||||
@@ -250,112 +251,107 @@ 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.'''
|
||||
System.Console.Clear()
|
||||
|
||||
def text(self, x, y, text, attr=None):
|
||||
'''Write text at the given position.'''
|
||||
self.pos(x,y)
|
||||
self.write_color(text,attr)
|
||||
u'''Write text at the given position.'''
|
||||
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*" ")
|
||||
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=' '):
|
||||
'''Fill Rectangle.'''
|
||||
pass
|
||||
oldtop=self.WindowTop
|
||||
oldpos=self.pos()
|
||||
def rectangle(self, rect, attr=None, fill=u' '):
|
||||
u'''Fill Rectangle.'''
|
||||
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=' '*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=' '):
|
||||
'''Scroll a rectangle.'''
|
||||
pass
|
||||
u'''Scroll a rectangle.'''
|
||||
raise NotImplementedError
|
||||
|
||||
def scroll_window(self, lines):
|
||||
'''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
|
||||
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
|
||||
|
||||
def getkeypress(self):
|
||||
'''Return next key press event from the queue, ignoring others.'''
|
||||
ck=System.ConsoleKey
|
||||
u'''Return next key press event from the queue, ignoring others.'''
|
||||
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)=="\000":#Drop deadkeys
|
||||
log_sock("Deadkey: %s"%e)
|
||||
return event(self,e)
|
||||
pass
|
||||
elif str(e.KeyChar) == u"\000":#Drop deadkeys
|
||||
log(u"Deadkey: %s"%e)
|
||||
return event(self, e)
|
||||
else:
|
||||
return event(self,e)
|
||||
return event(self, e)
|
||||
|
||||
def title(self, txt=None):
|
||||
'''Set/get title.'''
|
||||
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):
|
||||
'''Set/get window size.'''
|
||||
sc=System.Console
|
||||
|
||||
|
||||
u'''Set/get window size.'''
|
||||
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):
|
||||
'''Set cursor on or off.'''
|
||||
System.Console.CursorVisible=visible
|
||||
u'''Set cursor on or off.'''
|
||||
System.Console.CursorVisible = visible
|
||||
|
||||
def bell(self):
|
||||
System.Console.Beep()
|
||||
|
||||
def next_serial(self):
|
||||
'''Get next event serial number.'''
|
||||
u'''Get next event serial number.'''
|
||||
self.serial += 1
|
||||
return self.serial
|
||||
|
||||
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 = '??'
|
||||
u'''Initialize an event from the Windows input structure.'''
|
||||
self.type = u'??'
|
||||
self.serial = console.next_serial()
|
||||
self.width = 0
|
||||
self.height = 0
|
||||
@@ -364,65 +360,65 @@ class event(Event):
|
||||
self.char = str(input.KeyChar)
|
||||
self.keycode = input.Key
|
||||
self.state = input.Modifiers
|
||||
log_sock("%s,%s,%s"%(input.Modifiers,input.Key,input.KeyChar),"console")
|
||||
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="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("Control-c")
|
||||
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=""
|
||||
res = u""
|
||||
except EOFError:
|
||||
return None
|
||||
if res[-1:]=="\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()
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
if __name__ == u'__main__':
|
||||
import time, sys
|
||||
c = Console(0)
|
||||
sys.stdout = c
|
||||
sys.stderr = c
|
||||
c.page()
|
||||
c.pos(5, 10)
|
||||
c.write('hi there')
|
||||
c.title("Testing console")
|
||||
c.write(u'hi there')
|
||||
c.title(u"Testing console")
|
||||
# c.bell()
|
||||
print
|
||||
print "size",c.size()
|
||||
print ' some printed output'
|
||||
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()
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
u'''
|
||||
Example script using the callback interface of readline.
|
||||
|
||||
:author: strank
|
||||
'''
|
||||
|
||||
__docformat__ = u"restructuredtext en"
|
||||
|
||||
import sys
|
||||
import os
|
||||
import time
|
||||
|
||||
import readline
|
||||
|
||||
import msvcrt
|
||||
from pyreadline.rlmain import rl
|
||||
|
||||
prompting = True
|
||||
count = 0
|
||||
maxlines = 10
|
||||
|
||||
|
||||
def main():
|
||||
readline.callback_handler_install(u'Starting test, please do type:' + os.linesep, lineReceived)
|
||||
index = 0
|
||||
start = int(time.time())
|
||||
while prompting:
|
||||
# demonstrate that async stuff is possible:
|
||||
if start + index < time.time():
|
||||
rl.console.title(u"NON-BLOCKING: %d" % index)
|
||||
index += 1
|
||||
# ugly busy waiting/polling on windows, using 'select' on Unix: (or use twisted)
|
||||
if msvcrt.kbhit():
|
||||
readline.callback_read_char()
|
||||
print u"Done, index =", index
|
||||
|
||||
|
||||
def lineReceived(line):
|
||||
global count, prompting
|
||||
count += 1
|
||||
print u"Got line: %s" % line
|
||||
if count > maxlines:
|
||||
prompting = False
|
||||
readline.callback_handler_remove()
|
||||
else:
|
||||
readline.callback_handler_install(u'Got %s of %s, more typing please:' % (count, maxlines)
|
||||
+ os.linesep, lineReceived)
|
||||
|
||||
|
||||
|
||||
|
||||
if __name__ == u'__main__':
|
||||
main()
|
||||
@@ -0,0 +1,89 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#*****************************************************************************
|
||||
# Copyright (C) 2006 Jorgen Stenarson. <jorgen.stenarson@bostream.nu>
|
||||
#
|
||||
# Distributed under the terms of the BSD License. The full license is in
|
||||
# the file COPYING, distributed as part of this software.
|
||||
#*****************************************************************************
|
||||
|
||||
""" Mockup of gui-use of pyreadline
|
||||
|
||||
|
||||
"""
|
||||
from pyreadline.rlmain import BaseReadline
|
||||
from pyreadline.keysyms.common import KeyPress
|
||||
import pyreadline.logger as log
|
||||
log.sock_silent=False
|
||||
import Tkinter,sys
|
||||
|
||||
translate={"plus":"+","minus":"-","asterisk":"*","slash":"/","exclam":"!","quotedbl":'"',
|
||||
"parenleft":"(","parenright":")",}
|
||||
|
||||
|
||||
def KeyPress_from_event(event):
|
||||
keysym=event.keysym.lower()
|
||||
char=event.char
|
||||
if keysym in translate:
|
||||
keysym=translate[keysym]
|
||||
|
||||
shift=event.state&1!=0
|
||||
control=event.state&4!=0
|
||||
meta=event.state&(131072)!=0
|
||||
|
||||
if len(keysym)==1 and control and meta:
|
||||
keysym=""
|
||||
elif len(keysym)==1:
|
||||
char=keysym
|
||||
keysym=""
|
||||
|
||||
return KeyPress(char, shift, control, meta, keysym)
|
||||
|
||||
|
||||
class App:
|
||||
def __init__(self, master):
|
||||
self.frame=frame=Tkinter.Frame(master)
|
||||
frame.pack()
|
||||
self.lines=["Hello"]
|
||||
self.RL=BaseReadline()
|
||||
self.RL.read_inputrc()
|
||||
self.prompt=">>>"
|
||||
self.readline_setup(self.prompt)
|
||||
self.textvar = Tkinter.StringVar()
|
||||
self._update_line()
|
||||
self.text=Tkinter.Label(frame, textvariable=self.textvar,width=50,height=40,justify=Tkinter.LEFT,anchor=Tkinter.NW)
|
||||
self.text.pack(side=Tkinter.LEFT)
|
||||
master.bind("<Key>",self.handler)
|
||||
self.locals={}
|
||||
|
||||
def handler(self, event):
|
||||
keyevent=KeyPress_from_event(event)
|
||||
try:
|
||||
result=self.RL.process_keyevent(keyevent)
|
||||
except EOFError:
|
||||
self.frame.quit()
|
||||
return
|
||||
if result:
|
||||
self.lines.append(self.prompt+" "+self.RL.get_line_buffer())
|
||||
line=self.RL.get_line_buffer()
|
||||
if line.strip():
|
||||
try:
|
||||
result=eval(line, globals(), self.locals)
|
||||
self.lines.append(repr(result))
|
||||
except:
|
||||
self.lines.append("ERROR")
|
||||
self.readline_setup(self.prompt)
|
||||
self._update_line()
|
||||
|
||||
|
||||
def readline_setup(self, prompt=''):
|
||||
self.RL.readline_setup(prompt)
|
||||
|
||||
def _update_line(self):
|
||||
self.textvar.set("\n".join(self.lines+[self.prompt+" "+self.RL.get_line_buffer()]))
|
||||
|
||||
|
||||
|
||||
root=Tkinter.Tk()
|
||||
|
||||
display=App(root)
|
||||
root.mainloop()
|
||||
@@ -1,18 +1,18 @@
|
||||
import sys,textwrap
|
||||
|
||||
rlmain=sys.modules["pyreadline.rlmain"]
|
||||
rl=rlmain.rl
|
||||
rlmain = sys.modules[u"pyreadline.rlmain"]
|
||||
rl = rlmain.rl
|
||||
|
||||
def get_doc(rl):
|
||||
methods=[(x,getattr(rl,x)) for x in dir(rl) if callable(getattr(rl,x))]
|
||||
return [ (x,m.__doc__ )for x,m in methods if m.__doc__]
|
||||
methods = [(x, getattr(rl, x)) for x in dir(rl) if callable(getattr(rl, x))]
|
||||
return [ (x, m.__doc__ )for x, m in methods if m.__doc__]
|
||||
|
||||
|
||||
def get_rest(rl):
|
||||
q=get_doc(rl)
|
||||
out=[]
|
||||
for funcname,doc in q:
|
||||
q = get_doc(rl)
|
||||
out = []
|
||||
for funcname, doc in q:
|
||||
out.append(funcname)
|
||||
out.append("\n".join(textwrap.wrap(doc,80,initial_indent=" ")))
|
||||
out.append("")
|
||||
out.append(u"\n".join(textwrap.wrap(doc, 80, initial_indent=u" ")))
|
||||
out.append(u"")
|
||||
return out
|
||||
@@ -1,20 +1,20 @@
|
||||
import sys
|
||||
|
||||
success=False
|
||||
in_ironpython="IronPython" in sys.version
|
||||
success = False
|
||||
in_ironpython = u"IronPython" in sys.version
|
||||
|
||||
if in_ironpython:
|
||||
try:
|
||||
from ironpython_keysyms import *
|
||||
success=True
|
||||
except ImportError,x:
|
||||
success = True
|
||||
except ImportError, x:
|
||||
raise
|
||||
else:
|
||||
try:
|
||||
from keysyms import *
|
||||
success=True
|
||||
except ImportError,x:
|
||||
success = True
|
||||
except ImportError, x:
|
||||
pass
|
||||
|
||||
if not success:
|
||||
raise ImportError("Could not import keysym for local pythonversion",x)
|
||||
raise ImportError(u"Could not import keysym for local pythonversion", x)
|
||||
@@ -15,104 +15,113 @@ except NameError:
|
||||
|
||||
from pyreadline.unicode_helper import ensure_unicode
|
||||
|
||||
validkey =set(['cancel', 'backspace', 'tab', 'clear',
|
||||
'return', 'shift_l', 'control_l', 'alt_l',
|
||||
'pause', 'caps_lock', 'escape', 'space',
|
||||
'prior', 'next', 'end', 'home',
|
||||
'left', 'up', 'right', 'down',
|
||||
'select', 'print', 'execute', 'snapshot',
|
||||
'insert', 'delete', 'help', 'f1',
|
||||
'f2', 'f3', 'f4', 'f5',
|
||||
'f6', 'f7', 'f8', 'f9',
|
||||
'f10', 'f11', 'f12', 'f13',
|
||||
'f14', 'f15', 'f16', 'f17',
|
||||
'f18', 'f19', 'f20', 'f21',
|
||||
'f22', 'f23', 'f24', 'num_lock',
|
||||
'scroll_lock', 'vk_apps', 'vk_processkey','vk_attn',
|
||||
'vk_crsel', 'vk_exsel', 'vk_ereof', 'vk_play',
|
||||
'vk_zoom', 'vk_noname', 'vk_pa1', 'vk_oem_clear',
|
||||
'numpad0', 'numpad1', 'numpad2', 'numpad3',
|
||||
'numpad4', 'numpad5', 'numpad6', 'numpad7',
|
||||
'numpad8', 'numpad9', 'divide', 'multiply',
|
||||
'add', 'subtract', 'vk_decimal'])
|
||||
validkey =set([u'cancel', u'backspace', u'tab', u'clear',
|
||||
u'return', u'shift_l', u'control_l', u'alt_l',
|
||||
u'pause', u'caps_lock', u'escape', u'space',
|
||||
u'prior', u'next', u'end', u'home',
|
||||
u'left', u'up', u'right', u'down',
|
||||
u'select', u'print', u'execute', u'snapshot',
|
||||
u'insert', u'delete', u'help', u'f1',
|
||||
u'f2', u'f3', u'f4', u'f5',
|
||||
u'f6', u'f7', u'f8', u'f9',
|
||||
u'f10', u'f11', u'f12', u'f13',
|
||||
u'f14', u'f15', u'f16', u'f17',
|
||||
u'f18', u'f19', u'f20', u'f21',
|
||||
u'f22', u'f23', u'f24', u'num_lock',
|
||||
u'scroll_lock', u'vk_apps', u'vk_processkey',u'vk_attn',
|
||||
u'vk_crsel', u'vk_exsel', u'vk_ereof', u'vk_play',
|
||||
u'vk_zoom', u'vk_noname', u'vk_pa1', u'vk_oem_clear',
|
||||
u'numpad0', u'numpad1', u'numpad2', u'numpad3',
|
||||
u'numpad4', u'numpad5', u'numpad6', u'numpad7',
|
||||
u'numpad8', u'numpad9', u'divide', u'multiply',
|
||||
u'add', u'subtract', u'vk_decimal'])
|
||||
|
||||
escape_sequence_to_special_key={"\\e[a":"up","\\e[b":"down","del":"delete"}
|
||||
escape_sequence_to_special_key = {u"\\e[a" : u"up", u"\\e[b" : u"down", u"del" : u"delete"}
|
||||
|
||||
class KeyPress(object):
|
||||
def __init__(self,char="",shift=False,control=False,meta=False,keyname=""):
|
||||
def __init__(self, char=u"", shift=False, control=False, meta=False, keyname=u""):
|
||||
if control or meta or shift:
|
||||
char=char.upper()
|
||||
self.info=dict(char=char,
|
||||
shift=shift,
|
||||
control=control,
|
||||
meta=meta,
|
||||
keyname=keyname)
|
||||
char = char.upper()
|
||||
self.info = dict(char=char,
|
||||
shift=shift,
|
||||
control=control,
|
||||
meta=meta,
|
||||
keyname=keyname)
|
||||
|
||||
def create(name):
|
||||
def get(self):
|
||||
return self.info[name]
|
||||
def set(self,value):
|
||||
self.info[name]=value
|
||||
return property(get,set)
|
||||
char=create("char")
|
||||
shift=create("shift")
|
||||
control=create("control")
|
||||
meta=create("meta")
|
||||
keyname=create("keyname")
|
||||
|
||||
def set(self, value):
|
||||
self.info[name] = value
|
||||
return property(get, set)
|
||||
char = create(u"char")
|
||||
shift = create(u"shift")
|
||||
control = create(u"control")
|
||||
meta = create(u"meta")
|
||||
keyname = create(u"keyname")
|
||||
|
||||
def __repr__(self):
|
||||
return u"(%s,%s,%s,%s)"%tuple(map(ensure_unicode,self.tuple()))
|
||||
return u"(%s,%s,%s,%s)"%tuple(map(ensure_unicode, self.tuple()))
|
||||
|
||||
def tuple(self):
|
||||
if self.keyname:
|
||||
return (self.control,self.meta,self.shift,self.keyname)
|
||||
return (self.control, self.meta, self.shift, self.keyname)
|
||||
else:
|
||||
if self.control or self.meta or self.shift:
|
||||
return (self.control,self.meta,self.shift,self.char.upper())
|
||||
return (self.control, self.meta, self.shift, self.char.upper())
|
||||
else:
|
||||
return (self.control,self.meta,self.shift,self.char)
|
||||
return (self.control, self.meta, self.shift, self.char)
|
||||
|
||||
def __eq__(self, other):
|
||||
if isinstance(other, KeyPress):
|
||||
s = self.tuple()
|
||||
o = other.tuple()
|
||||
return s == o
|
||||
else:
|
||||
return False
|
||||
|
||||
def make_KeyPress_from_keydescr(keydescr):
|
||||
keyinfo=KeyPress()
|
||||
if len(keydescr)>2 and keydescr[:1]=='"' and keydescr[-1:]=='"':
|
||||
keydescr=keydescr[1:-1]
|
||||
keyinfo = KeyPress()
|
||||
if len(keydescr) > 2 and keydescr[:1] == u'"' and keydescr[-1:] == u'"':
|
||||
keydescr = keydescr[1:-1]
|
||||
|
||||
while 1:
|
||||
lkeyname = keydescr.lower()
|
||||
if lkeyname.startswith('control-'):
|
||||
if lkeyname.startswith(u'control-'):
|
||||
keyinfo.control = True
|
||||
keydescr = keydescr[8:]
|
||||
elif lkeyname.startswith('ctrl-'):
|
||||
elif lkeyname.startswith(u'ctrl-'):
|
||||
keyinfo.control = True
|
||||
keydescr = keydescr[5:]
|
||||
elif keydescr.lower().startswith('\\c-'):
|
||||
elif keydescr.lower().startswith(u'\\c-'):
|
||||
keyinfo.control = True
|
||||
keydescr = keydescr[3:]
|
||||
elif keydescr.lower().startswith('\\m-'):
|
||||
elif keydescr.lower().startswith(u'\\m-'):
|
||||
keyinfo.meta = True
|
||||
keydescr = keydescr[3:]
|
||||
elif keydescr in escape_sequence_to_special_key:
|
||||
keydescr = escape_sequence_to_special_key[keydescr]
|
||||
elif lkeyname.startswith('meta-'):
|
||||
elif lkeyname.startswith(u'meta-'):
|
||||
keyinfo.meta = True
|
||||
keydescr = keydescr[5:]
|
||||
elif lkeyname.startswith('alt-'):
|
||||
elif lkeyname.startswith(u'alt-'):
|
||||
keyinfo.meta = True
|
||||
keydescr = keydescr[4:]
|
||||
elif lkeyname.startswith('shift-'):
|
||||
elif lkeyname.startswith(u'shift-'):
|
||||
keyinfo.shift = True
|
||||
keydescr = keydescr[6:]
|
||||
else:
|
||||
if len(keydescr) > 1:
|
||||
if keydescr.strip().lower() in validkey:
|
||||
keyinfo.keyname=keydescr.strip().lower()
|
||||
keyinfo.char=""
|
||||
keyinfo.keyname = keydescr.strip().lower()
|
||||
keyinfo.char = ""
|
||||
else:
|
||||
raise IndexError("Not a valid key: '%s'"%keydescr)
|
||||
raise IndexError(u"Not a valid key: '%s'"%keydescr)
|
||||
else:
|
||||
keyinfo.char=keydescr
|
||||
keyinfo.char = keydescr
|
||||
return keyinfo
|
||||
|
||||
if __name__=="__main__":
|
||||
if __name__ == u"__main__":
|
||||
import startup
|
||||
|
||||
@@ -7,92 +7,92 @@
|
||||
# the file COPYING, distributed as part of this software.
|
||||
#*****************************************************************************
|
||||
import System
|
||||
from common import validkey,KeyPress,make_KeyPress_from_keydescr
|
||||
#from pyreadline.logger import log_sock
|
||||
c32=System.ConsoleKey
|
||||
Shift=System.ConsoleModifiers.Shift
|
||||
Control=System.ConsoleModifiers.Control
|
||||
Alt=System.ConsoleModifiers.Alt
|
||||
from common import validkey, KeyPress, make_KeyPress_from_keydescr
|
||||
|
||||
c32 = System.ConsoleKey
|
||||
Shift = System.ConsoleModifiers.Shift
|
||||
Control = System.ConsoleModifiers.Control
|
||||
Alt = System.ConsoleModifiers.Alt
|
||||
# table for translating virtual keys to X windows key symbols
|
||||
code2sym_map = {#c32.CANCEL: 'Cancel',
|
||||
c32.Backspace: 'BackSpace',
|
||||
c32.Tab: 'Tab',
|
||||
c32.Clear: 'Clear',
|
||||
c32.Enter: 'Return',
|
||||
# c32.Shift: 'Shift_L',
|
||||
# c32.Control: 'Control_L',
|
||||
# c32.Menu: 'Alt_L',
|
||||
c32.Pause: 'Pause',
|
||||
# c32.Capital: 'Caps_Lock',
|
||||
c32.Escape: 'Escape',
|
||||
# c32.Space: 'space',
|
||||
c32.PageUp: 'Prior',
|
||||
c32.PageDown: 'Next',
|
||||
c32.End: 'End',
|
||||
c32.Home: 'Home',
|
||||
c32.LeftArrow: 'Left',
|
||||
c32.UpArrow: 'Up',
|
||||
c32.RightArrow: 'Right',
|
||||
c32.DownArrow: 'Down',
|
||||
c32.Select: 'Select',
|
||||
c32.Print: 'Print',
|
||||
c32.Execute: 'Execute',
|
||||
# c32.Snapshot: 'Snapshot',
|
||||
c32.Insert: 'Insert',
|
||||
c32.Delete: 'Delete',
|
||||
c32.Help: 'Help',
|
||||
c32.F1: 'F1',
|
||||
c32.F2: 'F2',
|
||||
c32.F3: 'F3',
|
||||
c32.F4: 'F4',
|
||||
c32.F5: 'F5',
|
||||
c32.F6: 'F6',
|
||||
c32.F7: 'F7',
|
||||
c32.F8: 'F8',
|
||||
c32.F9: 'F9',
|
||||
c32.F10: 'F10',
|
||||
c32.F11: 'F11',
|
||||
c32.F12: 'F12',
|
||||
c32.F13: 'F13',
|
||||
c32.F14: 'F14',
|
||||
c32.F15: 'F15',
|
||||
c32.F16: 'F16',
|
||||
c32.F17: 'F17',
|
||||
c32.F18: 'F18',
|
||||
c32.F19: 'F19',
|
||||
c32.F20: 'F20',
|
||||
c32.F21: 'F21',
|
||||
c32.F22: 'F22',
|
||||
c32.F23: 'F23',
|
||||
c32.F24: 'F24',
|
||||
# c32.Numlock: 'Num_Lock,',
|
||||
# c32.Scroll: 'Scroll_Lock',
|
||||
# c32.Apps: 'VK_APPS',
|
||||
# c32.ProcesskeY: 'VK_PROCESSKEY',
|
||||
# c32.Attn: 'VK_ATTN',
|
||||
# c32.Crsel: 'VK_CRSEL',
|
||||
# c32.Exsel: 'VK_EXSEL',
|
||||
# c32.Ereof: 'VK_EREOF',
|
||||
# c32.Play: 'VK_PLAY',
|
||||
# c32.Zoom: 'VK_ZOOM',
|
||||
# c32.Noname: 'VK_NONAME',
|
||||
# c32.Pa1: 'VK_PA1',
|
||||
c32.OemClear: 'VK_OEM_CLEAR',
|
||||
c32.NumPad0: 'NUMPAD0',
|
||||
c32.NumPad1: 'NUMPAD1',
|
||||
c32.NumPad2: 'NUMPAD2',
|
||||
c32.NumPad3: 'NUMPAD3',
|
||||
c32.NumPad4: 'NUMPAD4',
|
||||
c32.NumPad5: 'NUMPAD5',
|
||||
c32.NumPad6: 'NUMPAD6',
|
||||
c32.NumPad7: 'NUMPAD7',
|
||||
c32.NumPad8: 'NUMPAD8',
|
||||
c32.NumPad9: 'NUMPAD9',
|
||||
c32.Divide: 'Divide',
|
||||
c32.Multiply: 'Multiply',
|
||||
c32.Add: 'Add',
|
||||
c32.Subtract: 'Subtract',
|
||||
c32.Decimal: 'VK_DECIMAL'
|
||||
code2sym_map = {#c32.CANCEL: u'Cancel',
|
||||
c32.Backspace: u'BackSpace',
|
||||
c32.Tab: u'Tab',
|
||||
c32.Clear: u'Clear',
|
||||
c32.Enter: u'Return',
|
||||
# c32.Shift: u'Shift_L',
|
||||
# c32.Control: u'Control_L',
|
||||
# c32.Menu: u'Alt_L',
|
||||
c32.Pause: u'Pause',
|
||||
# c32.Capital: u'Caps_Lock',
|
||||
c32.Escape: u'Escape',
|
||||
# c32.Space: u'space',
|
||||
c32.PageUp: u'Prior',
|
||||
c32.PageDown: u'Next',
|
||||
c32.End: u'End',
|
||||
c32.Home: u'Home',
|
||||
c32.LeftArrow: u'Left',
|
||||
c32.UpArrow: u'Up',
|
||||
c32.RightArrow: u'Right',
|
||||
c32.DownArrow: u'Down',
|
||||
c32.Select: u'Select',
|
||||
c32.Print: u'Print',
|
||||
c32.Execute: u'Execute',
|
||||
# c32.Snapshot: u'Snapshot',
|
||||
c32.Insert: u'Insert',
|
||||
c32.Delete: u'Delete',
|
||||
c32.Help: u'Help',
|
||||
c32.F1: u'F1',
|
||||
c32.F2: u'F2',
|
||||
c32.F3: u'F3',
|
||||
c32.F4: u'F4',
|
||||
c32.F5: u'F5',
|
||||
c32.F6: u'F6',
|
||||
c32.F7: u'F7',
|
||||
c32.F8: u'F8',
|
||||
c32.F9: u'F9',
|
||||
c32.F10: u'F10',
|
||||
c32.F11: u'F11',
|
||||
c32.F12: u'F12',
|
||||
c32.F13: u'F13',
|
||||
c32.F14: u'F14',
|
||||
c32.F15: u'F15',
|
||||
c32.F16: u'F16',
|
||||
c32.F17: u'F17',
|
||||
c32.F18: u'F18',
|
||||
c32.F19: u'F19',
|
||||
c32.F20: u'F20',
|
||||
c32.F21: u'F21',
|
||||
c32.F22: u'F22',
|
||||
c32.F23: u'F23',
|
||||
c32.F24: u'F24',
|
||||
# c32.Numlock: u'Num_Lock,',
|
||||
# c32.Scroll: u'Scroll_Lock',
|
||||
# c32.Apps: u'VK_APPS',
|
||||
# c32.ProcesskeY: u'VK_PROCESSKEY',
|
||||
# c32.Attn: u'VK_ATTN',
|
||||
# c32.Crsel: u'VK_CRSEL',
|
||||
# c32.Exsel: u'VK_EXSEL',
|
||||
# c32.Ereof: u'VK_EREOF',
|
||||
# c32.Play: u'VK_PLAY',
|
||||
# c32.Zoom: u'VK_ZOOM',
|
||||
# c32.Noname: u'VK_NONAME',
|
||||
# c32.Pa1: u'VK_PA1',
|
||||
c32.OemClear: u'VK_OEM_CLEAR',
|
||||
c32.NumPad0: u'NUMPAD0',
|
||||
c32.NumPad1: u'NUMPAD1',
|
||||
c32.NumPad2: u'NUMPAD2',
|
||||
c32.NumPad3: u'NUMPAD3',
|
||||
c32.NumPad4: u'NUMPAD4',
|
||||
c32.NumPad5: u'NUMPAD5',
|
||||
c32.NumPad6: u'NUMPAD6',
|
||||
c32.NumPad7: u'NUMPAD7',
|
||||
c32.NumPad8: u'NUMPAD8',
|
||||
c32.NumPad9: u'NUMPAD9',
|
||||
c32.Divide: u'Divide',
|
||||
c32.Multiply: u'Multiply',
|
||||
c32.Add: u'Add',
|
||||
c32.Subtract: u'Subtract',
|
||||
c32.Decimal: u'VK_DECIMAL'
|
||||
}
|
||||
|
||||
# function to handle the mapping
|
||||
@@ -100,7 +100,7 @@ def make_keysym(keycode):
|
||||
try:
|
||||
sym = code2sym_map[keycode]
|
||||
except KeyError:
|
||||
sym = ''
|
||||
sym = u''
|
||||
return sym
|
||||
|
||||
sym2code_map = {}
|
||||
@@ -108,7 +108,7 @@ for code,sym in code2sym_map.iteritems():
|
||||
sym2code_map[sym.lower()] = code
|
||||
|
||||
def key_text_to_keyinfo(keytext):
|
||||
'''Convert a GNU readline style textual description of a key to keycode with modifiers'''
|
||||
u'''Convert a GNU readline style textual description of a key to keycode with modifiers'''
|
||||
if keytext.startswith('"'): # "
|
||||
return keyseq_to_keyinfo(keytext[1:-1])
|
||||
else:
|
||||
@@ -118,8 +118,8 @@ def key_text_to_keyinfo(keytext):
|
||||
def char_to_keyinfo(char, control=False, meta=False, shift=False):
|
||||
vk = (ord(char))
|
||||
if vk & 0xffff == 0xffff:
|
||||
print 'VkKeyScan("%s") = %x' % (char, vk)
|
||||
raise ValueError, 'bad key'
|
||||
print u'VkKeyScan("%s") = %x' % (char, vk)
|
||||
raise ValueError, u'bad key'
|
||||
if vk & 0x100:
|
||||
shift = True
|
||||
if vk & 0x200:
|
||||
@@ -135,24 +135,24 @@ def keyname_to_keyinfo(keyname):
|
||||
|
||||
while 1:
|
||||
lkeyname = keyname.lower()
|
||||
if lkeyname.startswith('control-'):
|
||||
if lkeyname.startswith(u'control-'):
|
||||
control = True
|
||||
keyname = keyname[8:]
|
||||
elif lkeyname.startswith('ctrl-'):
|
||||
elif lkeyname.startswith(u'ctrl-'):
|
||||
control = True
|
||||
keyname = keyname[5:]
|
||||
elif lkeyname.startswith('meta-'):
|
||||
elif lkeyname.startswith(u'meta-'):
|
||||
meta = True
|
||||
keyname = keyname[5:]
|
||||
elif lkeyname.startswith('alt-'):
|
||||
elif lkeyname.startswith(u'alt-'):
|
||||
meta = True
|
||||
keyname = keyname[4:]
|
||||
elif lkeyname.startswith('shift-'):
|
||||
elif lkeyname.startswith(u'shift-'):
|
||||
shift = True
|
||||
keyname = keyname[6:]
|
||||
else:
|
||||
if len(keyname) > 1:
|
||||
return (control, meta, shift, sym2code_map.get(keyname.lower()," "))
|
||||
return (control, meta, shift, sym2code_map.get(keyname.lower(),u" "))
|
||||
else:
|
||||
return char_to_keyinfo(keyname, control, meta, shift)
|
||||
|
||||
@@ -163,14 +163,14 @@ def keyseq_to_keyinfo(keyseq):
|
||||
shift = False
|
||||
|
||||
while 1:
|
||||
if keyseq.startswith('\\C-'):
|
||||
if keyseq.startswith(u'\\C-'):
|
||||
control = True
|
||||
keyseq = keyseq[3:]
|
||||
elif keyseq.startswith('\\M-'):
|
||||
elif keyseq.startswith(u'\\M-'):
|
||||
meta = True
|
||||
keyseq = keyseq[3:]
|
||||
elif keyseq.startswith('\\e'):
|
||||
res.append(char_to_keyinfo('\033', control, meta, shift))
|
||||
elif keyseq.startswith(u'\\e'):
|
||||
res.append(char_to_keyinfo(u'\033', control, meta, shift))
|
||||
control = meta = shift = False
|
||||
keyseq = keyseq[2:]
|
||||
elif len(keyseq) >= 1:
|
||||
@@ -181,26 +181,22 @@ def keyseq_to_keyinfo(keyseq):
|
||||
return res[0]
|
||||
|
||||
def make_keyinfo(keycode, state):
|
||||
# control = (state & (4+8)) != 0
|
||||
# meta = (state & (1+2)) != 0
|
||||
# shift = (state & 0x10) != 0
|
||||
control=False
|
||||
meta=False
|
||||
shift=False
|
||||
control = False
|
||||
meta =False
|
||||
shift = False
|
||||
return (control, meta, shift, keycode)
|
||||
|
||||
|
||||
def make_KeyPress(char,state,keycode):
|
||||
def make_KeyPress(char, state, keycode):
|
||||
|
||||
shift=bool(int(state)&int(Shift))
|
||||
control=bool(int(state)&int(Control))
|
||||
meta=bool(int(state)&int(Alt))
|
||||
keyname=code2sym_map.get(keycode,"").lower()
|
||||
# log_sock("make key %s %s %s %s"%(shift,control,meta,keycode),"keysyms")
|
||||
shift = bool(int(state) & int(Shift))
|
||||
control = bool(int(state) & int(Control))
|
||||
meta = bool(int(state) & int(Alt))
|
||||
keyname = code2sym_map.get(keycode, u"").lower()
|
||||
if control and meta: #equivalent to altgr so clear flags
|
||||
control=False
|
||||
meta=False
|
||||
control = False
|
||||
meta = False
|
||||
elif control:
|
||||
char=str(keycode)
|
||||
return KeyPress(char,shift,control,meta,keyname)
|
||||
char = str(keycode)
|
||||
return KeyPress(char, shift, control, meta, keyname)
|
||||
|
||||
|
||||
@@ -7,91 +7,92 @@
|
||||
# the file COPYING, distributed as part of this software.
|
||||
#*****************************************************************************
|
||||
import winconstants as c32
|
||||
from pyreadline.logger import log
|
||||
from ctypes import windll
|
||||
import ctypes
|
||||
# table for translating virtual keys to X windows key symbols
|
||||
|
||||
from common import validkey,KeyPress,make_KeyPress_from_keydescr
|
||||
from common import validkey, KeyPress, make_KeyPress_from_keydescr
|
||||
|
||||
code2sym_map = {c32.VK_CANCEL: 'cancel',
|
||||
c32.VK_BACK: 'backspace',
|
||||
c32.VK_TAB: 'tab',
|
||||
c32.VK_CLEAR: 'clear',
|
||||
c32.VK_RETURN: 'return',
|
||||
c32.VK_SHIFT: 'shift_l',
|
||||
c32.VK_CONTROL: 'control_l',
|
||||
c32.VK_MENU: 'alt_l',
|
||||
c32.VK_PAUSE: 'pause',
|
||||
c32.VK_CAPITAL: 'caps_lock',
|
||||
c32.VK_ESCAPE: 'escape',
|
||||
c32.VK_SPACE: 'space',
|
||||
c32.VK_PRIOR: 'prior',
|
||||
c32.VK_NEXT: 'next',
|
||||
c32.VK_END: 'end',
|
||||
c32.VK_HOME: 'home',
|
||||
c32.VK_LEFT: 'left',
|
||||
c32.VK_UP: 'up',
|
||||
c32.VK_RIGHT: 'right',
|
||||
c32.VK_DOWN: 'down',
|
||||
c32.VK_SELECT: 'select',
|
||||
c32.VK_PRINT: 'print',
|
||||
c32.VK_EXECUTE: 'execute',
|
||||
c32.VK_SNAPSHOT: 'snapshot',
|
||||
c32.VK_INSERT: 'insert',
|
||||
c32.VK_DELETE: 'delete',
|
||||
c32.VK_HELP: 'help',
|
||||
c32.VK_F1: 'f1',
|
||||
c32.VK_F2: 'f2',
|
||||
c32.VK_F3: 'f3',
|
||||
c32.VK_F4: 'f4',
|
||||
c32.VK_F5: 'f5',
|
||||
c32.VK_F6: 'f6',
|
||||
c32.VK_F7: 'f7',
|
||||
c32.VK_F8: 'f8',
|
||||
c32.VK_F9: 'f9',
|
||||
c32.VK_F10: 'f10',
|
||||
c32.VK_F11: 'f11',
|
||||
c32.VK_F12: 'f12',
|
||||
c32.VK_F13: 'f13',
|
||||
c32.VK_F14: 'f14',
|
||||
c32.VK_F15: 'f15',
|
||||
c32.VK_F16: 'f16',
|
||||
c32.VK_F17: 'f17',
|
||||
c32.VK_F18: 'f18',
|
||||
c32.VK_F19: 'f19',
|
||||
c32.VK_F20: 'f20',
|
||||
c32.VK_F21: 'f21',
|
||||
c32.VK_F22: 'f22',
|
||||
c32.VK_F23: 'f23',
|
||||
c32.VK_F24: 'f24',
|
||||
c32.VK_NUMLOCK: 'num_lock,',
|
||||
c32.VK_SCROLL: 'scroll_lock',
|
||||
c32.VK_APPS: 'vk_apps',
|
||||
c32.VK_PROCESSKEY: 'vk_processkey',
|
||||
c32.VK_ATTN: 'vk_attn',
|
||||
c32.VK_CRSEL: 'vk_crsel',
|
||||
c32.VK_EXSEL: 'vk_exsel',
|
||||
c32.VK_EREOF: 'vk_ereof',
|
||||
c32.VK_PLAY: 'vk_play',
|
||||
c32.VK_ZOOM: 'vk_zoom',
|
||||
c32.VK_NONAME: 'vk_noname',
|
||||
c32.VK_PA1: 'vk_pa1',
|
||||
c32.VK_OEM_CLEAR :'vk_oem_clear',
|
||||
c32.VK_NUMPAD0: 'numpad0',
|
||||
c32.VK_NUMPAD1: 'numpad1',
|
||||
c32.VK_NUMPAD2: 'numpad2',
|
||||
c32.VK_NUMPAD3: 'numpad3',
|
||||
c32.VK_NUMPAD4: 'numpad4',
|
||||
c32.VK_NUMPAD5: 'numpad5',
|
||||
c32.VK_NUMPAD6: 'numpad6',
|
||||
c32.VK_NUMPAD7: 'numpad7',
|
||||
c32.VK_NUMPAD8: 'numpad8',
|
||||
c32.VK_NUMPAD9: 'numpad9',
|
||||
c32.VK_DIVIDE: 'divide',
|
||||
c32.VK_MULTIPLY: 'multiply',
|
||||
c32.VK_ADD: 'add',
|
||||
c32.VK_SUBTRACT: 'subtract',
|
||||
c32.VK_DECIMAL: 'vk_decimal'
|
||||
code2sym_map = {c32.VK_CANCEL: u'cancel',
|
||||
c32.VK_BACK: u'backspace',
|
||||
c32.VK_TAB: u'tab',
|
||||
c32.VK_CLEAR: u'clear',
|
||||
c32.VK_RETURN: u'return',
|
||||
c32.VK_SHIFT: u'shift_l',
|
||||
c32.VK_CONTROL: u'control_l',
|
||||
c32.VK_MENU: u'alt_l',
|
||||
c32.VK_PAUSE: u'pause',
|
||||
c32.VK_CAPITAL: u'caps_lock',
|
||||
c32.VK_ESCAPE: u'escape',
|
||||
c32.VK_SPACE: u'space',
|
||||
c32.VK_PRIOR: u'prior',
|
||||
c32.VK_NEXT: u'next',
|
||||
c32.VK_END: u'end',
|
||||
c32.VK_HOME: u'home',
|
||||
c32.VK_LEFT: u'left',
|
||||
c32.VK_UP: u'up',
|
||||
c32.VK_RIGHT: u'right',
|
||||
c32.VK_DOWN: u'down',
|
||||
c32.VK_SELECT: u'select',
|
||||
c32.VK_PRINT: u'print',
|
||||
c32.VK_EXECUTE: u'execute',
|
||||
c32.VK_SNAPSHOT: u'snapshot',
|
||||
c32.VK_INSERT: u'insert',
|
||||
c32.VK_DELETE: u'delete',
|
||||
c32.VK_HELP: u'help',
|
||||
c32.VK_F1: u'f1',
|
||||
c32.VK_F2: u'f2',
|
||||
c32.VK_F3: u'f3',
|
||||
c32.VK_F4: u'f4',
|
||||
c32.VK_F5: u'f5',
|
||||
c32.VK_F6: u'f6',
|
||||
c32.VK_F7: u'f7',
|
||||
c32.VK_F8: u'f8',
|
||||
c32.VK_F9: u'f9',
|
||||
c32.VK_F10: u'f10',
|
||||
c32.VK_F11: u'f11',
|
||||
c32.VK_F12: u'f12',
|
||||
c32.VK_F13: u'f13',
|
||||
c32.VK_F14: u'f14',
|
||||
c32.VK_F15: u'f15',
|
||||
c32.VK_F16: u'f16',
|
||||
c32.VK_F17: u'f17',
|
||||
c32.VK_F18: u'f18',
|
||||
c32.VK_F19: u'f19',
|
||||
c32.VK_F20: u'f20',
|
||||
c32.VK_F21: u'f21',
|
||||
c32.VK_F22: u'f22',
|
||||
c32.VK_F23: u'f23',
|
||||
c32.VK_F24: u'f24',
|
||||
c32.VK_NUMLOCK: u'num_lock,',
|
||||
c32.VK_SCROLL: u'scroll_lock',
|
||||
c32.VK_APPS: u'vk_apps',
|
||||
c32.VK_PROCESSKEY: u'vk_processkey',
|
||||
c32.VK_ATTN: u'vk_attn',
|
||||
c32.VK_CRSEL: u'vk_crsel',
|
||||
c32.VK_EXSEL: u'vk_exsel',
|
||||
c32.VK_EREOF: u'vk_ereof',
|
||||
c32.VK_PLAY: u'vk_play',
|
||||
c32.VK_ZOOM: u'vk_zoom',
|
||||
c32.VK_NONAME: u'vk_noname',
|
||||
c32.VK_PA1: u'vk_pa1',
|
||||
c32.VK_OEM_CLEAR: u'vk_oem_clear',
|
||||
c32.VK_NUMPAD0: u'numpad0',
|
||||
c32.VK_NUMPAD1: u'numpad1',
|
||||
c32.VK_NUMPAD2: u'numpad2',
|
||||
c32.VK_NUMPAD3: u'numpad3',
|
||||
c32.VK_NUMPAD4: u'numpad4',
|
||||
c32.VK_NUMPAD5: u'numpad5',
|
||||
c32.VK_NUMPAD6: u'numpad6',
|
||||
c32.VK_NUMPAD7: u'numpad7',
|
||||
c32.VK_NUMPAD8: u'numpad8',
|
||||
c32.VK_NUMPAD9: u'numpad9',
|
||||
c32.VK_DIVIDE: u'divide',
|
||||
c32.VK_MULTIPLY: u'multiply',
|
||||
c32.VK_ADD: u'add',
|
||||
c32.VK_SUBTRACT: u'subtract',
|
||||
c32.VK_DECIMAL: u'vk_decimal'
|
||||
}
|
||||
|
||||
VkKeyScan = windll.user32.VkKeyScanA
|
||||
@@ -100,8 +101,8 @@ def char_to_keyinfo(char, control=False, meta=False, shift=False):
|
||||
k=KeyPress()
|
||||
vk = VkKeyScan(ord(char))
|
||||
if vk & 0xffff == 0xffff:
|
||||
print 'VkKeyScan("%s") = %x' % (char, vk)
|
||||
raise ValueError, 'bad key'
|
||||
print u'VkKeyScan("%s") = %x' % (char, vk)
|
||||
raise ValueError, u'bad key'
|
||||
if vk & 0x100:
|
||||
k.shift = True
|
||||
if vk & 0x200:
|
||||
@@ -111,20 +112,22 @@ def char_to_keyinfo(char, control=False, meta=False, shift=False):
|
||||
k.char=chr(vk & 0xff)
|
||||
return k
|
||||
|
||||
def make_KeyPress(char,state,keycode):
|
||||
def make_KeyPress(char, state, keycode):
|
||||
control = (state & (4+8)) != 0
|
||||
meta = (state & (1+2)) != 0
|
||||
shift = (state & 0x10) != 0
|
||||
if control and char !="\x00":
|
||||
char = chr(VkKeyScan(ord(char)) & 0xff)
|
||||
elif control:
|
||||
char=chr(keycode)
|
||||
if control and not meta:#Matches ctrl- chords should pass keycode as char
|
||||
char = chr(keycode)
|
||||
elif control and meta: #Matches alt gr and should just pass on char
|
||||
control = False
|
||||
meta = False
|
||||
try:
|
||||
keyname=code2sym_map[keycode]
|
||||
except KeyError:
|
||||
keyname=""
|
||||
return KeyPress(char,shift,control,meta,keyname)
|
||||
keyname = u""
|
||||
out = KeyPress(char, shift, control, meta, keyname)
|
||||
return out
|
||||
|
||||
if __name__=="__main__":
|
||||
if __name__==u"__main__":
|
||||
import startup
|
||||
|
||||
@@ -5,13 +5,11 @@
|
||||
# Distributed under the terms of the BSD License. The full license is in
|
||||
# the file COPYING, distributed as part of this software.
|
||||
#*****************************************************************************
|
||||
import re,operator,string,sys,os
|
||||
import re, operator,string, sys,os
|
||||
|
||||
#import wordmatcher
|
||||
#import pyreadline.clipboard as clipboard
|
||||
from pyreadline.unicode_helper import ensure_unicode,ensure_str
|
||||
if "pyreadline" in sys.modules:
|
||||
pyreadline= sys.modules["pyreadline"]
|
||||
from pyreadline.unicode_helper import ensure_unicode, ensure_str
|
||||
if u"pyreadline" in sys.modules:
|
||||
pyreadline = sys.modules[u"pyreadline"]
|
||||
else:
|
||||
import pyreadline
|
||||
|
||||
@@ -22,69 +20,69 @@ import exceptions
|
||||
class EscapeHistory(exceptions.Exception):
|
||||
pass
|
||||
|
||||
from pyreadline.logger import log_sock
|
||||
from pyreadline.logger import log
|
||||
|
||||
_ignore_leading_spaces=False
|
||||
_ignore_leading_spaces = False
|
||||
|
||||
class LineHistory(object):
|
||||
def __init__(self):
|
||||
self.history=[]
|
||||
self._history_length=100
|
||||
self._history_cursor=0
|
||||
self.history_filename=os.path.expanduser('~/.history')
|
||||
self.lastcommand=None
|
||||
self.query=""
|
||||
self.history = []
|
||||
self._history_length = 100
|
||||
self._history_cursor = 0
|
||||
self.history_filename = os.path.expanduser('~/.history') #Cannot expand unicode strings correctly on python2.4
|
||||
self.lastcommand = None
|
||||
self.query = u""
|
||||
|
||||
def get_history_length(self):
|
||||
value=self._history_length
|
||||
log_sock("get_history_length:%d"%value,"history")
|
||||
value = self._history_length
|
||||
log(u"get_history_length:%d"%value)
|
||||
return value
|
||||
|
||||
def set_history_length(self,value):
|
||||
log_sock("set_history_length: old:%d new:%d"%(self._history_length,value),"history")
|
||||
self._history_length=value
|
||||
def set_history_length(self, value):
|
||||
log(u"set_history_length: old:%d new:%d"%(self._history_length, value))
|
||||
self._history_length = value
|
||||
|
||||
def get_history_cursor(self):
|
||||
value=self._history_cursor
|
||||
log_sock("get_history_cursor:%d"%value,"history")
|
||||
value = self._history_cursor
|
||||
log(u"get_history_cursor:%d"%value)
|
||||
return value
|
||||
|
||||
def set_history_cursor(self,value):
|
||||
log_sock("set_history_cursor: old:%d new:%d"%(self._history_cursor,value),"history")
|
||||
self._history_cursor=value
|
||||
def set_history_cursor(self, value):
|
||||
log(u"set_history_cursor: old:%d new:%d"%(self._history_cursor, value))
|
||||
self._history_cursor = value
|
||||
|
||||
history_length=property(get_history_length,set_history_length)
|
||||
history_cursor=property(get_history_cursor,set_history_cursor)
|
||||
history_length = property(get_history_length, set_history_length)
|
||||
history_cursor = property(get_history_cursor, set_history_cursor)
|
||||
|
||||
def clear_history(self):
|
||||
'''Clear readline history.'''
|
||||
u'''Clear readline history.'''
|
||||
self.history[:] = []
|
||||
self.history_cursor = 0
|
||||
|
||||
def read_history_file(self, filename=None):
|
||||
'''Load a readline history file.'''
|
||||
u'''Load a readline history file.'''
|
||||
if filename is None:
|
||||
filename=self.history_filename
|
||||
filename = self.history_filename
|
||||
try:
|
||||
for line in open(filename, 'r'):
|
||||
for line in open(filename, u'r'):
|
||||
self.add_history(lineobj.ReadLineTextBuffer(ensure_unicode(line.rstrip())))
|
||||
except IOError:
|
||||
self.history = []
|
||||
self.history_cursor = 0
|
||||
|
||||
def write_history_file(self, filename=None):
|
||||
'''Save a readline history file.'''
|
||||
def write_history_file(self, filename = None):
|
||||
u'''Save a readline history file.'''
|
||||
if filename is None:
|
||||
filename=self.history_filename
|
||||
fp = open(filename, 'wb')
|
||||
filename = self.history_filename
|
||||
fp = open(filename, u'wb')
|
||||
for line in self.history[-self.history_length:]:
|
||||
fp.write(ensure_str(line.get_line_text()))
|
||||
fp.write('\n')
|
||||
fp.write(u'\n')
|
||||
fp.close()
|
||||
|
||||
|
||||
def add_history(self, line):
|
||||
'''Append a line to the history buffer, as if it was the last line typed.'''
|
||||
u'''Append a line to the history buffer, as if it was the last line typed.'''
|
||||
if not line.get_line_text():
|
||||
pass
|
||||
elif len(self.history) > 0 and self.history[-1].get_line_text() == line.get_line_text():
|
||||
@@ -93,155 +91,125 @@ class LineHistory(object):
|
||||
self.history.append(line)
|
||||
self.history_cursor = len(self.history)
|
||||
|
||||
def previous_history(self,current): # (C-p)
|
||||
'''Move back through the history list, fetching the previous command. '''
|
||||
if self.history_cursor==len(self.history):
|
||||
def previous_history(self, current): # (C-p)
|
||||
u'''Move back through the history list, fetching the previous command. '''
|
||||
if self.history_cursor == len(self.history):
|
||||
self.history.append(current.copy()) #do not use add_history since we do not want to increment cursor
|
||||
|
||||
if self.history_cursor > 0:
|
||||
self.history_cursor -= 1
|
||||
current.set_line(self.history[self.history_cursor].get_line_text())
|
||||
current.point=lineobj.EndOfLine
|
||||
current.point = lineobj.EndOfLine
|
||||
|
||||
def next_history(self,current): # (C-n)
|
||||
'''Move forward through the history list, fetching the next command. '''
|
||||
if self.history_cursor < len(self.history)-1:
|
||||
def next_history(self, current): # (C-n)
|
||||
u'''Move forward through the history list, fetching the next command. '''
|
||||
if self.history_cursor < len(self.history) - 1:
|
||||
self.history_cursor += 1
|
||||
current.set_line(self.history[self.history_cursor].get_line_text())
|
||||
|
||||
def beginning_of_history(self): # (M-<)
|
||||
'''Move to the first line in the history.'''
|
||||
u'''Move to the first line in the history.'''
|
||||
self.history_cursor = 0
|
||||
if len(self.history) > 0:
|
||||
self.l_buffer = self.history[0]
|
||||
|
||||
def end_of_history(self,current): # (M->)
|
||||
'''Move to the end of the input history, i.e., the line currently
|
||||
def end_of_history(self, current): # (M->)
|
||||
u'''Move to the end of the input history, i.e., the line currently
|
||||
being entered.'''
|
||||
self.history_cursor=len(self.history)
|
||||
self.history_cursor = len(self.history)
|
||||
current.set_line(self.history[-1].get_line_text())
|
||||
|
||||
def reverse_search_history(self,searchfor,startpos=None):
|
||||
def reverse_search_history(self, searchfor, startpos=None):
|
||||
if startpos is None:
|
||||
startpos=self.history_cursor
|
||||
startpos = self.history_cursor
|
||||
if _ignore_leading_spaces:
|
||||
res=[(idx,line.lstrip()) for idx,line in enumerate(self.history[startpos:0:-1]) if line.lstrip().startswith(searchfor.lstrip())]
|
||||
res = [(idx, line.lstrip())
|
||||
for idx, line in enumerate(self.history[startpos:0:-1])
|
||||
if line.lstrip().startswith(searchfor.lstrip())]
|
||||
else:
|
||||
res=[(idx,line) for idx,line in enumerate(self.history[startpos:0:-1]) if line.startswith(searchfor)]
|
||||
res = [(idx, line)
|
||||
for idx, line in enumerate(self.history[startpos:0:-1])
|
||||
if line.startswith(searchfor)]
|
||||
if res:
|
||||
self.history_cursor-=res[0][0]
|
||||
self.history_cursor -= res[0][0]
|
||||
return res[0][1].get_line_text()
|
||||
return ""
|
||||
return u""
|
||||
|
||||
def forward_search_history(self,searchfor,startpos=None):
|
||||
def forward_search_history(self, searchfor, startpos=None):
|
||||
if startpos is None:
|
||||
startpos=self.history_cursor
|
||||
startpos = self.history_cursor
|
||||
if _ignore_leading_spaces:
|
||||
res=[(idx,line.lstrip()) for idx,line in enumerate(self.history[startpos:]) if line.lstrip().startswith(searchfor.lstrip())]
|
||||
res = [(idx, line.lstrip())
|
||||
for idx, line in enumerate(self.history[startpos:])
|
||||
if line.lstrip().startswith(searchfor.lstrip())]
|
||||
else:
|
||||
res=[(idx,line) for idx,line in enumerate(self.history[startpos:]) if line.startswith(searchfor)]
|
||||
res = [(idx, line)
|
||||
for idx, line in enumerate(self.history[startpos:])
|
||||
if line.startswith(searchfor)]
|
||||
if res:
|
||||
self.history_cursor+=res[0][0]
|
||||
self.history_cursor += res[0][0]
|
||||
return res[0][1].get_line_text()
|
||||
return ""
|
||||
|
||||
def _non_i_search(self, direction, current):
|
||||
c = pyreadline.rl.console
|
||||
line = current.get_line_text()
|
||||
query = ''
|
||||
while 1:
|
||||
c.pos(*pyreadline.rl.prompt_end_pos)
|
||||
scroll = c.write_scrolling(":%s" % query)
|
||||
pyreadline.rl._update_prompt_pos(scroll)
|
||||
pyreadline.rl._clear_after()
|
||||
|
||||
event = c.getkeypress()
|
||||
|
||||
if event.keyinfo.keyname == 'backspace':
|
||||
if len(query) > 0:
|
||||
query = query[:-1]
|
||||
else:
|
||||
break
|
||||
elif event.char in string.letters + string.digits + string.punctuation + ' ':
|
||||
query += event.char
|
||||
elif event.keyinfo.keyname == 'return':
|
||||
break
|
||||
else:
|
||||
pyreadline.rl._bell()
|
||||
res=""
|
||||
if query:
|
||||
if direction==-1:
|
||||
res=self.reverse_search_history(query)
|
||||
|
||||
else:
|
||||
res=self.forward_search_history(query)
|
||||
return lineobj.ReadLineTextBuffer(res,point=0)
|
||||
|
||||
def non_incremental_reverse_search_history(self,current): # (M-p)
|
||||
'''Search backward starting at the current line and moving up
|
||||
through the history as necessary using a non-incremental search for
|
||||
a string supplied by the user.'''
|
||||
return self._non_i_search(-1,current)
|
||||
|
||||
def non_incremental_forward_search_history(self,current): # (M-n)
|
||||
'''Search forward starting at the current line and moving down
|
||||
through the the history as necessary using a non-incremental search
|
||||
for a string supplied by the user.'''
|
||||
return self._non_i_search(1,current)
|
||||
return u""
|
||||
|
||||
def _search(self, direction, partial):
|
||||
try:
|
||||
if (self.lastcommand != self.history_search_forward and
|
||||
self.lastcommand != self.history_search_backward):
|
||||
self.query = ''.join(partial[0:partial.point].get_line_text())
|
||||
hcstart=max(self.history_cursor,0)
|
||||
self.query = u''.join(partial[0:partial.point].get_line_text())
|
||||
hcstart = max(self.history_cursor,0)
|
||||
hc = self.history_cursor + direction
|
||||
while (direction < 0 and hc >= 0) or (direction > 0 and hc < len(self.history)):
|
||||
h = self.history[hc]
|
||||
if not self.query:
|
||||
self.history_cursor = hc
|
||||
result=lineobj.ReadLineTextBuffer(h,point=len(h.get_line_text()))
|
||||
result = lineobj.ReadLineTextBuffer(h, point=len(h.get_line_text()))
|
||||
return result
|
||||
elif (h.get_line_text().startswith(self.query) and (h != partial.get_line_text())):
|
||||
self.history_cursor = hc
|
||||
result=lineobj.ReadLineTextBuffer(h,point=partial.point)
|
||||
result = lineobj.ReadLineTextBuffer(h, point=partial.point)
|
||||
return result
|
||||
hc += direction
|
||||
else:
|
||||
if len(self.history)==0:
|
||||
if len(self.history) == 0:
|
||||
pass
|
||||
elif hc>=len(self.history) and not self.query:
|
||||
self.history_cursor=len(self.history)
|
||||
return lineobj.ReadLineTextBuffer("",point=0)
|
||||
elif self.history[max(min(hcstart,len(self.history)-1),0)].get_line_text().startswith(self.query) and self.query:
|
||||
return lineobj.ReadLineTextBuffer(self.history[max(min(hcstart,len(self.history)-1),0)],point=partial.point)
|
||||
elif hc >= len(self.history) and not self.query:
|
||||
self.history_cursor = len(self.history)
|
||||
return lineobj.ReadLineTextBuffer(u"", point=0)
|
||||
elif self.history[max(min(hcstart, len(self.history) - 1), 0)]\
|
||||
.get_line_text().startswith(self.query) and self.query:
|
||||
return lineobj.ReadLineTextBuffer(self.history\
|
||||
[max(min(hcstart, len(self.history) - 1),0)],
|
||||
point = partial.point)
|
||||
else:
|
||||
return lineobj.ReadLineTextBuffer(partial,point=partial.point)
|
||||
return lineobj.ReadLineTextBuffer(self.query,point=min(len(self.query),partial.point))
|
||||
return lineobj.ReadLineTextBuffer(partial,
|
||||
point=partial.point)
|
||||
return lineobj.ReadLineTextBuffer(self.query,
|
||||
point=min(len(self.query),
|
||||
partial.point))
|
||||
except IndexError:
|
||||
raise
|
||||
|
||||
def history_search_forward(self,partial): # ()
|
||||
'''Search forward through the history for the string of characters
|
||||
def history_search_forward(self, partial): # ()
|
||||
u'''Search forward through the history for the string of characters
|
||||
between the start of the current line and the point. This is a
|
||||
non-incremental search. By default, this command is unbound.'''
|
||||
q= self._search(1,partial)
|
||||
q= self._search(1, partial)
|
||||
return q
|
||||
|
||||
def history_search_backward(self,partial): # ()
|
||||
'''Search backward through the history for the string of characters
|
||||
def history_search_backward(self, partial): # ()
|
||||
u'''Search backward through the history for the string of characters
|
||||
between the start of the current line and the point. This is a
|
||||
non-incremental search. By default, this command is unbound.'''
|
||||
|
||||
q= self._search(-1,partial)
|
||||
q= self._search(-1, partial)
|
||||
return q
|
||||
|
||||
if __name__=="__main__":
|
||||
q=LineHistory()
|
||||
RL=lineobj.ReadLineTextBuffer
|
||||
q.add_history(RL("aaaa"))
|
||||
q.add_history(RL("aaba"))
|
||||
q.add_history(RL("aaca"))
|
||||
q.add_history(RL("akca"))
|
||||
q.add_history(RL("bbb"))
|
||||
q.add_history(RL("ako"))
|
||||
if __name__==u"__main__":
|
||||
q = LineHistory()
|
||||
RL = lineobj.ReadLineTextBuffer
|
||||
q.add_history(RL(u"aaaa"))
|
||||
q.add_history(RL(u"aaba"))
|
||||
q.add_history(RL(u"aaca"))
|
||||
q.add_history(RL(u"akca"))
|
||||
q.add_history(RL(u"bbb"))
|
||||
q.add_history(RL(u"ako"))
|
||||
|
||||
+356
-358
File diff suppressed because it is too large
Load Diff
@@ -6,50 +6,50 @@
|
||||
# the file COPYING, distributed as part of this software.
|
||||
#*****************************************************************************
|
||||
|
||||
import re,operator
|
||||
import re, operator
|
||||
|
||||
|
||||
def str_find_all(str,ch):
|
||||
result=[]
|
||||
index=0
|
||||
while index>=0:
|
||||
index=str.find(ch,index)
|
||||
if index>=0:
|
||||
def str_find_all(str, ch):
|
||||
result = []
|
||||
index = 0
|
||||
while index >= 0:
|
||||
index = str.find(ch, index)
|
||||
if index >= 0:
|
||||
result.append(index)
|
||||
index+=1
|
||||
index += 1
|
||||
return result
|
||||
|
||||
|
||||
word_pattern=re.compile("(x*)")
|
||||
word_pattern = re.compile(u"(x*)")
|
||||
|
||||
def markwords(str,iswordfun):
|
||||
markers={True:"x",False:"o"}
|
||||
def markwords(str, iswordfun):
|
||||
markers = {True : u"x", False : u"o"}
|
||||
return "".join([markers[iswordfun(ch)] for ch in str])
|
||||
|
||||
def split_words(str,iswordfun):
|
||||
return [x for x in word_pattern.split(markwords(str,iswordfun)) if x !=""]
|
||||
def split_words(str, iswordfun):
|
||||
return [x for x in word_pattern.split(markwords(str,iswordfun)) if x != u""]
|
||||
|
||||
def mark_start_segment(str,is_segment):
|
||||
def mark_start_segment(str, is_segment):
|
||||
def mark_start(s):
|
||||
if s[0:1]=="x":
|
||||
return "s"+s[1:]
|
||||
if s[0:1] == u"x":
|
||||
return u"s" + s[1:]
|
||||
else:
|
||||
return s
|
||||
return "".join(map(mark_start,split_words(str,is_segment)))
|
||||
return u"".join(map(mark_start, split_words(str, is_segment)))
|
||||
|
||||
def mark_end_segment(str,is_segment):
|
||||
def mark_end_segment(str, is_segment):
|
||||
def mark_start(s):
|
||||
if s[0:1]=="x":
|
||||
return s[:-1]+"s"
|
||||
if s[0:1] == u"x":
|
||||
return s[:-1] + u"s"
|
||||
else:
|
||||
return s
|
||||
return "".join(map(mark_start,split_words(str,is_segment)))
|
||||
return u"".join(map(mark_start, split_words(str, is_segment)))
|
||||
|
||||
def mark_start_segment_index(str,is_segment):
|
||||
return str_find_all(mark_start_segment(str,is_segment),"s")
|
||||
def mark_start_segment_index(str, is_segment):
|
||||
return str_find_all(mark_start_segment(str, is_segment), u"s")
|
||||
|
||||
def mark_end_segment_index(str,is_segment):
|
||||
return [x+1 for x in str_find_all(mark_end_segment(str,is_segment),"s")]
|
||||
def mark_end_segment_index(str, is_segment):
|
||||
return [x + 1 for x in str_find_all(mark_end_segment(str, is_segment), u"s")]
|
||||
|
||||
|
||||
################ Following are used in lineobj ###########################
|
||||
@@ -58,46 +58,45 @@ def is_word_token(str):
|
||||
return not is_non_word_token(str)
|
||||
|
||||
def is_non_word_token(str):
|
||||
if len(str)!=1 or str in " \t\n":
|
||||
if len(str) != 1 or str in u" \t\n":
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def next_start_segment(str,is_segment):
|
||||
str="".join(str)
|
||||
result=[]
|
||||
for start in mark_start_segment_index(str,is_segment):
|
||||
result[len(result):start]=[start for x in range(start-len(result))]
|
||||
result[len(result):len(str)]=[len(str) for x in range(len(str)-len(result)+1)]
|
||||
def next_start_segment(str, is_segment):
|
||||
str = u"".join(str)
|
||||
result = []
|
||||
for start in mark_start_segment_index(str, is_segment):
|
||||
result[len(result):start] = [start for x in range(start - len(result))]
|
||||
result[len(result):len(str)] = [len(str) for x in range(len(str) - len(result) + 1)]
|
||||
return result
|
||||
|
||||
def next_end_segment(str,is_segment):
|
||||
str="".join(str)
|
||||
result=[]
|
||||
for start in mark_end_segment_index(str,is_segment):
|
||||
result[len(result):start]=[start for x in range(start-len(result))]
|
||||
result[len(result):len(str)]=[len(str) for x in range(len(str)-len(result)+1)]
|
||||
def next_end_segment(str, is_segment):
|
||||
str = u"".join(str)
|
||||
result = []
|
||||
for start in mark_end_segment_index(str, is_segment):
|
||||
result[len(result):start] = [start for x in range(start - len(result))]
|
||||
result[len(result):len(str)] = [len(str) for x in range(len(str) - len(result) + 1)]
|
||||
return result
|
||||
|
||||
|
||||
def prev_start_segment(str,is_segment):
|
||||
str="".join(str)
|
||||
result=[]
|
||||
prev=0
|
||||
for start in mark_start_segment_index(str,is_segment):
|
||||
result[len(result):start+1]=[prev for x in range(start-len(result)+1)]
|
||||
def prev_start_segment(str, is_segment):
|
||||
str = u"".join(str)
|
||||
result = []
|
||||
prev = 0
|
||||
for start in mark_start_segment_index(str, is_segment):
|
||||
result[len(result):start+1] = [prev for x in range(start - len(result) + 1)]
|
||||
prev=start
|
||||
result[len(result):len(str)]=[prev for x in range(len(str)-len(result)+1)]
|
||||
result[len(result):len(str)] = [prev for x in range(len(str) - len(result) + 1)]
|
||||
return result
|
||||
|
||||
def prev_end_segment(str,is_segment):
|
||||
str="".join(str)
|
||||
result=[]
|
||||
prev=0
|
||||
for start in mark_end_segment_index(str,is_segment):
|
||||
result[len(result):start+1]=[prev for x in range(start-len(result)+1)]
|
||||
def prev_end_segment(str, is_segment):
|
||||
str = u"".join(str)
|
||||
result = []
|
||||
prev = 0
|
||||
for start in mark_end_segment_index(str, is_segment):
|
||||
result[len(result):start + 1] = [prev for x in range(start - len(result) + 1)]
|
||||
prev=start
|
||||
result[len(result):len(str)]=[len(str) for x in range(len(str)-len(result)+1)]
|
||||
result[len(result):len(str)] = [len(str) for x in range(len(str) - len(result) + 1)]
|
||||
return result
|
||||
|
||||
|
||||
|
||||
+49
-32
@@ -6,42 +6,59 @@
|
||||
# the file COPYING, distributed as part of this software.
|
||||
#*****************************************************************************
|
||||
|
||||
import socket
|
||||
import socket, logging, logging.handlers
|
||||
from pyreadline.unicode_helper import ensure_str
|
||||
_logfile=False
|
||||
|
||||
def start_log(on,filename):
|
||||
global _logfile
|
||||
if on=="on":
|
||||
_logfile=open(filename,"w")
|
||||
else:
|
||||
_logfile=False
|
||||
|
||||
def log(s):
|
||||
if _logfile:
|
||||
s = ensure_str(s)
|
||||
print >>_logfile, s
|
||||
_logfile.flush()
|
||||
host = u"localhost"
|
||||
port = logging.handlers.DEFAULT_TCP_LOGGING_PORT
|
||||
|
||||
|
||||
host="localhost"
|
||||
port=8081
|
||||
logsocket=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
|
||||
root_logger = logging.getLogger(u'')
|
||||
root_logger.setLevel(logging.DEBUG)
|
||||
formatter = logging.Formatter('%(message)s')
|
||||
file_handler = None
|
||||
|
||||
show_event=["keypress","bound_function","bind_key","console"]
|
||||
show_event=["bound_function"]
|
||||
|
||||
sock_silent=True
|
||||
|
||||
def log_sock(s,event_type=None):
|
||||
if sock_silent:
|
||||
class NULLHandler(logging.Handler):
|
||||
def emit(self, s):
|
||||
pass
|
||||
else:
|
||||
if event_type is None:
|
||||
logsocket.sendto(ensure_str(s),(host,port))
|
||||
elif event_type in show_event:
|
||||
logsocket.sendto(ensure_str(s),(host,port))
|
||||
else:
|
||||
pass
|
||||
|
||||
|
||||
class SocketStream(object):
|
||||
def __init__(self, host, port):
|
||||
self.logsocket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
|
||||
|
||||
def write(self, s):
|
||||
self.logsocket.sendto(ensure_str(s), (host, port))
|
||||
|
||||
def flush(self):
|
||||
pass
|
||||
|
||||
def close(self):
|
||||
pass
|
||||
|
||||
socket_handler = logging.StreamHandler(SocketStream(host, port))
|
||||
socket_handler.setFormatter(formatter)
|
||||
root_logger.addHandler(NULLHandler())
|
||||
|
||||
|
||||
def start_socket_log():
|
||||
root_logger.addHandler(socket_handler)
|
||||
|
||||
def stop_socket_log():
|
||||
root_logger.removeHandler(socket_handler)
|
||||
|
||||
def start_file_log(filename):
|
||||
global file_handler
|
||||
file_handler = logging.handlers.FileHandler(filename, "w")
|
||||
root_logger.addHandler(file_handler)
|
||||
|
||||
def stop_file_log():
|
||||
global file_handler
|
||||
if file_handler:
|
||||
root_logger.removeHandler(file_handler)
|
||||
file_handler.close()
|
||||
file_handler = None
|
||||
|
||||
def log(s):
|
||||
s = ensure_str(s)
|
||||
root_logger.debug(s)
|
||||
|
||||
|
||||
+36
-39
@@ -5,56 +5,53 @@
|
||||
# Distributed under the terms of the BSD License. The full license is in
|
||||
# the file COPYING, distributed as part of this software.
|
||||
#*****************************************************************************
|
||||
import socket
|
||||
|
||||
import cPickle
|
||||
import logging
|
||||
import logging.handlers
|
||||
import SocketServer
|
||||
import struct,socket
|
||||
|
||||
try:
|
||||
import msvcrt
|
||||
except ImportError:
|
||||
msvcrt=None
|
||||
print "problem"
|
||||
|
||||
msvcrt = None
|
||||
print u"problem"
|
||||
|
||||
|
||||
port =8081
|
||||
|
||||
s=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
|
||||
|
||||
s.bind(("",port))
|
||||
s.settimeout(0.05)
|
||||
|
||||
print "Starting logserver on port:",port
|
||||
print "Press q to quit logserver",port
|
||||
singleline=False
|
||||
|
||||
port = logging.handlers.DEFAULT_TCP_LOGGING_PORT
|
||||
host = u'localhost'
|
||||
|
||||
def check_key():
|
||||
if msvcrt is None:
|
||||
return False
|
||||
else:
|
||||
if msvcrt.kbhit()!=0:
|
||||
q=msvcrt.getch()
|
||||
|
||||
return q in "q"
|
||||
else:
|
||||
return False
|
||||
if msvcrt.kbhit() != 0:
|
||||
q = msvcrt.getch()
|
||||
return q
|
||||
return u""
|
||||
|
||||
|
||||
while 1:
|
||||
try:
|
||||
data,addr=s.recvfrom(1024)
|
||||
except socket.timeout:
|
||||
if check_key():
|
||||
print "Quitting logserver"
|
||||
break
|
||||
else:
|
||||
continue
|
||||
if data.startswith("@@"):
|
||||
continue
|
||||
if singleline:
|
||||
print "\r"," "*78,"\r",data,#,addr
|
||||
else:
|
||||
print data
|
||||
|
||||
|
||||
singleline=False
|
||||
|
||||
def main():
|
||||
print u"Starting TCP logserver on port:", port
|
||||
print u"Press q to quit logserver", port
|
||||
print u"Press c to clear screen", port
|
||||
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||
|
||||
s.bind((u"", port))
|
||||
s.settimeout(1)
|
||||
while 1:
|
||||
try:
|
||||
data, addr = s.recvfrom(100000)
|
||||
print data,
|
||||
except socket.timeout:
|
||||
key = check_key().lower()
|
||||
if u"q" == key:
|
||||
print u"Quitting logserver"
|
||||
break
|
||||
elif u"c" == key:
|
||||
print u"\n" * 100
|
||||
|
||||
if __name__ == u"__main__":
|
||||
main()
|
||||
+240
-142
@@ -6,29 +6,58 @@
|
||||
# Distributed under the terms of the BSD License. The full license is in
|
||||
# the file COPYING, distributed as part of this software.
|
||||
#*****************************************************************************
|
||||
import os,re,math,glob,sys
|
||||
import os,re,math,glob,sys,time
|
||||
import pyreadline.logger as logger
|
||||
from pyreadline.logger import log,log_sock
|
||||
from pyreadline.logger import log
|
||||
from pyreadline.keysyms.common import make_KeyPress_from_keydescr
|
||||
import pyreadline.lineeditor.lineobj as lineobj
|
||||
import pyreadline.lineeditor.history as history
|
||||
import pyreadline.clipboard as clipboard
|
||||
from pyreadline.error import ReadlineError,GetSetError
|
||||
from pyreadline.unicode_helper import ensure_str, ensure_unicode
|
||||
in_ironpython="IronPython" in sys.version
|
||||
in_ironpython=u"IronPython" in sys.version
|
||||
|
||||
class BaseMode(object):
|
||||
mode="base"
|
||||
mode=u"base"
|
||||
def __init__(self,rlobj):
|
||||
self.argument=0
|
||||
self.rlobj=rlobj
|
||||
self.exit_dispatch = {}
|
||||
self.key_dispatch = {}
|
||||
self.argument=1
|
||||
self.prevargument=None
|
||||
self.l_buffer=lineobj.ReadLineTextBuffer("")
|
||||
self._history=history.LineHistory()
|
||||
self.completer_delims = u" \t\n\"\\'`@$><=;|&{("
|
||||
self.show_all_if_ambiguous = u'off'
|
||||
self.mark_directories = u'on'
|
||||
self.completer = None
|
||||
self.begidx = 0
|
||||
self.endidx = 0
|
||||
self.tabstop = 4
|
||||
self.startup_hook = None
|
||||
self.pre_input_hook = None
|
||||
self.first_prompt = True
|
||||
self.cursor_size=25
|
||||
|
||||
self.prompt = u">>> "
|
||||
|
||||
#Paste settings
|
||||
#assumes data on clipboard is path if shorter than 300 characters and doesn't contain \t or \n
|
||||
#and replace \ with / for easier use in ipython
|
||||
self.enable_ipython_paste_for_paths=True
|
||||
|
||||
#automatically convert tabseparated data to list of lists or array constructors
|
||||
self.enable_ipython_paste_list_of_lists=True
|
||||
self.enable_win32_clipboard=True
|
||||
|
||||
self.paste_line_buffer=[]
|
||||
|
||||
self._sub_modes=[]
|
||||
|
||||
|
||||
def __repr__(self):
|
||||
return "<BaseMode>"
|
||||
return u"<BaseMode>"
|
||||
|
||||
def _gs(x):
|
||||
def g(self):
|
||||
@@ -44,80 +73,111 @@ class BaseMode(object):
|
||||
|
||||
def _argreset(self):
|
||||
val=self.argument
|
||||
self.argument=1
|
||||
self.argument=0
|
||||
if val==0:
|
||||
val=1
|
||||
return val
|
||||
argument_reset=property(_argreset)
|
||||
|
||||
ctrl_c_tap_time_interval=property(*_gs("ctrl_c_tap_time_interval"))
|
||||
allow_ctrl_c=property(*_gs("allow_ctrl_c"))
|
||||
l_buffer=property(*_gs("l_buffer"))
|
||||
next_meta=property(*_gs("next_meta"))
|
||||
first_prompt=property(*_gs("first_prompt"))
|
||||
prompt=property(*_gs("prompt"))
|
||||
paste_line_buffer=property(*_gs("paste_line_buffer"))
|
||||
completer_delims=property(*_gs("completer_delims"))
|
||||
show_all_if_ambiguous=property(*_gs("show_all_if_ambiguous"))
|
||||
mark_directories=property(*_gs("mark_directories"))
|
||||
completer=property(*_gs("completer"))
|
||||
begidx=property(*_gs("begidx"))
|
||||
startup_hook=property(*_gs("startup_hook"))
|
||||
pre_input_hook=property(*_gs("pre_input_hook"))
|
||||
endidx=property(*_gs("endidx"))
|
||||
|
||||
console=property(_g("console"))
|
||||
insert_text=property(_g("insert_text"))
|
||||
_print_prompt=property(_g("_print_prompt"))
|
||||
_update_line=property(_g("_update_line"))
|
||||
add_history=property(_g("add_history"))
|
||||
_bell=property(_g("_bell"))
|
||||
_clear_after=property(_g("_clear_after"))
|
||||
_set_cursor=property(_g("_set_cursor"))
|
||||
_update_prompt_pos=property(_g("_update_prompt_pos"))
|
||||
_update_line=property(_g("_update_line"))
|
||||
enable_win32_clipboard=property(_g("enable_win32_clipboard"))
|
||||
enable_ipython_paste_list_of_lists=property(_g("enable_ipython_paste_list_of_lists"))
|
||||
enable_ipython_paste_for_paths=property(_g("enable_ipython_paste_for_paths"))
|
||||
_bell=property(_g("_bell"))
|
||||
_history=property(_g("_history"))
|
||||
prompt_end_pos=property(_g("prompt_end_pos"))
|
||||
prompt_begin_pos=property(_g("prompt_begin_pos"))
|
||||
#used in readline
|
||||
ctrl_c_tap_time_interval=property(*_gs(u"ctrl_c_tap_time_interval"))
|
||||
allow_ctrl_c=property(*_gs(u"allow_ctrl_c"))
|
||||
_print_prompt=property(_g(u"_print_prompt"))
|
||||
_update_line=property(_g(u"_update_line"))
|
||||
console=property(_g(u"console"))
|
||||
prompt_begin_pos=property(_g(u"prompt_begin_pos"))
|
||||
prompt_end_pos=property(_g(u"prompt_end_pos"))
|
||||
|
||||
rl_settings_to_string=property(_g("rl_settings_to_string"))
|
||||
#used in completer _completions
|
||||
# completer_delims=property(*_gs("completer_delims"))
|
||||
_bell=property(_g(u"_bell"))
|
||||
bell_style=property(_g(u"bell_style"))
|
||||
|
||||
def _readline_from_keyboard(self):
|
||||
#used in emacs
|
||||
_clear_after=property(_g(u"_clear_after"))
|
||||
_update_prompt_pos=property(_g(u"_update_prompt_pos"))
|
||||
|
||||
#not used in basemode or emacs
|
||||
|
||||
def process_keyevent(self, keyinfo):
|
||||
raise NotImplementedError
|
||||
|
||||
def readline(self, prompt=''):
|
||||
raise NotImplementedError
|
||||
def readline_setup(self, prompt=u''):
|
||||
self.l_buffer.selection_mark=-1
|
||||
if self.first_prompt:
|
||||
self.first_prompt = False
|
||||
if self.startup_hook:
|
||||
try:
|
||||
self.startup_hook()
|
||||
except:
|
||||
print u'startup hook failed'
|
||||
traceback.print_exc()
|
||||
|
||||
self.l_buffer.reset_line()
|
||||
self.prompt = prompt
|
||||
|
||||
if self.pre_input_hook:
|
||||
try:
|
||||
self.pre_input_hook()
|
||||
except:
|
||||
print u'pre_input_hook failed'
|
||||
traceback.print_exc()
|
||||
self.pre_input_hook = None
|
||||
|
||||
|
||||
####################################
|
||||
|
||||
|
||||
def finalize(self):
|
||||
u"""Every bindable command should call this function for cleanup.
|
||||
Except those that want to set argument to a non-zero value.
|
||||
"""
|
||||
self.argument=0
|
||||
|
||||
|
||||
def add_history(self, text):
|
||||
self._history.add_history(lineobj.ReadLineTextBuffer(text))
|
||||
|
||||
|
||||
#Create key bindings:
|
||||
def rl_settings_to_string(self):
|
||||
out=[u"%-20s: %s"%(u"show all if ambigous",self.show_all_if_ambiguous)]
|
||||
out.append(u"%-20s: %s"%(u"mark_directories",self.mark_directories))
|
||||
out.append(u"%-20s: %s"%(u"bell_style",self.bell_style))
|
||||
out.append(u"------------- key bindings ------------")
|
||||
tablepat=u"%-7s %-7s %-7s %-15s %-15s "
|
||||
out.append(tablepat%(u"Control",u"Meta",u"Shift",u"Keycode/char",u"Function"))
|
||||
bindings=[(k[0],k[1],k[2],k[3],v.__name__) for k,v in self.key_dispatch.iteritems()]
|
||||
bindings.sort()
|
||||
for key in bindings:
|
||||
out.append(tablepat%(key))
|
||||
return out
|
||||
|
||||
|
||||
def _bind_key(self, key, func):
|
||||
'''setup the mapping from key to call the function.'''
|
||||
u"""setup the mapping from key to call the function."""
|
||||
if type(func) != type(self._bind_key):
|
||||
print "Trying to bind non method to keystroke:%s,%s"%(key,func)
|
||||
raise PyreadlineError("Trying to bind non method to keystroke:%s,%s,%s,%s"%(key,func,type(func),type(self._bind_key)))
|
||||
print u"Trying to bind non method to keystroke:%s,%s"%(key,func)
|
||||
raise PyreadlineError(u"Trying to bind non method to keystroke:%s,%s,%s,%s"%(key,func,type(func),type(self._bind_key)))
|
||||
keyinfo = make_KeyPress_from_keydescr(key.lower()).tuple()
|
||||
log(">>>%s -> %s<<<"%(keyinfo,func.__name__))
|
||||
log(u">>>%s -> %s<<<"%(keyinfo,func.__name__))
|
||||
self.key_dispatch[keyinfo] = func
|
||||
|
||||
def _bind_exit_key(self, key):
|
||||
'''setup the mapping from key to call the function.'''
|
||||
u"""setup the mapping from key to call the function."""
|
||||
keyinfo = make_KeyPress_from_keydescr(key.lower()).tuple()
|
||||
self.exit_dispatch[keyinfo] = None
|
||||
|
||||
def init_editing_mode(self, e): # (C-e)
|
||||
'''When in vi command mode, this causes a switch to emacs editing
|
||||
mode.'''
|
||||
"""When in vi command mode, this causes a switch to emacs editing
|
||||
mode."""
|
||||
|
||||
raise NotImplementedError
|
||||
#completion commands
|
||||
|
||||
def _get_completions(self):
|
||||
|
||||
'''Return a list of possible completions for the string ending at the point.
|
||||
|
||||
Also set begidx and endidx in the process.'''
|
||||
"""Return a list of possible completions for the string ending at the point.
|
||||
Also set begidx and endidx in the process."""
|
||||
completions = []
|
||||
self.begidx = self.l_buffer.point
|
||||
self.endidx = self.l_buffer.point
|
||||
@@ -129,8 +189,8 @@ class BaseMode(object):
|
||||
if buf[self.begidx] in self.completer_delims:
|
||||
self.begidx += 1
|
||||
break
|
||||
text = ensure_str(''.join(buf[self.begidx:self.endidx]))
|
||||
log('complete text="%s"' % text)
|
||||
text = ensure_str(u''.join(buf[self.begidx:self.endidx]))
|
||||
log(u'complete text="%s"' % ensure_unicode(text))
|
||||
i = 0
|
||||
while 1:
|
||||
try:
|
||||
@@ -142,18 +202,18 @@ class BaseMode(object):
|
||||
completions.append(r)
|
||||
else:
|
||||
break
|
||||
log('text completions=%s' % completions)
|
||||
log(u'text completions=<%s>' % map(ensure_unicode, completions))
|
||||
if not completions:
|
||||
# get the filename to complete
|
||||
while self.begidx > 0:
|
||||
self.begidx -= 1
|
||||
if buf[self.begidx] in ' \t\n':
|
||||
if buf[self.begidx] in u' \t\n':
|
||||
self.begidx += 1
|
||||
break
|
||||
text = ensure_str(''.join(buf[self.begidx:self.endidx]))
|
||||
log('file complete text="%s"' % text)
|
||||
text = ensure_str(u''.join(buf[self.begidx:self.endidx]))
|
||||
log(u'file complete text="%s"' % ensure_unicode(text))
|
||||
completions = map(ensure_unicode, glob.glob(os.path.expanduser(text) + '*'))
|
||||
if self.mark_directories == 'on':
|
||||
if self.mark_directories == u'on':
|
||||
mc = []
|
||||
for f in completions:
|
||||
if os.path.isdir(f):
|
||||
@@ -161,33 +221,34 @@ class BaseMode(object):
|
||||
else:
|
||||
mc.append(f)
|
||||
completions = mc
|
||||
log('fnames=%s' % completions)
|
||||
log(u'fnames=<%s>' % map(ensure_unicode, completions))
|
||||
return completions
|
||||
|
||||
|
||||
|
||||
def _display_completions(self, completions):
|
||||
if not completions:
|
||||
return
|
||||
self.console.write('\n')
|
||||
self.console.write(u'\n')
|
||||
wmax = max(map(len, completions))
|
||||
w, h = self.console.size()
|
||||
cols = max(1, int((w-1) / (wmax+1)))
|
||||
rows = int(math.ceil(float(len(completions)) / cols))
|
||||
for row in range(rows):
|
||||
s = ''
|
||||
s = u''
|
||||
for col in range(cols):
|
||||
i = col*rows + row
|
||||
if i < len(completions):
|
||||
self.console.write(completions[i].ljust(wmax+1))
|
||||
self.console.write('\n')
|
||||
self.console.write(u'\n')
|
||||
if in_ironpython:
|
||||
self.prompt=sys.ps1
|
||||
self._print_prompt()
|
||||
|
||||
|
||||
def complete(self, e): # (TAB)
|
||||
'''Attempt to perform completion on the text before point. The
|
||||
u"""Attempt to perform completion on the text before point. The
|
||||
actual completion performed is application-specific. The default is
|
||||
filename completion.'''
|
||||
filename completion."""
|
||||
completions = self._get_completions()
|
||||
if completions:
|
||||
cprefix = commonprefix(completions)
|
||||
@@ -196,21 +257,23 @@ class BaseMode(object):
|
||||
self.l_buffer[self.begidx:self.endidx] = rep
|
||||
self.l_buffer.point = point + len(rep) - (self.endidx - self.begidx)
|
||||
if len(completions) > 1:
|
||||
if self.show_all_if_ambiguous == 'on':
|
||||
if self.show_all_if_ambiguous == u'on':
|
||||
self._display_completions(completions)
|
||||
else:
|
||||
self._bell()
|
||||
else:
|
||||
self._bell()
|
||||
self.finalize()
|
||||
|
||||
def possible_completions(self, e): # (M-?)
|
||||
'''List the possible completions of the text before point. '''
|
||||
u"""List the possible completions of the text before point. """
|
||||
completions = self._get_completions()
|
||||
self._display_completions(completions)
|
||||
self.finalize()
|
||||
|
||||
def insert_completions(self, e): # (M-*)
|
||||
'''Insert all completions of the text before point that would have
|
||||
been generated by possible-completions.'''
|
||||
u"""Insert all completions of the text before point that would have
|
||||
been generated by possible-completions."""
|
||||
completions = self._get_completions()
|
||||
b = self.begidx
|
||||
e = self.endidx
|
||||
@@ -221,9 +284,10 @@ class BaseMode(object):
|
||||
b += len(rep)
|
||||
e = b
|
||||
self.line_cursor = b
|
||||
self.finalize()
|
||||
|
||||
def menu_complete(self, e): # ()
|
||||
'''Similar to complete, but replaces the word to be completed with a
|
||||
u"""Similar to complete, but replaces the word to be completed with a
|
||||
single match from the list of possible completions. Repeated
|
||||
execution of menu-complete steps through the list of possible
|
||||
completions, inserting each match in turn. At the end of the list of
|
||||
@@ -231,167 +295,199 @@ class BaseMode(object):
|
||||
and the original text is restored. An argument of n moves n
|
||||
positions forward in the list of matches; a negative argument may be
|
||||
used to move backward through the list. This command is intended to
|
||||
be bound to TAB, but is unbound by default.'''
|
||||
pass
|
||||
be bound to TAB, but is unbound by default."""
|
||||
self.finalize()
|
||||
|
||||
### Methods below here are bindable emacs functions
|
||||
|
||||
|
||||
def insert_text(self, string):
|
||||
u"""Insert text into the command line."""
|
||||
self.l_buffer.insert_text(string, self.argument_reset)
|
||||
self.finalize()
|
||||
|
||||
def beginning_of_line(self, e): # (C-a)
|
||||
'''Move to the start of the current line. '''
|
||||
u"""Move to the start of the current line. """
|
||||
self.l_buffer.beginning_of_line()
|
||||
self.finalize()
|
||||
|
||||
def end_of_line(self, e): # (C-e)
|
||||
'''Move to the end of the line. '''
|
||||
u"""Move to the end of the line. """
|
||||
self.l_buffer.end_of_line()
|
||||
self.finalize()
|
||||
|
||||
def forward_char(self, e): # (C-f)
|
||||
'''Move forward a character. '''
|
||||
u"""Move forward a character. """
|
||||
self.l_buffer.forward_char(self.argument_reset)
|
||||
self.finalize()
|
||||
|
||||
def backward_char(self, e): # (C-b)
|
||||
'''Move back a character. '''
|
||||
u"""Move back a character. """
|
||||
self.l_buffer.backward_char(self.argument_reset)
|
||||
self.finalize()
|
||||
|
||||
def forward_word(self, e): # (M-f)
|
||||
'''Move forward to the end of the next word. Words are composed of
|
||||
letters and digits.'''
|
||||
u"""Move forward to the end of the next word. Words are composed of
|
||||
letters and digits."""
|
||||
self.l_buffer.forward_word(self.argument_reset)
|
||||
self.finalize()
|
||||
|
||||
def backward_word(self, e): # (M-b)
|
||||
'''Move back to the start of the current or previous word. Words are
|
||||
composed of letters and digits.'''
|
||||
u"""Move back to the start of the current or previous word. Words are
|
||||
composed of letters and digits."""
|
||||
self.l_buffer.backward_word(self.argument_reset)
|
||||
self.finalize()
|
||||
|
||||
def forward_word_end(self, e): # ()
|
||||
'''Move forward to the end of the next word. Words are composed of
|
||||
letters and digits.'''
|
||||
u"""Move forward to the end of the next word. Words are composed of
|
||||
letters and digits."""
|
||||
self.l_buffer.forward_word_end(self.argument_reset)
|
||||
self.finalize()
|
||||
|
||||
def backward_word_end(self, e): # ()
|
||||
'''Move forward to the end of the next word. Words are composed of
|
||||
letters and digits.'''
|
||||
u"""Move forward to the end of the next word. Words are composed of
|
||||
letters and digits."""
|
||||
self.l_buffer.backward_word_end(self.argument_reset)
|
||||
self.finalize()
|
||||
|
||||
### Movement with extend selection
|
||||
def beginning_of_line_extend_selection(self, e): #
|
||||
'''Move to the start of the current line. '''
|
||||
u"""Move to the start of the current line. """
|
||||
self.l_buffer.beginning_of_line_extend_selection()
|
||||
self.finalize()
|
||||
|
||||
def end_of_line_extend_selection(self, e): #
|
||||
'''Move to the end of the line. '''
|
||||
u"""Move to the end of the line. """
|
||||
self.l_buffer.end_of_line_extend_selection()
|
||||
self.finalize()
|
||||
|
||||
def forward_char_extend_selection(self, e): #
|
||||
'''Move forward a character. '''
|
||||
u"""Move forward a character. """
|
||||
self.l_buffer.forward_char_extend_selection(self.argument_reset)
|
||||
self.finalize()
|
||||
|
||||
def backward_char_extend_selection(self, e): #
|
||||
'''Move back a character. '''
|
||||
u"""Move back a character. """
|
||||
self.l_buffer.backward_char_extend_selection(self.argument_reset)
|
||||
self.finalize()
|
||||
|
||||
def forward_word_extend_selection(self, e): #
|
||||
'''Move forward to the end of the next word. Words are composed of
|
||||
letters and digits.'''
|
||||
u"""Move forward to the end of the next word. Words are composed of
|
||||
letters and digits."""
|
||||
self.l_buffer.forward_word_extend_selection(self.argument_reset)
|
||||
self.finalize()
|
||||
|
||||
def backward_word_extend_selection(self, e): #
|
||||
'''Move back to the start of the current or previous word. Words are
|
||||
composed of letters and digits.'''
|
||||
u"""Move back to the start of the current or previous word. Words are
|
||||
composed of letters and digits."""
|
||||
self.l_buffer.backward_word_extend_selection(self.argument_reset)
|
||||
self.finalize()
|
||||
|
||||
def forward_word_end_extend_selection(self, e): #
|
||||
'''Move forward to the end of the next word. Words are composed of
|
||||
letters and digits.'''
|
||||
u"""Move forward to the end of the next word. Words are composed of
|
||||
letters and digits."""
|
||||
self.l_buffer.forward_word_end_extend_selection(self.argument_reset)
|
||||
self.finalize()
|
||||
|
||||
def backward_word_end_extend_selection(self, e): #
|
||||
'''Move forward to the end of the next word. Words are composed of
|
||||
letters and digits.'''
|
||||
u"""Move forward to the end of the next word. Words are composed of
|
||||
letters and digits."""
|
||||
self.l_buffer.forward_word_end_extend_selection(self.argument_reset)
|
||||
self.finalize()
|
||||
|
||||
|
||||
######## Change case
|
||||
|
||||
def upcase_word(self, e): # (M-u)
|
||||
'''Uppercase the current (or following) word. With a negative
|
||||
argument, uppercase the previous word, but do not move the cursor.'''
|
||||
u"""Uppercase the current (or following) word. With a negative
|
||||
argument, uppercase the previous word, but do not move the cursor."""
|
||||
self.l_buffer.upcase_word()
|
||||
self.finalize()
|
||||
|
||||
def downcase_word(self, e): # (M-l)
|
||||
'''Lowercase the current (or following) word. With a negative
|
||||
argument, lowercase the previous word, but do not move the cursor.'''
|
||||
u"""Lowercase the current (or following) word. With a negative
|
||||
argument, lowercase the previous word, but do not move the cursor."""
|
||||
self.l_buffer.downcase_word()
|
||||
self.finalize()
|
||||
|
||||
def capitalize_word(self, e): # (M-c)
|
||||
'''Capitalize the current (or following) word. With a negative
|
||||
argument, capitalize the previous word, but do not move the cursor.'''
|
||||
u"""Capitalize the current (or following) word. With a negative
|
||||
argument, capitalize the previous word, but do not move the cursor."""
|
||||
self.l_buffer.capitalize_word()
|
||||
self.finalize()
|
||||
|
||||
|
||||
########
|
||||
def clear_screen(self, e): # (C-l)
|
||||
'''Clear the screen and redraw the current line, leaving the current
|
||||
line at the top of the screen.'''
|
||||
u"""Clear the screen and redraw the current line, leaving the current
|
||||
line at the top of the screen."""
|
||||
self.console.page()
|
||||
self.finalize()
|
||||
|
||||
def redraw_current_line(self, e): # ()
|
||||
'''Refresh the current line. By default, this is unbound.'''
|
||||
pass
|
||||
u"""Refresh the current line. By default, this is unbound."""
|
||||
self.finalize()
|
||||
|
||||
def accept_line(self, e): # (Newline or Return)
|
||||
'''Accept the line regardless of where the cursor is. If this line
|
||||
u"""Accept the line regardless of where the cursor is. If this line
|
||||
is non-empty, it may be added to the history list for future recall
|
||||
with add_history(). If this line is a modified history line, the
|
||||
history line is restored to its original state.'''
|
||||
history line is restored to its original state."""
|
||||
self.finalize()
|
||||
return True
|
||||
|
||||
|
||||
def delete_char(self, e): # (C-d)
|
||||
'''Delete the character at point. If point is at the beginning of
|
||||
u"""Delete the character at point. If point is at the beginning of
|
||||
the line, there are no characters in the line, and the last
|
||||
character typed was not bound to delete-char, then return EOF.'''
|
||||
character typed was not bound to delete-char, then return EOF."""
|
||||
self.l_buffer.delete_char(self.argument_reset)
|
||||
self.finalize()
|
||||
|
||||
def backward_delete_char(self, e): # (Rubout)
|
||||
'''Delete the character behind the cursor. A numeric argument means
|
||||
to kill the characters instead of deleting them.'''
|
||||
u"""Delete the character behind the cursor. A numeric argument means
|
||||
to kill the characters instead of deleting them."""
|
||||
self.l_buffer.backward_delete_char(self.argument_reset)
|
||||
self.finalize()
|
||||
|
||||
def backward_delete_word(self, e): # (Control-Rubout)
|
||||
'''Delete the character behind the cursor. A numeric argument means
|
||||
to kill the characters instead of deleting them.'''
|
||||
u"""Delete the character behind the cursor. A numeric argument means
|
||||
to kill the characters instead of deleting them."""
|
||||
self.l_buffer.backward_delete_word(self.argument_reset)
|
||||
self.finalize()
|
||||
|
||||
def forward_delete_word(self, e): # (Control-Delete)
|
||||
'''Delete the character behind the cursor. A numeric argument means
|
||||
to kill the characters instead of deleting them.'''
|
||||
u"""Delete the character behind the cursor. A numeric argument means
|
||||
to kill the characters instead of deleting them."""
|
||||
self.l_buffer.forward_delete_word(self.argument_reset)
|
||||
self.finalize()
|
||||
|
||||
def delete_horizontal_space(self, e): # ()
|
||||
'''Delete all spaces and tabs around point. By default, this is unbound. '''
|
||||
u"""Delete all spaces and tabs around point. By default, this is unbound. """
|
||||
self.l_buffer.delete_horizontal_space()
|
||||
self.finalize()
|
||||
|
||||
def self_insert(self, e): # (a, b, A, 1, !, ...)
|
||||
'''Insert yourself. '''
|
||||
|
||||
u"""Insert yourself. """
|
||||
if e.char and ord(e.char)!=0: #don't insert null character in buffer, can happen with dead keys.
|
||||
self.insert_text(e.char)
|
||||
self.finalize()
|
||||
|
||||
|
||||
# Paste from clipboard
|
||||
|
||||
def paste(self,e):
|
||||
'''Paste windows clipboard.
|
||||
Assume single line strip other lines and end of line markers and trailing spaces''' #(Control-v)
|
||||
u"""Paste windows clipboard.
|
||||
Assume single line strip other lines and end of line markers and trailing spaces""" #(Control-v)
|
||||
if self.enable_win32_clipboard:
|
||||
txt=clipboard.get_clipboard_text_and_convert(False)
|
||||
txt=txt.split("\n")[0].strip("\r").strip("\n")
|
||||
log("paste: >%s<"%map(ord,txt))
|
||||
self.insert_text(txt)
|
||||
self.finalize()
|
||||
|
||||
def paste_mulitline_code(self,e):
|
||||
'''Paste windows clipboard as multiline code.
|
||||
Removes any empty lines in the code'''
|
||||
u"""Paste windows clipboard as multiline code.
|
||||
Removes any empty lines in the code"""
|
||||
reg=re.compile("\r?\n")
|
||||
if self.enable_win32_clipboard:
|
||||
txt=clipboard.get_clipboard_text_and_convert(False)
|
||||
@@ -401,16 +497,17 @@ class BaseMode(object):
|
||||
self.insert_text(t[0])
|
||||
self.add_history(self.l_buffer.copy())
|
||||
self.paste_line_buffer=t[1:]
|
||||
log("multi: %s"%self.paste_line_buffer)
|
||||
log("multi: >%s<"%self.paste_line_buffer)
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
self.finalize()
|
||||
|
||||
def ipython_paste(self,e):
|
||||
'''Paste windows clipboard. If enable_ipython_paste_list_of_lists is
|
||||
u"""Paste windows clipboard. If enable_ipython_paste_list_of_lists is
|
||||
True then try to convert tabseparated data to repr of list of lists or
|
||||
repr of array.
|
||||
If enable_ipython_paste_for_paths==True then change \\ to / and spaces to \space'''
|
||||
If enable_ipython_paste_for_paths==True then change \\ to / and spaces to \space"""
|
||||
if self.enable_win32_clipboard:
|
||||
txt=clipboard.get_clipboard_text_and_convert(
|
||||
self.enable_ipython_paste_list_of_lists)
|
||||
@@ -418,42 +515,43 @@ class BaseMode(object):
|
||||
if len(txt)<300 and ("\t" not in txt) and ("\n" not in txt):
|
||||
txt=txt.replace("\\","/").replace(" ",r"\ ")
|
||||
self.insert_text(txt)
|
||||
self.finalize()
|
||||
|
||||
|
||||
def copy_region_to_clipboard(self, e): # ()
|
||||
'''Copy the text in the region to the windows clipboard.'''
|
||||
u"""Copy the text in the region to the windows clipboard."""
|
||||
self.l_buffer.copy_region_to_clipboard()
|
||||
self.finalize()
|
||||
|
||||
def copy_selection_to_clipboard(self, e): # ()
|
||||
'''Copy the text in the region to the windows clipboard.'''
|
||||
u"""Copy the text in the region to the windows clipboard."""
|
||||
self.l_buffer.copy_selection_to_clipboard()
|
||||
self.finalize()
|
||||
|
||||
def cut_selection_to_clipboard(self, e): # ()
|
||||
'''Copy the text in the region to the windows clipboard.'''
|
||||
u"""Copy the text in the region to the windows clipboard."""
|
||||
self.l_buffer.cut_selection_to_clipboard()
|
||||
|
||||
self.finalize()
|
||||
|
||||
def dump_functions(self, e): # ()
|
||||
'''Print all of the functions and their key bindings to the Readline
|
||||
u"""Print all of the functions and their key bindings to the Readline
|
||||
output stream. If a numeric argument is supplied, the output is
|
||||
formatted in such a way that it can be made part of an inputrc
|
||||
file. This command is unbound by default.'''
|
||||
file. This command is unbound by default."""
|
||||
print
|
||||
txt="\n".join(self.rl_settings_to_string())
|
||||
print txt
|
||||
self._print_prompt()
|
||||
|
||||
|
||||
|
||||
self.finalize()
|
||||
|
||||
def commonprefix(m):
|
||||
"Given a list of pathnames, returns the longest common leading component"
|
||||
if not m: return ''
|
||||
u"Given a list of pathnames, returns the longest common leading component"
|
||||
if not m: return u''
|
||||
prefix = m[0]
|
||||
for item in m:
|
||||
for i in range(len(prefix)):
|
||||
if prefix[:i+1].lower() != item[:i+1].lower():
|
||||
prefix = prefix[:i]
|
||||
if i == 0: return ''
|
||||
if i == 0: return u''
|
||||
break
|
||||
return prefix
|
||||
|
||||
+481
-426
File diff suppressed because it is too large
Load Diff
+115
-115
@@ -14,12 +14,12 @@ import pyreadline.lineeditor.history as history
|
||||
import basemode
|
||||
|
||||
class NotEmacsMode(basemode.BaseMode):
|
||||
mode="notemacs"
|
||||
mode=u"notemacs"
|
||||
def __init__(self,rlobj):
|
||||
super(NotEmacsMode,self).__init__(rlobj)
|
||||
|
||||
def __repr__(self):
|
||||
return "<NotEmacsMode>"
|
||||
return u"<NotEmacsMode>"
|
||||
|
||||
def _readline_from_keyboard(self):
|
||||
c=self.console
|
||||
@@ -37,7 +37,7 @@ class NotEmacsMode(basemode.BaseMode):
|
||||
raise EOFError
|
||||
|
||||
dispatch_func = self.key_dispatch.get(event.keyinfo,self.self_insert)
|
||||
log("readline from keyboard:%s"%(event.keyinfo,))
|
||||
log(u"readline from keyboard:%s"%(event.keyinfo,))
|
||||
r = None
|
||||
if dispatch_func:
|
||||
r = dispatch_func(event)
|
||||
@@ -49,7 +49,7 @@ class NotEmacsMode(basemode.BaseMode):
|
||||
break
|
||||
|
||||
def readline(self, prompt=''):
|
||||
'''Try to act like GNU readline.'''
|
||||
u'''Try to act like GNU readline.'''
|
||||
# handle startup_hook
|
||||
if self.first_prompt:
|
||||
self.first_prompt = False
|
||||
@@ -57,7 +57,7 @@ class NotEmacsMode(basemode.BaseMode):
|
||||
try:
|
||||
self.startup_hook()
|
||||
except:
|
||||
print 'startup hook failed'
|
||||
print u'startup hook failed'
|
||||
traceback.print_exc()
|
||||
|
||||
c = self.console
|
||||
@@ -69,64 +69,64 @@ class NotEmacsMode(basemode.BaseMode):
|
||||
try:
|
||||
self.pre_input_hook()
|
||||
except:
|
||||
print 'pre_input_hook failed'
|
||||
print u'pre_input_hook failed'
|
||||
traceback.print_exc()
|
||||
self.pre_input_hook = None
|
||||
|
||||
log("in readline: %s"%self.paste_line_buffer)
|
||||
log(u"in readline: %s"%self.paste_line_buffer)
|
||||
if len(self.paste_line_buffer)>0:
|
||||
self.l_buffer=lineobj.ReadlineTextBuffer(self.paste_line_buffer[0])
|
||||
self._update_line()
|
||||
self.paste_line_buffer=self.paste_line_buffer[1:]
|
||||
c.write('\r\n')
|
||||
c.write(u'\r\n')
|
||||
else:
|
||||
self._readline_from_keyboard()
|
||||
c.write('\r\n')
|
||||
c.write(u'\r\n')
|
||||
|
||||
self.add_history(self.l_buffer.copy())
|
||||
|
||||
log('returning(%s)' % self.l_buffer.get_line_text())
|
||||
log(u'returning(%s)' % self.l_buffer.get_line_text())
|
||||
return self.l_buffer.get_line_text() + '\n'
|
||||
|
||||
### Methods below here are bindable emacs functions
|
||||
|
||||
def beginning_of_line(self, e): # (C-a)
|
||||
'''Move to the start of the current line. '''
|
||||
u'''Move to the start of the current line. '''
|
||||
self.l_buffer.beginning_of_line()
|
||||
|
||||
def end_of_line(self, e): # (C-e)
|
||||
'''Move to the end of the line. '''
|
||||
u'''Move to the end of the line. '''
|
||||
self.l_buffer.end_of_line()
|
||||
|
||||
def forward_char(self, e): # (C-f)
|
||||
'''Move forward a character. '''
|
||||
u'''Move forward a character. '''
|
||||
self.l_buffer.forward_char()
|
||||
|
||||
def backward_char(self, e): # (C-b)
|
||||
'''Move back a character. '''
|
||||
u'''Move back a character. '''
|
||||
self.l_buffer.backward_char()
|
||||
|
||||
def forward_word(self, e): # (M-f)
|
||||
'''Move forward to the end of the next word. Words are composed of
|
||||
u'''Move forward to the end of the next word. Words are composed of
|
||||
letters and digits.'''
|
||||
self.l_buffer.forward_word()
|
||||
|
||||
def backward_word(self, e): # (M-b)
|
||||
'''Move back to the start of the current or previous word. Words are
|
||||
u'''Move back to the start of the current or previous word. Words are
|
||||
composed of letters and digits.'''
|
||||
self.l_buffer.backward_word()
|
||||
|
||||
def clear_screen(self, e): # (C-l)
|
||||
'''Clear the screen and redraw the current line, leaving the current
|
||||
u'''Clear the screen and redraw the current line, leaving the current
|
||||
line at the top of the screen.'''
|
||||
self.console.page()
|
||||
|
||||
def redraw_current_line(self, e): # ()
|
||||
'''Refresh the current line. By default, this is unbound.'''
|
||||
u'''Refresh the current line. By default, this is unbound.'''
|
||||
pass
|
||||
|
||||
def accept_line(self, e): # (Newline or Return)
|
||||
'''Accept the line regardless of where the cursor is. If this line
|
||||
u'''Accept the line regardless of where the cursor is. If this line
|
||||
is non-empty, it may be added to the history list for future recall
|
||||
with add_history(). If this line is a modified history line, the
|
||||
history line is restored to its original state.'''
|
||||
@@ -134,47 +134,47 @@ class NotEmacsMode(basemode.BaseMode):
|
||||
|
||||
######### History commands
|
||||
def previous_history(self, e): # (C-p)
|
||||
'''Move back through the history list, fetching the previous command. '''
|
||||
u'''Move back through the history list, fetching the previous command. '''
|
||||
self._history.previous_history(self.l_buffer)
|
||||
|
||||
def next_history(self, e): # (C-n)
|
||||
'''Move forward through the history list, fetching the next command. '''
|
||||
u'''Move forward through the history list, fetching the next command. '''
|
||||
self._history.next_history(self.l_buffer)
|
||||
|
||||
def beginning_of_history(self, e): # (M-<)
|
||||
'''Move to the first line in the history.'''
|
||||
u'''Move to the first line in the history.'''
|
||||
self._history.beginning_of_history()
|
||||
|
||||
def end_of_history(self, e): # (M->)
|
||||
'''Move to the end of the input history, i.e., the line currently
|
||||
u'''Move to the end of the input history, i.e., the line currently
|
||||
being entered.'''
|
||||
self._history.end_of_history(self.l_buffer)
|
||||
|
||||
def _i_search(self, searchfun, direction, init_event):
|
||||
c = self.console
|
||||
line = self.get_line_buffer()
|
||||
query = ''
|
||||
query = u''
|
||||
hc_start = self._history.history_cursor #+ direction
|
||||
while 1:
|
||||
x, y = self.prompt_end_pos
|
||||
c.pos(0, y)
|
||||
if direction < 0:
|
||||
prompt = 'reverse-i-search'
|
||||
prompt = u'reverse-i-search'
|
||||
else:
|
||||
prompt = 'forward-i-search'
|
||||
prompt = u'forward-i-search'
|
||||
|
||||
scroll = c.write_scrolling("%s`%s': %s" % (prompt, query, line))
|
||||
scroll = c.write_scrolling(u"%s`%s': %s" % (prompt, query, line))
|
||||
self._update_prompt_pos(scroll)
|
||||
self._clear_after()
|
||||
|
||||
event = c.getkeypress()
|
||||
if event.keysym == 'BackSpace':
|
||||
if event.keysym == u'BackSpace':
|
||||
if len(query) > 0:
|
||||
query = query[:-1]
|
||||
self._history.history_cursor = hc_start
|
||||
else:
|
||||
self._bell()
|
||||
elif event.char in string.letters + string.digits + string.punctuation + ' ':
|
||||
elif event.char in string.letters + string.digits + string.punctuation + u' ':
|
||||
self._history.history_cursor = hc_start
|
||||
query += event.char
|
||||
elif event.keyinfo == init_event.keyinfo:
|
||||
@@ -182,7 +182,7 @@ class NotEmacsMode(basemode.BaseMode):
|
||||
line=searchfun(query)
|
||||
pass
|
||||
else:
|
||||
if event.keysym != 'Return':
|
||||
if event.keysym != u'Return':
|
||||
self._bell()
|
||||
break
|
||||
line=searchfun(query)
|
||||
@@ -194,14 +194,14 @@ class NotEmacsMode(basemode.BaseMode):
|
||||
self._history.history_cursor=len(self._history.history)
|
||||
|
||||
def reverse_search_history(self, e): # (C-r)
|
||||
'''Search backward starting at the current line and moving up
|
||||
u'''Search backward starting at the current line and moving up
|
||||
through the history as necessary. This is an incremental search.'''
|
||||
# print "HEJ"
|
||||
# self.console.bell()
|
||||
self._i_search(self._history.reverse_search_history, -1, e)
|
||||
|
||||
def forward_search_history(self, e): # (C-s)
|
||||
'''Search forward starting at the current line and moving down
|
||||
u'''Search forward starting at the current line and moving down
|
||||
through the the history as necessary. This is an incremental search.'''
|
||||
# print "HEJ"
|
||||
# self.console.bell()
|
||||
@@ -209,31 +209,31 @@ class NotEmacsMode(basemode.BaseMode):
|
||||
|
||||
|
||||
def non_incremental_reverse_search_history(self, e): # (M-p)
|
||||
'''Search backward starting at the current line and moving up
|
||||
u'''Search backward starting at the current line and moving up
|
||||
through the history as necessary using a non-incremental search for
|
||||
a string supplied by the user.'''
|
||||
self._history.non_incremental_reverse_search_history(self.l_buffer)
|
||||
|
||||
def non_incremental_forward_search_history(self, e): # (M-n)
|
||||
'''Search forward starting at the current line and moving down
|
||||
u'''Search forward starting at the current line and moving down
|
||||
through the the history as necessary using a non-incremental search
|
||||
for a string supplied by the user.'''
|
||||
self._history.non_incremental_reverse_search_history(self.l_buffer)
|
||||
|
||||
def history_search_forward(self, e): # ()
|
||||
'''Search forward through the history for the string of characters
|
||||
u'''Search forward through the history for the string of characters
|
||||
between the start of the current line and the point. This is a
|
||||
non-incremental search. By default, this command is unbound.'''
|
||||
self.l_buffer=self._history.history_search_forward(self.l_buffer)
|
||||
|
||||
def history_search_backward(self, e): # ()
|
||||
'''Search backward through the history for the string of characters
|
||||
u'''Search backward through the history for the string of characters
|
||||
between the start of the current line and the point. This is a
|
||||
non-incremental search. By default, this command is unbound.'''
|
||||
self.l_buffer=self._history.history_search_backward(self.l_buffer)
|
||||
|
||||
def yank_nth_arg(self, e): # (M-C-y)
|
||||
'''Insert the first argument to the previous command (usually the
|
||||
u'''Insert the first argument to the previous command (usually the
|
||||
second word on the previous line) at point. With an argument n,
|
||||
insert the nth word from the previous command (the words in the
|
||||
previous command begin with word 0). A negative argument inserts the
|
||||
@@ -241,76 +241,76 @@ class NotEmacsMode(basemode.BaseMode):
|
||||
pass
|
||||
|
||||
def yank_last_arg(self, e): # (M-. or M-_)
|
||||
'''Insert last argument to the previous command (the last word of
|
||||
u'''Insert last argument to the previous command (the last word of
|
||||
the previous history entry). With an argument, behave exactly like
|
||||
yank-nth-arg. Successive calls to yank-last-arg move back through
|
||||
the history list, inserting the last argument of each line in turn.'''
|
||||
pass
|
||||
|
||||
def delete_char(self, e): # (C-d)
|
||||
'''Delete the character at point. If point is at the beginning of
|
||||
u'''Delete the character at point. If point is at the beginning of
|
||||
the line, there are no characters in the line, and the last
|
||||
character typed was not bound to delete-char, then return EOF.'''
|
||||
self.l_buffer.delete_char()
|
||||
|
||||
def backward_delete_char(self, e): # (Rubout)
|
||||
'''Delete the character behind the cursor. A numeric argument means
|
||||
u'''Delete the character behind the cursor. A numeric argument means
|
||||
to kill the characters instead of deleting them.'''
|
||||
self.l_buffer.backward_delete_char()
|
||||
|
||||
def forward_backward_delete_char(self, e): # ()
|
||||
'''Delete the character under the cursor, unless the cursor is at
|
||||
u'''Delete the character under the cursor, unless the cursor is at
|
||||
the end of the line, in which case the character behind the cursor
|
||||
is deleted. By default, this is not bound to a key.'''
|
||||
pass
|
||||
|
||||
def quoted_insert(self, e): # (C-q or C-v)
|
||||
'''Add the next character typed to the line verbatim. This is how to
|
||||
u'''Add the next character typed to the line verbatim. This is how to
|
||||
insert key sequences like C-q, for example.'''
|
||||
e = self.console.getkeypress()
|
||||
self.insert_text(e.char)
|
||||
|
||||
def tab_insert(self, e): # (M-TAB)
|
||||
'''Insert a tab character. '''
|
||||
u'''Insert a tab character. '''
|
||||
cursor = min(self.l_buffer.point, len(self.l_buffer.line_buffer))
|
||||
ws = ' ' * (self.tabstop - (cursor % self.tabstop))
|
||||
self.insert_text(ws)
|
||||
|
||||
def self_insert(self, e): # (a, b, A, 1, !, ...)
|
||||
'''Insert yourself. '''
|
||||
u'''Insert yourself. '''
|
||||
if ord(e.char)!=0: #don't insert null character in buffer, can happen with dead keys.
|
||||
self.insert_text(e.char)
|
||||
|
||||
def transpose_chars(self, e): # (C-t)
|
||||
'''Drag the character before the cursor forward over the character
|
||||
u'''Drag the character before the cursor forward over the character
|
||||
at the cursor, moving the cursor forward as well. If the insertion
|
||||
point is at the end of the line, then this transposes the last two
|
||||
characters of the line. Negative arguments have no effect.'''
|
||||
self.l_buffer.transpose_chars()
|
||||
|
||||
def transpose_words(self, e): # (M-t)
|
||||
'''Drag the word before point past the word after point, moving
|
||||
u'''Drag the word before point past the word after point, moving
|
||||
point past that word as well. If the insertion point is at the end
|
||||
of the line, this transposes the last two words on the line.'''
|
||||
self.l_buffer.transpose_words()
|
||||
|
||||
def upcase_word(self, e): # (M-u)
|
||||
'''Uppercase the current (or following) word. With a negative
|
||||
u'''Uppercase the current (or following) word. With a negative
|
||||
argument, uppercase the previous word, but do not move the cursor.'''
|
||||
self.l_buffer.upcase_word()
|
||||
|
||||
def downcase_word(self, e): # (M-l)
|
||||
'''Lowercase the current (or following) word. With a negative
|
||||
u'''Lowercase the current (or following) word. With a negative
|
||||
argument, lowercase the previous word, but do not move the cursor.'''
|
||||
self.l_buffer.downcase_word()
|
||||
|
||||
def capitalize_word(self, e): # (M-c)
|
||||
'''Capitalize the current (or following) word. With a negative
|
||||
u'''Capitalize the current (or following) word. With a negative
|
||||
argument, capitalize the previous word, but do not move the cursor.'''
|
||||
self.l_buffer.capitalize_word()
|
||||
|
||||
def overwrite_mode(self, e): # ()
|
||||
'''Toggle overwrite mode. With an explicit positive numeric
|
||||
u'''Toggle overwrite mode. With an explicit positive numeric
|
||||
argument, switches to overwrite mode. With an explicit non-positive
|
||||
numeric argument, switches to insert mode. This command affects only
|
||||
emacs mode; vi mode does overwrite differently. Each call to
|
||||
@@ -321,54 +321,54 @@ class NotEmacsMode(basemode.BaseMode):
|
||||
pass
|
||||
|
||||
def kill_line(self, e): # (C-k)
|
||||
'''Kill the text from point to the end of the line. '''
|
||||
u'''Kill the text from point to the end of the line. '''
|
||||
self.l_buffer.kill_line()
|
||||
|
||||
def backward_kill_line(self, e): # (C-x Rubout)
|
||||
'''Kill backward to the beginning of the line. '''
|
||||
u'''Kill backward to the beginning of the line. '''
|
||||
self.l_buffer.backward_kill_line()
|
||||
|
||||
def unix_line_discard(self, e): # (C-u)
|
||||
'''Kill backward from the cursor to the beginning of the current line. '''
|
||||
u'''Kill backward from the cursor to the beginning of the current line. '''
|
||||
# how is this different from backward_kill_line?
|
||||
self.l_buffer.unix_line_discard()
|
||||
|
||||
def kill_whole_line(self, e): # ()
|
||||
'''Kill all characters on the current line, no matter where point
|
||||
u'''Kill all characters on the current line, no matter where point
|
||||
is. By default, this is unbound.'''
|
||||
self.l_buffer.kill_whole_line()
|
||||
|
||||
def kill_word(self, e): # (M-d)
|
||||
'''Kill from point to the end of the current word, or if between
|
||||
u'''Kill from point to the end of the current word, or if between
|
||||
words, to the end of the next word. Word boundaries are the same as
|
||||
forward-word.'''
|
||||
self.l_buffer.kill_word()
|
||||
|
||||
def backward_kill_word(self, e): # (M-DEL)
|
||||
'''Kill the word behind point. Word boundaries are the same as
|
||||
u'''Kill the word behind point. Word boundaries are the same as
|
||||
backward-word. '''
|
||||
self.l_buffer.backward_kill_word()
|
||||
|
||||
def unix_word_rubout(self, e): # (C-w)
|
||||
'''Kill the word behind point, using white space as a word
|
||||
u'''Kill the word behind point, using white space as a word
|
||||
boundary. The killed text is saved on the kill-ring.'''
|
||||
self.l_buffer.unix_word_rubout()
|
||||
|
||||
def delete_horizontal_space(self, e): # ()
|
||||
'''Delete all spaces and tabs around point. By default, this is unbound. '''
|
||||
u'''Delete all spaces and tabs around point. By default, this is unbound. '''
|
||||
pass
|
||||
|
||||
def kill_region(self, e): # ()
|
||||
'''Kill the text in the current region. By default, this command is unbound. '''
|
||||
u'''Kill the text in the current region. By default, this command is unbound. '''
|
||||
pass
|
||||
|
||||
def copy_region_as_kill(self, e): # ()
|
||||
'''Copy the text in the region to the kill buffer, so it can be
|
||||
u'''Copy the text in the region to the kill buffer, so it can be
|
||||
yanked right away. By default, this command is unbound.'''
|
||||
pass
|
||||
|
||||
def copy_region_to_clipboard(self, e): # ()
|
||||
'''Copy the text in the region to the windows clipboard.'''
|
||||
u'''Copy the text in the region to the windows clipboard.'''
|
||||
if self.enable_win32_clipboard:
|
||||
mark=min(self.l_buffer.mark,len(self.l_buffer.line_buffer))
|
||||
cursor=min(self.l_buffer.point,len(self.l_buffer.line_buffer))
|
||||
@@ -376,72 +376,72 @@ class NotEmacsMode(basemode.BaseMode):
|
||||
return
|
||||
begin=min(cursor,mark)
|
||||
end=max(cursor,mark)
|
||||
toclipboard="".join(self.l_buffer.line_buffer[begin:end])
|
||||
toclipboard=u"".join(self.l_buffer.line_buffer[begin:end])
|
||||
clipboard.SetClipboardText(str(toclipboard))
|
||||
|
||||
def copy_backward_word(self, e): # ()
|
||||
'''Copy the word before point to the kill buffer. The word
|
||||
u'''Copy the word before point to the kill buffer. The word
|
||||
boundaries are the same as backward-word. By default, this command
|
||||
is unbound.'''
|
||||
pass
|
||||
|
||||
def copy_forward_word(self, e): # ()
|
||||
'''Copy the word following point to the kill buffer. The word
|
||||
u'''Copy the word following point to the kill buffer. The word
|
||||
boundaries are the same as forward-word. By default, this command is
|
||||
unbound.'''
|
||||
pass
|
||||
|
||||
def paste(self,e):
|
||||
'''Paste windows clipboard'''
|
||||
u'''Paste windows clipboard'''
|
||||
if self.enable_win32_clipboard:
|
||||
txt=clipboard.get_clipboard_text_and_convert(False)
|
||||
self.insert_text(txt)
|
||||
|
||||
def paste_mulitline_code(self,e):
|
||||
'''Paste windows clipboard'''
|
||||
reg=re.compile("\r?\n")
|
||||
u'''Paste windows clipboard'''
|
||||
reg=re.compile(u"\r?\n")
|
||||
if self.enable_win32_clipboard:
|
||||
txt=clipboard.get_clipboard_text_and_convert(False)
|
||||
t=reg.split(txt)
|
||||
t=[row for row in t if row.strip()!=""] #remove empty lines
|
||||
if t!=[""]:
|
||||
t=[row for row in t if row.strip()!=u""] #remove empty lines
|
||||
if t!=[u""]:
|
||||
self.insert_text(t[0])
|
||||
self.add_history(self.l_buffer.copy())
|
||||
self.paste_line_buffer=t[1:]
|
||||
log("multi: %s"%self.paste_line_buffer)
|
||||
log(u"multi: %s"%self.paste_line_buffer)
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def ipython_paste(self,e):
|
||||
'''Paste windows clipboard. If enable_ipython_paste_list_of_lists is
|
||||
u'''Paste windows clipboard. If enable_ipython_paste_list_of_lists is
|
||||
True then try to convert tabseparated data to repr of list of lists or
|
||||
repr of array'''
|
||||
if self.enable_win32_clipboard:
|
||||
txt=clipboard.get_clipboard_text_and_convert(
|
||||
self.enable_ipython_paste_list_of_lists)
|
||||
if self.enable_ipython_paste_for_paths:
|
||||
if len(txt)<300 and ("\t" not in txt) and ("\n" not in txt):
|
||||
txt=txt.replace("\\","/").replace(" ",r"\ ")
|
||||
if len(txt)<300 and (u"\t" not in txt) and (u"\n" not in txt):
|
||||
txt=txt.replace(u"\\", u"/").replace(u" ", ur"\ ")
|
||||
self.insert_text(txt)
|
||||
|
||||
def yank(self, e): # (C-y)
|
||||
'''Yank the top of the kill ring into the buffer at point. '''
|
||||
u'''Yank the top of the kill ring into the buffer at point. '''
|
||||
pass
|
||||
|
||||
def yank_pop(self, e): # (M-y)
|
||||
'''Rotate the kill-ring, and yank the new top. You can only do this
|
||||
u'''Rotate the kill-ring, and yank the new top. You can only do this
|
||||
if the prior command is yank or yank-pop.'''
|
||||
pass
|
||||
|
||||
|
||||
def digit_argument(self, e): # (M-0, M-1, ... M--)
|
||||
'''Add this digit to the argument already accumulating, or start a
|
||||
u'''Add this digit to the argument already accumulating, or start a
|
||||
new argument. M-- starts a negative argument.'''
|
||||
pass
|
||||
|
||||
def universal_argument(self, e): # ()
|
||||
'''This is another way to specify an argument. If this command is
|
||||
u'''This is another way to specify an argument. If this command is
|
||||
followed by one or more digits, optionally with a leading minus
|
||||
sign, those digits define the argument. If the command is followed
|
||||
by digits, executing universal-argument again ends the numeric
|
||||
@@ -455,83 +455,83 @@ class NotEmacsMode(basemode.BaseMode):
|
||||
pass
|
||||
|
||||
def delete_char_or_list(self, e): # ()
|
||||
'''Deletes the character under the cursor if not at the beginning or
|
||||
u'''Deletes the character under the cursor if not at the beginning or
|
||||
end of the line (like delete-char). If at the end of the line,
|
||||
behaves identically to possible-completions. This command is unbound
|
||||
by default.'''
|
||||
pass
|
||||
|
||||
def start_kbd_macro(self, e): # (C-x ()
|
||||
'''Begin saving the characters typed into the current keyboard macro. '''
|
||||
u'''Begin saving the characters typed into the current keyboard macro. '''
|
||||
pass
|
||||
|
||||
def end_kbd_macro(self, e): # (C-x ))
|
||||
'''Stop saving the characters typed into the current keyboard macro
|
||||
u'''Stop saving the characters typed into the current keyboard macro
|
||||
and save the definition.'''
|
||||
pass
|
||||
|
||||
def call_last_kbd_macro(self, e): # (C-x e)
|
||||
'''Re-execute the last keyboard macro defined, by making the
|
||||
u'''Re-execute the last keyboard macro defined, by making the
|
||||
characters in the macro appear as if typed at the keyboard.'''
|
||||
pass
|
||||
|
||||
def re_read_init_file(self, e): # (C-x C-r)
|
||||
'''Read in the contents of the inputrc file, and incorporate any
|
||||
u'''Read in the contents of the inputrc file, and incorporate any
|
||||
bindings or variable assignments found there.'''
|
||||
pass
|
||||
|
||||
def abort(self, e): # (C-g)
|
||||
'''Abort the current editing command and ring the terminals bell
|
||||
u'''Abort the current editing command and ring the terminals bell
|
||||
(subject to the setting of bell-style).'''
|
||||
self._bell()
|
||||
|
||||
def do_uppercase_version(self, e): # (M-a, M-b, M-x, ...)
|
||||
'''If the metafied character x is lowercase, run the command that is
|
||||
u'''If the metafied character x is lowercase, run the command that is
|
||||
bound to the corresponding uppercase character.'''
|
||||
pass
|
||||
|
||||
def prefix_meta(self, e): # (ESC)
|
||||
'''Metafy the next character typed. This is for keyboards without a
|
||||
u'''Metafy the next character typed. This is for keyboards without a
|
||||
meta key. Typing ESC f is equivalent to typing M-f. '''
|
||||
self.next_meta = True
|
||||
|
||||
def undo(self, e): # (C-_ or C-x C-u)
|
||||
'''Incremental undo, separately remembered for each line.'''
|
||||
u'''Incremental undo, separately remembered for each line.'''
|
||||
self.l_buffer.pop_undo()
|
||||
|
||||
def revert_line(self, e): # (M-r)
|
||||
'''Undo all changes made to this line. This is like executing the
|
||||
u'''Undo all changes made to this line. This is like executing the
|
||||
undo command enough times to get back to the beginning.'''
|
||||
pass
|
||||
|
||||
def tilde_expand(self, e): # (M-~)
|
||||
'''Perform tilde expansion on the current word.'''
|
||||
u'''Perform tilde expansion on the current word.'''
|
||||
pass
|
||||
|
||||
def set_mark(self, e): # (C-@)
|
||||
'''Set the mark to the point. If a numeric argument is supplied, the
|
||||
u'''Set the mark to the point. If a numeric argument is supplied, the
|
||||
mark is set to that position.'''
|
||||
self.l_buffer.set_mark()
|
||||
|
||||
def exchange_point_and_mark(self, e): # (C-x C-x)
|
||||
'''Swap the point with the mark. The current cursor position is set
|
||||
u'''Swap the point with the mark. The current cursor position is set
|
||||
to the saved position, and the old cursor position is saved as the
|
||||
mark.'''
|
||||
pass
|
||||
|
||||
def character_search(self, e): # (C-])
|
||||
'''A character is read and point is moved to the next occurrence of
|
||||
u'''A character is read and point is moved to the next occurrence of
|
||||
that character. A negative count searches for previous occurrences.'''
|
||||
pass
|
||||
|
||||
def character_search_backward(self, e): # (M-C-])
|
||||
'''A character is read and point is moved to the previous occurrence
|
||||
u'''A character is read and point is moved to the previous occurrence
|
||||
of that character. A negative count searches for subsequent
|
||||
occurrences.'''
|
||||
pass
|
||||
|
||||
def insert_comment(self, e): # (M-#)
|
||||
'''Without a numeric argument, the value of the comment-begin
|
||||
u'''Without a numeric argument, the value of the comment-begin
|
||||
variable is inserted at the beginning of the current line. If a
|
||||
numeric argument is supplied, this command acts as a toggle: if the
|
||||
characters at the beginning of the line do not match the value of
|
||||
@@ -541,21 +541,21 @@ class NotEmacsMode(basemode.BaseMode):
|
||||
pass
|
||||
|
||||
def dump_functions(self, e): # ()
|
||||
'''Print all of the functions and their key bindings to the Readline
|
||||
u'''Print all of the functions and their key bindings to the Readline
|
||||
output stream. If a numeric argument is supplied, the output is
|
||||
formatted in such a way that it can be made part of an inputrc
|
||||
file. This command is unbound by default.'''
|
||||
pass
|
||||
|
||||
def dump_variables(self, e): # ()
|
||||
'''Print all of the settable variables and their values to the
|
||||
u'''Print all of the settable variables and their values to the
|
||||
Readline output stream. If a numeric argument is supplied, the
|
||||
output is formatted in such a way that it can be made part of an
|
||||
inputrc file. This command is unbound by default.'''
|
||||
pass
|
||||
|
||||
def dump_macros(self, e): # ()
|
||||
'''Print all of the Readline key sequences bound to macros and the
|
||||
u'''Print all of the Readline key sequences bound to macros and the
|
||||
strings they output. If a numeric argument is supplied, the output
|
||||
is formatted in such a way that it can be made part of an inputrc
|
||||
file. This command is unbound by default.'''
|
||||
@@ -565,38 +565,38 @@ class NotEmacsMode(basemode.BaseMode):
|
||||
#Create key bindings:
|
||||
|
||||
def init_editing_mode(self, e): # (C-e)
|
||||
'''When in vi command mode, this causes a switch to emacs editing
|
||||
u'''When in vi command mode, this causes a switch to emacs editing
|
||||
mode.'''
|
||||
|
||||
self._bind_exit_key('Control-d')
|
||||
self._bind_exit_key('Control-z')
|
||||
self._bind_exit_key(u'Control-d')
|
||||
self._bind_exit_key(u'Control-z')
|
||||
|
||||
# I often accidentally hold the shift or control while typing space
|
||||
self._bind_key('Shift-space', self.self_insert)
|
||||
self._bind_key('Control-space', self.self_insert)
|
||||
self._bind_key('Return', self.accept_line)
|
||||
self._bind_key('Left', self.backward_char)
|
||||
self._bind_key('Control-b', self.backward_char)
|
||||
self._bind_key('Right', self.forward_char)
|
||||
self._bind_key('Control-f', self.forward_char)
|
||||
self._bind_key('BackSpace', self.backward_delete_char)
|
||||
self._bind_key('Home', self.beginning_of_line)
|
||||
self._bind_key('End', self.end_of_line)
|
||||
self._bind_key('Delete', self.delete_char)
|
||||
self._bind_key('Control-d', self.delete_char)
|
||||
self._bind_key('Clear', self.clear_screen)
|
||||
self._bind_key(u'Shift-space', self.self_insert)
|
||||
self._bind_key(u'Control-space', self.self_insert)
|
||||
self._bind_key(u'Return', self.accept_line)
|
||||
self._bind_key(u'Left', self.backward_char)
|
||||
self._bind_key(u'Control-b', self.backward_char)
|
||||
self._bind_key(u'Right', self.forward_char)
|
||||
self._bind_key(u'Control-f', self.forward_char)
|
||||
self._bind_key(u'BackSpace', self.backward_delete_char)
|
||||
self._bind_key(u'Home', self.beginning_of_line)
|
||||
self._bind_key(u'End', self.end_of_line)
|
||||
self._bind_key(u'Delete', self.delete_char)
|
||||
self._bind_key(u'Control-d', self.delete_char)
|
||||
self._bind_key(u'Clear', self.clear_screen)
|
||||
|
||||
|
||||
# make it case insensitive
|
||||
def commonprefix(m):
|
||||
"Given a list of pathnames, returns the longest common leading component"
|
||||
if not m: return ''
|
||||
u"Given a list of pathnames, returns the longest common leading component"
|
||||
if not m: return u''
|
||||
prefix = m[0]
|
||||
for item in m:
|
||||
for i in range(len(prefix)):
|
||||
if prefix[:i+1].lower() != item[:i+1].lower():
|
||||
prefix = prefix[:i]
|
||||
if i == 0: return ''
|
||||
if i == 0: return u''
|
||||
break
|
||||
return prefix
|
||||
|
||||
|
||||
+26
-72
@@ -9,7 +9,7 @@
|
||||
#*****************************************************************************
|
||||
import os
|
||||
import pyreadline.logger as logger
|
||||
from pyreadline.logger import log,log_sock
|
||||
from pyreadline.logger import log
|
||||
import pyreadline.lineeditor.lineobj as lineobj
|
||||
import pyreadline.lineeditor.history as history
|
||||
import basemode
|
||||
@@ -23,73 +23,29 @@ class ViMode(basemode.BaseMode):
|
||||
def __repr__(self):
|
||||
return "<ViMode>"
|
||||
|
||||
def _readline_from_keyboard(self):
|
||||
c=self.console
|
||||
while 1:
|
||||
def process_keyevent(self, keyinfo):
|
||||
def nop(e):
|
||||
pass
|
||||
keytuple=keyinfo.tuple()
|
||||
|
||||
#Process exit keys. Only exit on empty line
|
||||
if keytuple in self.exit_dispatch:
|
||||
if lineobj.EndOfLine(self.l_buffer) == 0:
|
||||
raise EOFError
|
||||
|
||||
dispatch_func = self.key_dispatch.get(keytuple,self.vi_key)
|
||||
log("readline from keyboard:%s->%s"%(keytuple,dispatch_func))
|
||||
r = None
|
||||
if dispatch_func:
|
||||
r = dispatch_func(keyinfo)
|
||||
self.l_buffer.push_undo()
|
||||
|
||||
self.previous_func = dispatch_func
|
||||
if r:
|
||||
self._update_line()
|
||||
event = c.getkeypress()
|
||||
if self.next_meta:
|
||||
self.next_meta = False
|
||||
control, meta, shift, code = event.keyinfo
|
||||
event.keyinfo = (control, True, shift, code)
|
||||
|
||||
#Process exit keys. Only exit on empty line
|
||||
if event.keyinfo in self.exit_dispatch:
|
||||
if lineobj.EndOfLine(self.l_buffer) == 0:
|
||||
raise EOFError
|
||||
|
||||
dispatch_func = self.key_dispatch.get(event.keyinfo.tuple(),self.vi_key)
|
||||
log("readline from keyboard:%s->%s"%(event.keyinfo.tuple(),dispatch_func))
|
||||
r = None
|
||||
if dispatch_func:
|
||||
r = dispatch_func(event)
|
||||
self.l_buffer.push_undo()
|
||||
|
||||
self.previous_func = dispatch_func
|
||||
if r:
|
||||
self._update_line()
|
||||
break
|
||||
|
||||
def readline(self, prompt=''):
|
||||
'''Try to act like GNU readline.'''
|
||||
# handle startup_hook
|
||||
if self.first_prompt:
|
||||
self.first_prompt = False
|
||||
if self.startup_hook:
|
||||
try:
|
||||
self.startup_hook()
|
||||
except:
|
||||
print 'startup hook failed'
|
||||
traceback.print_exc()
|
||||
|
||||
c = self.console
|
||||
self.l_buffer.reset_line()
|
||||
self.prompt = prompt
|
||||
self._print_prompt()
|
||||
|
||||
if self.pre_input_hook:
|
||||
try:
|
||||
self.pre_input_hook()
|
||||
except:
|
||||
print 'pre_input_hook failed'
|
||||
traceback.print_exc()
|
||||
self.pre_input_hook = None
|
||||
|
||||
log("in readline: %s"%self.paste_line_buffer)
|
||||
if len(self.paste_line_buffer)>0:
|
||||
self.l_buffer=lineobj.ReadlineTextBuffer(self.paste_line_buffer[0])
|
||||
self._update_line()
|
||||
self.paste_line_buffer=self.paste_line_buffer[1:]
|
||||
c.write('\r\n')
|
||||
else:
|
||||
self._readline_from_keyboard()
|
||||
c.write('\r\n')
|
||||
|
||||
self.add_history(self.l_buffer.copy())
|
||||
|
||||
log('returning(%s)' % self.l_buffer.get_line_text())
|
||||
return self.l_buffer.get_line_text() + '\n'
|
||||
|
||||
return True
|
||||
return False
|
||||
|
||||
### Methods below here are bindable emacs functions
|
||||
|
||||
def init_editing_mode(self, e): # (M-C-j)
|
||||
@@ -156,8 +112,6 @@ class ViMode(basemode.BaseMode):
|
||||
else:
|
||||
self._vi_command = ViCommand (self)
|
||||
self.vi_set_insert_mode (False)
|
||||
# if self.line_cursor > 0:
|
||||
# self.line_cursor -= 1
|
||||
self.l_buffer.point=lineobj.PrevChar
|
||||
elif self._vi_command and self._vi_command.is_replace_one:
|
||||
self._vi_command.add_char (e.char)
|
||||
@@ -204,9 +158,9 @@ class ViMode(basemode.BaseMode):
|
||||
self.__vi_insert_mode = value
|
||||
if value:
|
||||
self.vi_save_line ()
|
||||
self.console.cursor (size=25)
|
||||
self.cursor_size=25
|
||||
else:
|
||||
self.console.cursor (size=100)
|
||||
self.cursor_size=100
|
||||
|
||||
def vi_undo_restart (self):
|
||||
tpl_undo = (self.l_buffer.point, self.l_buffer.line_buffer[:], )
|
||||
@@ -402,7 +356,7 @@ class ViCommand:
|
||||
if char == '\x1b': # escape
|
||||
self.escape (char)
|
||||
elif char == '\x09': # tab
|
||||
ts = self.readline.tabstop
|
||||
ts = self.tabstop
|
||||
ws = ' ' * (ts - (self.readline.l_buffer.point%ts))
|
||||
self.set_text (ws)
|
||||
elif char == '\x08': # backspace
|
||||
|
||||
+18
-18
@@ -1,5 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""Release data for the pyreadline project.
|
||||
u"""Release data for the pyreadline project.
|
||||
|
||||
$Id$"""
|
||||
|
||||
@@ -13,23 +13,23 @@ $Id$"""
|
||||
|
||||
# Name of the package for release purposes. This is the name which labels
|
||||
# the tarballs and RPMs made by distutils, so it's best to lowercase it.
|
||||
name = 'pyreadline'
|
||||
name = u'pyreadline'
|
||||
|
||||
# For versions with substrings (like 0.6.16.svn), use an extra . to separate
|
||||
# the new substring. We have to avoid using either dashes or underscores,
|
||||
# because bdist_rpm does not accept dashes (an RPM) convention, and
|
||||
# bdist_deb does not accept underscores (a Debian convention).
|
||||
|
||||
branch = ''
|
||||
branch = u''
|
||||
|
||||
version = '1.6.svn'
|
||||
version = u'1.6.svn'
|
||||
|
||||
revision = '$Revision$'
|
||||
revision = u'$Revision$'
|
||||
|
||||
description = "A python implmementation of GNU readline."
|
||||
description = u"A python implmementation of GNU readline."
|
||||
|
||||
long_description = \
|
||||
"""
|
||||
u"""
|
||||
The pyreadline package is a python implementation of GNU readline functionality
|
||||
it is based on the ctypes based UNC readline package by Gary Bishop.
|
||||
It is not complete. It has been tested for use with windows 2000 and windows xp.
|
||||
@@ -52,23 +52,23 @@ Features:
|
||||
.. _repository: http://ipython.scipy.org/svn/ipython/pyreadline/trunk#egg=pyreadline-dev
|
||||
"""
|
||||
|
||||
license = 'BSD'
|
||||
license = u'BSD'
|
||||
|
||||
authors = {'Jorgen' : ('Jorgen Stenarson','jorgen.stenarson@bostream.nu'),
|
||||
'Gary': ('Gary Bishop', ''),
|
||||
'Jack': ('Jack Trainor', ''),
|
||||
authors = {u'Jorgen' : (u'Jorgen Stenarson',u'jorgen.stenarson@bostream.nu'),
|
||||
u'Gary': (u'Gary Bishop', ''),
|
||||
u'Jack': (u'Jack Trainor', ''),
|
||||
}
|
||||
|
||||
url = 'http://ipython.scipy.org/moin/PyReadline/Intro'
|
||||
url = u'http://ipython.scipy.org/moin/PyReadline/Intro'
|
||||
|
||||
download_url = ''
|
||||
download_url = u''
|
||||
|
||||
platforms = ['Windows XP/2000/NT','Windows 95/98/ME']
|
||||
platforms = [u'Windows XP/2000/NT',u'Windows 95/98/ME']
|
||||
|
||||
keywords = ['readline','pyreadline']
|
||||
keywords = [u'readline',u'pyreadline']
|
||||
|
||||
classifiers = ['Development Status :: 4 - Beta',
|
||||
'Environment :: Console',
|
||||
'Operating System :: Microsoft :: Windows',]
|
||||
classifiers = [u'Development Status :: 4 - Beta',
|
||||
u'Environment :: Console',
|
||||
u'Operating System :: Microsoft :: Windows',]
|
||||
|
||||
|
||||
|
||||
+397
-275
@@ -6,190 +6,161 @@
|
||||
# Distributed under the terms of the BSD License. The full license is in
|
||||
# the file COPYING, distributed as part of this software.
|
||||
#*****************************************************************************
|
||||
''' an attempt to implement readline for Python in Python using ctypes'''
|
||||
import sys,os,re
|
||||
u''' an attempt to implement readline for Python in Python using ctypes'''
|
||||
import sys,os,re,time
|
||||
from glob import glob
|
||||
|
||||
import clipboard,logger,console
|
||||
from logger import log,log_sock
|
||||
from error import ReadlineError,GetSetError
|
||||
from pyreadline.keysyms.common import make_KeyPress_from_keydescr
|
||||
import release
|
||||
|
||||
import pyreadline.lineeditor.lineobj as lineobj
|
||||
import pyreadline.lineeditor.history as history
|
||||
import release
|
||||
import pyreadline.clipboard as clipboard
|
||||
import pyreadline.console as console
|
||||
import pyreadline.logger as logger
|
||||
|
||||
from pyreadline.keysyms.common import make_KeyPress_from_keydescr
|
||||
from pyreadline.unicode_helper import ensure_unicode
|
||||
from logger import log
|
||||
from modes import editingmodes
|
||||
from error import ReadlineError, GetSetError
|
||||
|
||||
in_ironpython="IronPython" in sys.version
|
||||
in_ironpython = u"IronPython" in sys.version
|
||||
if in_ironpython:#ironpython does not provide a prompt string to readline
|
||||
import System
|
||||
default_prompt=">>> "
|
||||
default_prompt = u">>> "
|
||||
else:
|
||||
default_prompt=""
|
||||
default_prompt = u""
|
||||
import pdb
|
||||
|
||||
|
||||
def quote_char(c):
|
||||
if ord(c)>0:
|
||||
return c
|
||||
class MockConsoleError(Exception):
|
||||
pass
|
||||
|
||||
def inword(buffer,point):
|
||||
return buffer[point:point+1] in [A-Za-z0-9]
|
||||
class MockConsole(object):
|
||||
u"""object used during refactoring. Should raise errors when someone tries to use it.
|
||||
"""
|
||||
def __setattr__(self, x):
|
||||
raise MockConsoleError(u"Should not try to get attributes from MockConsole")
|
||||
|
||||
def cursor(self, size=50):
|
||||
pass
|
||||
|
||||
class Readline(object):
|
||||
class BaseReadline(object):
|
||||
def __init__(self):
|
||||
self.startup_hook = None
|
||||
self.pre_input_hook = None
|
||||
self.completer = None
|
||||
self.completer_delims = " \t\n\"\\'`@$><=;|&{("
|
||||
self.console = console.Console()
|
||||
self.size = self.console.size()
|
||||
self.prompt_color = None
|
||||
self.command_color = None
|
||||
self.selection_color = self.console.saveattr<<4
|
||||
self.key_dispatch = {}
|
||||
self.previous_func = None
|
||||
self.first_prompt = True
|
||||
self.next_meta = False # True to force meta on next character
|
||||
self.tabstop = 4
|
||||
self.allow_ctrl_c=False
|
||||
self.ctrl_c_tap_time_interval=0.3
|
||||
self.debug=False
|
||||
|
||||
self.begidx = 0
|
||||
self.endidx = 0
|
||||
|
||||
# variables you can control with parse_and_bind
|
||||
self.show_all_if_ambiguous = 'off'
|
||||
self.mark_directories = 'on'
|
||||
self.bell_style = 'none'
|
||||
self.mark=-1
|
||||
self.l_buffer=lineobj.ReadLineTextBuffer("")
|
||||
self._history=history.LineHistory()
|
||||
self.allow_ctrl_c = False
|
||||
self.ctrl_c_tap_time_interval = 0.3
|
||||
|
||||
self.debug = False
|
||||
self.bell_style = u'none'
|
||||
self.mark = -1
|
||||
self.console=MockConsole()
|
||||
# this code needs to follow l_buffer and history creation
|
||||
self.editingmodes=[mode(self) for mode in editingmodes]
|
||||
self.editingmodes = [mode(self) for mode in editingmodes]
|
||||
for mode in self.editingmodes:
|
||||
mode.init_editing_mode(None)
|
||||
self.mode=self.editingmodes[0]
|
||||
self.mode = self.editingmodes[0]
|
||||
|
||||
self.read_inputrc()
|
||||
log("\n".join(self.rl_settings_to_string()))
|
||||
log(u"\n".join(self.mode.rl_settings_to_string()))
|
||||
|
||||
#Paste settings
|
||||
#assumes data on clipboard is path if shorter than 300 characters and doesn't contain \t or \n
|
||||
#and replace \ with / for easier use in ipython
|
||||
self.enable_ipython_paste_for_paths=True
|
||||
self.callback = None
|
||||
|
||||
#automatically convert tabseparated data to list of lists or array constructors
|
||||
self.enable_ipython_paste_list_of_lists=True
|
||||
self.enable_win32_clipboard=True
|
||||
|
||||
self.paste_line_buffer=[]
|
||||
|
||||
#Below is for refactoring, raise errors when using old style attributes
|
||||
#that should be refactored out
|
||||
def _g(x):
|
||||
def g(self):
|
||||
raise GetSetError("GET %s"%x)
|
||||
def s(self,q):
|
||||
raise GetSetError("SET %s"%x)
|
||||
return g,s
|
||||
line_buffer=property(*_g("line_buffer"))
|
||||
line_cursor=property(*_g("line_buffer"))
|
||||
undo_stack =property(*_g("undo_stack")) # each entry is a tuple with cursor_position and line_text
|
||||
history_length =property(*_g("history_length")) # each entry is a tuple with cursor_position and line_text
|
||||
history =property(*_g("history")) # each entry is a tuple with cursor_position and line_text
|
||||
history_cursor =property(*_g("history_cursor")) # each entry is a tuple with cursor_position and line_text
|
||||
|
||||
|
||||
# To export as readline interface
|
||||
|
||||
def parse_and_bind(self, string):
|
||||
'''Parse and execute single line of a readline init file.'''
|
||||
u'''Parse and execute single line of a readline init file.'''
|
||||
try:
|
||||
log('parse_and_bind("%s")' % string)
|
||||
if string.startswith('#'):
|
||||
log(u'parse_and_bind("%s")' % string)
|
||||
if string.startswith(u'#'):
|
||||
return
|
||||
if string.startswith('set'):
|
||||
m = re.compile(r'set\s+([-a-zA-Z0-9]+)\s+(.+)\s*$').match(string)
|
||||
if string.startswith(u'set'):
|
||||
m = re.compile(ur'set\s+([-a-zA-Z0-9]+)\s+(.+)\s*$').match(string)
|
||||
if m:
|
||||
var_name = m.group(1)
|
||||
val = m.group(2)
|
||||
try:
|
||||
setattr(self, var_name.replace('-','_'), val)
|
||||
setattr(self, var_name.replace(u'-',u'_'), val)
|
||||
except AttributeError:
|
||||
log('unknown var="%s" val="%s"' % (var_name, val))
|
||||
log(u'unknown var="%s" val="%s"' % (var_name, val))
|
||||
else:
|
||||
log('bad set "%s"' % string)
|
||||
log(u'bad set "%s"' % string)
|
||||
return
|
||||
m = re.compile(r'\s*(.+)\s*:\s*([-a-zA-Z]+)\s*$').match(string)
|
||||
m = re.compile(ur'\s*(.+)\s*:\s*([-a-zA-Z]+)\s*$').match(string)
|
||||
if m:
|
||||
key = m.group(1)
|
||||
func_name = m.group(2)
|
||||
py_name = func_name.replace('-', '_')
|
||||
py_name = func_name.replace(u'-', u'_')
|
||||
try:
|
||||
func = getattr(self.mode, py_name)
|
||||
except AttributeError:
|
||||
log('unknown func key="%s" func="%s"' % (key, func_name))
|
||||
log(u'unknown func key="%s" func="%s"' % (key, func_name))
|
||||
if self.debug:
|
||||
print 'pyreadline parse_and_bind error, unknown function to bind: "%s"' % func_name
|
||||
print u'pyreadline parse_and_bind error, unknown function to bind: "%s"' % func_name
|
||||
return
|
||||
self.mode._bind_key(key, func)
|
||||
except:
|
||||
log('error')
|
||||
log(u'error')
|
||||
raise
|
||||
|
||||
def _set_prompt(self, prompt):
|
||||
self.mode.prompt = prompt
|
||||
|
||||
def _get_prompt(self):
|
||||
return self.mode.prompt
|
||||
|
||||
prompt = property(_get_prompt, _set_prompt)
|
||||
|
||||
|
||||
def get_line_buffer(self):
|
||||
'''Return the current contents of the line buffer.'''
|
||||
return self.l_buffer.get_line_text()
|
||||
u'''Return the current contents of the line buffer.'''
|
||||
return self.mode.l_buffer.get_line_text()
|
||||
|
||||
def insert_text(self, string):
|
||||
'''Insert text into the command line.'''
|
||||
self.l_buffer.insert_text(string)
|
||||
u'''Insert text into the command line.'''
|
||||
self.mode.insert_text(string)
|
||||
|
||||
def read_init_file(self, filename=None):
|
||||
'''Parse a readline initialization file. The default filename is the last filename used.'''
|
||||
log('read_init_file("%s")' % filename)
|
||||
u'''Parse a readline initialization file. The default filename is the last filename used.'''
|
||||
log(u'read_init_file("%s")' % filename)
|
||||
|
||||
#History file book keeping methods (non-bindable)
|
||||
|
||||
def add_history(self, line):
|
||||
'''Append a line to the history buffer, as if it was the last line typed.'''
|
||||
self._history.add_history(line)
|
||||
u'''Append a line to the history buffer, as if it was the last line typed.'''
|
||||
self.mode._history.add_history(line)
|
||||
|
||||
def get_history_length(self ):
|
||||
'''Return the desired length of the history file.
|
||||
u'''Return the desired length of the history file.
|
||||
|
||||
Negative values imply unlimited history file size.'''
|
||||
return self._history.get_history_length()
|
||||
return self.mode._history.get_history_length()
|
||||
|
||||
def set_history_length(self, length):
|
||||
'''Set the number of lines to save in the history file.
|
||||
u'''Set the number of lines to save in the history file.
|
||||
|
||||
write_history_file() uses this value to truncate the history file
|
||||
when saving. Negative values imply unlimited history file size.
|
||||
'''
|
||||
self._history.set_history_length(length)
|
||||
self.mode._history.set_history_length(length)
|
||||
|
||||
def clear_history(self):
|
||||
'''Clear readline history'''
|
||||
self._history.clear_history()
|
||||
u'''Clear readline history'''
|
||||
self.mode._history.clear_history()
|
||||
|
||||
def read_history_file(self, filename=None):
|
||||
'''Load a readline history file. The default filename is ~/.history.'''
|
||||
self._history.read_history_file(filename)
|
||||
u'''Load a readline history file. The default filename is ~/.history.'''
|
||||
if filename is None:
|
||||
filename = self.mode._history.history_filename
|
||||
log(u"read_history_file from %s"%ensure_unicode(filename))
|
||||
self.mode._history.read_history_file(filename)
|
||||
|
||||
def write_history_file(self, filename=None):
|
||||
'''Save a readline history file. The default filename is ~/.history.'''
|
||||
self._history.write_history_file(filename)
|
||||
u'''Save a readline history file. The default filename is ~/.history.'''
|
||||
self.mode._history.write_history_file(filename)
|
||||
|
||||
#Completer functions
|
||||
|
||||
def set_completer(self, function=None):
|
||||
'''Set or remove the completer function.
|
||||
u'''Set or remove the completer function.
|
||||
|
||||
If function is specified, it will be used as the new completer
|
||||
function; if omitted or None, any completer function already
|
||||
@@ -198,34 +169,33 @@ class Readline(object):
|
||||
non-string value. It should return the next possible completion
|
||||
starting with text.
|
||||
'''
|
||||
log('set_completer')
|
||||
self.completer = function
|
||||
log(u'set_completer')
|
||||
self.mode.completer = function
|
||||
|
||||
def get_completer(self):
|
||||
'''Get the completer function.
|
||||
'''
|
||||
|
||||
log('get_completer')
|
||||
return self.completer
|
||||
u'''Get the completer function.
|
||||
'''
|
||||
log(u'get_completer')
|
||||
return self.mode.completer
|
||||
|
||||
def get_begidx(self):
|
||||
'''Get the beginning index of the readline tab-completion scope.'''
|
||||
return self.begidx
|
||||
u'''Get the beginning index of the readline tab-completion scope.'''
|
||||
return self.mode.begidx
|
||||
|
||||
def get_endidx(self):
|
||||
'''Get the ending index of the readline tab-completion scope.'''
|
||||
return self.endidx
|
||||
u'''Get the ending index of the readline tab-completion scope.'''
|
||||
return self.mode.endidx
|
||||
|
||||
def set_completer_delims(self, string):
|
||||
'''Set the readline word delimiters for tab-completion.'''
|
||||
self.completer_delims = string
|
||||
u'''Set the readline word delimiters for tab-completion.'''
|
||||
self.mode.completer_delims = string
|
||||
|
||||
def get_completer_delims(self):
|
||||
'''Get the readline word delimiters for tab-completion.'''
|
||||
return self.completer_delims
|
||||
u'''Get the readline word delimiters for tab-completion.'''
|
||||
return self.mode.completer_delims.encode("ascii")
|
||||
|
||||
def set_startup_hook(self, function=None):
|
||||
'''Set or remove the startup_hook function.
|
||||
u'''Set or remove the startup_hook function.
|
||||
|
||||
If function is specified, it will be used as the new startup_hook
|
||||
function; if omitted or None, any hook function already installed is
|
||||
@@ -233,10 +203,10 @@ class Readline(object):
|
||||
before readline prints the first prompt.
|
||||
|
||||
'''
|
||||
self.startup_hook = function
|
||||
self.mode.startup_hook = function
|
||||
|
||||
def set_pre_input_hook(self, function=None):
|
||||
'''Set or remove the pre_input_hook function.
|
||||
u'''Set or remove the pre_input_hook function.
|
||||
|
||||
If function is specified, it will be used as the new pre_input_hook
|
||||
function; if omitted or None, any hook function already installed is
|
||||
@@ -245,34 +215,202 @@ class Readline(object):
|
||||
starts reading input characters.
|
||||
|
||||
'''
|
||||
self.pre_input_hook = function
|
||||
self.mode.pre_input_hook = function
|
||||
|
||||
#Functions that are not relevant for all Readlines but should at least have a NOP
|
||||
|
||||
def _bell(self):
|
||||
pass
|
||||
|
||||
#
|
||||
# Standard call, not available for all implementations
|
||||
#
|
||||
|
||||
def readline(self, prompt=u''):
|
||||
raise NotImplementedError
|
||||
|
||||
#
|
||||
# Callback interface
|
||||
#
|
||||
def process_keyevent(self, keyinfo):
|
||||
return self.mode.process_keyevent(keyinfo)
|
||||
|
||||
def readline_setup(self, prompt=u""):
|
||||
return self.mode.readline_setup(prompt)
|
||||
|
||||
def keyboard_poll(self):
|
||||
return self.mode._readline_from_keyboard_poll()
|
||||
|
||||
def callback_handler_install(self, prompt, callback):
|
||||
u'''bool readline_callback_handler_install ( string prompt, callback callback)
|
||||
Initializes the readline callback interface and terminal, prints the prompt and returns immediately
|
||||
'''
|
||||
self.callback = callback
|
||||
self.readline_setup(prompt)
|
||||
|
||||
def callback_handler_remove(self):
|
||||
u'''Removes a previously installed callback handler and restores terminal settings'''
|
||||
self.callback = None
|
||||
|
||||
def callback_read_char(self):
|
||||
u'''Reads a character and informs the readline callback interface when a line is received'''
|
||||
if self.keyboard_poll():
|
||||
line = self.get_line_buffer() + u'\n'
|
||||
# however there is another newline added by
|
||||
# self.mode.readline_setup(prompt) which is called by callback_handler_install
|
||||
# this differs from GNU readline
|
||||
self.add_history(self.mode.l_buffer)
|
||||
# TADA:
|
||||
self.callback(line)
|
||||
|
||||
def read_inputrc(self, #in 2.4 we cannot call expanduser with unicode string
|
||||
inputrcpath=os.path.expanduser("~/pyreadlineconfig.ini")):
|
||||
modes = dict([(x.mode,x) for x in self.editingmodes])
|
||||
mode = self.editingmodes[0].mode
|
||||
def setmode(name):
|
||||
self.mode = modes[name]
|
||||
def bind_key(key, name):
|
||||
if hasattr(modes[mode], name):
|
||||
modes[mode]._bind_key(key, getattr(modes[mode], name))
|
||||
else:
|
||||
print u"Trying to bind unknown command '%s' to key '%s'"%(name, key)
|
||||
def un_bind_key(key):
|
||||
keyinfo = make_KeyPress_from_keydescr(key).tuple()
|
||||
if keyinfo in modes[mode].key_dispatch:
|
||||
del modes[mode].key_dispatch[keyinfo]
|
||||
|
||||
def bind_exit_key(key):
|
||||
modes[mode]._bind_exit_key(key)
|
||||
|
||||
def un_bind_exit_key(key):
|
||||
keyinfo = make_KeyPress_from_keydescr(key).tuple()
|
||||
if keyinfo in modes[mode].exit_dispatch:
|
||||
del modes[mode].exit_dispatch[keyinfo]
|
||||
|
||||
def setkill_ring_to_clipboard(killring):
|
||||
import pyreadline.lineeditor.lineobj
|
||||
pyreadline.lineeditor.lineobj.kill_ring_to_clipboard = killring
|
||||
|
||||
def sethistoryfilename(filename):
|
||||
self.mode._history.history_filename=os.path.expanduser(filename)
|
||||
|
||||
def setbellstyle(mode):
|
||||
self.bell_style = mode
|
||||
|
||||
def sethistorylength(length):
|
||||
self.mode._history.history_length = int(length)
|
||||
|
||||
def allow_ctrl_c(mode):
|
||||
log(u"allow_ctrl_c:%s:%s"%(self.allow_ctrl_c, mode))
|
||||
self.allow_ctrl_c = mode
|
||||
|
||||
def setbellstyle(mode):
|
||||
self.bell_style = mode
|
||||
|
||||
def show_all_if_ambiguous(mode):
|
||||
self.mode.show_all_if_ambiguous = mode
|
||||
|
||||
def ctrl_c_tap_time_interval(mode):
|
||||
self.ctrl_c_tap_time_interval = mode
|
||||
|
||||
def mark_directories(mode):
|
||||
self.mode.mark_directories = mode
|
||||
|
||||
def completer_delims(delims):
|
||||
self.mode.completer_delims = delims
|
||||
|
||||
def debug_output(on, filename=u"pyreadline_debug_log.txt"): #Not implemented yet
|
||||
if on in [u"on", u"on_nologfile"]:
|
||||
self.debug=True
|
||||
|
||||
if on == "on":
|
||||
logger.start_file_log(filename)
|
||||
logger.start_socket_log()
|
||||
logger.log(u"STARTING LOG")
|
||||
elif on == u"on_nologfile":
|
||||
logger.start_socket_log()
|
||||
logger.log(u"STARTING LOG")
|
||||
else:
|
||||
logger.log(u"STOPING LOG")
|
||||
logger.stop_file_log()
|
||||
logger.stop_socket_log()
|
||||
|
||||
_color_trtable={u"black":0, u"darkred":4, u"darkgreen":2,
|
||||
u"darkyellow":6, u"darkblue":1, u"darkmagenta":5,
|
||||
u"darkcyan":3, u"gray":7, u"red":4+8,
|
||||
u"green":2+8, u"yellow":6+8, u"blue":1+8,
|
||||
u"magenta":5+8, u"cyan":3+8, u"white":7+8}
|
||||
|
||||
def set_prompt_color(color):
|
||||
self.prompt_color = self._color_trtable.get(color.lower(),7)
|
||||
|
||||
def set_input_color(color):
|
||||
self.command_color=self._color_trtable.get(color.lower(),7)
|
||||
|
||||
loc = {u"branch":release.branch,
|
||||
u"version":release.version,
|
||||
u"mode":mode,
|
||||
u"modes":modes,
|
||||
u"set_mode":setmode,
|
||||
u"bind_key":bind_key,
|
||||
u"bind_exit_key":bind_exit_key,
|
||||
u"un_bind_key":un_bind_key,
|
||||
u"un_bind_exit_key":un_bind_exit_key,
|
||||
u"bell_style":setbellstyle,
|
||||
u"mark_directories":mark_directories,
|
||||
u"show_all_if_ambiguous":show_all_if_ambiguous,
|
||||
u"completer_delims":completer_delims,
|
||||
u"debug_output":debug_output,
|
||||
u"history_filename":sethistoryfilename,
|
||||
u"history_length":sethistorylength,
|
||||
u"set_prompt_color":set_prompt_color,
|
||||
u"set_input_color":set_input_color,
|
||||
u"allow_ctrl_c":allow_ctrl_c,
|
||||
u"ctrl_c_tap_time_interval":ctrl_c_tap_time_interval,
|
||||
u"kill_ring_to_clipboard":setkill_ring_to_clipboard,
|
||||
}
|
||||
if os.path.isfile(inputrcpath):
|
||||
try:
|
||||
execfile(inputrcpath, loc, loc)
|
||||
except Exception,x:
|
||||
raise
|
||||
import traceback
|
||||
print >>sys.stderr, u"Error reading .pyinputrc"
|
||||
filepath,lineno=traceback.extract_tb(sys.exc_traceback)[1][:2]
|
||||
print >>sys.stderr, u"Line: %s in file %s"%(lineno, filepath)
|
||||
print >>sys.stderr, x
|
||||
raise ReadlineError(u"Error reading .pyinputrc")
|
||||
|
||||
|
||||
|
||||
class Readline(BaseReadline):
|
||||
"""Baseclass for readline based on a console
|
||||
"""
|
||||
def __init__(self):
|
||||
BaseReadline.__init__(self)
|
||||
self.console = console.Console()
|
||||
self.selection_color = self.console.saveattr<<4
|
||||
self.command_color = None
|
||||
self.prompt_color = None
|
||||
self.size = self.console.size()
|
||||
|
||||
# variables you can control with parse_and_bind
|
||||
|
||||
# To export as readline interface
|
||||
|
||||
|
||||
## Internal functions
|
||||
|
||||
def rl_settings_to_string(self):
|
||||
out=["%-20s: %s"%("show all if ambigous",self.show_all_if_ambiguous)]
|
||||
out.append("%-20s: %s"%("mark_directories",self.mark_directories))
|
||||
out.append("%-20s: %s"%("bell_style",self.bell_style))
|
||||
out.append("%-20s: %s"%("mark_directories",self.mark_directories))
|
||||
out.append("------------- key bindings ------------")
|
||||
tablepat="%-7s %-7s %-7s %-15s %-15s "
|
||||
out.append(tablepat%("Control","Meta","Shift","Keycode/char","Function"))
|
||||
bindings=[(k[0],k[1],k[2],k[3],v.__name__) for k,v in self.mode.key_dispatch.iteritems()]
|
||||
bindings.sort()
|
||||
for key in bindings:
|
||||
out.append(tablepat%(key))
|
||||
return out
|
||||
|
||||
def _bell(self):
|
||||
'''ring the bell if requested.'''
|
||||
if self.bell_style == 'none':
|
||||
u'''ring the bell if requested.'''
|
||||
if self.bell_style == u'none':
|
||||
pass
|
||||
elif self.bell_style == 'visible':
|
||||
raise NotImplementedError("Bellstyle visible is not implemented yet.")
|
||||
elif self.bell_style == 'audible':
|
||||
elif self.bell_style == u'visible':
|
||||
raise NotImplementedError(u"Bellstyle visible is not implemented yet.")
|
||||
elif self.bell_style == u'audible':
|
||||
self.console.bell()
|
||||
else:
|
||||
raise ReadlineError("Bellstyle %s unknown."%self.bell_style)
|
||||
raise ReadlineError(u"Bellstyle %s unknown."%self.bell_style)
|
||||
|
||||
def _clear_after(self):
|
||||
c = self.console
|
||||
@@ -285,7 +423,7 @@ class Readline(object):
|
||||
c = self.console
|
||||
xc, yc = self.prompt_end_pos
|
||||
w, h = c.size()
|
||||
xc += self.l_buffer.visible_line_width()
|
||||
xc += self.mode.l_buffer.visible_line_width()
|
||||
while(xc >= w):
|
||||
xc -= w
|
||||
yc += 1
|
||||
@@ -308,171 +446,155 @@ class Readline(object):
|
||||
self.prompt_end_pos = (ex, ey - n)
|
||||
|
||||
def _update_line(self):
|
||||
c=self.console
|
||||
c = self.console
|
||||
l_buffer = self.mode.l_buffer
|
||||
c.cursor(0) #Hide cursor avoiding flicking
|
||||
c.pos(*self.prompt_end_pos)
|
||||
ltext = self.l_buffer.quoted_text()
|
||||
if self.l_buffer.enable_selection and self.l_buffer.selection_mark>=0:
|
||||
start=len(self.l_buffer[:self.l_buffer.selection_mark].quoted_text())
|
||||
stop=len(self.l_buffer[:self.l_buffer.point].quoted_text())
|
||||
if start>stop:
|
||||
stop,start=start,stop
|
||||
c.pos(*self.prompt_begin_pos)
|
||||
self._print_prompt()
|
||||
ltext = l_buffer.quoted_text()
|
||||
if l_buffer.enable_selection and (l_buffer.selection_mark >= 0):
|
||||
start = len(l_buffer[:l_buffer.selection_mark].quoted_text())
|
||||
stop = len(l_buffer[:l_buffer.point].quoted_text())
|
||||
if start > stop:
|
||||
stop,start = start,stop
|
||||
n = c.write_scrolling(ltext[:start], self.command_color)
|
||||
n = c.write_scrolling(ltext[start:stop], self.selection_color)
|
||||
n = c.write_scrolling(ltext[stop:], self.command_color)
|
||||
else:
|
||||
n = c.write_scrolling(ltext, self.command_color)
|
||||
|
||||
x,y = c.pos() #Preserve one line for Asian IME(Input Method Editor) statusbar
|
||||
w,h = c.size()
|
||||
if y >= h - 1 or n > 0:
|
||||
x, y = c.pos() #Preserve one line for Asian IME(Input Method Editor) statusbar
|
||||
w, h = c.size()
|
||||
if (y >= h - 1) or (n > 0):
|
||||
c.scroll_window(-1)
|
||||
c.scroll((0,0,w,h),0,-1)
|
||||
c.scroll((0, 0, w, h), 0, -1)
|
||||
n += 1
|
||||
|
||||
self._update_prompt_pos(n)
|
||||
if hasattr(c,"clear_to_end_of_window"): #Work around function for ironpython due
|
||||
if hasattr(c, u"clear_to_end_of_window"): #Work around function for ironpython due
|
||||
c.clear_to_end_of_window() #to System.Console's lack of FillFunction
|
||||
else:
|
||||
self._clear_after()
|
||||
c.cursor(1) #Show cursor
|
||||
|
||||
#Show cursor, set size vi mode changes size in insert/overwrite mode
|
||||
c.cursor(1, size=self.mode.cursor_size)
|
||||
self._set_cursor()
|
||||
|
||||
def readline(self, prompt=''):
|
||||
return self.mode.readline(prompt)
|
||||
|
||||
def read_inputrc(self,inputrcpath=os.path.expanduser("~/pyreadlineconfig.ini")):
|
||||
modes=dict([(x.mode,x) for x in self.editingmodes])
|
||||
mode=self.editingmodes[0].mode
|
||||
def setmode(name):
|
||||
self.mode=modes[name]
|
||||
def bind_key(key,name):
|
||||
log("bind %s %s"%(key,name))
|
||||
if hasattr(modes[mode],name):
|
||||
modes[mode]._bind_key(key,getattr(modes[mode],name))
|
||||
|
||||
def callback_read_char(self):
|
||||
#Override base to get automatic newline
|
||||
u'''Reads a character and informs the readline callback interface when a line is received'''
|
||||
if self.keyboard_poll():
|
||||
line = self.get_line_buffer() + u'\n'
|
||||
self.console.write(u"\r\n")
|
||||
# however there is another newline added by
|
||||
# self.mode.readline_setup(prompt) which is called by callback_handler_install
|
||||
# this differs from GNU readline
|
||||
self.add_history(self.mode.l_buffer)
|
||||
# TADA:
|
||||
self.callback(line)
|
||||
|
||||
|
||||
def event_available(self):
|
||||
return self.console.peek() or (len(self.paste_line_buffer) > 0)
|
||||
|
||||
|
||||
def _readline_from_keyboard(self):
|
||||
while 1:
|
||||
if self._readline_from_keyboard_poll():
|
||||
break
|
||||
|
||||
def _readline_from_keyboard_poll(self):
|
||||
pastebuffer = self.mode.paste_line_buffer
|
||||
if len(pastebuffer) > 0:
|
||||
#paste first line in multiline paste buffer
|
||||
self.l_buffer = lineobj.ReadLineTextBuffer(pastebuffer[0])
|
||||
self._update_line()
|
||||
self.mode.paste_line_buffer = pastebuffer[1:]
|
||||
return True
|
||||
|
||||
c = self.console
|
||||
def nop(e):
|
||||
pass
|
||||
try:
|
||||
event = c.getkeypress()
|
||||
except KeyboardInterrupt:
|
||||
event = self.handle_ctrl_c()
|
||||
result = self.mode.process_keyevent(event.keyinfo)
|
||||
self._update_line()
|
||||
return result
|
||||
|
||||
def readline_setup(self, prompt=u''):
|
||||
BaseReadline.readline_setup(self, prompt)
|
||||
self._print_prompt()
|
||||
self._update_line()
|
||||
|
||||
def readline(self, prompt=u''):
|
||||
self.readline_setup(prompt)
|
||||
self.ctrl_c_timeout = time.time()
|
||||
self._readline_from_keyboard()
|
||||
self.console.write(u'\r\n')
|
||||
log(u'returning(%s)' % self.get_line_buffer())
|
||||
return self.get_line_buffer() + u'\n'
|
||||
|
||||
def handle_ctrl_c(self):
|
||||
from pyreadline.keysyms.common import KeyPress
|
||||
from pyreadline.console.event import Event
|
||||
log(u"KBDIRQ")
|
||||
event = Event(0,0)
|
||||
event.char = u"c"
|
||||
event.keyinfo = KeyPress(u"c", shift=False, control=True,
|
||||
meta=False, keyname=None)
|
||||
if self.allow_ctrl_c:
|
||||
now = time.time()
|
||||
if (now - self.ctrl_c_timeout) < self.ctrl_c_tap_time_interval:
|
||||
log(u"Raise KeyboardInterrupt")
|
||||
raise KeyboardInterrupt
|
||||
else:
|
||||
print "Trying to bind unknown command '%s' to key '%s'"%(name,key)
|
||||
def un_bind_key(key):
|
||||
keyinfo = make_KeyPress_from_keydescr(key).tuple()
|
||||
if keyinfo in modes[mode].key_dispatch:
|
||||
del modes[mode].key_dispatch[keyinfo]
|
||||
|
||||
def bind_exit_key(key):
|
||||
modes[mode]._bind_exit_key(key)
|
||||
def un_bind_exit_key(key):
|
||||
keyinfo = make_KeyPress_from_keydescr(key).tuple()
|
||||
if keyinfo in modes[mode].exit_dispatch:
|
||||
del modes[mode].exit_dispatch[keyinfo]
|
||||
|
||||
def setkill_ring_to_clipboard(killring):
|
||||
import pyreadline.lineeditor.lineobj
|
||||
pyreadline.lineeditor.lineobj.kill_ring_to_clipboard=killring
|
||||
def sethistoryfilename(filename):
|
||||
self._history.history_filename=os.path.expanduser(filename)
|
||||
def setbellstyle(mode):
|
||||
self.bell_style=mode
|
||||
def sethistorylength(length):
|
||||
self._history.history_length=int(length)
|
||||
def allow_ctrl_c(mode):
|
||||
log_sock("allow_ctrl_c:%s:%s"%(self.allow_ctrl_c,mode))
|
||||
self.allow_ctrl_c=mode
|
||||
def setbellstyle(mode):
|
||||
self.bell_style=mode
|
||||
def show_all_if_ambiguous(mode):
|
||||
self.show_all_if_ambiguous=mode
|
||||
def ctrl_c_tap_time_interval(mode):
|
||||
self.ctrl_c_tap_time_interval=mode
|
||||
def mark_directories(mode):
|
||||
self.mark_directories=mode
|
||||
def completer_delims(mode):
|
||||
self.completer_delims=mode
|
||||
def debug_output(on,filename="pyreadline_debug_log.txt"): #Not implemented yet
|
||||
if on in ["on","on_nologfile"]:
|
||||
self.debug=True
|
||||
logger.start_log(on,filename)
|
||||
logger.log("STARTING LOG")
|
||||
# print release.branch
|
||||
def set_prompt_color(color):
|
||||
trtable={"black":0,"darkred":4,"darkgreen":2,"darkyellow":6,"darkblue":1,"darkmagenta":5,"darkcyan":3,"gray":7,
|
||||
"red":4+8,"green":2+8,"yellow":6+8,"blue":1+8,"magenta":5+8,"cyan":3+8,"white":7+8}
|
||||
self.prompt_color=trtable.get(color.lower(),7)
|
||||
|
||||
def set_input_color(color):
|
||||
trtable={"black":0,"darkred":4,"darkgreen":2,"darkyellow":6,"darkblue":1,"darkmagenta":5,"darkcyan":3,"gray":7,
|
||||
"red":4+8,"green":2+8,"yellow":6+8,"blue":1+8,"magenta":5+8,"cyan":3+8,"white":7+8}
|
||||
self.command_color=trtable.get(color.lower(),7)
|
||||
loc={"branch":release.branch,
|
||||
"version":release.version,
|
||||
"mode":mode,
|
||||
"modes":modes,
|
||||
"set_mode":setmode,
|
||||
"bind_key":bind_key,
|
||||
"bind_exit_key":bind_exit_key,
|
||||
"un_bind_key":un_bind_key,
|
||||
"un_bind_exit_key":un_bind_exit_key,
|
||||
"bell_style":setbellstyle,
|
||||
"mark_directories":mark_directories,
|
||||
"show_all_if_ambiguous":show_all_if_ambiguous,
|
||||
"completer_delims":completer_delims,
|
||||
"debug_output":debug_output,
|
||||
"history_filename":sethistoryfilename,
|
||||
"history_length":sethistorylength,
|
||||
"set_prompt_color":set_prompt_color,
|
||||
"set_input_color":set_input_color,
|
||||
"allow_ctrl_c":allow_ctrl_c,
|
||||
"ctrl_c_tap_time_interval":ctrl_c_tap_time_interval,
|
||||
"kill_ring_to_clipboard":setkill_ring_to_clipboard,
|
||||
}
|
||||
if os.path.isfile(inputrcpath):
|
||||
try:
|
||||
execfile(inputrcpath,loc,loc)
|
||||
except Exception,x:
|
||||
raise
|
||||
import traceback
|
||||
print >>sys.stderr, "Error reading .pyinputrc"
|
||||
filepath,lineno=traceback.extract_tb(sys.exc_traceback)[1][:2]
|
||||
print >>sys.stderr, "Line: %s in file %s"%(lineno,filepath)
|
||||
print >>sys.stderr, x
|
||||
raise ReadlineError("Error reading .pyinputrc")
|
||||
self.ctrl_c_timeout = now
|
||||
else:
|
||||
raise KeyboardInterrupt
|
||||
return event
|
||||
|
||||
|
||||
|
||||
|
||||
def CTRL(c):
|
||||
'''make a control character'''
|
||||
assert '@' <= c <= '_'
|
||||
return chr(ord(c) - ord('@'))
|
||||
|
||||
# create a Readline object to contain the state
|
||||
rl = Readline()
|
||||
|
||||
|
||||
def GetOutputFile():
|
||||
'''Return the console object used by readline so that it can be used for printing in color.'''
|
||||
u'''Return the console object used by readline so that it can be used for printing in color.'''
|
||||
return rl.console
|
||||
|
||||
# make these available so this looks like the python readline module
|
||||
parse_and_bind = rl.parse_and_bind
|
||||
get_line_buffer = rl.get_line_buffer
|
||||
insert_text = rl.insert_text
|
||||
read_init_file = rl.read_init_file
|
||||
add_history = rl.add_history
|
||||
get_history_length = rl.get_history_length
|
||||
set_history_length = rl.set_history_length
|
||||
parse_and_bind = rl.parse_and_bind
|
||||
clear_history = rl.clear_history
|
||||
read_history_file = rl.read_history_file
|
||||
add_history = rl.add_history
|
||||
insert_text = rl.insert_text
|
||||
|
||||
write_history_file = rl.write_history_file
|
||||
read_history_file = rl.read_history_file
|
||||
|
||||
get_completer_delims = rl.get_completer_delims
|
||||
get_history_length = rl.get_history_length
|
||||
get_line_buffer = rl.get_line_buffer
|
||||
set_completer = rl.set_completer
|
||||
get_completer = rl.get_completer
|
||||
get_begidx = rl.get_begidx
|
||||
get_endidx = rl.get_endidx
|
||||
set_completer_delims = rl.set_completer_delims
|
||||
get_completer_delims = rl.get_completer_delims
|
||||
set_startup_hook = rl.set_startup_hook
|
||||
set_pre_input_hook = rl.set_pre_input_hook
|
||||
|
||||
if __name__ == '__main__':
|
||||
res = [ rl.readline('In[%d] ' % i) for i in range(3) ]
|
||||
set_completer_delims = rl.set_completer_delims
|
||||
set_history_length = rl.set_history_length
|
||||
set_pre_input_hook = rl.set_pre_input_hook
|
||||
set_startup_hook = rl.set_startup_hook
|
||||
|
||||
callback_handler_install=rl.callback_handler_install
|
||||
callback_handler_remove=rl.callback_handler_remove
|
||||
callback_read_char=rl.callback_read_char
|
||||
|
||||
if __name__ == u'__main__':
|
||||
res = [ rl.readline(u'In[%d] ' % i) for i in range(3) ]
|
||||
print res
|
||||
else:
|
||||
console.install_readline(rl.readline)
|
||||
|
||||
@@ -13,7 +13,7 @@ from pyreadline.keysyms.common import make_KeyPress_from_keydescr
|
||||
import unittest
|
||||
class MockReadline:
|
||||
def __init__ (self):
|
||||
self.l_buffer=lineobj.ReadLineTextBuffer("")
|
||||
self.l_buffer=lineobj.ReadLineTextBuffer(u"")
|
||||
self._history=history.LineHistory()
|
||||
|
||||
def add_history (self, line):
|
||||
@@ -26,7 +26,7 @@ class MockReadline:
|
||||
pass
|
||||
|
||||
def insert_text(self, string):
|
||||
'''Insert text into the command line.'''
|
||||
u'''Insert text into the command line.'''
|
||||
self.l_buffer.insert_text(string)
|
||||
|
||||
|
||||
@@ -52,16 +52,16 @@ class MockConsole:
|
||||
|
||||
class Event:
|
||||
def __init__ (self, char):
|
||||
if char=="escape":
|
||||
self.char='\x1b'
|
||||
elif char=="backspace":
|
||||
self.char='\x08'
|
||||
if char==u"escape":
|
||||
self.char=u'\x1b'
|
||||
elif char==u"backspace":
|
||||
self.char=u'\x08'
|
||||
else:
|
||||
self.char = char
|
||||
|
||||
def keytext_to_keyinfo_and_event (keytext):
|
||||
keyinfo = keysyms.common.make_KeyPress_from_keydescr (keytext)
|
||||
if len(keytext) == 3 and keytext[0] == '"' and keytext[2] == '"':
|
||||
if len(keytext) == 3 and keytext[0] == u'"' and keytext[2] == u'"':
|
||||
event = Event (keytext[1])
|
||||
else:
|
||||
event = Event (keyinfo.tuple() [3])
|
||||
|
||||
+179
-179
@@ -9,16 +9,16 @@
|
||||
|
||||
import sys, unittest
|
||||
import pdb
|
||||
sys.path.append ('../..')
|
||||
sys.path.append (u'../..')
|
||||
from pyreadline.modes.emacs import *
|
||||
from pyreadline import keysyms
|
||||
from pyreadline.lineeditor import lineobj
|
||||
|
||||
from common import *
|
||||
from pyreadline.logger import log_sock
|
||||
from pyreadline.logger import log
|
||||
import pyreadline.logger as logger
|
||||
logger.sock_silent=True
|
||||
logger.show_event=["debug"]
|
||||
logger.show_event=[u"debug"]
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
@@ -31,7 +31,7 @@ class EmacsModeTest (EmacsMode):
|
||||
self.init_editing_mode (None)
|
||||
self.lst_completions = []
|
||||
self.completer = self.mock_completer
|
||||
self.completer_delims = ' '
|
||||
self.completer_delims = u' u'
|
||||
self.tabstop = 4
|
||||
self.mark_directories=False
|
||||
self.show_all_if_ambiguous=False
|
||||
@@ -52,15 +52,15 @@ class EmacsModeTest (EmacsMode):
|
||||
line_cursor = property (get_line_cursor)
|
||||
|
||||
def input (self, keytext):
|
||||
if keytext[0:1] == '"' and keytext[-1:] == '"':
|
||||
lst_key = ['"%s"' % c for c in keytext[1:-1]]
|
||||
if keytext[0:1] == u'"' and keytext[-1:] == u'"':
|
||||
lst_key = [u'"%s"' % c for c in keytext[1:-1]]
|
||||
else:
|
||||
lst_key = [keytext]
|
||||
for key in lst_key:
|
||||
keyinfo, event = keytext_to_keyinfo_and_event (key)
|
||||
dispatch_func = self.key_dispatch.get(keyinfo.tuple(),self.self_insert)
|
||||
self.tested_commands[dispatch_func.__name__]=dispatch_func
|
||||
log_sock("keydisp: %s %s"%( key,dispatch_func.__name__),"debug")
|
||||
log(u"keydisp: %s %s"%( key,dispatch_func.__name__))
|
||||
dispatch_func (event)
|
||||
self.previous_func=dispatch_func
|
||||
|
||||
@@ -78,141 +78,141 @@ class EmacsModeTest (EmacsMode):
|
||||
class TestsKeyinfo (unittest.TestCase):
|
||||
|
||||
def test_keyinfo (self):
|
||||
keyinfo, event = keytext_to_keyinfo_and_event ('"d"')
|
||||
self.assertEqual ('d', event.char)
|
||||
keyinfo, event = keytext_to_keyinfo_and_event ('"D"')
|
||||
self.assertEqual ('D', event.char)
|
||||
keyinfo, event = keytext_to_keyinfo_and_event ('"$"')
|
||||
self.assertEqual ('$', event.char)
|
||||
keyinfo, event = keytext_to_keyinfo_and_event ('Escape')
|
||||
self.assertEqual ('\x1b', event.char)
|
||||
keyinfo, event = keytext_to_keyinfo_and_event (u'"d"')
|
||||
self.assertEqual (u'd', event.char)
|
||||
keyinfo, event = keytext_to_keyinfo_and_event (u'"D"')
|
||||
self.assertEqual (u'D', event.char)
|
||||
keyinfo, event = keytext_to_keyinfo_and_event (u'"$"')
|
||||
self.assertEqual (u'$', event.char)
|
||||
keyinfo, event = keytext_to_keyinfo_and_event (u'Escape')
|
||||
self.assertEqual (u'\x1b', event.char)
|
||||
|
||||
|
||||
class TestsMovement (unittest.TestCase):
|
||||
def test_cursor (self):
|
||||
r = EmacsModeTest ()
|
||||
self.assertEqual (r.line, '')
|
||||
r.input('"First Second Third"')
|
||||
self.assertEqual (r.line, 'First Second Third')
|
||||
self.assertEqual (r.line, u'')
|
||||
r.input(u'"First Second Third"')
|
||||
self.assertEqual (r.line, u'First Second Third')
|
||||
self.assertEqual (r.line_cursor, 18)
|
||||
r.input('Control-a')
|
||||
self.assertEqual (r.line, 'First Second Third')
|
||||
r.input(u'Control-a')
|
||||
self.assertEqual (r.line, u'First Second Third')
|
||||
self.assertEqual (r.line_cursor, 0)
|
||||
r.input('Control-e')
|
||||
self.assertEqual (r.line, 'First Second Third')
|
||||
r.input(u'Control-e')
|
||||
self.assertEqual (r.line, u'First Second Third')
|
||||
self.assertEqual (r.line_cursor, 18)
|
||||
r.input('Home')
|
||||
self.assertEqual (r.line, 'First Second Third')
|
||||
r.input(u'Home')
|
||||
self.assertEqual (r.line, u'First Second Third')
|
||||
self.assertEqual (r.line_cursor, 0)
|
||||
r.input('Right')
|
||||
self.assertEqual (r.line, 'First Second Third')
|
||||
r.input(u'Right')
|
||||
self.assertEqual (r.line, u'First Second Third')
|
||||
self.assertEqual (r.line_cursor, 1)
|
||||
r.input('Ctrl-f')
|
||||
self.assertEqual (r.line, 'First Second Third')
|
||||
r.input(u'Ctrl-f')
|
||||
self.assertEqual (r.line, u'First Second Third')
|
||||
self.assertEqual (r.line_cursor, 2)
|
||||
r.input('Ctrl-Right')
|
||||
self.assertEqual (r.line, 'First Second Third')
|
||||
r.input(u'Ctrl-Right')
|
||||
self.assertEqual (r.line, u'First Second Third')
|
||||
self.assertEqual (r.line_cursor, 5)
|
||||
r.input('Ctrl-Right')
|
||||
self.assertEqual (r.line, 'First Second Third')
|
||||
r.input(u'Ctrl-Right')
|
||||
self.assertEqual (r.line, u'First Second Third')
|
||||
self.assertEqual (r.line_cursor, 12)
|
||||
r.input('Ctrl-Right')
|
||||
self.assertEqual (r.line, 'First Second Third')
|
||||
r.input(u'Ctrl-Right')
|
||||
self.assertEqual (r.line, u'First Second Third')
|
||||
self.assertEqual (r.line_cursor, 18)
|
||||
r.input('Ctrl-Right')
|
||||
self.assertEqual (r.line, 'First Second Third')
|
||||
r.input(u'Ctrl-Right')
|
||||
self.assertEqual (r.line, u'First Second Third')
|
||||
self.assertEqual (r.line_cursor, 18)
|
||||
r.input('Ctrl-Left')
|
||||
self.assertEqual (r.line, 'First Second Third')
|
||||
r.input(u'Ctrl-Left')
|
||||
self.assertEqual (r.line, u'First Second Third')
|
||||
self.assertEqual (r.line_cursor, 13)
|
||||
r.input('Ctrl-Left')
|
||||
self.assertEqual (r.line, 'First Second Third')
|
||||
r.input(u'Ctrl-Left')
|
||||
self.assertEqual (r.line, u'First Second Third')
|
||||
self.assertEqual (r.line_cursor, 6)
|
||||
r.input('Ctrl-Left')
|
||||
self.assertEqual (r.line, 'First Second Third')
|
||||
r.input(u'Ctrl-Left')
|
||||
self.assertEqual (r.line, u'First Second Third')
|
||||
self.assertEqual (r.line_cursor, 0)
|
||||
r.input('Ctrl-Left')
|
||||
self.assertEqual (r.line, 'First Second Third')
|
||||
r.input(u'Ctrl-Left')
|
||||
self.assertEqual (r.line, u'First Second Third')
|
||||
self.assertEqual (r.line_cursor, 0)
|
||||
|
||||
|
||||
class TestsDelete (unittest.TestCase):
|
||||
def test_delete (self):
|
||||
r = EmacsModeTest ()
|
||||
self.assertEqual (r.line, '')
|
||||
r.input('"First Second Third"')
|
||||
self.assertEqual (r.line, 'First Second Third')
|
||||
self.assertEqual (r.line, u'')
|
||||
r.input(u'"First Second Third"')
|
||||
self.assertEqual (r.line, u'First Second Third')
|
||||
self.assertEqual (r.line_cursor, 18)
|
||||
r.input('Delete')
|
||||
self.assertEqual (r.line, 'First Second Third')
|
||||
r.input(u'Delete')
|
||||
self.assertEqual (r.line, u'First Second Third')
|
||||
self.assertEqual (r.line_cursor, 18)
|
||||
r.input('Left')
|
||||
r.input('Left')
|
||||
r.input('Delete')
|
||||
self.assertEqual (r.line, 'First Second Thid')
|
||||
r.input(u'Left')
|
||||
r.input(u'Left')
|
||||
r.input(u'Delete')
|
||||
self.assertEqual (r.line, u'First Second Thid')
|
||||
self.assertEqual (r.line_cursor, 16)
|
||||
r.input('Delete')
|
||||
self.assertEqual (r.line, 'First Second Thi')
|
||||
r.input(u'Delete')
|
||||
self.assertEqual (r.line, u'First Second Thi')
|
||||
self.assertEqual (r.line_cursor, 16)
|
||||
r.input('Backspace')
|
||||
self.assertEqual (r.line, 'First Second Th')
|
||||
r.input(u'Backspace')
|
||||
self.assertEqual (r.line, u'First Second Th')
|
||||
self.assertEqual (r.line_cursor, 15)
|
||||
r.input('Home')
|
||||
r.input('Right')
|
||||
r.input('Right')
|
||||
self.assertEqual (r.line, 'First Second Th')
|
||||
r.input(u'Home')
|
||||
r.input(u'Right')
|
||||
r.input(u'Right')
|
||||
self.assertEqual (r.line, u'First Second Th')
|
||||
self.assertEqual (r.line_cursor, 2)
|
||||
r.input('Backspace')
|
||||
self.assertEqual (r.line, 'Frst Second Th')
|
||||
r.input(u'Backspace')
|
||||
self.assertEqual (r.line, u'Frst Second Th')
|
||||
self.assertEqual (r.line_cursor, 1)
|
||||
r.input('Backspace')
|
||||
self.assertEqual (r.line, 'rst Second Th')
|
||||
r.input(u'Backspace')
|
||||
self.assertEqual (r.line, u'rst Second Th')
|
||||
self.assertEqual (r.line_cursor, 0)
|
||||
r.input('Backspace')
|
||||
self.assertEqual (r.line, 'rst Second Th')
|
||||
r.input(u'Backspace')
|
||||
self.assertEqual (r.line, u'rst Second Th')
|
||||
self.assertEqual (r.line_cursor, 0)
|
||||
r.input('Escape')
|
||||
self.assertEqual (r.line, '')
|
||||
r.input(u'Escape')
|
||||
self.assertEqual (r.line, u'')
|
||||
self.assertEqual (r.line_cursor, 0)
|
||||
|
||||
def test_delete_word (self):
|
||||
r = EmacsModeTest ()
|
||||
self.assertEqual (r.line, '')
|
||||
r.input('"First Second Third"')
|
||||
self.assertEqual (r.line, 'First Second Third')
|
||||
self.assertEqual (r.line, u'')
|
||||
r.input(u'"First Second Third"')
|
||||
self.assertEqual (r.line, u'First Second Third')
|
||||
self.assertEqual (r.line_cursor, 18)
|
||||
r.input('Control-Backspace')
|
||||
self.assertEqual (r.line, 'First Second ')
|
||||
r.input(u'Control-Backspace')
|
||||
self.assertEqual (r.line, u'First Second ')
|
||||
self.assertEqual (r.line_cursor, 13)
|
||||
r.input('Backspace')
|
||||
r.input('Left')
|
||||
r.input('Left')
|
||||
self.assertEqual (r.line, 'First Second')
|
||||
r.input(u'Backspace')
|
||||
r.input(u'Left')
|
||||
r.input(u'Left')
|
||||
self.assertEqual (r.line, u'First Second')
|
||||
self.assertEqual (r.line_cursor, 10)
|
||||
r.input('Control-Backspace')
|
||||
self.assertEqual (r.line, 'First nd')
|
||||
r.input(u'Control-Backspace')
|
||||
self.assertEqual (r.line, u'First nd')
|
||||
self.assertEqual (r.line_cursor, 6)
|
||||
r.input('Escape')
|
||||
self.assertEqual (r.line, '')
|
||||
r.input(u'Escape')
|
||||
self.assertEqual (r.line, u'')
|
||||
self.assertEqual (r.line_cursor, 0)
|
||||
r.input('"First Second Third"')
|
||||
r.input('Home')
|
||||
r.input('Right')
|
||||
r.input('Right')
|
||||
r.input('Control-Delete')
|
||||
self.assertEqual (r.line, 'FiSecond Third')
|
||||
r.input(u'"First Second Third"')
|
||||
r.input(u'Home')
|
||||
r.input(u'Right')
|
||||
r.input(u'Right')
|
||||
r.input(u'Control-Delete')
|
||||
self.assertEqual (r.line, u'FiSecond Third')
|
||||
self.assertEqual (r.line_cursor, 2)
|
||||
r.input('Control-Delete')
|
||||
self.assertEqual (r.line, 'FiThird')
|
||||
r.input(u'Control-Delete')
|
||||
self.assertEqual (r.line, u'FiThird')
|
||||
self.assertEqual (r.line_cursor, 2)
|
||||
r.input('Control-Delete')
|
||||
self.assertEqual (r.line, 'Fi')
|
||||
r.input(u'Control-Delete')
|
||||
self.assertEqual (r.line, u'Fi')
|
||||
self.assertEqual (r.line_cursor, 2)
|
||||
r.input('Control-Delete')
|
||||
self.assertEqual (r.line, 'Fi')
|
||||
r.input(u'Control-Delete')
|
||||
self.assertEqual (r.line, u'Fi')
|
||||
self.assertEqual (r.line_cursor, 2)
|
||||
r.input('Escape')
|
||||
self.assertEqual (r.line, '')
|
||||
r.input(u'Escape')
|
||||
self.assertEqual (r.line, u'')
|
||||
self.assertEqual (r.line_cursor, 0)
|
||||
|
||||
|
||||
@@ -220,30 +220,30 @@ class TestsDelete (unittest.TestCase):
|
||||
class TestsSelectionMovement (unittest.TestCase):
|
||||
def test_cursor (self):
|
||||
r = EmacsModeTest ()
|
||||
self.assertEqual (r.line, '')
|
||||
r.input('"First Second Third"')
|
||||
self.assertEqual (r.line, 'First Second Third')
|
||||
self.assertEqual (r.line, u'')
|
||||
r.input(u'"First Second Third"')
|
||||
self.assertEqual (r.line, u'First Second Third')
|
||||
self.assertEqual (r.line_cursor, 18)
|
||||
self.assertEqual (r.l_buffer.selection_mark, -1)
|
||||
r.input('Home')
|
||||
r.input('Shift-Right')
|
||||
self.assertEqual (r.line, 'First Second Third')
|
||||
r.input(u'Home')
|
||||
r.input(u'Shift-Right')
|
||||
self.assertEqual (r.line, u'First Second Third')
|
||||
self.assertEqual (r.line_cursor, 1)
|
||||
self.assertEqual (r.l_buffer.selection_mark, 0)
|
||||
r.input('Shift-Control-Right')
|
||||
self.assertEqual (r.line, 'First Second Third')
|
||||
r.input(u'Shift-Control-Right')
|
||||
self.assertEqual (r.line, u'First Second Third')
|
||||
self.assertEqual (r.line_cursor, 5)
|
||||
self.assertEqual (r.l_buffer.selection_mark, 0)
|
||||
r.input('"a"')
|
||||
self.assertEqual (r.line, 'a Second Third')
|
||||
r.input(u'"a"')
|
||||
self.assertEqual (r.line, u'a Second Third')
|
||||
self.assertEqual (r.line_cursor, 1)
|
||||
self.assertEqual (r.l_buffer.selection_mark, -1)
|
||||
r.input('Shift-End')
|
||||
self.assertEqual (r.line, 'a Second Third')
|
||||
r.input(u'Shift-End')
|
||||
self.assertEqual (r.line, u'a Second Third')
|
||||
self.assertEqual (r.line_cursor, 14)
|
||||
self.assertEqual (r.l_buffer.selection_mark, 1)
|
||||
r.input('Delete')
|
||||
self.assertEqual (r.line, 'a')
|
||||
r.input(u'Delete')
|
||||
self.assertEqual (r.line, u'a')
|
||||
self.assertEqual (r.line_cursor, 1)
|
||||
self.assertEqual (r.l_buffer.selection_mark, -1)
|
||||
|
||||
@@ -252,119 +252,119 @@ class TestsSelectionMovement (unittest.TestCase):
|
||||
class TestsHistory (unittest.TestCase):
|
||||
def test_history_1 (self):
|
||||
r = EmacsModeTest ()
|
||||
r.add_history ('aa')
|
||||
r.add_history ('bbb')
|
||||
self.assertEqual (r.line, '')
|
||||
r.input ('Up')
|
||||
self.assertEqual (r.line, 'bbb')
|
||||
r.add_history (u'aa')
|
||||
r.add_history (u'bbb')
|
||||
self.assertEqual (r.line, u'')
|
||||
r.input (u'Up')
|
||||
self.assertEqual (r.line, u'bbb')
|
||||
self.assertEqual (r.line_cursor, 3)
|
||||
r.input ('Up')
|
||||
self.assertEqual (r.line, 'aa')
|
||||
r.input (u'Up')
|
||||
self.assertEqual (r.line, u'aa')
|
||||
self.assertEqual (r.line_cursor, 2)
|
||||
r.input ('Up')
|
||||
self.assertEqual (r.line, 'aa')
|
||||
r.input (u'Up')
|
||||
self.assertEqual (r.line, u'aa')
|
||||
self.assertEqual (r.line_cursor, 2)
|
||||
r.input ('Down')
|
||||
self.assertEqual (r.line, 'bbb')
|
||||
r.input (u'Down')
|
||||
self.assertEqual (r.line, u'bbb')
|
||||
self.assertEqual (r.line_cursor, 3)
|
||||
r.input ('Down')
|
||||
self.assertEqual (r.line, '')
|
||||
r.input (u'Down')
|
||||
self.assertEqual (r.line, u'')
|
||||
self.assertEqual (r.line_cursor, 0)
|
||||
|
||||
def test_history_2 (self):
|
||||
r = EmacsModeTest ()
|
||||
r.add_history ('aaaa')
|
||||
r.add_history ('aaba')
|
||||
r.add_history ('aaca')
|
||||
r.add_history ('akca')
|
||||
r.add_history ('bbb')
|
||||
r.add_history ('ako')
|
||||
r.add_history (u'aaaa')
|
||||
r.add_history (u'aaba')
|
||||
r.add_history (u'aaca')
|
||||
r.add_history (u'akca')
|
||||
r.add_history (u'bbb')
|
||||
r.add_history (u'ako')
|
||||
self.assert_line(r,'',0)
|
||||
r.input ('"a"')
|
||||
r.input ('Up')
|
||||
r.input (u'"a"')
|
||||
r.input (u'Up')
|
||||
self.assert_line(r,'ako',1)
|
||||
r.input ('Up')
|
||||
r.input (u'Up')
|
||||
self.assert_line(r,'akca',1)
|
||||
r.input ('Up')
|
||||
r.input (u'Up')
|
||||
self.assert_line(r,'aaca',1)
|
||||
r.input ('Up')
|
||||
r.input (u'Up')
|
||||
self.assert_line(r,'aaba',1)
|
||||
r.input ('Up')
|
||||
r.input (u'Up')
|
||||
self.assert_line(r,'aaaa',1)
|
||||
r.input ('Right')
|
||||
r.input (u'Right')
|
||||
self.assert_line(r,'aaaa',2)
|
||||
r.input ('Down')
|
||||
r.input (u'Down')
|
||||
self.assert_line(r,'aaba',2)
|
||||
r.input ('Down')
|
||||
r.input (u'Down')
|
||||
self.assert_line(r,'aaca',2)
|
||||
r.input ('Down')
|
||||
r.input (u'Down')
|
||||
self.assert_line(r,'aaca',2)
|
||||
r.input ('Left')
|
||||
r.input ('Left')
|
||||
r.input ('Down')
|
||||
r.input ('Down')
|
||||
r.input (u'Left')
|
||||
r.input (u'Left')
|
||||
r.input (u'Down')
|
||||
r.input (u'Down')
|
||||
self.assert_line(r,'bbb',3)
|
||||
r.input ('Left')
|
||||
r.input (u'Left')
|
||||
self.assert_line(r,'bbb',2)
|
||||
r.input ('Down')
|
||||
r.input (u'Down')
|
||||
self.assert_line(r,'bbb',2)
|
||||
r.input ('Up')
|
||||
r.input (u'Up')
|
||||
self.assert_line(r,'bbb',2)
|
||||
|
||||
|
||||
def test_history_3 (self):
|
||||
r = EmacsModeTest ()
|
||||
r.add_history ('aaaa')
|
||||
r.add_history ('aaba')
|
||||
r.add_history ('aaca')
|
||||
r.add_history ('akca')
|
||||
r.add_history ('bbb')
|
||||
r.add_history ('ako')
|
||||
r.add_history (u'aaaa')
|
||||
r.add_history (u'aaba')
|
||||
r.add_history (u'aaca')
|
||||
r.add_history (u'akca')
|
||||
r.add_history (u'bbb')
|
||||
r.add_history (u'ako')
|
||||
self.assert_line(r,'',0)
|
||||
r.input ('')
|
||||
r.input ('Up')
|
||||
r.input (u'')
|
||||
r.input (u'Up')
|
||||
self.assert_line(r,'ako',3)
|
||||
r.input ('Down')
|
||||
r.input (u'Down')
|
||||
self.assert_line(r,'',0)
|
||||
r.input ('Up')
|
||||
r.input (u'Up')
|
||||
self.assert_line(r,'ako',3)
|
||||
|
||||
def test_history_3 (self):
|
||||
r = EmacsModeTest ()
|
||||
r.add_history ('aaaa')
|
||||
r.add_history ('aaba')
|
||||
r.add_history ('aaca')
|
||||
r.add_history ('akca')
|
||||
r.add_history ('bbb')
|
||||
r.add_history ('ako')
|
||||
r.add_history (u'aaaa')
|
||||
r.add_history (u'aaba')
|
||||
r.add_history (u'aaca')
|
||||
r.add_history (u'akca')
|
||||
r.add_history (u'bbb')
|
||||
r.add_history (u'ako')
|
||||
self.assert_line(r,'',0)
|
||||
r.input ('k')
|
||||
r.input ('Up')
|
||||
r.input (u'k')
|
||||
r.input (u'Up')
|
||||
self.assert_line(r,'k',1)
|
||||
|
||||
def test_complete (self):
|
||||
import rlcompleter
|
||||
logger.sock_silent=False
|
||||
|
||||
log_sock("-"*50,"debug")
|
||||
log("-"*50)
|
||||
r=EmacsModeTest()
|
||||
r.completer=rlcompleter.Completer().complete
|
||||
r._bind_key("tab",r.complete)
|
||||
r.input('"exi(ksdjksjd)"')
|
||||
r.input('Control-a')
|
||||
r.input('Right')
|
||||
r.input('Right')
|
||||
r.input('Right')
|
||||
r.input('Tab')
|
||||
r.input(u'"exi(ksdjksjd)"')
|
||||
r.input(u'Control-a')
|
||||
r.input(u'Right')
|
||||
r.input(u'Right')
|
||||
r.input(u'Right')
|
||||
r.input(u'Tab')
|
||||
self.assert_line(r,"exit(ksdjksjd)",4)
|
||||
|
||||
r.input('Escape')
|
||||
r.input('"exi"')
|
||||
r.input('Control-a')
|
||||
r.input('Right')
|
||||
r.input('Right')
|
||||
r.input('Right')
|
||||
r.input('Tab')
|
||||
r.input(u'Escape')
|
||||
r.input(u'"exi"')
|
||||
r.input(u'Control-a')
|
||||
r.input(u'Right')
|
||||
r.input(u'Right')
|
||||
r.input(u'Right')
|
||||
r.input(u'Tab')
|
||||
self.assert_line(r,"exit",4)
|
||||
|
||||
|
||||
@@ -378,7 +378,7 @@ class TestsHistory (unittest.TestCase):
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
if __name__ == '__main__':
|
||||
if __name__ == u'__main__':
|
||||
Tester()
|
||||
tested=EmacsModeTest.tested_commands.keys()
|
||||
tested.sort()
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# Copyright (C) 2007 Jörgen Stenarson. <>
|
||||
|
||||
import sys, unittest
|
||||
sys.path.append ('../..')
|
||||
sys.path.append (u'../..')
|
||||
#from pyreadline.modes.vi import *
|
||||
#from pyreadline import keysyms
|
||||
from pyreadline.lineeditor import lineobj
|
||||
@@ -11,7 +11,7 @@ import pyreadline.lineeditor.history as history
|
||||
|
||||
import pyreadline.logger
|
||||
pyreadline.logger.sock_silent=False
|
||||
from pyreadline.logger import log_sock
|
||||
from pyreadline.logger import log
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -19,76 +19,76 @@ from pyreadline.logger import log_sock
|
||||
RL=lineobj.ReadLineTextBuffer
|
||||
|
||||
class Test_linepos (unittest.TestCase):
|
||||
t="test text"
|
||||
t=u"test text"
|
||||
|
||||
def init_test(self):
|
||||
history._ignore_leading_spaces=False
|
||||
self.q=q=LineHistory()
|
||||
for x in ["aaaa","aaba","aaca","akca","bbb","ako"]:
|
||||
for x in [u"aaaa",u"aaba",u"aaca",u"akca",u"bbb",u"ako"]:
|
||||
q.add_history(RL(x))
|
||||
|
||||
def test_previous_history (self):
|
||||
self.init_test()
|
||||
hist=self.q
|
||||
assert hist.history_cursor==6
|
||||
l=RL("")
|
||||
l=RL(u"")
|
||||
hist.previous_history(l)
|
||||
assert l.get_line_text()=="ako"
|
||||
assert l.get_line_text()==u"ako"
|
||||
hist.previous_history(l)
|
||||
assert l.get_line_text()=="bbb"
|
||||
assert l.get_line_text()==u"bbb"
|
||||
hist.previous_history(l)
|
||||
assert l.get_line_text()=="akca"
|
||||
assert l.get_line_text()==u"akca"
|
||||
hist.previous_history(l)
|
||||
assert l.get_line_text()=="aaca"
|
||||
assert l.get_line_text()==u"aaca"
|
||||
hist.previous_history(l)
|
||||
assert l.get_line_text()=="aaba"
|
||||
assert l.get_line_text()==u"aaba"
|
||||
hist.previous_history(l)
|
||||
assert l.get_line_text()=="aaaa"
|
||||
assert l.get_line_text()==u"aaaa"
|
||||
hist.previous_history(l)
|
||||
assert l.get_line_text()=="aaaa"
|
||||
assert l.get_line_text()==u"aaaa"
|
||||
|
||||
def test_next_history (self):
|
||||
self.init_test()
|
||||
hist=self.q
|
||||
hist.beginning_of_history()
|
||||
assert hist.history_cursor==0
|
||||
l=RL("")
|
||||
l=RL(u"")
|
||||
hist.next_history(l)
|
||||
assert l.get_line_text()=="aaba"
|
||||
assert l.get_line_text()==u"aaba"
|
||||
hist.next_history(l)
|
||||
assert l.get_line_text()=="aaca"
|
||||
assert l.get_line_text()==u"aaca"
|
||||
hist.next_history(l)
|
||||
assert l.get_line_text()=="akca"
|
||||
assert l.get_line_text()==u"akca"
|
||||
hist.next_history(l)
|
||||
assert l.get_line_text()=="bbb"
|
||||
assert l.get_line_text()==u"bbb"
|
||||
hist.next_history(l)
|
||||
assert l.get_line_text()=="ako"
|
||||
assert l.get_line_text()==u"ako"
|
||||
hist.next_history(l)
|
||||
assert l.get_line_text()=="ako"
|
||||
assert l.get_line_text()==u"ako"
|
||||
|
||||
def init_test2(self):
|
||||
self.q=q=LineHistory()
|
||||
for x in ["aaaa","aaba","aaca","akca","bbb","ako"]:
|
||||
for x in [u"aaaa",u"aaba",u"aaca",u"akca",u"bbb",u"ako"]:
|
||||
q.add_history(RL(x))
|
||||
|
||||
def test_history_search_backward (self):
|
||||
history._ignore_leading_spaces=False
|
||||
q=LineHistory()
|
||||
for x in ["aaaa","aaba","aaca"," aacax","akca","bbb","ako"]:
|
||||
for x in [u"aaaa",u"aaba",u"aaca",u" aacax",u"akca",u"bbb",u"ako"]:
|
||||
q.add_history(RL(x))
|
||||
a=RL("aa",point=2)
|
||||
for x in ["aaca","aaba","aaaa","aaaa"]:
|
||||
a=RL(u"aa",point=2)
|
||||
for x in [u"aaca",u"aaba",u"aaaa",u"aaaa"]:
|
||||
res=q.history_search_backward(a)
|
||||
assert res.get_line_text()==x
|
||||
|
||||
def test_history_search_forward (self):
|
||||
history._ignore_leading_spaces=False
|
||||
q=LineHistory()
|
||||
for x in ["aaaa","aaba","aaca"," aacax","akca","bbb","ako"]:
|
||||
for x in [u"aaaa",u"aaba",u"aaca",u" aacax",u"akca",u"bbb",u"ako"]:
|
||||
q.add_history(RL(x))
|
||||
q.beginning_of_history()
|
||||
a=RL("aa",point=2)
|
||||
for x in ["aaba","aaca","aaca"]:
|
||||
a=RL(u"aa",point=2)
|
||||
for x in [u"aaba",u"aaca",u"aaca"]:
|
||||
res=q.history_search_forward(a)
|
||||
assert res.get_line_text()==x
|
||||
|
||||
@@ -98,7 +98,7 @@ class Test_linepos (unittest.TestCase):
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
if __name__ == '__main__':
|
||||
if __name__ == u'__main__':
|
||||
unittest.main()
|
||||
|
||||
l=lineobj.ReadLineTextBuffer("First Second Third")
|
||||
l=lineobj.ReadLineTextBuffer(u"First Second Third")
|
||||
+137
-137
@@ -1,7 +1,7 @@
|
||||
# Copyright (C) 2006 Michael Graz. <mgraz@plan10.com>
|
||||
|
||||
import sys, unittest
|
||||
sys.path.append ('../..')
|
||||
sys.path.append (u'../..')
|
||||
#from pyreadline.modes.vi import *
|
||||
#from pyreadline import keysyms
|
||||
from pyreadline.lineeditor import lineobj
|
||||
@@ -13,14 +13,14 @@ from pyreadline.lineeditor import lineobj
|
||||
|
||||
class Test_copy (unittest.TestCase):
|
||||
def test_copy1 (self):
|
||||
l=lineobj.ReadLineTextBuffer("first second")
|
||||
l=lineobj.ReadLineTextBuffer(u"first second")
|
||||
q=l.copy()
|
||||
self.assertEqual(q.get_line_text(),l.get_line_text())
|
||||
self.assertEqual(q.point,l.point)
|
||||
self.assertEqual(q.mark,l.mark)
|
||||
|
||||
def test_copy2 (self):
|
||||
l=lineobj.ReadLineTextBuffer("first second",point=5)
|
||||
l=lineobj.ReadLineTextBuffer(u"first second",point=5)
|
||||
q=l.copy()
|
||||
self.assertEqual(q.get_line_text(),l.get_line_text())
|
||||
self.assertEqual(q.point,l.point)
|
||||
@@ -77,19 +77,19 @@ class Test_movement (unittest.TestCase):
|
||||
def test_NextChar (self):
|
||||
cmd=lineobj.NextChar
|
||||
tests=[
|
||||
# "First"
|
||||
# u"First"
|
||||
(cmd,
|
||||
"First",
|
||||
"# ",
|
||||
" # "),
|
||||
u"First",
|
||||
u"# u",
|
||||
u" # u"),
|
||||
(cmd,
|
||||
"First",
|
||||
" # ",
|
||||
" #"),
|
||||
u"First",
|
||||
u" # u",
|
||||
u" #"),
|
||||
(cmd,
|
||||
"First",
|
||||
" #",
|
||||
" #"),
|
||||
u"First",
|
||||
u" #",
|
||||
u" #"),
|
||||
]
|
||||
for cmd,text,init_point,expected_point in tests:
|
||||
l=lineobj.ReadLineTextBuffer(text,get_point_pos(init_point))
|
||||
@@ -99,19 +99,19 @@ class Test_movement (unittest.TestCase):
|
||||
def test_PrevChar (self):
|
||||
cmd=lineobj.PrevChar
|
||||
tests=[
|
||||
# "First"
|
||||
# u"First"
|
||||
(cmd,
|
||||
"First",
|
||||
" #",
|
||||
" # "),
|
||||
u"First",
|
||||
u" #",
|
||||
u" # u"),
|
||||
(cmd,
|
||||
"First",
|
||||
" # ",
|
||||
"# "),
|
||||
u"First",
|
||||
u" # u",
|
||||
u"# u"),
|
||||
(cmd,
|
||||
"First",
|
||||
"# ",
|
||||
"# "),
|
||||
u"First",
|
||||
u"# u",
|
||||
u"# u"),
|
||||
]
|
||||
for cmd,text,init_point,expected_point in tests:
|
||||
l=lineobj.ReadLineTextBuffer(text,get_point_pos(init_point))
|
||||
@@ -123,23 +123,23 @@ class Test_movement (unittest.TestCase):
|
||||
def test_PrevWordStart (self):
|
||||
cmd=lineobj.PrevWordStart
|
||||
tests=[
|
||||
# "First Second Third"
|
||||
# u"First Second Third"
|
||||
(cmd,
|
||||
"First Second Third",
|
||||
" #",
|
||||
" # "),
|
||||
u"First Second Third",
|
||||
u" #",
|
||||
u" # u"),
|
||||
(cmd,
|
||||
"First Second Third",
|
||||
" # ",
|
||||
" # "),
|
||||
u"First Second Third",
|
||||
u" # u",
|
||||
u" # u"),
|
||||
(cmd,
|
||||
"First Second Third",
|
||||
" # ",
|
||||
"# "),
|
||||
u"First Second Third",
|
||||
u" # u",
|
||||
u"# u"),
|
||||
(cmd,
|
||||
"First Second Third",
|
||||
"# ",
|
||||
"# "),
|
||||
u"First Second Third",
|
||||
u"# u",
|
||||
u"# u"),
|
||||
]
|
||||
for cmd,text,init_point,expected_point in tests:
|
||||
l=lineobj.ReadLineTextBuffer(text,get_point_pos(init_point))
|
||||
@@ -149,23 +149,23 @@ class Test_movement (unittest.TestCase):
|
||||
def test_NextWordStart (self):
|
||||
cmd=lineobj.NextWordStart
|
||||
tests=[
|
||||
# "First Second Third"
|
||||
# u"First Second Third"
|
||||
(cmd,
|
||||
"First Second Third",
|
||||
"# ",
|
||||
" # "),
|
||||
u"First Second Third",
|
||||
u"# u",
|
||||
u" # u"),
|
||||
(cmd,
|
||||
"First Second Third",
|
||||
" # ",
|
||||
" # "),
|
||||
u"First Second Third",
|
||||
u" # u",
|
||||
u" # u"),
|
||||
(cmd,
|
||||
"First Second Third",
|
||||
" # ",
|
||||
" # "),
|
||||
u"First Second Third",
|
||||
u" # u",
|
||||
u" # u"),
|
||||
(cmd,
|
||||
"First Second Third",
|
||||
" # ",
|
||||
" #"),
|
||||
u"First Second Third",
|
||||
u" # u",
|
||||
u" #"),
|
||||
]
|
||||
for cmd,text,init_point,expected_point in tests:
|
||||
l=lineobj.ReadLineTextBuffer(text,get_point_pos(init_point))
|
||||
@@ -175,23 +175,23 @@ class Test_movement (unittest.TestCase):
|
||||
def test_NextWordEnd (self):
|
||||
cmd=lineobj.NextWordEnd
|
||||
tests=[
|
||||
# "First Second Third"
|
||||
# u"First Second Third"
|
||||
(cmd,
|
||||
"First Second Third",
|
||||
"# ",
|
||||
" # "),
|
||||
u"First Second Third",
|
||||
u"# u",
|
||||
u" # u"),
|
||||
(cmd,
|
||||
"First Second Third",
|
||||
" # ",
|
||||
" # "),
|
||||
u"First Second Third",
|
||||
u" # u",
|
||||
u" # u"),
|
||||
(cmd,
|
||||
"First Second Third",
|
||||
" # ",
|
||||
" # "),
|
||||
u"First Second Third",
|
||||
u" # u",
|
||||
u" # u"),
|
||||
(cmd,
|
||||
"First Second Third",
|
||||
" # ",
|
||||
" #"),
|
||||
u"First Second Third",
|
||||
u" # u",
|
||||
u" #"),
|
||||
]
|
||||
for cmd,text,init_point,expected_point in tests:
|
||||
l=lineobj.ReadLineTextBuffer(text,get_point_pos(init_point))
|
||||
@@ -201,23 +201,23 @@ class Test_movement (unittest.TestCase):
|
||||
def test_PrevWordEnd (self):
|
||||
cmd=lineobj.PrevWordEnd
|
||||
tests=[
|
||||
# "First Second Third"
|
||||
# u"First Second Third"
|
||||
(cmd,
|
||||
"First Second Third",
|
||||
" #",
|
||||
" # "),
|
||||
u"First Second Third",
|
||||
u" #",
|
||||
u" # u"),
|
||||
(cmd,
|
||||
"First Second Third",
|
||||
" # ",
|
||||
" # "),
|
||||
u"First Second Third",
|
||||
u" # u",
|
||||
u" # u"),
|
||||
(cmd,
|
||||
"First Second Third",
|
||||
" # ",
|
||||
"# "),
|
||||
u"First Second Third",
|
||||
u" # u",
|
||||
u"# u"),
|
||||
(cmd,
|
||||
"First Second Third",
|
||||
"# ",
|
||||
"# "),
|
||||
u"First Second Third",
|
||||
u"# u",
|
||||
u"# u"),
|
||||
]
|
||||
for cmd,text,init_point,expected_point in tests:
|
||||
l=lineobj.ReadLineTextBuffer(text,get_point_pos(init_point))
|
||||
@@ -227,19 +227,19 @@ class Test_movement (unittest.TestCase):
|
||||
def test_WordEnd_1 (self):
|
||||
cmd=lineobj.WordEnd
|
||||
tests=[
|
||||
# "First Second Third"
|
||||
# u"First Second Third"
|
||||
(cmd,
|
||||
"First Second Third",
|
||||
"# ",
|
||||
" # "),
|
||||
u"First Second Third",
|
||||
u"# u",
|
||||
u" # u"),
|
||||
(cmd,
|
||||
"First Second Third",
|
||||
" # ",
|
||||
" # "),
|
||||
u"First Second Third",
|
||||
u" # u",
|
||||
u" # u"),
|
||||
(cmd,
|
||||
"First Second Third",
|
||||
" # ",
|
||||
" #"),
|
||||
u"First Second Third",
|
||||
u" # u",
|
||||
u" #"),
|
||||
]
|
||||
for cmd,text,init_point,expected_point in tests:
|
||||
l=lineobj.ReadLineTextBuffer(text,get_point_pos(init_point))
|
||||
@@ -249,16 +249,16 @@ class Test_movement (unittest.TestCase):
|
||||
def test_WordEnd_2 (self):
|
||||
cmd=lineobj.WordEnd
|
||||
tests=[
|
||||
# "First Second Third"
|
||||
# u"First Second Third"
|
||||
(cmd,
|
||||
"First Second Third",
|
||||
" # "),
|
||||
u"First Second Third",
|
||||
u" # u"),
|
||||
(cmd,
|
||||
"First Second Third",
|
||||
" # "),
|
||||
u"First Second Third",
|
||||
u" # u"),
|
||||
(cmd,
|
||||
"First Second Third",
|
||||
" #"),
|
||||
u"First Second Third",
|
||||
u" #"),
|
||||
]
|
||||
|
||||
for cmd,text,init_point in tests:
|
||||
@@ -269,19 +269,19 @@ class Test_movement (unittest.TestCase):
|
||||
def test_WordStart_1 (self):
|
||||
cmd=lineobj.WordStart
|
||||
tests=[
|
||||
# "First Second Third"
|
||||
# u"First Second Third"
|
||||
(cmd,
|
||||
"First Second Third",
|
||||
"# ",
|
||||
"# "),
|
||||
u"First Second Third",
|
||||
u"# u",
|
||||
u"# u"),
|
||||
(cmd,
|
||||
"First Second Third",
|
||||
" # ",
|
||||
"# "),
|
||||
u"First Second Third",
|
||||
u" # u",
|
||||
u"# u"),
|
||||
(cmd,
|
||||
"First Second Third",
|
||||
" # ",
|
||||
" # "),
|
||||
u"First Second Third",
|
||||
u" # u",
|
||||
u" # u"),
|
||||
]
|
||||
for cmd,text,init_point,expected_point in tests:
|
||||
l=lineobj.ReadLineTextBuffer(text,get_point_pos(init_point))
|
||||
@@ -291,16 +291,16 @@ class Test_movement (unittest.TestCase):
|
||||
def test_WordStart_2 (self):
|
||||
cmd=lineobj.WordStart
|
||||
tests=[
|
||||
# "First Second Third"
|
||||
# u"First Second Third"
|
||||
(cmd,
|
||||
"First Second Third",
|
||||
" # "),
|
||||
u"First Second Third",
|
||||
u" # u"),
|
||||
(cmd,
|
||||
"First Second Third",
|
||||
" # "),
|
||||
u"First Second Third",
|
||||
u" # u"),
|
||||
(cmd,
|
||||
"First Second Third",
|
||||
" #"),
|
||||
u"First Second Third",
|
||||
u" #"),
|
||||
]
|
||||
|
||||
for cmd,text,init_point in tests:
|
||||
@@ -311,19 +311,19 @@ class Test_movement (unittest.TestCase):
|
||||
def test_StartOfLine (self):
|
||||
cmd=lineobj.StartOfLine
|
||||
tests=[
|
||||
# "First Second Third"
|
||||
# u"First Second Third"
|
||||
(cmd,
|
||||
"First Second Third",
|
||||
"# ",
|
||||
"# "),
|
||||
u"First Second Third",
|
||||
u"# u",
|
||||
u"# u"),
|
||||
(cmd,
|
||||
"First Second Third",
|
||||
" # ",
|
||||
"# "),
|
||||
u"First Second Third",
|
||||
u" # u",
|
||||
u"# u"),
|
||||
(cmd,
|
||||
"First Second Third",
|
||||
" #",
|
||||
"# "),
|
||||
u"First Second Third",
|
||||
u" #",
|
||||
u"# u"),
|
||||
]
|
||||
for cmd,text,init_point,expected_point in tests:
|
||||
l=lineobj.ReadLineTextBuffer(text,get_point_pos(init_point))
|
||||
@@ -333,19 +333,19 @@ class Test_movement (unittest.TestCase):
|
||||
def test_EndOfLine (self):
|
||||
cmd=lineobj.EndOfLine
|
||||
tests=[
|
||||
# "First Second Third"
|
||||
# u"First Second Third"
|
||||
(cmd,
|
||||
"First Second Third",
|
||||
"# ",
|
||||
" #"),
|
||||
u"First Second Third",
|
||||
u"# u",
|
||||
u" #"),
|
||||
(cmd,
|
||||
"First Second Third",
|
||||
" # ",
|
||||
" #"),
|
||||
u"First Second Third",
|
||||
u" # u",
|
||||
u" #"),
|
||||
(cmd,
|
||||
"First Second Third",
|
||||
" #",
|
||||
" #"),
|
||||
u"First Second Third",
|
||||
u" #",
|
||||
u" #"),
|
||||
]
|
||||
for cmd,text,init_point,expected_point in tests:
|
||||
l=lineobj.ReadLineTextBuffer(text,get_point_pos(init_point))
|
||||
@@ -355,15 +355,15 @@ class Test_movement (unittest.TestCase):
|
||||
def test_Point(self):
|
||||
cmd=lineobj.Point
|
||||
tests=[
|
||||
# "First Second Third"
|
||||
# u"First Second Third"
|
||||
(cmd,
|
||||
"First Second Third",
|
||||
u"First Second Third",
|
||||
0),
|
||||
(cmd,
|
||||
"First Second Third",
|
||||
u"First Second Third",
|
||||
12),
|
||||
(cmd,
|
||||
"First Second Third",
|
||||
u"First Second Third",
|
||||
18),
|
||||
]
|
||||
for cmd,text,p in tests:
|
||||
@@ -375,16 +375,16 @@ class Test_movement (unittest.TestCase):
|
||||
# utility functions
|
||||
|
||||
def get_point_pos(pstr):
|
||||
return pstr.index("#")
|
||||
return pstr.index(u"#")
|
||||
|
||||
def get_mark_pos(mstr):
|
||||
try:
|
||||
return mstr.index("#")
|
||||
return mstr.index(u"#")
|
||||
except ValueError:
|
||||
return -1
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
if __name__ == '__main__':
|
||||
if __name__ == u'__main__':
|
||||
unittest.main()
|
||||
|
||||
l=lineobj.ReadLineTextBuffer("First Second Third")
|
||||
l=lineobj.ReadLineTextBuffer(u"First Second Third")
|
||||
|
||||
+1284
-1284
File diff suppressed because it is too large
Load Diff
@@ -8,26 +8,26 @@
|
||||
import sys
|
||||
|
||||
try:
|
||||
pyreadline_codepage=sys.stdout.encoding
|
||||
pyreadline_codepage = sys.stdout.encoding
|
||||
except AttributeError: #This error occurs when pdb imports readline and doctest has replaced
|
||||
#stdout with stdout collector
|
||||
pyreadline_codepage="ascii" #assume ascii codepage
|
||||
pyreadline_codepage = u"ascii" #assume ascii codepage
|
||||
|
||||
|
||||
def ensure_unicode(text):
|
||||
"""helper to ensure that text passed to WriteConsoleW is unicode"""
|
||||
u"""helper to ensure that text passed to WriteConsoleW is unicode"""
|
||||
if isinstance(text, str):
|
||||
try:
|
||||
return text.decode(pyreadline_codepage, "replace")
|
||||
return text.decode(pyreadline_codepage, u"replace")
|
||||
except (LookupError, TypeError):
|
||||
return text.decode("ascii", "replace")
|
||||
return text.decode(u"ascii", u"replace")
|
||||
return text
|
||||
|
||||
def ensure_str(text):
|
||||
"""Convert unicode to str using pyreadline_codepage"""
|
||||
u"""Convert unicode to str using pyreadline_codepage"""
|
||||
if isinstance(text, unicode):
|
||||
try:
|
||||
return text.encode(pyreadline_codepage, "replace")
|
||||
return text.encode(pyreadline_codepage, u"replace")
|
||||
except (LookupError, TypeError):
|
||||
return text.encode("ascii", "replace")
|
||||
return text.encode(u"ascii", u"replace")
|
||||
return text
|
||||
|
||||
Reference in New Issue
Block a user