Skip to content
Browse files

Fixed everything.

  • Loading branch information...
0 parents commit f5da99052f559a2e339dc96791c01ae776186aee @Raynes committed Sep 17, 2010
7 .gitignore
@@ -0,0 +1,7 @@
+.cake
+pom.xml
+*.jar
+*.war
+lib
+classes
+build
227 LICENSE
@@ -0,0 +1,227 @@
+Eclipse Public License - v 1.0
+
+THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE
+PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF
+THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.
+
+1. DEFINITIONS
+
+"Contribution" means:
+
+a) in the case of the initial Contributor, the initial code and
+documentation distributed under this Agreement, and
+
+b) in the case of each subsequent Contributor:
+
+i) changes to the Program, and
+
+ii) additions to the Program;
+
+where such changes and/or additions to the Program originate from and
+are distributed by that particular Contributor. A Contribution
+'originates' from a Contributor if it was added to the Program by such
+Contributor itself or anyone acting on such Contributor's
+behalf. Contributions do not include additions to the Program which:
+(i) are separate modules of software distributed in conjunction with
+the Program under their own license agreement, and (ii) are not
+derivative works of the Program.
+
+"Contributor" means any person or entity that distributes the Program.
+
+"Licensed Patents" mean patent claims licensable by a Contributor
+which are necessarily infringed by the use or sale of its Contribution
+alone or when combined with the Program.
+
+"Program" means the Contributions distributed in accordance with this
+Agreement.
+
+"Recipient" means anyone who receives the Program under this
+Agreement, including all Contributors.
+
+2. GRANT OF RIGHTS
+
+a) Subject to the terms of this Agreement, each Contributor hereby
+grants Recipient a non-exclusive, worldwide, royalty-free copyright
+license to reproduce, prepare derivative works of, publicly display,
+publicly perform, distribute and sublicense the Contribution of such
+Contributor, if any, and such derivative works, in source code and
+object code form.
+
+b) Subject to the terms of this Agreement, each Contributor hereby
+grants Recipient a non-exclusive, worldwide, royalty-free patent
+license under Licensed Patents to make, use, sell, offer to sell,
+import and otherwise transfer the Contribution of such Contributor, if
+any, in source code and object code form. This patent license shall
+apply to the combination of the Contribution and the Program if, at
+the time the Contribution is added by the Contributor, such addition
+of the Contribution causes such combination to be covered by the
+Licensed Patents. The patent license shall not apply to any other
+combinations which include the Contribution. No hardware per se is
+licensed hereunder.
+
+c) Recipient understands that although each Contributor grants the
+licenses to its Contributions set forth herein, no assurances are
+provided by any Contributor that the Program does not infringe the
+patent or other intellectual property rights of any other entity. Each
+Contributor disclaims any liability to Recipient for claims brought by
+any other entity based on infringement of intellectual property rights
+or otherwise. As a condition to exercising the rights and licenses
+granted hereunder, each Recipient hereby assumes sole responsibility
+to secure any other intellectual property rights needed, if any. For
+example, if a third party patent license is required to allow
+Recipient to distribute the Program, it is Recipient's responsibility
+to acquire that license before distributing the Program.
+
+d) Each Contributor represents that to its knowledge it has sufficient
+copyright rights in its Contribution, if any, to grant the copyright
+license set forth in this Agreement.
+
+3. REQUIREMENTS
+
+A Contributor may choose to distribute the Program in object code form
+under its own license agreement, provided that:
+
+a) it complies with the terms and conditions of this Agreement; and
+
+b) its license agreement:
+
+i) effectively disclaims on behalf of all Contributors all warranties
+and conditions, express and implied, including warranties or
+conditions of title and non-infringement, and implied warranties or
+conditions of merchantability and fitness for a particular purpose;
+
+ii) effectively excludes on behalf of all Contributors all liability
+for damages, including direct, indirect, special, incidental and
+consequential damages, such as lost profits;
+
+iii) states that any provisions which differ from this Agreement are
+offered by that Contributor alone and not by any other party; and
+
+iv) states that source code for the Program is available from such
+Contributor, and informs licensees how to obtain it in a reasonable
+manner on or through a medium customarily used for software exchange.
+
+When the Program is made available in source code form:
+
+a) it must be made available under this Agreement; and
+
+b) a copy of this Agreement must be included with each copy of the Program.
+
+Contributors may not remove or alter any copyright notices contained
+within the Program.
+
+Each Contributor must identify itself as the originator of its
+Contribution, if any, in a manner that reasonably allows subsequent
+Recipients to identify the originator of the Contribution.
+
+4. COMMERCIAL DISTRIBUTION
+
+Commercial distributors of software may accept certain
+responsibilities with respect to end users, business partners and the
+like. While this license is intended to facilitate the commercial use
+of the Program, the Contributor who includes the Program in a
+commercial product offering should do so in a manner which does not
+create potential liability for other Contributors. Therefore, if a
+Contributor includes the Program in a commercial product offering,
+such Contributor ("Commercial Contributor") hereby agrees to defend
+and indemnify every other Contributor ("Indemnified Contributor")
+against any losses, damages and costs (collectively "Losses") arising
+from claims, lawsuits and other legal actions brought by a third party
+against the Indemnified Contributor to the extent caused by the acts
+or omissions of such Commercial Contributor in connection with its
+distribution of the Program in a commercial product offering. The
+obligations in this section do not apply to any claims or Losses
+relating to any actual or alleged intellectual property
+infringement. In order to qualify, an Indemnified Contributor must: a)
+promptly notify the Commercial Contributor in writing of such claim,
+and b) allow the Commercial Contributor tocontrol, and cooperate with
+the Commercial Contributor in, the defense and any related settlement
+negotiations. The Indemnified Contributor may participate in any such
+claim at its own expense.
+
+For example, a Contributor might include the Program in a commercial
+product offering, Product X. That Contributor is then a Commercial
+Contributor. If that Commercial Contributor then makes performance
+claims, or offers warranties related to Product X, those performance
+claims and warranties are such Commercial Contributor's responsibility
+alone. Under this section, the Commercial Contributor would have to
+defend claims against the other Contributors related to those
+performance claims and warranties, and if a court requires any other
+Contributor to pay any damages as a result, the Commercial Contributor
+must pay those damages.
+
+5. NO WARRANTY
+
+EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS
+PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
+WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY
+OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely
+responsible for determining the appropriateness of using and
+distributing the Program and assumes all risks associated with its
+exercise of rights under this Agreement , including but not limited to
+the risks and costs of program errors, compliance with applicable
+laws, damage to or loss of data, programs or equipment, and
+unavailability or interruption of operations.
+
+6. DISCLAIMER OF LIABILITY
+
+EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR
+ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING
+WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR
+DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
+HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+7. GENERAL
+
+If any provision of this Agreement is invalid or unenforceable under
+applicable law, it shall not affect the validity or enforceability of
+the remainder of the terms of this Agreement, and without further
+action by the parties hereto, such provision shall be reformed to the
+minimum extent necessary to make such provision valid and enforceable.
+
+If Recipient institutes patent litigation against any entity
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+the Program itself (excluding combinations of the Program with other
+software or hardware) infringes such Recipient's patent(s), then such
+Recipient's rights granted under Section 2(b) shall terminate as of
+the date such litigation is filed.
+
+All Recipient's rights under this Agreement shall terminate if it
+fails to comply with any of the material terms or conditions of this
+Agreement and does not cure such failure in a reasonable period of
+time after becoming aware of such noncompliance. If all Recipient's
+rights under this Agreement terminate, Recipient agrees to cease use
+and distribution of the Program as soon as reasonably
+practicable. However, Recipient's obligations under this Agreement and
+any licenses granted by Recipient relating to the Program shall
+continue and survive.
+
+Everyone is permitted to copy and distribute copies of this Agreement,
+but in order to avoid inconsistency the Agreement is copyrighted and
+may only be modified in the following manner. The Agreement Steward
+reserves the right to publish new versions (including revisions) of
+this Agreement from time to time. No one other than the Agreement
+Steward has the right to modify this Agreement. The Eclipse Foundation
+is the initial Agreement Steward. The Eclipse Foundation may assign
+the responsibility to serve as the Agreement Steward to a suitable
+separate entity. Each new version of the Agreement will be given a
+distinguishing version number. The Program (including Contributions)
+may always be distributed subject to the version of the Agreement
+under which it was received. In addition, after a new version of the
+Agreement is published, Contributor may elect to distribute the
+Program (including its Contributions) under the new version. Except as
+expressly stated in Sections 2(a) and 2(b) above, Recipient receives
+no rights or licenses to the intellectual property of any Contributor
+under this Agreement, whether expressly, by implication, estoppel or
+otherwise. All rights in the Program not expressly granted under this
+Agreement are reserved.
+
+This Agreement is governed by the laws of the State of Washington and
+the intellectual property laws of the United States of America. No
+party to this Agreement will bring a legal action under this Agreement
+more than one year after the cause of action arose. Each party waives
+its rights to a jury trial in any resulting litigation.
5 README.markdown
@@ -0,0 +1,5 @@
+# webrepl
+
+This is just a simple REPL applet that uses Beanshell's JConsole component (at least for now). It's pretty basic right now, and looks like clj-swingrepl.
+
+The primary reason for this project is so that I can focus on making try-clojure a learning thing rather than an all purpose web REPL for everybody. People tend to complain about try-clojure's sandboxing (which certainly isn't perfect, but mostly does the trick), and this is for those people. It's an applet, so sandboxing is not needed.
28 index.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+ <head>
+ <title>Clojure Web REPL</title>
+ </head>
+ <body>
+ <div style="height: 400px; width: 600px; margin: 50px auto auto auto;">
+ <div style="padding-bottom: 5px;">
+ <applet archive="webrepl-0.0.1-SNAPSHOT-standalone.jar" code="webrepl/core.class" width="600" height="400"></applet>
+ </div>
+ <p>This is a Clojure REPL applet written by <a href="http://github.com/Raynes">Anthony Simpson</a>
+ using Beanshell's JConsole Swing component.</p>
+ <p>Chances are, you'll get a weird permission error when this applet tries to run. The only way
+ that I know how to fix this right now is to put this in ~/.java.policy:</p>
+ <pre>grant {
+ permission java.security.AllPermission;
+};</pre>
+ <p>This is likely unsafe to have around <i>all</i> the time, but for the purposes of a web REPL,
+ I suppose it's reasonable. If anybody else knows how to fix it without granting such daunting
+ permissions, feel free to contact me via email or github (linked above).
+ </p>
+ <p>Also, if you haven't noticed already, this REPL is absolutely <b>not</b> sandboxed, so don't be silly.
+ It's your machine you'll screw up, not mine. :p</p>
+ <p>Find more information at this project's <a href="http://github.com/Raynes/webrepl">Github page</a>.
+ </p>
+ </div>
+ </body>
+</html>
7 project.clj
@@ -0,0 +1,7 @@
+(defproject webrepl "0.0.1-SNAPSHOT"
+ :description "TODO: add summary of your project"
+ :dependencies [[clojure "1.2.0"]]
+ :dev-dependencies [[swank-clojure "1.2.1"]]
+ :aot [webrepl.core]
+ :source-path "src/clj"
+ :java-source-path "src/jvm")
15 src/clj/webrepl/core.clj
@@ -0,0 +1,15 @@
+(ns webrepl.core
+ (:use [clojure.main :only [main]])
+ (:import javax.swing.JApplet)
+ (:gen-class :extends javax.swing.JApplet))
+
+(defn make-console [applet]
+ (let [console (bsh.util.JConsole.)]
+ (.add applet console)
+ (binding [*out* (java.io.OutputStreamWriter. (.getOut console))
+ *in* (clojure.lang.LineNumberingPushbackReader. (.getIn console))
+ *err* (.getOut console)]
+ (.start (Thread. (bound-fn [] (main)))))))
+
+(defn -init [this]
+ (make-console this))
55 src/jvm/bsh/ConsoleInterface.java
@@ -0,0 +1,55 @@
+/*****************************************************************************
+ * *
+ * This file is part of the BeanShell Java Scripting distribution. *
+ * Documentation and updates may be found at http://www.beanshell.org/ *
+ * *
+ * Sun Public License Notice: *
+ * *
+ * The contents of this file are subject to the Sun Public License Version *
+ * 1.0 (the "License"); you may not use this file except in compliance with *
+ * the License. A copy of the License is available at http://www.sun.com *
+ * *
+ * The Original Code is BeanShell. The Initial Developer of the Original *
+ * Code is Pat Niemeyer. Portions created by Pat Niemeyer are Copyright *
+ * (C) 2000. All Rights Reserved. *
+ * *
+ * GNU Public License Notice: *
+ * *
+ * Alternatively, the contents of this file may be used under the terms of *
+ * the GNU Lesser General Public License (the "LGPL"), in which case the *
+ * provisions of LGPL are applicable instead of those above. If you wish to *
+ * allow use of your version of this file only under the terms of the LGPL *
+ * and not to allow others to use your version of this file under the SPL, *
+ * indicate your decision by deleting the provisions above and replace *
+ * them with the notice and other provisions required by the LGPL. If you *
+ * do not delete the provisions above, a recipient may use your version of *
+ * this file under either the SPL or the LGPL. *
+ * *
+ * Patrick Niemeyer (pat@pat.net) *
+ * Author of Learning Java, O'Reilly & Associates *
+ * http://www.pat.net/~pat/ *
+ * *
+ *****************************************************************************/
+
+
+package bsh;
+
+import java.io.*;
+
+/**
+ The capabilities of a minimal console for BeanShell.
+ Stream I/O and optimized print for output.
+
+ A simple console may ignore some of these or map them to trivial
+ implementations. e.g. print() with color can be mapped to plain text.
+ @see bsh.util.GUIConsoleInterface
+*/
+public interface ConsoleInterface {
+ public Reader getIn();
+ public PrintStream getOut();
+ public PrintStream getErr();
+ public void println( Object o );
+ public void print( Object o );
+ public void error( Object o );
+}
+
55 src/jvm/bsh/util/GUIConsoleInterface.java
@@ -0,0 +1,55 @@
+/*****************************************************************************
+ * *
+ * This file is part of the BeanShell Java Scripting distribution. *
+ * Documentation and updates may be found at http://www.beanshell.org/ *
+ * *
+ * Sun Public License Notice: *
+ * *
+ * The contents of this file are subject to the Sun Public License Version *
+ * 1.0 (the "License"); you may not use this file except in compliance with *
+ * the License. A copy of the License is available at http://www.sun.com *
+ * *
+ * The Original Code is BeanShell. The Initial Developer of the Original *
+ * Code is Pat Niemeyer. Portions created by Pat Niemeyer are Copyright *
+ * (C) 2000. All Rights Reserved. *
+ * *
+ * GNU Public License Notice: *
+ * *
+ * Alternatively, the contents of this file may be used under the terms of *
+ * the GNU Lesser General Public License (the "LGPL"), in which case the *
+ * provisions of LGPL are applicable instead of those above. If you wish to *
+ * allow use of your version of this file only under the terms of the LGPL *
+ * and not to allow others to use your version of this file under the SPL, *
+ * indicate your decision by deleting the provisions above and replace *
+ * them with the notice and other provisions required by the LGPL. If you *
+ * do not delete the provisions above, a recipient may use your version of *
+ * this file under either the SPL or the LGPL. *
+ * *
+ * Patrick Niemeyer (pat@pat.net) *
+ * Author of Learning Java, O'Reilly & Associates *
+ * http://www.pat.net/~pat/ *
+ * *
+ *****************************************************************************/
+
+package bsh.util;
+
+import bsh.ConsoleInterface;
+import java.awt.Color;
+
+/**
+ Additional capabilities of an interactive console for BeanShell.
+ Althought this is called "GUIConsoleInterface" it might just as well be
+ used by a more sophisticated text-only command line.
+ <p>
+ Note: we may want to express the command line history, editing,
+ and cut & paste functionality here as well at some point.
+*/
+public interface GUIConsoleInterface extends ConsoleInterface
+{
+ public void print( Object o, Color color );
+ public void setNameCompletion( NameCompletion nc );
+
+ /** e.g. the wait cursor */
+ public void setWaitFeedback( boolean on );
+}
+
811 src/jvm/bsh/util/JConsole.java
@@ -0,0 +1,811 @@
+/*****************************************************************************
+ * *
+ * This file is part of the BeanShell Java Scripting distribution. *
+ * Documentation and updates may be found at http://www.beanshell.org/ *
+ * *
+ * Sun Public License Notice: *
+ * *
+ * The contents of this file are subject to the Sun Public License Version *
+ * 1.0 (the "License"); you may not use this file except in compliance with *
+ * the License. A copy of the License is available at http://www.sun.com *
+ * *
+ * The Original Code is BeanShell. The Initial Developer of the Original *
+ * Code is Pat Niemeyer. Portions created by Pat Niemeyer are Copyright *
+ * (C) 2000. All Rights Reserved. *
+ * *
+ * GNU Public License Notice: *
+ * *
+ * Alternatively, the contents of this file may be used under the terms of *
+ * the GNU Lesser General Public License (the "LGPL"), in which case the *
+ * provisions of LGPL are applicable instead of those above. If you wish to *
+ * allow use of your version of this file only under the terms of the LGPL *
+ * and not to allow others to use your version of this file under the SPL, *
+ * indicate your decision by deleting the provisions above and replace *
+ * them with the notice and other provisions required by the LGPL. If you *
+ * do not delete the provisions above, a recipient may use your version of *
+ * this file under either the SPL or the LGPL. *
+ * *
+ * Patrick Niemeyer (pat@pat.net) *
+ * Author of Learning Java, O'Reilly & Associates *
+ * http://www.pat.net/~pat/ *
+ * *
+ *****************************************************************************/
+
+package bsh.util;
+
+import java.awt.Component;
+import java.awt.Font;
+import java.awt.Color;
+import java.awt.Insets;
+import java.awt.event.*;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.io.*;
+import java.util.Vector;
+import java.awt.Cursor;
+import javax.swing.text.*;
+import javax.swing.*;
+
+// Things that are not in the core packages
+
+import bsh.util.NameCompletion;
+
+/**
+ A JFC/Swing based console for the BeanShell desktop.
+ This is a descendant of the old AWTConsole.
+
+ Improvements by: Mark Donszelmann <Mark.Donszelmann@cern.ch>
+ including Cut & Paste
+
+ Improvements by: Daniel Leuck
+ including Color and Image support, key press bug workaround
+*/
+public class JConsole extends JScrollPane
+ implements GUIConsoleInterface, Runnable, KeyListener,
+ MouseListener, ActionListener, PropertyChangeListener
+{
+ private final static String CUT = "Cut";
+ private final static String COPY = "Copy";
+ private final static String PASTE = "Paste";
+
+ private OutputStream outPipe;
+ private InputStream inPipe;
+ private InputStream in;
+ private PrintStream out;
+
+ public InputStream getInputStream() { return in; }
+ public Reader getIn() { return new InputStreamReader(in); }
+ public PrintStream getOut() { return out; }
+ public PrintStream getErr() { return out; }
+
+ private int cmdStart = 0;
+ private Vector <String>history = new Vector<String>();
+ private String startedLine;
+ private int histLine = 0;
+
+ private JPopupMenu menu;
+ private JTextPane text;
+ private DefaultStyledDocument doc;
+
+ NameCompletion nameCompletion;
+ final int SHOW_AMBIG_MAX = 10;
+
+ // hack to prevent key repeat for some reason?
+ private boolean gotUp = true;
+
+ public JConsole() {
+ this(null, null);
+ }
+
+ public JConsole( InputStream cin, OutputStream cout )
+ {
+ super();
+
+ // Special TextPane which catches for cut and paste, both L&F keys and
+ // programmatic behaviour
+ text = new JTextPane( doc=new DefaultStyledDocument() )
+ {
+ public void cut() {
+ if (text.getCaretPosition() < cmdStart) {
+ super.copy();
+ } else {
+ super.cut();
+ }
+ }
+
+ public void paste() {
+ forceCaretMoveToEnd();
+ super.paste();
+ }
+ };
+
+ Font font = new Font("Monospaced",Font.PLAIN,14);
+ text.setText("");
+ text.setFont( font );
+ text.setMargin( new Insets(7,5,7,5) );
+ text.addKeyListener(this);
+ setViewportView(text);
+
+ // create popup menu
+ menu = new JPopupMenu("JConsole Menu");
+ menu.add(new JMenuItem(CUT)).addActionListener(this);
+ menu.add(new JMenuItem(COPY)).addActionListener(this);
+ menu.add(new JMenuItem(PASTE)).addActionListener(this);
+
+ text.addMouseListener(this);
+
+ // make sure popup menu follows Look & Feel
+ UIManager.addPropertyChangeListener(this);
+
+ outPipe = cout;
+ if ( outPipe == null ) {
+ outPipe = new PipedOutputStream();
+ try {
+ in = new PipedInputStream((PipedOutputStream)outPipe);
+ } catch ( IOException e ) {
+ print("Console internal error (1)...", Color.red);
+ }
+ }
+
+ inPipe = cin;
+ if ( inPipe == null ) {
+ PipedOutputStream pout = new PipedOutputStream();
+ out = new PrintStream( pout );
+ try {
+ inPipe = new BlockingPipedInputStream(pout);
+ } catch ( IOException e ) { print("Console internal error: "+e); }
+ }
+ // Start the inpipe watcher
+ new Thread( this ).start();
+
+ requestFocus();
+ }
+
+ public void requestFocus()
+ {
+ super.requestFocus();
+ text.requestFocus();
+ }
+
+ public void keyPressed( KeyEvent e ) {
+ type( e );
+ gotUp=false;
+ }
+
+ public void keyTyped(KeyEvent e) {
+ type( e );
+ }
+
+ public void keyReleased(KeyEvent e) {
+ gotUp=true;
+ type( e );
+ }
+
+ private synchronized void type( KeyEvent e ) {
+ switch ( e.getKeyCode() )
+ {
+ case ( KeyEvent.VK_ENTER ):
+ if (e.getID() == KeyEvent.KEY_PRESSED) {
+ if (gotUp) {
+ enter();
+ resetCommandStart();
+ text.setCaretPosition(cmdStart);
+ }
+ }
+ e.consume();
+ text.repaint();
+ break;
+
+ case ( KeyEvent.VK_UP ):
+ if (e.getID() == KeyEvent.KEY_PRESSED) {
+ historyUp();
+ }
+ e.consume();
+ break;
+
+ case ( KeyEvent.VK_DOWN ):
+ if (e.getID() == KeyEvent.KEY_PRESSED) {
+ historyDown();
+ }
+ e.consume();
+ break;
+
+ case ( KeyEvent.VK_LEFT ):
+ case ( KeyEvent.VK_BACK_SPACE ):
+ case ( KeyEvent.VK_DELETE ):
+ if (text.getCaretPosition() <= cmdStart) {
+ // This doesn't work for backspace.
+ // See default case for workaround
+ e.consume();
+ }
+ break;
+
+ case ( KeyEvent.VK_RIGHT ):
+ forceCaretMoveToStart();
+ break;
+
+ case ( KeyEvent.VK_HOME ):
+ text.setCaretPosition(cmdStart);
+ e.consume();
+ break;
+
+ case ( KeyEvent.VK_U ): // clear line
+ if ( (e.getModifiers() & InputEvent.CTRL_MASK) > 0 ) {
+ replaceRange( "", cmdStart, textLength());
+ histLine = 0;
+ e.consume();
+ }
+ break;
+
+ case ( KeyEvent.VK_ALT ):
+ case ( KeyEvent.VK_CAPS_LOCK ):
+ case ( KeyEvent.VK_CONTROL ):
+ case ( KeyEvent.VK_META ):
+ case ( KeyEvent.VK_SHIFT ):
+ case ( KeyEvent.VK_PRINTSCREEN ):
+ case ( KeyEvent.VK_SCROLL_LOCK ):
+ case ( KeyEvent.VK_PAUSE ):
+ case ( KeyEvent.VK_INSERT ):
+ case ( KeyEvent.VK_F1):
+ case ( KeyEvent.VK_F2):
+ case ( KeyEvent.VK_F3):
+ case ( KeyEvent.VK_F4):
+ case ( KeyEvent.VK_F5):
+ case ( KeyEvent.VK_F6):
+ case ( KeyEvent.VK_F7):
+ case ( KeyEvent.VK_F8):
+ case ( KeyEvent.VK_F9):
+ case ( KeyEvent.VK_F10):
+ case ( KeyEvent.VK_F11):
+ case ( KeyEvent.VK_F12):
+ case ( KeyEvent.VK_ESCAPE ):
+
+ // only modifier pressed
+ break;
+
+ // Control-C
+ case ( KeyEvent.VK_C ):
+ if (text.getSelectedText() == null) {
+ if (( (e.getModifiers() & InputEvent.CTRL_MASK) > 0 )
+ && (e.getID() == KeyEvent.KEY_PRESSED)) {
+ append("^C");
+ }
+ e.consume();
+ }
+ break;
+
+ case ( KeyEvent.VK_TAB ):
+ if (e.getID() == KeyEvent.KEY_RELEASED) {
+ String part = text.getText().substring( cmdStart );
+ doCommandCompletion( part );
+ }
+ e.consume();
+ break;
+
+ default:
+ if (
+ (e.getModifiers() &
+ (InputEvent.CTRL_MASK
+ | InputEvent.ALT_MASK | InputEvent.META_MASK)) == 0 )
+ {
+ // plain character
+ forceCaretMoveToEnd();
+ }
+
+ /*
+ The getKeyCode function always returns VK_UNDEFINED for
+ keyTyped events, so backspace is not fully consumed.
+ */
+ if (e.paramString().indexOf("Backspace") != -1)
+ {
+ if (text.getCaretPosition() <= cmdStart) {
+ e.consume();
+ break;
+ }
+ }
+
+ break;
+ }
+ }
+
+ private void doCommandCompletion( String part ) {
+ if ( nameCompletion == null )
+ return;
+
+ int i=part.length()-1;
+
+ // Character.isJavaIdentifierPart() How convenient for us!!
+ while (
+ i >= 0 &&
+ ( Character.isJavaIdentifierPart(part.charAt(i))
+ || part.charAt(i) == '.' )
+ )
+ i--;
+
+ part = part.substring(i+1);
+
+ if ( part.length() < 2 ) // reasonable completion length
+ return;
+
+ //System.out.println("completing part: "+part);
+
+ // no completion
+ String [] complete = nameCompletion.completeName(part);
+ if ( complete.length == 0 ) {
+ java.awt.Toolkit.getDefaultToolkit().beep();
+ return;
+ }
+
+ // Found one completion (possibly what we already have)
+ if ( complete.length == 1 && !complete.equals(part) ) {
+ String append = complete[0].substring(part.length());
+ append( append );
+ return;
+ }
+
+ // Found ambiguous, show (some of) them
+
+ String line = text.getText();
+ String command = line.substring( cmdStart );
+ // Find prompt
+ for(i=cmdStart; line.charAt(i) != '\n' && i > 0; i--);
+ String prompt = line.substring( i+1, cmdStart );
+
+ // Show ambiguous
+ StringBuffer sb = new StringBuffer("\n");
+ for( i=0; i<complete.length && i<SHOW_AMBIG_MAX; i++)
+ sb.append( complete[i] +"\n" );
+ if ( i == SHOW_AMBIG_MAX )
+ sb.append("...\n");
+
+ print( sb, Color.gray );
+ print( prompt ); // print resets command start
+ append( command ); // append does not reset command start
+ }
+
+ private void resetCommandStart() {
+ cmdStart = textLength();
+ }
+
+ private void append(String string) {
+ int slen = textLength();
+ text.select(slen, slen);
+ text.replaceSelection(string);
+ }
+
+ private String replaceRange(Object s, int start, int end) {
+ String st = s.toString();
+ text.select(start, end);
+ text.replaceSelection(st);
+ //text.repaint();
+ return st;
+ }
+
+ private void forceCaretMoveToEnd() {
+ if (text.getCaretPosition() < cmdStart) {
+ // move caret first!
+ text.setCaretPosition(textLength());
+ }
+ text.repaint();
+ }
+
+ private void forceCaretMoveToStart() {
+ if (text.getCaretPosition() < cmdStart) {
+ // move caret first!
+ }
+ text.repaint();
+ }
+
+
+ private void enter() {
+ String s = getCmd();
+
+ if ( s.length() == 0 ) // special hack for empty return!
+ s = ";\n";
+ else {
+ history.addElement( s );
+ s = s +"\n";
+ }
+
+ append("\n");
+ histLine = 0;
+ acceptLine( s );
+ text.repaint();
+ }
+
+ private String getCmd() {
+ String s = "";
+ try {
+ s = text.getText(cmdStart, textLength() - cmdStart);
+ } catch (BadLocationException e) {
+ // should not happen
+ System.out.println("Internal JConsole Error: "+e);
+ }
+ return s;
+ }
+
+ private void historyUp() {
+ if ( history.size() == 0 )
+ return;
+ if ( histLine == 0 ) // save current line
+ startedLine = getCmd();
+ if ( histLine < history.size() ) {
+ histLine++;
+ showHistoryLine();
+ }
+ }
+
+ private void historyDown() {
+ if ( histLine == 0 )
+ return;
+
+ histLine--;
+ showHistoryLine();
+ }
+
+ private void showHistoryLine() {
+ String showline;
+ if ( histLine == 0 )
+ showline = startedLine;
+ else
+ showline = (String)history.elementAt( history.size() - histLine );
+
+ replaceRange( showline, cmdStart, textLength() );
+ text.setCaretPosition(textLength());
+ text.repaint();
+ }
+
+ String ZEROS = "000";
+
+ private void acceptLine( String line )
+ {
+ // Patch to handle Unicode characters
+ // Submitted by Daniel Leuck
+ StringBuffer buf = new StringBuffer();
+ int lineLength = line.length();
+ for(int i=0; i<lineLength; i++) {
+ char c = line.charAt(i);
+ if(c>127) {
+ String val = Integer.toString(c, 16);
+ val=ZEROS.substring(0,4-val.length()) + val;
+ buf.append("\\u" + val);
+ } else {
+ buf.append(c);
+ }
+ }
+ line = buf.toString();
+ // End unicode patch
+
+
+ if (outPipe == null )
+ print("Console internal error: cannot output ...", Color.red);
+ else
+ try {
+ outPipe.write( line.getBytes() );
+ outPipe.flush();
+ } catch ( IOException e ) {
+ outPipe = null;
+ throw new RuntimeException("Console pipe broken...");
+ }
+ //text.repaint();
+ }
+
+ public void println(Object o) {
+ print( String.valueOf(o) + "\n" );
+ text.repaint();
+ }
+
+ public void print(final Object o) {
+ invokeAndWait(new Runnable() {
+ public void run() {
+ append(String.valueOf(o));
+ resetCommandStart();
+ text.setCaretPosition(cmdStart);
+ }
+ });
+ }
+
+ /**
+ * Prints "\\n" (i.e. newline)
+ */
+ public void println() {
+ print("\n");
+ text.repaint();
+ }
+
+ public void error( Object o ) {
+ print( o, Color.red );
+ }
+
+ public void println(Icon icon) {
+ print(icon);
+ println();
+ text.repaint();
+ }
+
+ public void print(final Icon icon) {
+ if (icon==null)
+ return;
+
+ invokeAndWait(new Runnable() {
+ public void run() {
+ text.insertIcon(icon);
+ resetCommandStart();
+ text.setCaretPosition(cmdStart);
+ }
+ });
+ }
+
+ public void print(Object s, Font font) {
+ print(s, font, null);
+ }
+
+ public void print(Object s, Color color) {
+ print(s, null, color);
+ }
+
+ public void print(final Object o, final Font font, final Color color) {
+ invokeAndWait(new Runnable() {
+ public void run() {
+ AttributeSet old = getStyle();
+ setStyle(font, color);
+ append(String.valueOf(o));
+ resetCommandStart();
+ text.setCaretPosition(cmdStart);
+ setStyle(old, true);
+ }
+ });
+ }
+
+ public void print(
+ Object s,
+ String fontFamilyName,
+ int size,
+ Color color
+ ) {
+
+ print(s,fontFamilyName,size,color,false,false,false);
+ }
+
+ public void print(
+ final Object o,
+ final String fontFamilyName,
+ final int size,
+ final Color color,
+ final boolean bold,
+ final boolean italic,
+ final boolean underline
+ )
+ {
+ invokeAndWait(new Runnable() {
+ public void run() {
+ AttributeSet old = getStyle();
+ setStyle(fontFamilyName, size, color, bold, italic, underline);
+ append(String.valueOf(o));
+ resetCommandStart();
+ text.setCaretPosition(cmdStart);
+ setStyle(old, true);
+ }
+ });
+ }
+
+ private AttributeSet setStyle(Font font) {
+ return setStyle(font, null);
+ }
+
+ private AttributeSet setStyle(Color color) {
+ return setStyle(null, color);
+ }
+
+ private AttributeSet setStyle( Font font, Color color)
+ {
+ if (font!=null)
+ return setStyle( font.getFamily(), font.getSize(), color,
+ font.isBold(), font.isItalic(),
+ StyleConstants.isUnderline(getStyle()) );
+ else
+ return setStyle(null,-1,color);
+ }
+
+ private AttributeSet setStyle (
+ String fontFamilyName, int size, Color color)
+ {
+ MutableAttributeSet attr = new SimpleAttributeSet();
+ if (color!=null)
+ StyleConstants.setForeground(attr, color);
+ if (fontFamilyName!=null)
+ StyleConstants.setFontFamily(attr, fontFamilyName);
+ if (size!=-1)
+ StyleConstants.setFontSize(attr, size);
+
+ setStyle(attr);
+
+ return getStyle();
+ }
+
+ private AttributeSet setStyle(
+ String fontFamilyName,
+ int size,
+ Color color,
+ boolean bold,
+ boolean italic,
+ boolean underline
+ )
+ {
+ MutableAttributeSet attr = new SimpleAttributeSet();
+ if (color!=null)
+ StyleConstants.setForeground(attr, color);
+ if (fontFamilyName!=null)
+ StyleConstants.setFontFamily(attr, fontFamilyName);
+ if (size!=-1)
+ StyleConstants.setFontSize(attr, size);
+ StyleConstants.setBold(attr, bold);
+ StyleConstants.setItalic(attr, italic);
+ StyleConstants.setUnderline(attr, underline);
+
+ setStyle(attr);
+
+ return getStyle();
+ }
+
+ private void setStyle(AttributeSet attributes) {
+ setStyle(attributes, false);
+ }
+
+ private void setStyle(AttributeSet attributes, boolean overWrite) {
+ text.setCharacterAttributes(attributes, overWrite);
+ }
+
+ private AttributeSet getStyle() {
+ return text.getCharacterAttributes();
+ }
+
+ public void setFont( Font font ) {
+ super.setFont( font );
+
+ if ( text != null )
+ text.setFont( font );
+ }
+
+ private void inPipeWatcher() throws IOException {
+ byte [] ba = new byte [256]; // arbitrary blocking factor
+ int read;
+ while ( (read = inPipe.read(ba)) != -1 ) {
+ print( new String(ba, 0, read) );
+ //text.repaint();
+ }
+
+ println("Console: Input closed...");
+ }
+
+ public void run() {
+ try {
+ inPipeWatcher();
+ } catch ( IOException e ) {
+ print("Console: I/O Error: "+e+"\n", Color.red);
+ }
+ }
+
+ public String toString() {
+ return "BeanShell console";
+ }
+
+ // MouseListener Interface
+ public void mouseClicked(MouseEvent event) {
+ }
+
+ public void mousePressed(MouseEvent event) {
+ if (event.isPopupTrigger()) {
+ menu.show(
+ (Component)event.getSource(), event.getX(), event.getY());
+ }
+ }
+
+ public void mouseReleased(MouseEvent event) {
+ if (event.isPopupTrigger()) {
+ menu.show((Component)event.getSource(), event.getX(),
+ event.getY());
+ }
+ text.repaint();
+ }
+
+ public void mouseEntered(MouseEvent event) { }
+
+ public void mouseExited(MouseEvent event) { }
+
+ // property change
+ public void propertyChange(PropertyChangeEvent event) {
+ if (event.getPropertyName().equals("lookAndFeel")) {
+ SwingUtilities.updateComponentTreeUI(menu);
+ }
+ }
+
+ // handle cut, copy and paste
+ public void actionPerformed(ActionEvent event) {
+ String cmd = event.getActionCommand();
+ if (cmd.equals(CUT)) {
+ text.cut();
+ } else if (cmd.equals(COPY)) {
+ text.copy();
+ } else if (cmd.equals(PASTE)) {
+ text.paste();
+ }
+ }
+
+ /**
+ * If not in the event thread run via SwingUtilities.invokeAndWait()
+ */
+ private void invokeAndWait(Runnable run) {
+ if(!SwingUtilities.isEventDispatchThread()) {
+ try {
+ SwingUtilities.invokeAndWait(run);
+ } catch(Exception e) {
+ // shouldn't happen
+ e.printStackTrace();
+ }
+ } else {
+ run.run();
+ }
+ }
+
+ /**
+ The overridden read method in this class will not throw "Broken pipe"
+ IOExceptions; It will simply wait for new writers and data.
+ This is used by the JConsole internal read thread to allow writers
+ in different (and in particular ephemeral) threads to write to the pipe.
+
+ It also checks a little more frequently than the original read().
+
+ Warning: read() will not even error on a read to an explicitly closed
+ pipe (override closed to for that).
+ */
+ public static class BlockingPipedInputStream extends PipedInputStream
+ {
+ boolean closed;
+ public BlockingPipedInputStream( PipedOutputStream pout )
+ throws IOException
+ {
+ super(pout);
+ }
+ public synchronized int read() throws IOException {
+ if ( closed )
+ throw new IOException("stream closed");
+
+ while (super.in < 0) { // While no data */
+ notifyAll(); // Notify any writers to wake up
+ try {
+ wait(750);
+ } catch ( InterruptedException e ) {
+ throw new InterruptedIOException();
+ }
+ }
+ // This is what the superclass does.
+ int ret = buffer[super.out++] & 0xFF;
+ if (super.out >= buffer.length)
+ super.out = 0;
+ if (super.in == super.out)
+ super.in = -1; /* now empty */
+ return ret;
+ }
+ public void close() throws IOException {
+ closed = true;
+ super.close();
+ }
+ }
+
+ public void setNameCompletion( NameCompletion nc ) {
+ this.nameCompletion = nc;
+ }
+
+ public void setWaitFeedback( boolean on ) {
+ if ( on )
+ setCursor( Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR) );
+ else
+ setCursor( Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR) );
+ }
+
+ private int textLength() { return text.getDocument().getLength(); }
+
+}
+
+
57 src/jvm/bsh/util/NameCompletion.java
@@ -0,0 +1,57 @@
+/*****************************************************************************
+ * *
+ * This file is part of the BeanShell Java Scripting distribution. *
+ * Documentation and updates may be found at http://www.beanshell.org/ *
+ * *
+ * Sun Public License Notice: *
+ * *
+ * The contents of this file are subject to the Sun Public License Version *
+ * 1.0 (the "License"); you may not use this file except in compliance with *
+ * the License. A copy of the License is available at http://www.sun.com *
+ * *
+ * The Original Code is BeanShell. The Initial Developer of the Original *
+ * Code is Pat Niemeyer. Portions created by Pat Niemeyer are Copyright *
+ * (C) 2000. All Rights Reserved. *
+ * *
+ * GNU Public License Notice: *
+ * *
+ * Alternatively, the contents of this file may be used under the terms of *
+ * the GNU Lesser General Public License (the "LGPL"), in which case the *
+ * provisions of LGPL are applicable instead of those above. If you wish to *
+ * allow use of your version of this file only under the terms of the LGPL *
+ * and not to allow others to use your version of this file under the SPL, *
+ * indicate your decision by deleting the provisions above and replace *
+ * them with the notice and other provisions required by the LGPL. If you *
+ * do not delete the provisions above, a recipient may use your version of *
+ * this file under either the SPL or the LGPL. *
+ * *
+ * Patrick Niemeyer (pat@pat.net) *
+ * Author of Learning Java, O'Reilly & Associates *
+ * http://www.pat.net/~pat/ *
+ * *
+ *****************************************************************************/
+
+package bsh.util;
+
+import java.util.*;
+
+/**
+ The interface for name completion.
+*/
+public interface NameCompletion
+{
+ /**
+ Return an array containing a string element of the maximum
+ unambiguous namespace completion or, if there is no common prefix,
+ return the list of ambiguous names.
+ e.g.
+ input: "java.l"
+ output: [ "java.lang." ]
+ input: "java.lang."
+ output: [ "java.lang.Thread", "java.lang.Integer", ... ]
+
+ Note: Alternatively, make a NameCompletionResult object someday...
+ */
+ public String [] completeName( String part );
+
+}

0 comments on commit f5da990

Please sign in to comment.
Something went wrong with that request. Please try again.