diff --git a/pyreadline/__init__.py b/pyreadline/__init__.py index 02da956..c0845c5 100644 --- a/pyreadline/__init__.py +++ b/pyreadline/__init__.py @@ -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'] diff --git a/pyreadline/examples/callback_example.py b/pyreadline/examples/callback_example.py new file mode 100644 index 0000000..d7fdc44 --- /dev/null +++ b/pyreadline/examples/callback_example.py @@ -0,0 +1,53 @@ +''' +Example script using the callback interface of readline. + +:author: strank +''' + +__docformat__ = "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('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("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 "Done, index =", index + + +def lineReceived(line): + global count, prompting + count += 1 + print "Got line: %s" % line + if count > maxlines: + prompting = False + readline.callback_handler_remove() + else: + readline.callback_handler_install('Got %s of %s, more typing please:' % (count, maxlines) + + os.linesep, lineReceived) + + + + +if __name__ == '__main__': + main() diff --git a/pyreadline/modes/basemode.py b/pyreadline/modes/basemode.py index 524861b..7eb58b5 100644 --- a/pyreadline/modes/basemode.py +++ b/pyreadline/modes/basemode.py @@ -55,10 +55,6 @@ class BaseMode(object): return val argument_reset=property(_argreset) -# _history=property(_g("_history")) -# l_buffer=property(*_gs("l_buffer")) - - #used in readline ctrl_c_tap_time_interval=property(*_gs("ctrl_c_tap_time_interval")) allow_ctrl_c=property(*_gs("allow_ctrl_c")) @@ -77,8 +73,6 @@ class BaseMode(object): _bell=property(_g("_bell")) bell_style=property(_g("bell_style")) - rl_settings_to_string=property(_g("rl_settings_to_string")) - #used in emacs _clear_after=property(_g("_clear_after")) _update_prompt_pos=property(_g("_update_prompt_pos")) @@ -91,12 +85,65 @@ class BaseMode(object): #not used in basemode or emacs + def readline_event_available(self): + return self.console.peek() or (len(self.paste_line_buffer)>0) + def _readline_from_keyboard(self): - raise NotImplementedError + while 1: + if self._readline_from_keyboard_poll(): + break + + def _readline_from_keyboard_poll(self): + if len(self.paste_line_buffer)>0: + #paste first line in multiline paste buffer + self.l_buffer=lineobj.ReadLineTextBuffer(self.paste_line_buffer[0]) + self._update_line() + self.paste_line_buffer=self.paste_line_buffer[1:] + return True + + c=self.console + def nop(e): + pass + try: + event = c.getkeypress() + except KeyboardInterrupt: + event=self.handle_ctrl_c() + + if self.next_meta: + self.next_meta = False + control, meta, shift, code = event.keyinfo + event.keyinfo = (control, True, shift, code) + result=self.process_keyevent(event.keyinfo) + self._update_line() + return result def readline(self, prompt=''): - '''Try to act like GNU readline.''' - # handle startup_hook + self.readline_setup(prompt) + self._readline_from_keyboard() + self.console.write('\r\n') + log('returning(%s)' % self.l_buffer.get_line_text()) + return self.l_buffer.get_line_text() + '\n' + + def handle_ctrl_c(self): + from pyreadline.keysyms.common import KeyPress + from pyreadline.console.event import Event + log_sock("KBDIRQ") + event=Event(0,0) + event.char="c" + event.keyinfo=KeyPress("c",shift=False,control=True,meta=False,keyname=None) + if self.allow_ctrl_c: + now=time.time() + if (now-self.ctrl_c_timeout)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: - while 1: - self._update_line() - lbuf=self.l_buffer - log_sock("point:%d mark:%d selection_mark:%d"%(lbuf.point,lbuf.mark,lbuf.selection_mark)) - try: - event = c.getkeypress() - log_sock(u">>%s"%event) - except KeyboardInterrupt: - from pyreadline.keysyms.common import KeyPress - from pyreadline.console.event import Event - event=Event(0,0) - event.char="c" - event.keyinfo=KeyPress("c",shift=False,control=True,meta=False,keyname=None) - log_sock("KBDIRQ") - if self.allow_ctrl_c: - now=time.time() - if (now-self.ctrl_c_timeout)