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