From 6081024aaa5b455bd4c730992809d5f2f6fec05e Mon Sep 17 00:00:00 2001 From: Jorgen Stenarson Date: Tue, 6 Oct 2009 19:36:27 +0200 Subject: [PATCH] Fix for incremental search. Ctrl-S only generates events on key release events --- pyreadline/console/console.py | 15 +++++++------ pyreadline/keysyms/common.py | 10 ++++++++- pyreadline/modes/emacs.py | 42 ++++++++++++++++++----------------- pyreadline/rlmain.py | 9 ++++---- 4 files changed, 43 insertions(+), 33 deletions(-) diff --git a/pyreadline/console/console.py b/pyreadline/console/console.py index 6c9af69..2204003 100644 --- a/pyreadline/console/console.py +++ b/pyreadline/console/console.py @@ -21,7 +21,7 @@ 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 +from pyreadline.keysyms import make_KeyPress, KeyPress from pyreadline.console.ansi import AnsiState,AnsiWriter try: @@ -33,7 +33,7 @@ except ImportError: def nolog(string): pass -log=nolog +log = nolog # some constants we need @@ -500,7 +500,6 @@ class Console(object): byref(Cevent), 1, byref(count)) if status and count.value == 1: e = event(self, Cevent) - log(u"console.get %s"%ensure_unicode(e.keyinfo)) return e def getkeypress(self): @@ -508,17 +507,18 @@ class Console(object): while 1: e = self.get() if e.type == u'KeyPress' and e.keycode not in key_modifiers: - log(u"console.getleypress %s"%e) - if e.keyinfo.keyname == 'next': + 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 == u'KeyRelease') and - (e.keyinfo == (True, False, False, 83))): + (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): u'''Get next character from queue.''' @@ -650,6 +650,7 @@ class event(Event): self.type = u"Menu" self.state = input.Event.MenuEvent.dwCommandId + def getconsole(buffer=1): """Get a console handle. diff --git a/pyreadline/keysyms/common.py b/pyreadline/keysyms/common.py index df43ec7..d76b356 100644 --- a/pyreadline/keysyms/common.py +++ b/pyreadline/keysyms/common.py @@ -39,7 +39,7 @@ validkey =set([u'cancel', u'backspace', u'tab', u'clear', 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=u""): + 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, @@ -73,6 +73,14 @@ class KeyPress(object): else: 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] == u'"' and keydescr[-1:] == u'"': diff --git a/pyreadline/modes/emacs.py b/pyreadline/modes/emacs.py index 77074b4..dcf35ba 100644 --- a/pyreadline/modes/emacs.py +++ b/pyreadline/modes/emacs.py @@ -30,51 +30,51 @@ class IncrementalSearchPromptMode(object): pass def _process_incremental_search_keyevent(self, keyinfo): - keytuple=keyinfo.tuple() - log(u"IncrementalSearchPromptMode %s %s"%(keyinfo,keytuple)) + keytuple = keyinfo.tuple() + log(u"IncrementalSearchPromptMode %s %s"%(keyinfo, keytuple)) if keyinfo.keyname == u'backspace': self.subsearch_query = self.subsearch_query[:-1] if len(self.subsearch_query) > 0: self.line=self.subsearch_fun(self.subsearch_query) else: self._bell() - self.line="" #empty query means no search result + self.line = "" #empty query means no search result elif keyinfo.keyname in [u'return', u'escape']: self._bell() - self.prompt=self.subsearch_oldprompt - self.process_keyevent_queue=self.process_keyevent_queue[:-1] - self._history.history_cursor=len(self._history.history) + self.prompt = self.subsearch_oldprompt + self.process_keyevent_queue = self.process_keyevent_queue[:-1] + self._history.history_cursor = len(self._history.history) if keyinfo.keyname == u'escape': self.l_buffer.set_line(self.subsearch_old_line) return False elif keyinfo.keyname: pass - elif keytuple==self.subsearch_init_event: + elif keytuple == self.subsearch_init_event: self._history.history_cursor += self.subsearch_direction - self.line=self.subsearch_fun(self.subsearch_query) - elif keyinfo.control==False and keyinfo.meta==False : + self.line = self.subsearch_fun(self.subsearch_query) + elif keyinfo.control == False and keyinfo.meta == False : self.subsearch_query += keyinfo.char self.line=self.subsearch_fun(self.subsearch_query) else: pass - self.prompt=self.subsearch_prompt%self.subsearch_query + self.prompt = self.subsearch_prompt%self.subsearch_query self.l_buffer.set_line(self.line) def _init_incremental_search(self, searchfun, direction, init_event): u"""Initialize search prompt """ - self.subsearch_init_event=init_event.tuple() - self.subsearch_direction=direction + self.subsearch_init_event = init_event.tuple() + self.subsearch_direction = direction self.subsearch_query = u'' self.subsearch_fun = searchfun self.subsearch_old_line = self.l_buffer.get_line_text() self.process_keyevent_queue.append(self._process_incremental_search_keyevent) - self.subsearch_oldprompt=self.prompt + self.subsearch_oldprompt = self.prompt if (self.previous_func != self.history_search_forward and - self.previous_func != self.history_search_backward): + self.previous_func != self.history_search_backward): self.subsearch_query = u''.join(self.l_buffer[0:Point].get_line_text()) @@ -82,11 +82,13 @@ class IncrementalSearchPromptMode(object): self.subsearch_prompt = u"reverse-i-search`%s': " else: self.subsearch_prompt = u"forward-i-search`%s': " - self.prompt=self.subsearch_prompt%"" + + self.prompt = self.subsearch_prompt%"" + if self.subsearch_query: - self.line=self._process_search_keyevent(init_event) + self.line = self._process_incremental_search_keyevent(init_event) else: - self.line=u"" + self.line = u"" class SearchPromptMode(object): def __init__(self, rlobj): @@ -125,10 +127,10 @@ class SearchPromptMode(object): def _init_non_i_search(self, direction): self.non_inc_direction = direction self.non_inc_query = u"" - self.non_inc_oldprompt=self.prompt - self.non_inc_oldline=self.l_buffer.copy() + self.non_inc_oldprompt = self.prompt + self.non_inc_oldline = self.l_buffer.copy() self.l_buffer.reset_line() - self.prompt=self.non_inc_oldprompt+u":" + self.prompt = self.non_inc_oldprompt + u":" self.process_keyevent_queue.append(self._process_non_incremental_search_keyevent) def non_incremental_reverse_search_history(self, e): # (M-p) diff --git a/pyreadline/rlmain.py b/pyreadline/rlmain.py index cd213a8..c47e1ac 100644 --- a/pyreadline/rlmain.py +++ b/pyreadline/rlmain.py @@ -174,10 +174,9 @@ class BaseReadline(object): def get_completer(self): u'''Get the completer function. - ''' - - log(u'get_completer') - return self.mode.completer + ''' + log(u'get_completer') + return self.mode.completer def get_begidx(self): u'''Get the beginning index of the readline tab-completion scope.''' @@ -193,7 +192,7 @@ class BaseReadline(object): def get_completer_delims(self): u'''Get the readline word delimiters for tab-completion.''' - return self.mode.completer_delims + return self.mode.completer_delims.encode("ascii") def set_startup_hook(self, function=None): u'''Set or remove the startup_hook function.