--- BeanShell/src/bsh/Interpreter.java~ 2003-09-03 19:56:58.000000000 -0400 +++ BeanShell/src/bsh/Interpreter.java 2004-01-25 09:59:41.730059108 -0500 @@ -38,6 +38,13 @@ import java.lang.reflect.Method; import java.lang.reflect.InvocationTargetException; +import bsh.util.BshCompleter; +import bsh.util.NameCompletionTable; +import bsh.classpath.ClassManagerImpl; +import org.gnu.readline.Readline; +import org.gnu.readline.ReadlineLibrary; +import org.gnu.readline.ReadlineReader; + /** The BeanShell script interpreter. @@ -394,10 +401,59 @@ else src = System.in; - Reader in = new CommandLineReader( new InputStreamReader(src)); - Interpreter interpreter = - new Interpreter( in, System.out, System.err, true ); - interpreter.run(); + Reader in = null; + boolean usingReadline = false; + String backingLib = System.getProperty("bsh.console.readlinelib"); + if (backingLib != null) { + try { + File history = new File(System.getProperty("user.home") + + File.separator + ".bsh_history"); + if (!history.exists()) { + try { + history.createNewFile(); + } catch(IOException ioe) { + debug("Unable to create history " + history.getAbsolutePath()); + } + } + ReadlineLibrary lib = ReadlineLibrary.byName(backingLib); + // should I wrap CommandLineReader around it? + if (history.canWrite() && history.canRead()) { + in = new ReadlineReader("bsh % ", history,lib); + } else { + in = new ReadlineReader("bsh % ",lib); + debug("Unable to read/write history " + history.getAbsolutePath()); + } + } catch (IOException ioe) { + System.err.println("Unable to invoke ReadlineReader " + + "due to: " + ioe); + } + } + if (in == null) + in = new CommandLineReader( new InputStreamReader(src)); + else + usingReadline = true; + Interpreter interpreter = + new Interpreter( in, System.out, System.err, true ); + if (usingReadline) { + NameCompletionTable nct = new NameCompletionTable(); + nct.add(interpreter.getNameSpace()); + + /** ClassManager does a lot of chatting to the stdout, + * so this has been commented out for the time being + **/ + +// try { +// BshClassManager bcm = BshClassManager.getClassManager(); +// if (bcm != null) { +// nct.add(((ClassManagerImpl)bcm).getClassPath()); +// } +// } catch(ClassPathException cpe) { +// debug("classpath exception in name compl:" + cpe); +// } + + Readline.setCompleter(new BshCompleter(nct)); + } + interpreter.run(); } } @@ -445,7 +501,7 @@ System.err.flush(); Thread.yield(); // this helps a little - if ( interactive ) + if ( interactive && !(in instanceof ReadlineReader)) print( getBshPrompt() ); eof = Line(); @@ -548,10 +604,17 @@ } } - if ( interactive && exitOnEOF ) - System.exit(0); + if ( interactive && exitOnEOF ) { + /* should be done for all streams in general, but this + * ensures that the history for readline is flushed */ + try { + in.close(); + } catch (IOException ioe) { + } + + System.exit(0); } - + } // begin source and eval /** --- /dev/null 2003-10-19 02:52:03.000000000 -0400 +++ BeanShell/src/bsh/util/BshCompleter.java 2004-01-25 10:14:10.184458217 -0500 @@ -0,0 +1,38 @@ +package bsh.util; + +import org.gnu.readline.ReadlineCompleter; + +/** + * An adapter for org.gnu.readline's ReadlineCompleter interface to map to + * BeanShell's NameCompleter interface. + * + * @see org.gnu.readline.ReadlineReader + * @version $Revision: 1.1 $ + * @author Shane Celis + **/ +public class BshCompleter implements ReadlineCompleter { + + private NameCompletion completer; + + /** + * Constructs a ReadlineCompleter out of a + * NameCompleter object. + **/ + public BshCompleter(NameCompletion completer) { + this.completer = completer; + } + + /** + * Returns String of completion if unambiguous, otherwise null + **/ + public String completer(String text, int state) { + // Not sure what state is used for in ReadlineCompleter + String[] completions = completer.completeName(text); + if (completions.length == 1 && state == 0) { + return completions[0]; + } else { + return null; // ambiguous result + } + } + +}