mirror of
https://github.com/wassname/pyreadline.git
synced 2026-07-21 12:40:29 +08:00
pyreadline-refactor: improved support for ironpython. Seems quite ok now. Also another bug fix in history search
This commit is contained in:
@@ -1,15 +1,19 @@
|
||||
import sys
|
||||
success=False
|
||||
in_ironpython=sys.version.startswith("IronPython")
|
||||
|
||||
try:
|
||||
from clipboard import GetClipboardText,SetClipboardText
|
||||
success=True
|
||||
except ImportError:
|
||||
if in_ironpython:
|
||||
try:
|
||||
from ironpython_clipboard import GetClipboardText,SetClipboardText
|
||||
success=True
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
else:
|
||||
try:
|
||||
from clipboard import GetClipboardText,SetClipboardText
|
||||
success=True
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,15 +1,18 @@
|
||||
import glob
|
||||
import glob,sys
|
||||
|
||||
success=False
|
||||
in_ironpython=sys.version.startswith("IronPython")
|
||||
|
||||
try:
|
||||
from console import *
|
||||
success=True
|
||||
except ImportError:
|
||||
|
||||
if in_ironpython:
|
||||
try:
|
||||
from ironpython_console import *
|
||||
success=True
|
||||
except ImportError:
|
||||
raise
|
||||
else:
|
||||
try:
|
||||
from console import *
|
||||
success=True
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
|
||||
@@ -209,6 +209,14 @@ class Console(object):
|
||||
self.SetConsoleMode(self.hin, self.inmode)
|
||||
self.FreeConsole()
|
||||
|
||||
def _get_top_bot(self):
|
||||
info = CONSOLE_SCREEN_BUFFER_INFO()
|
||||
self.GetConsoleScreenBufferInfo(self.hout, byref(info))
|
||||
rect = info.srWindow
|
||||
top = rect.Top
|
||||
bot = rect.Bottom
|
||||
return top,bot
|
||||
|
||||
def fixcoord(self, x, y):
|
||||
'''Return a long with x and y packed inside, also handle negative x and y.'''
|
||||
if x < 0 or y < 0:
|
||||
@@ -279,7 +287,6 @@ class Console(object):
|
||||
x, y = self.pos()
|
||||
w, h = self.size()
|
||||
scroll = 0 # the result
|
||||
|
||||
# split the string into ordinary characters and funny characters
|
||||
chunks = self.motion_char_re.split(text)
|
||||
for chunk in chunks:
|
||||
@@ -344,12 +351,9 @@ class Console(object):
|
||||
return n
|
||||
|
||||
def write_color(self, text, attr=None):
|
||||
log_sock(text)
|
||||
log_sock("%s"%attr)
|
||||
n,res= self.ansiwriter.write_color(text,attr)
|
||||
junk = c_int(0)
|
||||
for attr,chunk in res:
|
||||
log_sock("%s:%s"%(attr,chunk))
|
||||
log(str(attr))
|
||||
log(str(chunk))
|
||||
self.SetConsoleTextAttribute(self.hout, attr.winattr)
|
||||
@@ -409,8 +413,17 @@ class Console(object):
|
||||
self.WriteConsoleOutputCharacterA(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))
|
||||
|
||||
def rectangle(self, rect, attr=None, fill=' '):
|
||||
'''Fill Rectangle.'''
|
||||
log_sock("rect:%s"%[rect])
|
||||
x0, y0, x1, y1 = rect
|
||||
n = c_int(0)
|
||||
if attr is None:
|
||||
@@ -445,7 +458,6 @@ class Console(object):
|
||||
bot = rect.Bottom + lines
|
||||
h = bot - top
|
||||
maxbot = info.dwSize.Y-1
|
||||
log('sw: lines=%d mb=%d top=%d bot=%d' % (lines,maxbot,top,bot))
|
||||
if top < 0:
|
||||
top = 0
|
||||
bot = h
|
||||
@@ -491,7 +503,6 @@ class Console(object):
|
||||
return e
|
||||
elif e.type == 'KeyRelease' and e.keyinfo==(True, False, False, 83):
|
||||
log("getKeypress:%s,%s,%s"%(e.keyinfo,e.keycode,e.type))
|
||||
# log_sock(str(e))
|
||||
return e
|
||||
|
||||
def getchar(self):
|
||||
|
||||
@@ -9,6 +9,21 @@
|
||||
'''Cursor control and color for the .NET console.
|
||||
'''
|
||||
|
||||
#
|
||||
# Ironpython requires a patch to work do:
|
||||
#
|
||||
# In file PythonCommandLine.cs patch line:
|
||||
# class PythonCommandLine
|
||||
# {
|
||||
|
||||
# to:
|
||||
# public class PythonCommandLine
|
||||
# {
|
||||
#
|
||||
#
|
||||
#
|
||||
|
||||
|
||||
# primitive debug printing that won't interfere with the screen
|
||||
|
||||
import clr
|
||||
@@ -23,14 +38,14 @@ import os
|
||||
import System
|
||||
|
||||
from event import Event
|
||||
from pyreadline.logger import log
|
||||
from pyreadline.logger import log,log_sock
|
||||
|
||||
#print "Codepage",System.Console.InputEncoding.CodePage
|
||||
from pyreadline.keysyms import make_keysym, make_keyinfo,make_KeyPress
|
||||
|
||||
from pyreadline.keysyms import make_keysym, make_keyinfo,make_KeyPress,make_KeyPress_from_keydescr
|
||||
from pyreadline.console.ansi import AnsiState
|
||||
color=System.ConsoleColor
|
||||
|
||||
ansicolor={
|
||||
ansicolor={"0;30": color.Black,
|
||||
"0;31": color.DarkRed,
|
||||
"0;32": color.DarkGreen,
|
||||
"0;33": color.DarkYellow,
|
||||
@@ -38,6 +53,7 @@ ansicolor={
|
||||
"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,
|
||||
@@ -47,6 +63,15 @@ ansicolor={
|
||||
"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}
|
||||
|
||||
class Console(object):
|
||||
'''Console driver for Windows.
|
||||
|
||||
@@ -60,15 +85,25 @@ class Console(object):
|
||||
'''
|
||||
self.serial=0
|
||||
self.attr = System.Console.ForegroundColor
|
||||
self.saveattr = 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)
|
||||
|
||||
def _get(self):
|
||||
top=System.Console.WindowTop
|
||||
log_sock("WindowTop:%s"%top,"console")
|
||||
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 __del__(self):
|
||||
'''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)
|
||||
self.FreeConsole()
|
||||
pass
|
||||
|
||||
def pos(self, x=None, y=None):
|
||||
'''Move or query the window cursor.'''
|
||||
@@ -153,6 +188,11 @@ 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}
|
||||
|
||||
def write_color(self, text, attr=None):
|
||||
'''write text at current cursor position and interpret color escapes.
|
||||
|
||||
@@ -161,17 +201,24 @@ class Console(object):
|
||||
log('write_color("%s", %s)' % (text, attr))
|
||||
chunks = self.terminal_escape.split(text)
|
||||
log('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]
|
||||
except TypeError:
|
||||
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)
|
||||
n += len(chunk)
|
||||
log('attr=%s' % attr)
|
||||
System.Console.ForegroundColor=attr
|
||||
System.Console.ForegroundColor=fg
|
||||
System.Console.BackgroundColor=bg
|
||||
#self.WriteConsoleA(self.hout, chunk, len(chunk), byref(junk), None)
|
||||
System.Console.Write(chunk)
|
||||
return n
|
||||
@@ -215,9 +262,21 @@ class Console(object):
|
||||
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*" ")
|
||||
self.pos(*pos)
|
||||
self.WindowTop=oldtop
|
||||
|
||||
def rectangle(self, rect, attr=None, fill=' '):
|
||||
'''Fill Rectangle.'''
|
||||
pass
|
||||
oldtop=self.WindowTop
|
||||
oldpos=self.pos()
|
||||
#raise NotImplementedError
|
||||
x0, y0, x1, y1 = rect
|
||||
if attr is None:
|
||||
@@ -229,6 +288,7 @@ class Console(object):
|
||||
for y in range(y0, y1):
|
||||
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.'''
|
||||
@@ -237,23 +297,28 @@ class Console(object):
|
||||
|
||||
def scroll_window(self, lines):
|
||||
'''Scroll the window by the indicated number of lines.'''
|
||||
top=System.Console.WindowTop+lines
|
||||
top=self.WindowTop+lines
|
||||
if top<0:
|
||||
top=0
|
||||
if top+System.Console.WindowHeight>System.Console.BufferHeight:
|
||||
top=System.Console.BufferHeight
|
||||
System.Console.WindowTop=top
|
||||
self.WindowTop=top
|
||||
|
||||
def getkeypress(self):
|
||||
'''Return next key press event from the queue, ignoring others.'''
|
||||
ck=System.ConsoleKey
|
||||
while 1:
|
||||
e = System.Console.ReadKey(True)
|
||||
try:
|
||||
e = System.Console.ReadKey(True)
|
||||
except KeyboardInterrupt:
|
||||
return CTRL_C_EVENT
|
||||
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
|
||||
else:
|
||||
return event(self,e)
|
||||
@@ -268,10 +333,17 @@ class Console(object):
|
||||
def size(self, width=None, height=None):
|
||||
'''Set/get window size.'''
|
||||
sc=System.Console
|
||||
|
||||
|
||||
if width is not None and height is not None:
|
||||
sc.BufferWidth,sc.BufferHeight=width,height
|
||||
else:
|
||||
return sc.BufferWidth,sc.BufferHeight
|
||||
|
||||
if width is not None and height is not None:
|
||||
sc.WindowWidth,sc.WindowHeight=width,height
|
||||
else:
|
||||
return sc.WindowWidth,sc.WindowHeight
|
||||
return sc.WindowWidth-1,sc.WindowHeight-1
|
||||
|
||||
def cursor(self, visible=True, size=None):
|
||||
'''Set cursor on or off.'''
|
||||
@@ -298,12 +370,25 @@ 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"
|
||||
|
||||
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)
|
||||
del input.next_serial
|
||||
keyinfo=make_KeyPress_from_keydescr(keydescr)
|
||||
e.keyinfo=keyinfo
|
||||
return e
|
||||
|
||||
CTRL_C_EVENT=make_event_from_keydescr("Control-c")
|
||||
|
||||
def install_readline(hook):
|
||||
class IronPythonWrapper(IronPythonConsole.IConsole):
|
||||
@@ -343,4 +428,4 @@ if __name__ == '__main__':
|
||||
print e.Key,chr(e.KeyChar),ord(e.KeyChar),e.Modifiers
|
||||
del c
|
||||
|
||||
System.Console.Clear()
|
||||
System.Console.Clear()
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#*****************************************************************************
|
||||
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
|
||||
@@ -196,7 +196,11 @@ def make_KeyPress(char,state,keycode):
|
||||
control=bool(int(state)&int(Control))
|
||||
meta=bool(int(state)&int(Alt))
|
||||
keyname=code2sym_map.get(keycode,"").lower()
|
||||
if control:
|
||||
log_sock("make key %s %s %s %s"%(shift,control,meta,keycode),"keysyms")
|
||||
if control and meta: #equivalent to altgr so clear flags
|
||||
control=False
|
||||
meta=False
|
||||
elif control:
|
||||
char=str(keycode)
|
||||
return KeyPress(char,shift,control,meta,keyname)
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@ class LineHistory(object):
|
||||
if filename is None:
|
||||
filename=self.history_filename
|
||||
try:
|
||||
for line in open(filename, 'rt'):
|
||||
for line in open(filename, 'r'):
|
||||
self.add_history(lineobj.ReadLineTextBuffer(line.rstrip()))
|
||||
except IOError:
|
||||
self.history = []
|
||||
@@ -179,33 +179,38 @@ class LineHistory(object):
|
||||
return self._non_i_search(1,current)
|
||||
|
||||
def _search(self, direction, partial):
|
||||
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)
|
||||
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()))
|
||||
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)
|
||||
return result
|
||||
hc += direction
|
||||
else:
|
||||
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[hcstart].get_line_text().startswith(self.query) and self.query:
|
||||
return lineobj.ReadLineTextBuffer(self.history[hcstart],point=partial.point)
|
||||
else:
|
||||
return lineobj.ReadLineTextBuffer(partial,point=partial.point)
|
||||
return lineobj.ReadLineTextBuffer(self.query,point=min(len(self.query),partial.point))
|
||||
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)
|
||||
log_sock("hcstart %s"%hcstart)
|
||||
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()))
|
||||
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)
|
||||
return result
|
||||
hc += direction
|
||||
else:
|
||||
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)
|
||||
else:
|
||||
return lineobj.ReadLineTextBuffer(partial,point=partial.point)
|
||||
return lineobj.ReadLineTextBuffer(self.query,point=min(len(self.query),partial.point))
|
||||
except IndexError:
|
||||
log_sock("hcstart:%s %s"%(hcstart,len(self.history)))
|
||||
raise
|
||||
|
||||
def history_search_forward(self,partial): # ()
|
||||
'''Search forward through the history for the string of characters
|
||||
@@ -218,6 +223,7 @@ class LineHistory(object):
|
||||
'''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)
|
||||
return q
|
||||
|
||||
|
||||
@@ -26,10 +26,10 @@ host="localhost"
|
||||
port=8081
|
||||
logsocket=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
|
||||
|
||||
show_event=["keypress","bound_function","bind_key"]
|
||||
show_event=["keypress","bound_function","bind_key","console"]
|
||||
show_event=["bound_function"]
|
||||
|
||||
sock_silent=False
|
||||
sock_silent=True
|
||||
|
||||
def log_sock(s,event_type=None):
|
||||
if sock_silent:
|
||||
@@ -43,4 +43,3 @@ def log_sock(s,event_type=None):
|
||||
pass
|
||||
|
||||
|
||||
log_sock("Starting pyreadline")
|
||||
@@ -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 os,re,math,glob
|
||||
import os,re,math,glob,sys
|
||||
import pyreadline.logger as logger
|
||||
from pyreadline.logger import log
|
||||
from pyreadline.keysyms.common import make_KeyPress_from_keydescr
|
||||
@@ -14,6 +14,7 @@ import pyreadline.lineeditor.lineobj as lineobj
|
||||
import pyreadline.lineeditor.history as history
|
||||
import pyreadline.clipboard as clipboard
|
||||
from pyreadline.error import ReadlineError,GetSetError
|
||||
in_ironpython=sys.version.startswith("IronPython")
|
||||
|
||||
class BaseMode(object):
|
||||
mode="base"
|
||||
@@ -173,6 +174,8 @@ class BaseMode(object):
|
||||
if i < len(completions):
|
||||
self.console.write(completions[i].ljust(wmax+1))
|
||||
self.console.write('\n')
|
||||
if in_ironpython:
|
||||
self.prompt=sys.ps1
|
||||
self._print_prompt()
|
||||
|
||||
def complete(self, e): # (TAB)
|
||||
|
||||
@@ -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 os
|
||||
import os,sys
|
||||
import pyreadline.logger as logger
|
||||
from pyreadline.logger import log,log_sock
|
||||
from pyreadline.lineeditor.lineobj import Point
|
||||
@@ -21,6 +21,8 @@ def format(keyinfo):
|
||||
k=keyinfo+(ord(keyinfo[-1]),)
|
||||
|
||||
return "(%s,%s,%s,%s,%x)"%k
|
||||
in_ironpython=sys.version.startswith("IronPython")
|
||||
|
||||
|
||||
class EmacsMode(basemode.BaseMode):
|
||||
mode="emacs"
|
||||
@@ -28,7 +30,7 @@ class EmacsMode(basemode.BaseMode):
|
||||
super(EmacsMode,self).__init__(rlobj)
|
||||
self._keylog=(lambda x,y: None)
|
||||
self.previous_func=None
|
||||
self.prompt=""
|
||||
self.prompt=">>>"
|
||||
def __repr__(self):
|
||||
return "<EmacsMode>"
|
||||
|
||||
@@ -105,7 +107,13 @@ class EmacsMode(basemode.BaseMode):
|
||||
self.paste_line_buffer=self.paste_line_buffer[1:]
|
||||
c.write('\r\n')
|
||||
else:
|
||||
self._readline_from_keyboard()
|
||||
try:
|
||||
self._readline_from_keyboard()
|
||||
except EOFError:
|
||||
if in_ironpython:
|
||||
return None
|
||||
else:
|
||||
raise
|
||||
c.write('\r\n')
|
||||
|
||||
self.add_history(self.l_buffer.copy())
|
||||
|
||||
+16
-8
@@ -29,6 +29,14 @@ import release
|
||||
|
||||
from modes import editingmodes
|
||||
|
||||
in_ironpython=sys.version.startswith("IronPython")
|
||||
if in_ironpython:#ironpython does not provide a prompt string to readline
|
||||
import System
|
||||
default_prompt=">>> "
|
||||
else:
|
||||
default_prompt=""
|
||||
|
||||
|
||||
def quote_char(c):
|
||||
if ord(c)>0:
|
||||
return c
|
||||
@@ -47,7 +55,7 @@ class Readline(object):
|
||||
self.size = self.console.size()
|
||||
self.prompt_color = None
|
||||
self.command_color = None
|
||||
self.selection_color =0x00f0
|
||||
self.selection_color = self.console.saveattr<<4
|
||||
self.key_dispatch = {}
|
||||
self.previous_func = None
|
||||
self.first_prompt = True
|
||||
@@ -270,7 +278,7 @@ class Readline(object):
|
||||
c = self.console
|
||||
x, y = c.pos()
|
||||
w, h = c.size()
|
||||
c.rectangle((x, y, w, y+1))
|
||||
c.rectangle((x, y, w+1, y+1))
|
||||
c.rectangle((0, y+1, w, min(y+3,h)))
|
||||
|
||||
def _set_cursor(self):
|
||||
@@ -278,15 +286,15 @@ class Readline(object):
|
||||
xc, yc = self.prompt_end_pos
|
||||
w, h = c.size()
|
||||
xc += self.l_buffer.visible_line_width()
|
||||
while(xc > w):
|
||||
while(xc >= w):
|
||||
xc -= w
|
||||
yc += 1
|
||||
c.pos(xc, yc)
|
||||
|
||||
def _print_prompt(self):
|
||||
c = self.console
|
||||
log('prompt="%s"' % repr(self.prompt))
|
||||
x, y = c.pos()
|
||||
|
||||
n = c.write_scrolling(self.prompt, self.prompt_color)
|
||||
self.prompt_begin_pos = (x, y - n)
|
||||
self.prompt_end_pos = c.pos()
|
||||
@@ -313,9 +321,11 @@ class Readline(object):
|
||||
n = c.write_scrolling(ltext[stop:], self.command_color)
|
||||
else:
|
||||
n = c.write_scrolling(ltext, self.command_color)
|
||||
|
||||
self._update_prompt_pos(n)
|
||||
self._clear_after()
|
||||
if hasattr(c,"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()
|
||||
self._set_cursor()
|
||||
|
||||
def readline(self, prompt=''):
|
||||
@@ -329,9 +339,7 @@ class Readline(object):
|
||||
self.mode=modes[name]
|
||||
def bind_key(key,name):
|
||||
log("bind %s %s"%(key,name))
|
||||
log_sock("bindkey: %s %s"%(key,name),"bind_key")
|
||||
if hasattr(modes[mode],name):
|
||||
# print "can bind",key,name
|
||||
modes[mode]._bind_key(key,getattr(modes[mode],name))
|
||||
else:
|
||||
print "Trying to bind unknown command '%s' to key '%s'"%(name,key)
|
||||
|
||||
@@ -304,6 +304,19 @@ class TestsHistory (unittest.TestCase):
|
||||
r.input ('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')
|
||||
self.assert_line(r,'',0)
|
||||
r.input ('k')
|
||||
r.input ('Up')
|
||||
self.assert_line(r,'k',1)
|
||||
|
||||
|
||||
|
||||
def assert_line(self,r,line,cursor):
|
||||
|
||||
Reference in New Issue
Block a user