From: <zy...@us...> - 2010-10-17 04:51:22
|
Revision: 7153 http://jython.svn.sourceforge.net/jython/?rev=7153&view=rev Author: zyasoft Date: 2010-10-17 04:51:15 +0000 (Sun, 17 Oct 2010) Log Message: ----------- Modified readline, specifically completion support and various hooks, so that it supports ipython 0.10.1 (with a minor patch on os.name in that codebase). Still requires user to provide an alternative properties file, that should be fixed before RC1. Fixes #1133. Modified Paths: -------------- trunk/jython/Lib/readline.py trunk/jython/src/org/python/util/JLineConsole.java Modified: trunk/jython/Lib/readline.py =================================================================== --- trunk/jython/Lib/readline.py 2010-10-16 16:15:33 UTC (rev 7152) +++ trunk/jython/Lib/readline.py 2010-10-17 04:51:15 UTC (rev 7153) @@ -7,6 +7,24 @@ except AttributeError: raise ImportError("Cannot access JLineConsole") +history_list = None + +def _setup_history(): + # This is obviously not desirable, but avoids O(n) workarounds to + # modify the history (ipython uses the function + # remove_history_item to mutate the history relatively frequently) + global history_list + + history = reader.history + try: + history_list_field = history.class.getDeclaredField("history") + history_list_field.setAccessible(True) + history_list = history_list_field.get(history) + except: + pass + +_setup_history() + def parse_and_bind(string): # TODO this should probably reinitialize the reader, if possible # with any desired settings; this will require some more work to implement @@ -14,24 +32,28 @@ # most importantly, need to support at least # readline.parse_and_bind("tab: complete") # but it's possible we can readily support other aspects of a readline file + + # XXX first time through, print a warning message about the required setup + # with jline properties (or potentially test...) pass def get_line_buffer(): - return str(reader.cursorBuffer.buffer) # or use toString to get unicode? + return str(reader.cursorBuffer.buffer) def insert_text(string): reader.putString(string) def read_init_file(filename=None): - pass + print "Not implemented: read_init_file", filename def read_history_file(filename="~/.history"): expanded = os.path.expanduser(filename) new_history = reader.getHistory().getClass()() with open(expanded) as f: for line in f: - new_history.addToHistory(line) + new_history.addToHistory(line.rstrip()) reader.history = new_history + _setup_history() def write_history_file(filename="~/.history"): expanded = os.path.expanduser(filename) @@ -42,6 +64,9 @@ def clear_history(): reader.history.clear() +def add_history(line): + reader.addToHistory(line) + def get_history_length(): return reader.history.maxSize @@ -55,23 +80,22 @@ return reader.history.historyList[index] def remove_history_item(pos): - # TODO possible? - raise Exception("not implemented") + if history_list: + history_list.remove(pos) + else: + print "Cannot remove history item at position:", pos def redisplay(): reader.redrawLine() def set_startup_hook(function=None): - # TODO add - pass - + sys._jy_interpreter.startupHook = function + def set_pre_input_hook(function=None): - # TODO add - pass + print "Not implemented: set_pre_input_hook", function +_completer_function = None -_completion_function = None - def set_completer(function=None): """set_completer([function]) -> None Set or remove the completer function. @@ -79,42 +103,50 @@ for state in 0, 1, 2, ..., until it returns a non-string. It should return the next possible completion starting with 'text'.""" - _completion_function = function + global _completer_function + _completer_function = function def complete_handler(buffer, cursor, candidates): + start = _get_delimited(buffer, cursor)[0] + delimited = buffer[start:cursor] for state in xrange(100): # TODO arbitrary, what's the number used by gnu readline? completion = None try: - completion = function(buffer[:cursor], state) + completion = function(delimited, state) except: pass if completion: candidates.add(completion) else: break - return 0 + return start reader.addCompletor(complete_handler) def get_completer(): - return _completion_function + return _completer_function +def _get_delimited(buffer, cursor): + start = cursor + for i in xrange(cursor-1, -1, -1): + if buffer[i] in _completer_delims: + break + start = i + return start, cursor + def get_begidx(): - # TODO add - pass + return _get_delimited(str(reader.cursorBuffer.buffer), reader.cursorBuffer.cursor)[0] def get_endidx(): - # TODO add - pass + return _get_delimited(str(reader.cursorBuffer.buffer), reader.cursorBuffer.cursor)[1] def set_completer_delims(string): - pass + global _completer_delims, _completer_delims_set + _completer_delims = string + _completer_delims_set = set(string) def get_completer_delims(): - pass + return _completer_delims -def add_history(line): - reader.addToHistory(line) - - +set_completer_delims(' \t\n`~!@#$%^&*()-=+[{]}\\|;:\'",<>/?') Modified: trunk/jython/src/org/python/util/JLineConsole.java =================================================================== --- trunk/jython/src/org/python/util/JLineConsole.java 2010-10-16 16:15:33 UTC (rev 7152) +++ trunk/jython/src/org/python/util/JLineConsole.java 2010-10-17 04:51:15 UTC (rev 7153) @@ -32,6 +32,11 @@ /** Main interface to JLine. */ protected ConsoleReader reader; + /** Set by readline.set_startup_hook */ + protected PyObject startup_hook; + + protected PyObject pre_input_hook; + /** Whether reader is a WindowsTerminal. */ private boolean windows; @@ -116,6 +121,13 @@ while (true) { try { + if (startup_hook != null) { + try { + startup_hook.__call__(); + } catch (Exception ex) { + System.err.println(ex); + } + } line = reader.readLine(promptString); break; } catch (IOException ioe) { @@ -163,4 +175,19 @@ public ConsoleReader getReader() { return reader; } + + + /** + * @return the startup hook (called prior to each readline) + */ + public PyObject getStartupHook() { + return startup_hook; + } + + /** + * Sets the startup hook (called prior to each readline) + */ + public void setStartupHook(PyObject hook) { + startup_hook = hook; + } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |