Index: src/org/python/util/jython.java =================================================================== --- src/org/python/util/jython.java (revision 7089) +++ src/org/python/util/jython.java (working copy) @@ -155,17 +155,19 @@ } Py.getSystemState().setWarnoptions(warnoptions); + PySystemState systemState = Py.getSystemState(); // Decide if stdin is interactive if (!opts.fixInteractive && opts.interactive) { opts.interactive = ((PyFile)Py.defaultSystemState.stdin).isatty(); if (!opts.interactive) { - PySystemState systemState = Py.getSystemState(); + systemState.ps1 = systemState.ps2 = Py.EmptyString; } } // Now create an interpreter InteractiveConsole interp = newInterpreter(opts.interactive); + systemState.__setattr__("_jy_interpreter", Py.java2py(interp)); // Print banner and copyright information (or not) if (opts.interactive && opts.notice && !opts.runModule) { Index: src/org/python/util/JLineConsole.java =================================================================== --- src/org/python/util/JLineConsole.java (revision 7089) +++ src/org/python/util/JLineConsole.java (working copy) @@ -156,4 +156,11 @@ private boolean isEOF(String line) { return line == null || (windows && CTRL_Z.equals(line)); } + + /** + * @return the JLine console reader associated with this interpreter + */ + public ConsoleReader getReader() { + return reader; + } } Index: Lib/readline.py =================================================================== --- Lib/readline.py (revision 7089) +++ Lib/readline.py (working copy) @@ -5,80 +5,121 @@ """ -try: - from org.gnu.readline import Readline, ReadlineCompleter -except ImportError, msg: - raise ImportError, '%s. The readline module requires that java-readline from http://java-readline.sourceforge.net/ be on the classpath' % msg +from __future__ import with_statement +import os.path +import sys -__all__ = ["readline"] +# XXX move to _jline_readline.py, just like our _gnu_readline.py (which is orphaned) +# then simply try successive imports to see what is installed -def parse_and_bind (bindings): - """Parse and execute single line of a readline init file.\ - - """ - Readline.parseAndBind(bindings) +# XXX what's oru character encoding issues here, if any? +try: + reader = sys._jy_interpreter.reader + #from JLine import Completor +except AttributeError: + raise ImportError("Cannot access JLineConsole") + +def parse_and_bind(string): + # XXX this should probably reinitialize the reader, if possible + # with any desired settings; this will require some more work to implement + + # most importantly, need to support + # readline.parse_and_bind("tab: complete") + # but it's possible we can readily support other aspects of a readline file + pass + def get_line_buffer(): - """Return the current contents of the line buffer. - - """ - return Readline.getLineBuffer() + return str(reader.cursorBuffer.buffer) # or use toString to get unicode? -def read_init_file(filename): - """Parse a readline initialization file. - The default filename is the last filename used. +def insert_text(string): + reader.putString(string) + +def read_init_file(filename=None): + pass - """ - Readline.readInitFile(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) + reader.history = new_history -def read_history_file(filename): - """Load a readline history file. - The default filename is '~/.history'. +def write_history_file(filename="~/.history"): + expanded = os.path.expanduser(filename) + with open(expanded, 'w') as f: + for line in reader.history.historyList: + f.write(line) - """ - Readline.readHistoryFile(filename) +def clear_history(): + reader.history.clear() -def write_history_file(filename): - """Save a readline history file. - The default filename is '~/.history'. +def get_history_length(): + return reader.history.maxSize - """ - Readline.writeHistoryFile(filename) +def set_history_length(length): + reader.history.maxSize = length -def set_completer(completionfunction = None): - """Set or remove the completer instance. If an instance of ReadlineCompleter is specified, - it will be used as the new completer; if omitted or None, any completer already installed is removed. +def get_current_history_length(): + return len(reader.history.historyList) - The completer method is called as completerclass.completer(text, state), for state in 0, 1, 2, ..., - until it returns a non-string value. It should return the next possible completion starting with text. +def get_history_item(index): + return reader.history.historyList[index] - """ - class DerivedCompleter (ReadlineCompleter): - def __init__ (self, method): - self.method = method +def remove_history_item(pos): + raise Exception("not implemented") - def completer (self, text, state): - return self.method(text, state) +def redisplay(): + reader.drawLine() # XXX not certain - Readline.setCompleter(DerivedCompleter(completionfunction)) +def set_startup_hook(function=None): + pass +def set_pre_input_hook(function=None): + pass + + +_completion_function = None + +def set_completer(function=None): + # XXX single method interface, http://jline.sourceforge.net/apidocs/jline/Completor.html + # just need to figure out what's necessary to adapt to Python's convention, + # but it should be fine :) + + """The completer method is called as completerclass.completer(text, state), for state in 0, 1, 2, ..., + until it returns a non-string value. It should return the next possible completion starting with text.""" + + _completion_function = function + + def complete_handler(buffer, cursor, candidates): + for state in xrange(100): + completion = function(buffer[:cursor], state) + if completion: + candidates.add(completion) + else: + break + return 0 + + reader.addCompletor(complete_handler) + + def get_completer(): - """Get the current completer instance.""" - return Readline.getCompleter() + return _completion_function -def set_completer_delims(delimiters): - """Set the readline word delimiters for tab-completion.""" - Readline.setWordBreakCharacters(delimiters) +def get_begidx(): + pass +def get_endidx(): + pass + +def set_completer_delims(string): + pass + def get_completer_delims(): - """Get the readline word delimiters for tab-completion.""" - return Readline.getWordBreakCharacters() + pass def add_history(line): - """Append a line to the history buffer, as if it was the last line typed.""" - Readline.addToHistory(line) + reader.addToHistory(line) -def get_current_history_length(): - """Get the number of lines currently available in history.""" - return Readline.getHistorySize()