From: <cg...@us...> - 2007-04-22 21:09:34
|
Revision: 3176 http://svn.sourceforge.net/jython/?rev=3176&view=rev Author: cgroves Date: 2007-04-22 14:09:32 -0700 (Sun, 22 Apr 2007) Log Message: ----------- Added JLineConsole to provide readline like functionality through JLine. Moved the raw_input replacement out of ReadlineConsole into InteractiveConsole so the JLine and Readline consoles could share it. Modified Paths: -------------- trunk/jython/NEWS trunk/jython/build.xml trunk/jython/src/org/python/util/InteractiveConsole.java trunk/jython/src/org/python/util/ReadlineConsole.java Added Paths: ----------- trunk/jython/src/org/python/util/JLineConsole.java Modified: trunk/jython/NEWS =================================================================== --- trunk/jython/NEWS 2007-04-20 04:21:44 UTC (rev 3175) +++ trunk/jython/NEWS 2007-04-22 21:09:32 UTC (rev 3176) @@ -6,6 +6,8 @@ functions - Classmethods added to newstyle classes - array is a newstyle class + - org.python.util.JLineConsole provides readline-like functionality with + JLine without requiring native readline Bugs fixed - [ 1599012 ] current directory is prepended to entries in sys.path Modified: trunk/jython/build.xml =================================================================== --- trunk/jython/build.xml 2007-04-20 04:21:44 UTC (rev 3175) +++ trunk/jython/build.xml 2007-04-22 21:09:32 UTC (rev 3176) @@ -91,7 +91,10 @@ # - org.gnu.readline readline.jar=${basedir}/../externals/external-jars/readline.jar +# - jline +jline.jar=${basedir}/../externals/external-jars/jline-0.9.91.jar + # - zxJDBC # (for mysql, see www.mysql.com/downloads/api-jdbc-stable.html) # (for postgres, see http://jdbc.postgresql.org/) @@ -172,6 +175,7 @@ <!-- classpaths --> <path id="main.classpath"> <pathelement path="${readline.jar}" /> + <pathelement path="${jline.jar}" /> <pathelement path="${servlet.jar}" /> <pathelement path="${informix.jar}" /> <pathelement path="${oracle.jar}" /> @@ -186,6 +190,7 @@ <available property="secureclassloader.present" classname="java.security.SecureClassLoader" /> <available property="servlet.present" classname="javax.servlet.Servlet" classpath="${servlet.jar}" /> <available property="readline.present" classname="org.gnu.readline.Readline" classpath="${readline.jar}" /> + <available property="jline.present" classname="jline.Terminal" classpath="${jline.jar}" /> <available property="informix.present" classname="com.informix.jdbc.IfxDriver" classpath="${informix.jar}" /> <available property="mysql.present" classname="org.gjt.mm.mysql.Driver" classpath="${mysql.jar}" /> <available property="postgresql.present" classname="org.postgresql.Driver" classpath="${postgresql.jar}" /> @@ -247,6 +252,7 @@ <taskdef name="svn" classname="org.tigris.subversion.svnant.SvnTask" classpathref="svn.classpath" /> <!-- Require all of the optional jars for a full build --> <fail unless="readline.present" message="readline jar not present" /> + <fail unless="jline.present" message="jline jar not present" /> <fail unless="servlet.present" message="servlet jar not present" /> <fail unless="informix.present" message="informix jar not present" /> <fail unless="mysql.present" message="mysql jar not present" /> @@ -268,6 +274,7 @@ <echo>secureclassloader = '${secureclassloader.present}'</echo> <echo>servlet = '${servlet.present}'</echo> <echo>readline = '${readline.present}'</echo> + <echo>jline = '${jline.present}'</echo> <echo>oracle = '${oracle.present}'</echo> <echo>informix = '${informix.present}'</echo> <echo>mysql = '${mysql.present}'</echo> @@ -436,6 +443,7 @@ <exclude name="org/python/parser/python.java" /> <exclude name="**/PyServlet.java" unless="servlet.present" /> <exclude name="**/ReadlineConsole.java" unless="readline.present" /> + <exclude name="**/JLineConsole.java" unless="jline.present" /> <exclude name="**/handler/InformixDataHandler.java" unless="informix.present" /> <exclude name="**/handler/MySQLDataHandler.java" unless="mysql.present" /> <exclude name="**/handler/OracleDataHandler.java" unless="oracle.present" /> @@ -503,6 +511,7 @@ <attribute name="secureclassloader" value="${secureclassloader.present}" /> <attribute name="servlet" value="${servlet.present}" /> <attribute name="readline" value="${readline.present}" /> + <attribute name="jline" value="${jline.present}" /> <attribute name="oracle" value="${oracle.present}" /> <attribute name="informix" value="${informix.present}" /> <attribute name="mysql" value="${mysql.present}" /> @@ -674,6 +683,7 @@ <attribute name="secureclassloader" value="${secureclassloader.present}" /> <attribute name="servlet" value="${servlet.present}" /> <attribute name="readline" value="${readline.present}" /> + <attribute name="jline" value="${jline.present}" /> <attribute name="oracle" value="${oracle.present}" /> <attribute name="informix" value="${informix.present}" /> <attribute name="mysql" value="${mysql.present}" /> Modified: trunk/jython/src/org/python/util/InteractiveConsole.java =================================================================== --- trunk/jython/src/org/python/util/InteractiveConsole.java 2007-04-20 04:21:44 UTC (rev 3175) +++ trunk/jython/src/org/python/util/InteractiveConsole.java 2007-04-22 21:09:32 UTC (rev 3176) @@ -1,57 +1,85 @@ // Copyright (c) Corporation for National Research Initiatives package org.python.util; -import org.python.core.*; +import org.python.core.Py; +import org.python.core.PyBuiltinFunctionSet; +import org.python.core.PyException; +import org.python.core.PyObject; +import org.python.core.PySystemState; +import org.python.core.__builtin__; + // Based on CPython-1.5.2's code module +public class InteractiveConsole extends InteractiveInterpreter { -public class InteractiveConsole extends InteractiveInterpreter { + public static final String CONSOLE_FILENAME = "<console>"; + public String filename; public InteractiveConsole() { - this(null, "<console>"); + this(null, CONSOLE_FILENAME); } + public InteractiveConsole(PyObject locals) { - this(locals, "<console>"); + this(locals, CONSOLE_FILENAME); } + public InteractiveConsole(PyObject locals, String filename) { + this(locals, filename, false); + } + + /** + * @param replaceRawInput - + * if true, we hook this Class's raw_input into the builtins + * table so that clients like cmd.Cmd use it. + */ + public InteractiveConsole(PyObject locals, String filename, boolean replaceRawInput) { super(locals); this.filename = filename; + if(replaceRawInput) { + PyObject newRawInput = new PyBuiltinFunctionSet("raw_input", 0, 0, 1) { + + public PyObject __call__() { + return __call__(Py.EmptyString); + } + + public PyObject __call__(PyObject prompt) { + return Py.newString(raw_input(prompt)); + } + }; + Py.getSystemState().builtins.__setitem__("raw_input", newRawInput); + } } /** * Closely emulate the interactive Python console. - * - * The optional banner argument specifies the banner to print before - * the first interaction; by default it prints a banner similar to the - * one printed by the real Python interpreter, followed by the current - * class name in parentheses (so as not to confuse this with the real - * interpreter -- since it's so close!). - **/ + * + * The optional banner argument specifies the banner to print before the + * first interaction; by default it prints "Jython <version> on <platform>". + */ public void interact() { interact(getDefaultBanner()); } public static String getDefaultBanner() { - return "Jython " + PySystemState.version + " on " - + PySystemState.platform; + return "Jython " + PySystemState.version + " on " + PySystemState.platform; } public void interact(String banner) { - if (banner != null) { + if(banner != null) { write(banner); write("\n"); } // Dummy exec in order to speed up response on first command exec("2"); - //System.err.println("interp2"); + // System.err.println("interp2"); boolean more = false; - while (true) { + while(true) { PyObject prompt = more ? systemState.ps2 : systemState.ps1; String line; try { line = raw_input(prompt); - } catch (PyException exc) { - if (!Py.matchException(exc, Py.EOFError)) + } catch(PyException exc) { + if(!Py.matchException(exc, Py.EOFError)) throw exc; write("\n"); break; @@ -62,36 +90,35 @@ /** * Push a line to the interpreter. - * + * * The line should not have a trailing newline; it may have internal - * newlines. The line is appended to a buffer and the interpreter's - * runsource() method is called with the concatenated contents of the - * buffer as source. If this indicates that the command was executed - * or invalid, the buffer is reset; otherwise, the command is - * incomplete, and the buffer is left as it was after the line was - * appended. The return value is 1 if more input is required, 0 if the - * line was dealt with in some way (this is the same as runsource()). - **/ - + * newlines. The line is appended to a buffer and the interpreter's + * runsource() method is called with the concatenated contents of the buffer + * as source. If this indicates that the command was executed or invalid, + * the buffer is reset; otherwise, the command is incomplete, and the buffer + * is left as it was after the line was appended. The return value is 1 if + * more input is required, 0 if the line was dealt with in some way (this is + * the same as runsource()). + */ public boolean push(String line) { - if (buffer.length() > 0) + if(buffer.length() > 0) buffer.append("\n"); buffer.append(line); boolean more = runsource(buffer.toString(), filename); - if (!more) + if(!more) resetbuffer(); return more; } /** * Write a prompt and read a line. - * - * The returned line does not include the trailing newline. When the - * user enters the EOF key sequence, EOFError is raised. - * + * + * The returned line does not include the trailing newline. When the user + * enters the EOF key sequence, EOFError is raised. + * * The base implementation uses the built-in function raw_input(); a * subclass may replace this with a different implementation. - **/ + */ public String raw_input(PyObject prompt) { return __builtin__.raw_input(prompt); } Added: trunk/jython/src/org/python/util/JLineConsole.java =================================================================== --- trunk/jython/src/org/python/util/JLineConsole.java (rev 0) +++ trunk/jython/src/org/python/util/JLineConsole.java 2007-04-22 21:09:32 UTC (rev 3176) @@ -0,0 +1,48 @@ +package org.python.util; + +import java.io.IOException; +import jline.ConsoleReader; +import jline.Terminal; +import org.python.core.Py; +import org.python.core.PyObject; + +/** + * This class uses <a href="http://jline.sourceforge.net/">JLine</a> to provide + * readline like functionality to its console without requiring native readline + * support. + */ +public class JLineConsole extends InteractiveConsole { + + public JLineConsole() { + this(null); + } + + public JLineConsole(PyObject locals) { + this(locals, CONSOLE_FILENAME); + } + + public JLineConsole(PyObject locals, String filename) { + super(locals, filename, true); + Terminal.setupTerminal(); + try { + reader = new ConsoleReader(); + } catch(IOException e) { + throw new RuntimeException(e); + } + } + + public String raw_input(PyObject prompt) { + String line = null; + try { + line = reader.readLine(prompt.toString()); + } catch(IOException io) { + throw Py.IOError(io); + } + if(line == null) { + throw Py.EOFError("Ctrl-D exit"); + } + return line.endsWith("\n") ? line.substring(0, line.length() - 1) : line; + } + + private ConsoleReader reader; +} Modified: trunk/jython/src/org/python/util/ReadlineConsole.java =================================================================== --- trunk/jython/src/org/python/util/ReadlineConsole.java 2007-04-20 04:21:44 UTC (rev 3175) +++ trunk/jython/src/org/python/util/ReadlineConsole.java 2007-04-22 21:09:32 UTC (rev 3176) @@ -3,81 +3,57 @@ import org.gnu.readline.Readline; import org.gnu.readline.ReadlineLibrary; -import org.python.core.ArgParser; import org.python.core.Py; import org.python.core.PyException; import org.python.core.PyObject; -import org.python.core.PyString; import org.python.core.PySystemState; /** - * Uses: - * <a href="http://java-readline.sourceforge.net/">Java Readline</a> - * <p/> - * + * Uses: <a href="http://java-readline.sourceforge.net/">Java Readline</a> <p/> + * * Based on CPython-1.5.2's code module - * + * */ public class ReadlineConsole extends InteractiveConsole { + public String filename; public ReadlineConsole() { - this(null, "<console>"); + this(null, CONSOLE_FILENAME); } + public ReadlineConsole(PyObject locals) { - this(locals, "<console>"); + this(locals, CONSOLE_FILENAME); } + public ReadlineConsole(PyObject locals, String filename) { - super(locals,filename); - String backingLib = PySystemState.registry.getProperty( - "python.console.readlinelib", "Editline"); + super(locals, filename, true); + String backingLib = PySystemState.registry.getProperty("python.console.readlinelib", + "Editline"); try { Readline.load(ReadlineLibrary.byName(backingLib)); - } catch (RuntimeException e) { + } catch(RuntimeException e) { // Silently ignore errors during load of the native library. // Will use a pure java fallback. } - - // hook into the builtins table so that clients like cmd.Cmd can - // also use readline. - Py.getSystemState().builtins.__setitem__("raw_input", - Py.newJavaFunc(this.getClass(), "_raw_input")); - Readline.initReadline("jython"); } - /** * Write a prompt and read a line. - * - * The returned line does not include the trailing newline. When the - * user enters the EOF key sequence, EOFError is raised. - * + * + * The returned line does not include the trailing newline. When the user + * enters the EOF key sequence, EOFError is raised. + * * This subclass implements the functionality using JavaReadline. - **/ + */ public String raw_input(PyObject prompt) { - return _raw_input(new PyObject[] { prompt }, new String[0]); - } - - /** - * Central point of dispatch to Readline library for all clients, - * whether the console itself or others like cmd.Cmd interpreters. - * Both of these uses come through here. - * - * @param args should contain a single prompt - * @param kws keywords - * @return the user input - **/ - public static String _raw_input(PyObject args[], String kws[]) { - ArgParser ap = new ArgParser("raw_input", args, kws, "prompt"); - PyObject prompt = ap.getPyObject(0, new PyString("")); try { - String line = Readline.readline( - prompt==null ? "" : prompt.toString()); + String line = Readline.readline(prompt == null ? "" : prompt.toString()); return (line == null ? "" : line); - } catch (java.io.EOFException eofe) { + } catch(java.io.EOFException eofe) { throw new PyException(Py.EOFError); - } catch (java.io.IOException e) { + } catch(java.io.IOException e) { throw new PyException(Py.IOError); } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |