mirror of
https://github.com/wassname/pyreadline.git
synced 2026-08-11 11:23:56 +08:00
pyreadline-refactor: Merge ansi patch and tab patch from trunk.
This commit is contained in:
@@ -1,3 +1,12 @@
|
||||
2006-09-11 Jörgen Stenarson <jorgen.stenarson -at- bostream.nu>
|
||||
* Added logserver. Socket based server that can receive logmessage.
|
||||
To be used when debugging keypresses, could be a security risk as a keyboard sniffer.
|
||||
* Added log_sock call to send logging to logserver
|
||||
* Merging ANSI parsing from trunk
|
||||
* Parsing escape sequence for up down key in parse_bind
|
||||
* Merging bugfix for self_insert of tabs from trunk
|
||||
* Add bindable function that prints keybindings
|
||||
|
||||
2006-07-13 Jörgen Stenarson <jorgen.stenarson -at- bostream.nu>
|
||||
* Work to get selection between ironpython and cpython to work
|
||||
* Some editing works but there are issues with control keys for ironpython
|
||||
|
||||
@@ -0,0 +1,175 @@
|
||||
# -*- coding: ISO-8859-1 -*-
|
||||
import re,sys,os,pprint
|
||||
pprint=pprint.pprint
|
||||
|
||||
terminal_escape = re.compile('(\001?\033\\[[0-9;]*m\002?)')
|
||||
escape_parts = re.compile('\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
|
||||
|
||||
trtable={"black":0,"red":4,"green":2,"yellow":6,"blue":1,"magenta":5,"cyan":3,"white":7}
|
||||
revtable=dict(zip(trtable.values(),trtable.keys()))
|
||||
def get_winattr(self):
|
||||
attr=0
|
||||
if self.bold:
|
||||
attr|=0x0008
|
||||
if self.backgroundbold:
|
||||
attr|=0x0080
|
||||
if self.inverse:
|
||||
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]
|
||||
|
||||
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)
|
||||
|
||||
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
|
||||
return x
|
||||
defaultstate=AnsiState(False,False,"white")
|
||||
|
||||
trtable={0:"black",1:"red",2:"green",3:"yellow",4:"blue",5:"magenta",6:"cyan",7:"white"}
|
||||
|
||||
class AnsiWriter(object):
|
||||
def __init__(self,default=defaultstate):
|
||||
if isinstance(defaultstate,AnsiState):
|
||||
self.defaultstate=default
|
||||
else:
|
||||
self.defaultstate=AnsiState()
|
||||
self.defaultstate.winattr=defaultstate
|
||||
|
||||
|
||||
def write_color(self,text, attr=None):
|
||||
'''write text at current cursor position and interpret color escapes.
|
||||
|
||||
return the number of characters written.
|
||||
'''
|
||||
if isinstance(attr,AnsiState):
|
||||
defaultstate=attr
|
||||
elif attr is None: #use attribute form initial console
|
||||
attr = self.defaultstate.copy()
|
||||
else:
|
||||
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:
|
||||
for part in m.group(1).split(";"):
|
||||
if part == "0": # No text attribute
|
||||
attr = self.defaultstate.copy()
|
||||
elif part == "7": # switch on reverse
|
||||
attr.inverse=True
|
||||
elif part == "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.color = trtable[int(part)-40]
|
||||
continue
|
||||
n += len(chunk)
|
||||
if True:
|
||||
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]
|
||||
|
||||
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.
|
||||
|
||||
return the number of characters written.
|
||||
'''
|
||||
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
|
||||
attr = 15
|
||||
for chunk in chunks:
|
||||
m = escape_parts.match(chunk)
|
||||
if m:
|
||||
for part in m.group(1).split(";"):
|
||||
if part == "0": # No text attribute
|
||||
attr = 0
|
||||
elif part == "7": # switch on reverse
|
||||
attr |= 0x4000
|
||||
if part == "1": # switch on bold (i.e. intensify foreground color)
|
||||
attr |= 0x08
|
||||
elif len(part) == 2 and "30" <= part <= "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
|
||||
# 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))
|
||||
return res
|
||||
|
||||
|
||||
#trtable={0:"black",1:"red",2:"green",3:"yellow",4:"blue",5:"magenta",6:"cyan",7:"white"}
|
||||
|
||||
if __name__=="__main__":
|
||||
import startup
|
||||
s="\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"
|
||||
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"
|
||||
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"
|
||||
pprint (write_color(s))
|
||||
pprint (write_color_old(s))
|
||||
|
||||
|
||||
if __name__=="__main__":
|
||||
import console
|
||||
|
||||
c=console.Console()
|
||||
c.write_color("dhsjdhs")
|
||||
c.write_color("\033[0;32mIn [\033[1;32m1\033[0;32m]:")
|
||||
print
|
||||
pprint (write_color("\033[0;32mIn [\033[1;32m1\033[0;32m]:"))
|
||||
|
||||
@@ -16,7 +16,7 @@ This was modeled after the C extension of the same name by Fredrik Lundh.
|
||||
import sys
|
||||
import traceback
|
||||
import re
|
||||
from pyreadline.logger import log
|
||||
from pyreadline.logger import log,log_sock
|
||||
|
||||
try:
|
||||
# I developed this with ctypes 0.6
|
||||
@@ -27,6 +27,7 @@ except ImportError:
|
||||
|
||||
# my code
|
||||
from pyreadline.keysyms import make_KeyPress
|
||||
from pyreadline.console.ansi import AnsiState,AnsiWriter
|
||||
|
||||
# some constants we need
|
||||
STD_INPUT_HANDLE = -10
|
||||
@@ -183,6 +184,11 @@ class Console(object):
|
||||
self.GetConsoleScreenBufferInfo(self.hout, byref(info))
|
||||
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)
|
||||
|
||||
background = self.attr & 0xf0
|
||||
for escape in self.escape_to_color:
|
||||
if self.escape_to_color[escape] is not None:
|
||||
@@ -336,6 +342,17 @@ class Console(object):
|
||||
self.WriteConsoleA(self.hout, chunk, len(chunk), byref(junk), None)
|
||||
return n
|
||||
|
||||
def write_color(self, text, attr=None):
|
||||
n,res= self.ansiwriter.write_color(text,attr)
|
||||
junk = c_int(0)
|
||||
for attr,chunk in res:
|
||||
log(str(attr))
|
||||
log(str(chunk))
|
||||
self.SetConsoleTextAttribute(self.hout, attr.winattr)
|
||||
self.WriteConsoleA(self.hout, chunk, len(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))
|
||||
@@ -453,6 +470,7 @@ class Console(object):
|
||||
status = self.ReadConsoleInputA(self.hin, byref(Cevent), 1, byref(count))
|
||||
if status and count.value == 1:
|
||||
e = event(self, Cevent)
|
||||
log_sock(str(e.keyinfo),"keypress")
|
||||
return e
|
||||
|
||||
def getkeypress(self):
|
||||
@@ -469,6 +487,7 @@ 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):
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
# -*- 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.
|
||||
#*****************************************************************************
|
||||
|
||||
|
||||
class ReadlineError(Exception):
|
||||
pass
|
||||
|
||||
class GetSetError(ReadlineError):
|
||||
pass
|
||||
@@ -29,6 +29,8 @@ validkey =set(['cancel', 'backspace', 'tab', 'clear',
|
||||
'numpad8', 'numpad9', 'divide', 'multiply',
|
||||
'add', 'subtract', 'vk_decimal'])
|
||||
|
||||
escape_sequence_to_special_key={"\\e[a":"up","\\e[b":"down","del":"delete"}
|
||||
|
||||
class KeyPress(object):
|
||||
def __init__(self,char="",shift=False,control=False,meta=False,keyname=""):
|
||||
if control or meta or shift:
|
||||
@@ -65,7 +67,9 @@ class KeyPress(object):
|
||||
|
||||
def make_KeyPress_from_keydescr(keydescr):
|
||||
keyinfo=KeyPress()
|
||||
|
||||
if len(keydescr)>2 and keydescr[:1]=='"' and keydescr[-1:]=='"':
|
||||
keydescr=keydescr[1:-1]
|
||||
|
||||
while 1:
|
||||
lkeyname = keydescr.lower()
|
||||
if lkeyname.startswith('control-'):
|
||||
@@ -74,14 +78,14 @@ def make_KeyPress_from_keydescr(keydescr):
|
||||
elif lkeyname.startswith('ctrl-'):
|
||||
keyinfo.control = True
|
||||
keydescr = keydescr[5:]
|
||||
elif keydescr.startswith('\\C-'):
|
||||
elif keydescr.lower().startswith('\\c-'):
|
||||
keyinfo.control = True
|
||||
keydescr = keydescr[3:]
|
||||
elif keydescr.startswith('\\M-'):
|
||||
elif keydescr.lower().startswith('\\m-'):
|
||||
keyinfo.meta = True
|
||||
keydescr = keydescr[3:]
|
||||
elif keydescr.startswith('\\e-'):
|
||||
keydescr = "escape"+keydescr[3:]
|
||||
elif keydescr in escape_sequence_to_special_key:
|
||||
keydescr = escape_sequence_to_special_key[keydescr]
|
||||
elif lkeyname.startswith('meta-'):
|
||||
keyinfo.meta = True
|
||||
keydescr = keydescr[5:]
|
||||
|
||||
@@ -21,6 +21,8 @@ import exceptions
|
||||
class EscapeHistory(exceptions.Exception):
|
||||
pass
|
||||
|
||||
from pyreadline.logger import log_sock
|
||||
|
||||
class LineHistory(object):
|
||||
def __init__(self):
|
||||
self.history=[]
|
||||
@@ -96,15 +98,19 @@ class LineHistory(object):
|
||||
self.history_cursor=len(self.history)
|
||||
current.set_line(self.history[-1].get_line_text())
|
||||
|
||||
def reverse_search_history(self,searchfor):
|
||||
res=[(idx,line) for idx,line in enumerate(self.history[self.history_cursor:0:-1]) if searchfor in line]
|
||||
def reverse_search_history(self,searchfor,startpos=None):
|
||||
if startpos is None:
|
||||
startpos=self.history_cursor
|
||||
res=[(idx,line) for idx,line in enumerate(self.history[startpos:0:-1]) if searchfor in line]
|
||||
if res:
|
||||
self.history_cursor-=res[0][0]
|
||||
return res[0][1].get_line_text()
|
||||
return ""
|
||||
|
||||
def forward_search_history(self,searchfor):
|
||||
res=[(idx,line) for idx,line in enumerate(self.history[self.history_cursor:]) if searchfor in line]
|
||||
def forward_search_history(self,searchfor,startpos=None):
|
||||
if startpos is None:
|
||||
startpos=self.history_cursor
|
||||
res=[(idx,line) for idx,line in enumerate(self.history[startpos:]) if searchfor in line]
|
||||
if res:
|
||||
self.history_cursor+=res[0][0]
|
||||
return res[0][1].get_line_text()
|
||||
@@ -121,41 +127,41 @@ class LineHistory(object):
|
||||
pyreadline.rl._clear_after()
|
||||
|
||||
event = c.getkeypress()
|
||||
if event.keysym == 'BackSpace':
|
||||
log_sock(str(event))
|
||||
|
||||
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.keysym == 'Return':
|
||||
elif event.keyinfo.keyname == 'return':
|
||||
break
|
||||
else:
|
||||
pyreadline.rl._bell()
|
||||
|
||||
log_sock(query)
|
||||
res=""
|
||||
if query:
|
||||
hc = self.history_cursor - 1
|
||||
while (direction < 0 and hc >= 0) or (direction > 0 and hc < len(self.history)):
|
||||
if self.history[hc].startswith(query) >= 0:
|
||||
current=self.history[hc]
|
||||
self.history_cursor = hc
|
||||
return
|
||||
hc += direction
|
||||
if direction==-1:
|
||||
res=self.reverse_search_history(query)
|
||||
|
||||
else:
|
||||
pyreadline.rl._bell()
|
||||
|
||||
|
||||
res=self.forward_search_history(query)
|
||||
log_sock(res)
|
||||
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.'''
|
||||
self._non_i_search(-1,current)
|
||||
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.'''
|
||||
self._non_i_search(1,current)
|
||||
return self._non_i_search(1,current)
|
||||
|
||||
def _search(self, direction, partial):
|
||||
if (self.lastcommand != self.history_search_forward and
|
||||
|
||||
@@ -223,7 +223,7 @@ class TextLine(object):
|
||||
|
||||
def visible_line_width(self,position=Point):
|
||||
"""Return the visible width of the text in line buffer up to position."""
|
||||
return len(self[:position].quoted_text())
|
||||
return len(self[:position].quoted_text())+self[:position].line_buffer.count("\t")*7
|
||||
|
||||
def quoted_text(self):
|
||||
quoted = [ quote_char(c) for c in self.line_buffer ]
|
||||
|
||||
+20
-1
@@ -6,7 +6,7 @@
|
||||
# the file COPYING, distributed as part of this software.
|
||||
#*****************************************************************************
|
||||
|
||||
|
||||
import socket
|
||||
_logfile=False
|
||||
|
||||
def start_log(on,filename):
|
||||
@@ -20,3 +20,22 @@ def log(s):
|
||||
if _logfile:
|
||||
print >>_logfile, s
|
||||
_logfile.flush()
|
||||
|
||||
|
||||
host="localhost"
|
||||
port=8081
|
||||
logsocket=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
|
||||
|
||||
show_event=["keypress","bound_function"]
|
||||
show_event=["bound_function"]
|
||||
|
||||
def log_sock(s,event_type=None):
|
||||
if event_type is None:
|
||||
logsocket.sendto(s,(host,port))
|
||||
elif event_type in show_event:
|
||||
logsocket.sendto(s,(host,port))
|
||||
else:
|
||||
pass
|
||||
|
||||
|
||||
log_sock("Starting pyreadline")
|
||||
@@ -0,0 +1,60 @@
|
||||
# -*- 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.
|
||||
#*****************************************************************************
|
||||
import socket
|
||||
|
||||
|
||||
try:
|
||||
import msvcrt
|
||||
except ImportError:
|
||||
msvcrt=None
|
||||
print "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
|
||||
|
||||
|
||||
def check_key():
|
||||
if msvcrt is None:
|
||||
return False
|
||||
else:
|
||||
if msvcrt.kbhit()!=0:
|
||||
q=msvcrt.getch()
|
||||
|
||||
return q in "q"
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
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
|
||||
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ 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
|
||||
|
||||
class BaseMode(object):
|
||||
mode="base"
|
||||
@@ -64,6 +65,10 @@ class BaseMode(object):
|
||||
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"))
|
||||
|
||||
rl_settings_to_string=property(_g("rl_settings_to_string"))
|
||||
|
||||
def _readline_from_keyboard(self):
|
||||
raise NotImplementedError
|
||||
@@ -75,6 +80,9 @@ class BaseMode(object):
|
||||
|
||||
def _bind_key(self, key, func):
|
||||
'''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)))
|
||||
keyinfo = make_KeyPress_from_keydescr(key.lower()).tuple()
|
||||
self.key_dispatch[keyinfo] = func
|
||||
|
||||
|
||||
+52
-16
@@ -8,11 +8,19 @@
|
||||
#*****************************************************************************
|
||||
import os
|
||||
import pyreadline.logger as logger
|
||||
from pyreadline.logger import log
|
||||
from pyreadline.logger import log,log_sock
|
||||
from pyreadline.lineeditor.lineobj import Point
|
||||
import pyreadline.lineeditor.lineobj as lineobj
|
||||
import pyreadline.lineeditor.history as history
|
||||
import basemode
|
||||
|
||||
import string
|
||||
def format(keyinfo):
|
||||
if len(keyinfo[-1])!=1:
|
||||
k=keyinfo+(-1,)
|
||||
else:
|
||||
k=keyinfo+(ord(keyinfo[-1]),)
|
||||
|
||||
return "(%s,%s,%s,%s,%x)"%k
|
||||
|
||||
class EmacsMode(basemode.BaseMode):
|
||||
mode="emacs"
|
||||
@@ -30,6 +38,8 @@ class EmacsMode(basemode.BaseMode):
|
||||
|
||||
def _readline_from_keyboard(self):
|
||||
c=self.console
|
||||
def nop(e):
|
||||
pass
|
||||
while 1:
|
||||
self._update_line()
|
||||
event = c.getkeypress()
|
||||
@@ -39,12 +49,18 @@ class EmacsMode(basemode.BaseMode):
|
||||
event.keyinfo = (control, True, shift, code)
|
||||
|
||||
#Process exit keys. Only exit on empty line
|
||||
if event.keyinfo.tuple() in self.exit_dispatch:
|
||||
keyinfo=event.keyinfo.tuple()
|
||||
if keyinfo in self.exit_dispatch:
|
||||
if lineobj.EndOfLine(self.l_buffer) == 0:
|
||||
raise EOFError
|
||||
if len(keyinfo[-1])>1:
|
||||
default=nop
|
||||
else:
|
||||
default=self.self_insert
|
||||
dispatch_func = self.key_dispatch.get(keyinfo,default)
|
||||
|
||||
dispatch_func = self.key_dispatch.get(event.keyinfo.tuple(),self.self_insert)
|
||||
log("readline from keyboard:%s"%(event.keyinfo.tuple(),))
|
||||
log("readline from keyboard:%s,%s"%(keyinfo,dispatch_func))
|
||||
log_sock("%s|%s"%(format(keyinfo),dispatch_func.__name__))
|
||||
r = None
|
||||
if dispatch_func:
|
||||
r = dispatch_func(event)
|
||||
@@ -118,11 +134,12 @@ class EmacsMode(basemode.BaseMode):
|
||||
|
||||
def _i_search(self, searchfun, direction, init_event):
|
||||
c = self.console
|
||||
line = self.get_line_buffer()
|
||||
line = self.l_buffer.get_line_text()
|
||||
log_sock(str(line))
|
||||
query = ''
|
||||
if (self.previous_func != self.history_search_forward and
|
||||
self.previous_func != self.history_search_backward):
|
||||
self.query = ''.join(self.line_buffer[0:self.point].get_line_text())
|
||||
self.query = ''.join(self.l_buffer[0:Point].get_line_text())
|
||||
hc_start = self._history.history_cursor #+ direction
|
||||
while 1:
|
||||
x, y = self.prompt_end_pos
|
||||
@@ -137,24 +154,25 @@ class EmacsMode(basemode.BaseMode):
|
||||
self._clear_after()
|
||||
|
||||
event = c.getkeypress()
|
||||
if event.keysym == 'BackSpace':
|
||||
if event.keyinfo.keyname == 'backspace':
|
||||
query = query[:-1]
|
||||
if len(query) > 0:
|
||||
query = query[:-1]
|
||||
self._history.history_cursor = hc_start
|
||||
#self._history.history_cursor = hc_start #forces search to restart when search empty
|
||||
line=searchfun(query)
|
||||
else:
|
||||
self._bell()
|
||||
line="" #empty query means no search result
|
||||
elif event.char in string.letters + string.digits + string.punctuation + ' ':
|
||||
self._history.history_cursor = hc_start
|
||||
#self._history.history_cursor = hc_start
|
||||
query += event.char
|
||||
line=searchfun(query)
|
||||
elif event.keyinfo == init_event.keyinfo:
|
||||
self._history.history_cursor += direction
|
||||
line=searchfun(query)
|
||||
pass
|
||||
else:
|
||||
if event.keysym != 'Return':
|
||||
if event.keyinfo.keyname != 'return':
|
||||
self._bell()
|
||||
break
|
||||
line=searchfun(query)
|
||||
|
||||
px, py = self.prompt_begin_pos
|
||||
c.pos(0, py)
|
||||
@@ -177,13 +195,15 @@ class EmacsMode(basemode.BaseMode):
|
||||
'''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)
|
||||
q=self._history.non_incremental_reverse_search_history(self.l_buffer)
|
||||
self.l_buffer=q
|
||||
|
||||
def non_incremental_forward_search_history(self, e): # (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.'''
|
||||
self._history.non_incremental_reverse_search_history(self.l_buffer)
|
||||
q=self._history.non_incremental_reverse_search_history(self.l_buffer)
|
||||
self.l_buffer=q
|
||||
|
||||
def history_search_forward(self, e): # ()
|
||||
'''Search forward through the history for the string of characters
|
||||
@@ -487,6 +507,7 @@ class EmacsMode(basemode.BaseMode):
|
||||
self._bind_exit_key('Control-z')
|
||||
|
||||
# I often accidentally hold the shift or control while typing space
|
||||
self._bind_key('space', self.self_insert)
|
||||
self._bind_key('Shift-space', self.self_insert)
|
||||
self._bind_key('Control-space', self.self_insert)
|
||||
self._bind_key('Return', self.accept_line)
|
||||
@@ -540,6 +561,21 @@ class EmacsMode(basemode.BaseMode):
|
||||
self._bind_key("Shift-Control-Left", self.backward_word_extend_selection)
|
||||
self._bind_key("Shift-Home", self.beginning_of_line_extend_selection)
|
||||
self._bind_key("Shift-End", self.end_of_line_extend_selection)
|
||||
self._bind_key("numpad0", self.self_insert)
|
||||
self._bind_key("numpad1", self.self_insert)
|
||||
self._bind_key("numpad2", self.self_insert)
|
||||
self._bind_key("numpad3", self.self_insert)
|
||||
self._bind_key("numpad4", self.self_insert)
|
||||
self._bind_key("numpad5", self.self_insert)
|
||||
self._bind_key("numpad6", self.self_insert)
|
||||
self._bind_key("numpad7", self.self_insert)
|
||||
self._bind_key("numpad8", self.self_insert)
|
||||
self._bind_key("numpad9", self.self_insert)
|
||||
self._bind_key("add", self.self_insert)
|
||||
self._bind_key("subtract", self.self_insert)
|
||||
self._bind_key("multiply", self.self_insert)
|
||||
self._bind_key("divide", self.self_insert)
|
||||
self._bind_key("vk_decimal", self.self_insert)
|
||||
|
||||
# make it case insensitive
|
||||
def commonprefix(m):
|
||||
|
||||
@@ -20,6 +20,7 @@ import exceptions
|
||||
|
||||
import clipboard,logger,console
|
||||
from logger import log
|
||||
from error import ReadlineError,GetSetError
|
||||
from pyreadline.keysyms.common import make_KeyPress_from_keydescr
|
||||
|
||||
import pyreadline.lineeditor.lineobj as lineobj
|
||||
@@ -32,14 +33,9 @@ def quote_char(c):
|
||||
if ord(c)>0:
|
||||
return c
|
||||
|
||||
class ReadlineError(exceptions.Exception):
|
||||
pass
|
||||
|
||||
def inword(buffer,point):
|
||||
return buffer[point:point+1] in [A-Za-z0-9]
|
||||
|
||||
class GetSetError(ReadlineError):
|
||||
pass
|
||||
|
||||
class Readline(object):
|
||||
def __init__(self):
|
||||
@@ -245,7 +241,7 @@ class Readline(object):
|
||||
|
||||
## Internal functions
|
||||
|
||||
def rl_settings_to_string(self):
|
||||
def rl_settings_to_string(self,e=None):
|
||||
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))
|
||||
@@ -253,7 +249,7 @@ class Readline(object):
|
||||
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=[(k[0],k[1],k[2],k[3],v.__name__) for k,v in self.mode.key_dispatch.iteritems()]
|
||||
#print self.mode.key_dispatch
|
||||
#bindings=[str(v) for k,v in self.mode.key_dispatch.iteritems()]
|
||||
bindings.sort()
|
||||
@@ -261,6 +257,8 @@ class Readline(object):
|
||||
pass
|
||||
# out.append(str(key))
|
||||
out.append(tablepat%(key))
|
||||
if e:
|
||||
print "\n".join(out)
|
||||
return out
|
||||
|
||||
def _bell(self):
|
||||
|
||||
Reference in New Issue
Block a user