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