/* (comment * * Copyright (c) ThorTech, L.L.C.. All rights reserved. * The use and distribution terms for this software are covered by the * Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php) * which can be found in the file epl-v10.html at the root of this distribution. * By using this software in any fashion, you are agreeing to be bound by * the terms of this license. * You must not remove this notice, or any other, from this software. * * Author: Narayan Singhal, Eric Thorsen ) */ /* * ReplPanel.java * * Created on Nov 24, 2008, 11:52:02 AM */ package org.enclojure.ide.repl; import clojure.lang.IFn; import clojure.lang.RT; import clojure.lang.Symbol; import clojure.lang.Var; import java.awt.Event; import java.awt.event.KeyEvent; import java.util.logging.Level; import java.util.logging.Logger; import javax.swing.JCheckBoxMenuItem; import javax.swing.JEditorPane; import javax.swing.JPopupMenu.Separator; import javax.swing.KeyStroke; import javax.swing.event.UndoableEditEvent; import javax.swing.event.UndoableEditListener; import javax.swing.text.BadLocationException; import javax.swing.text.Document; import javax.swing.undo.UndoManager; /** * * @author nsinghal */ public class ReplPanel extends javax.swing.JPanel { public int _promptPos = 0; volatile IFn _evaluateInReplFn = (IFn)RT.var("org.enclojure.ide.repl.repl-panel", "evaluate-in-repl"); volatile IFn _processKeyEventFunc = (IFn)RT.var("org.enclojure.ide.repl.repl-panel", "process-key-input"); volatile IFn _dispShowHistoryEventsFunc = (IFn)RT.var("org.enclojure.ide.repl.repl-panel", "show-repl-history"); volatile IFn _clearReplHistoryEventsFunc = (IFn)RT.var("org.enclojure.ide.repl.repl-panel", "clear-history"); volatile IFn _toggleStackTraceFunc = (IFn)RT.var("org.enclojure.ide.repl.repl-panel", "set-print-stack-trace-on-error"); volatile IFn _togglePrettyPrintFunc = (IFn)RT.var("org.enclojure.ide.repl.repl-panel", "set-print-pretty"); static final Var getPrettyInfo = RT.var("org.enclojure.ide.repl.repl-manager", "get-pretty-info"); volatile IFn _replDataFn; static { try { RT.var("clojure.core", "require").invoke(Symbol.create("org.enclojure.ide.repl.repl-panel")); RT.var("clojure.core", "require").invoke(Symbol.create("org.enclojure.repl.main")); } catch (Exception ex) { Logger.getLogger(ReplPanel.class.getName()).log(Level.SEVERE, null, ex); } } ///////////////////////////////////////////////////// /////////NEW START ///////////////////////////////////////////////////// static final Var bindLocalRepl = RT.var("org.enclojure.repl.repl-main", "bind-local-repl"); String _replID; private IFn _replFn = null; private IFn _resetReplFn = null; private Boolean menuSetupDone = false; public int _debugPort = 0; private UndoManager _undoManager = new UndoManager(); public ReplPanel(String replID) { _replID = replID; initComponents(); createReplEditorPane(); setupMenu(); } public javax.swing.JEditorPane _replEditorPane; public void createReplEditorPane() { try { Var createReplEditorPaneFn = RT.var("org.enclojure.ide.repl.repl-panel" , "create-repl-editor-pane"); _replEditorPane = (JEditorPane) createReplEditorPaneFn.invoke(this); } catch (Exception ex) { Logger.getLogger(ReplPanel.class.getName()).log(Level.SEVERE, null, ex); } //??_replEditorPane.setInheritsPopupMenu(true); jScrollPaneRepl.setViewportView(_replEditorPane); _replEditorPane.getDocument().addUndoableEditListener(new UndoableEditListener() { public void undoableEditHappened(UndoableEditEvent e) { _undoManager.addEdit(e.getEdit()); } }); _replEditorPane.addKeyListener(new java.awt.event.KeyAdapter() { public void keyTyped(java.awt.event.KeyEvent evt) { processCharInput(evt); } public void keyPressed(java.awt.event.KeyEvent evt) { processKeyInput(evt); } }); } public void resultReceived(JEditorPane pane, String result) { Document doc = (Document) pane.getDocument(); try { if(pane != _replEditorPane) result = "\n" + result; doc.insertString(doc.getLength(), result, null); pane.setCaretPosition(doc.getLength()); } catch (BadLocationException ex) { Logger.getLogger(ReplPanel.class.getName()).log(Level.SEVERE, null, ex); } if(pane == jEditorPaneOut && result.contains("Listening for transport dt_socket at address")) { //Listening for transport dt_socket at address: 58896 String portString = result.substring(result.indexOf(":") + 1); _debugPort = Integer.parseInt(portString.trim()); } if(pane == _replEditorPane) { _promptPos = _replEditorPane.getDocument().getLength(); jTabbedPane1.setSelectedIndex(0); _undoManager.die(); } } public void setReplFunction(IFn replFn) { _promptPos = 0; _replFn = replFn; } public void setResetReplFn(IFn resetReplFn) { _resetReplFn = resetReplFn; } protected void processCharInput(java.awt.event.KeyEvent evt) { try { int code = evt.getKeyCode(); char kc = evt.getKeyChar(); int caretPos = _replEditorPane.getCaretPosition(); if ((!(code == evt.VK_UP || code == evt.VK_DOWN || code == evt.VK_LEFT || code == evt.VK_RIGHT) && caretPos < _promptPos) || (code == evt.VK_BACK_SPACE && caretPos <= _promptPos) || (kc == '\b' && caretPos <= _promptPos)) { evt.consume(); return; } } catch (Exception e) { //cljLog.log(java.util.logging.Level.SEVERE, "Exception in jEditorPane1KeyTyped: " + e.getMessage()); } } protected void processKeyInput(java.awt.event.KeyEvent evt) { try { this._processKeyEventFunc.invoke (_replID, _replEditorPane, _promptPos, evt); } catch (Exception ex) { Logger.getLogger(ReplPanel.class.getName()).log(Level.SEVERE, null, ex); } } private void showReplHistoryActionPerformed(java.awt.event.ActionEvent evt) { try { _dispShowHistoryEventsFunc.invoke(this._replID,this); } catch (Exception ex) { Logger.getLogger(ReplPanel.class.getName()).log(Level.SEVERE, null, ex); } } private void clearReplHistoryActionPerformed(java.awt.event.ActionEvent evt) { try { _clearReplHistoryEventsFunc.invoke(this._replID); } catch (Exception ex) { Logger.getLogger(ReplPanel.class.getName()).log(Level.SEVERE, null, ex); } } private void showReplInfoMenuActionPerformed(java.awt.event.ActionEvent evt) { try { ReplInfoFrame.Show(_replID + ": Repl Startup Information", (String) getPrettyInfo.invoke(_replID)); } catch (Exception ex) { Logger.getLogger(ReplPanel.class.getName()).log(Level.SEVERE, null, ex); } } private void ResetRepl() { if(_resetReplFn != null) { try { _resetReplFn.invoke(); } catch (Exception ex) { Logger.getLogger(ReplPanel.class.getName()).log(Level.SEVERE, null, ex); } } } public void printStackTrace () { EvaluateInRepl("(.printStackTrace *e *out*)", null); } Boolean _stackTraceOnError = false; public JCheckBoxMenuItem stackTraceOnErrorMenu = new JCheckBoxMenuItem("*print-stack-trace-on-error*", _stackTraceOnError); private void setupMenu() { if (menuSetupDone) return; menuSetupDone = true; javax.swing.JPopupMenu contextMenu = _replEditorPane.getComponentPopupMenu(); if(contextMenu == null) contextMenu = new javax.swing.JPopupMenu(); javax.swing.JMenuItem showStackTrace = new javax.swing.JMenuItem("Print StackTrace"); showStackTrace.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_J, Event.CTRL_MASK, false)); showStackTrace.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { printStackTrace(); } }); contextMenu.add(showStackTrace); stackTraceOnErrorMenu.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { printStackTraceToggleButtonActionPerformed(evt); // _stackTraceOnError = !_stackTraceOnError; // if(_stackTraceOnError) // { // EvaluateInRepl("(set! org.enclojure.repl.main/*print-stack-trace-on-error* true)", null); // } // else // { // EvaluateInRepl("(set! org.enclojure.repl.main/*print-stack-trace-on-error* false)", null); // } } }); contextMenu.add(stackTraceOnErrorMenu); javax.swing.JMenuItem replHistoryInfoMenu = new javax.swing.JMenuItem(); replHistoryInfoMenu.setText("Repl History"); replHistoryInfoMenu.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { showReplHistoryActionPerformed(evt); } }); //Show Repl Information javax.swing.JMenuItem showReplInfoMenu = new javax.swing.JMenuItem(); showReplInfoMenu.setText("Show Repl Information"); showReplInfoMenu.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { showReplInfoMenuActionPerformed(evt); } }); //Reset Repl javax.swing.JMenuItem resetReplMenu = new javax.swing.JMenuItem(); resetReplMenu.setText("Reset Repl"); resetReplMenu.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { ResetRepl(); } }); contextMenu.add(new Separator()); contextMenu.add(showReplInfoMenu); contextMenu.add(resetReplMenu); _replEditorPane.setComponentPopupMenu(contextMenu); } public void bindKeyListeners() { _replEditorPane.addKeyListener(new java.awt.event.KeyAdapter() { public void keyTyped(java.awt.event.KeyEvent evt) { processCharInput(evt); } public void keyPressed(java.awt.event.KeyEvent evt) { processKeyInput(evt); } }); _replErrorPane.addKeyListener(new java.awt.event.KeyAdapter() { public void keyPressed(java.awt.event.KeyEvent evt) { processKeyInput(evt); } }); jEditorPaneOut.addKeyListener(new java.awt.event.KeyAdapter() { public void keyPressed(java.awt.event.KeyEvent evt) { processKeyInput(evt); } }); } public JEditorPane GetEditorPane() { return _replEditorPane; } public void Disconnect() { EvaluateInRepl("(in-ns 'user)", null); //??replAppendText("REPL is disconnected.", null); } public void EvaluateInRepl(String exp, String nsNode) { try { if(nsNode != null) { this._evaluateInReplFn.invoke(this._replID, exp, nsNode); } else { this._evaluateInReplFn.invoke(this._replID, exp); } } catch (Exception ex) { Logger.getLogger(ReplPanel.class.getName()).log(Level.SEVERE, null, ex); } } //@Override //public String getUIClassID() { return "ReplEditorPaneUI";} /** This method is called from within the constructor to * initialize the form. * WARNING: Do NOT modify this code. The content of this method is * always regenerated by the Form Editor. */ @SuppressWarnings("unchecked") // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents private void initComponents() { jToolBar1 = new javax.swing.JToolBar(); jTabbedPane1 = new javax.swing.JTabbedPane(); jScrollPaneRepl = new javax.swing.JScrollPane(); jScrollPaneErr = new javax.swing.JScrollPane(); _replErrorPane = new javax.swing.JEditorPane(); jScrollPaneOut = new javax.swing.JScrollPane(); jEditorPaneOut = new javax.swing.JEditorPane(); replTooBar = new javax.swing.JToolBar(); prettyPrintToggleButton = new javax.swing.JToggleButton(); printStackTraceToggleButton = new javax.swing.JToggleButton(); printStackTraceButton = new javax.swing.JButton(); replHistoryButton = new javax.swing.JButton(); clearReplHistoryButton = new javax.swing.JButton(); replStartupSettingsButton = new javax.swing.JButton(); replResetButton = new javax.swing.JButton(); jToolBar1.setRollover(true); jTabbedPane1.setTabPlacement(javax.swing.JTabbedPane.BOTTOM); jTabbedPane1.addTab("Repl", jScrollPaneRepl); jScrollPaneErr.setViewportView(_replErrorPane); jTabbedPane1.addTab("*err*", jScrollPaneErr); jScrollPaneOut.setViewportView(jEditorPaneOut); jTabbedPane1.addTab("*out*", jScrollPaneOut); replTooBar.setFloatable(false); replTooBar.setOrientation(1); replTooBar.setRollover(true); prettyPrintToggleButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/enclojure/ide/resources/toggle_pprint.png"))); // NOI18N prettyPrintToggleButton.setSelected(true); prettyPrintToggleButton.setToolTipText("Toggle Pretty Print"); prettyPrintToggleButton.setFocusable(false); prettyPrintToggleButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); prettyPrintToggleButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); prettyPrintToggleButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { prettyPrintToggleButtonActionPerformed(evt); } }); replTooBar.add(prettyPrintToggleButton); printStackTraceToggleButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/enclojure/ide/resources/toggle_print_stacktrace.png"))); // NOI18N printStackTraceToggleButton.setToolTipText("Toggle Print Stacktrace"); printStackTraceToggleButton.setFocusable(false); printStackTraceToggleButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); printStackTraceToggleButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); printStackTraceToggleButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { printStackTraceToggleButtonActionPerformed(evt); } }); replTooBar.add(printStackTraceToggleButton); printStackTraceButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/enclojure/ide/resources/print_last_stacktrace.png"))); // NOI18N printStackTraceButton.setToolTipText("Print stack trace of last error."); printStackTraceButton.setFocusable(false); printStackTraceButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); printStackTraceButton.setPreferredSize(new java.awt.Dimension(28, 28)); printStackTraceButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); printStackTraceButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { printStackTraceButtonActionPerformed(evt); } }); replTooBar.add(printStackTraceButton); replHistoryButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/enclojure/ide/resources/repl_history.png"))); // NOI18N replHistoryButton.setToolTipText("Show Repl History"); replHistoryButton.setFocusable(false); replHistoryButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); replHistoryButton.setPreferredSize(new java.awt.Dimension(28, 28)); replHistoryButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); replHistoryButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { replHistoryButtonActionPerformed(evt); } }); replTooBar.add(replHistoryButton); clearReplHistoryButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/enclojure/ide/resources/clear_repl_history.png"))); // NOI18N clearReplHistoryButton.setToolTipText("Clear Repl History"); clearReplHistoryButton.setFocusable(false); clearReplHistoryButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); clearReplHistoryButton.setPreferredSize(new java.awt.Dimension(28, 28)); clearReplHistoryButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); clearReplHistoryButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { clearReplHistoryButtonActionPerformed(evt); } }); replTooBar.add(clearReplHistoryButton); replStartupSettingsButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/enclojure/ide/resources/metadata.png"))); // NOI18N replStartupSettingsButton.setToolTipText("Show Repl Startup Settings"); replStartupSettingsButton.setFocusable(false); replStartupSettingsButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); replStartupSettingsButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); replStartupSettingsButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { replStartupSettingsButtonActionPerformed(evt); } }); replTooBar.add(replStartupSettingsButton); replResetButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/enclojure/ide/resources/reset_repl.png"))); // NOI18N replResetButton.setToolTipText("Reset REPL"); replResetButton.setFocusable(false); replResetButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); replResetButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); replResetButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { replResetButtonActionPerformed(evt); } }); replTooBar.add(replResetButton); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addComponent(replTooBar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jTabbedPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 524, Short.MAX_VALUE)) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jTabbedPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 177, Short.MAX_VALUE) .addComponent(replTooBar, javax.swing.GroupLayout.DEFAULT_SIZE, 177, Short.MAX_VALUE) ); }// </editor-fold>//GEN-END:initComponents private void prettyPrintToggleButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_prettyPrintToggleButtonActionPerformed try { _togglePrettyPrintFunc.invoke(this._replID, this, this.prettyPrintToggleButton.isSelected()); } catch (Exception ex) { Logger.getLogger(ReplPanel.class.getName()).log(Level.SEVERE, null, ex); } }//GEN-LAST:event_prettyPrintToggleButtonActionPerformed private void printStackTraceToggleButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_printStackTraceToggleButtonActionPerformed try { _toggleStackTraceFunc.invoke(this._replID, this, this.printStackTraceToggleButton.isSelected()); } catch (Exception ex) { Logger.getLogger(ReplPanel.class.getName()).log(Level.SEVERE, null, ex); } }//GEN-LAST:event_printStackTraceToggleButtonActionPerformed private void replResetButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_replResetButtonActionPerformed this.ResetRepl(); }//GEN-LAST:event_replResetButtonActionPerformed private void replStartupSettingsButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_replStartupSettingsButtonActionPerformed showReplInfoMenuActionPerformed(evt); }//GEN-LAST:event_replStartupSettingsButtonActionPerformed private void printStackTraceButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_printStackTraceButtonActionPerformed printStackTrace(); }//GEN-LAST:event_printStackTraceButtonActionPerformed private void replHistoryButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_replHistoryButtonActionPerformed showReplHistoryActionPerformed(evt); }//GEN-LAST:event_replHistoryButtonActionPerformed private void clearReplHistoryButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_clearReplHistoryButtonActionPerformed clearReplHistoryActionPerformed(evt); }//GEN-LAST:event_clearReplHistoryButtonActionPerformed // Variables declaration - do not modify//GEN-BEGIN:variables public javax.swing.JEditorPane _replErrorPane; public javax.swing.JButton clearReplHistoryButton; public javax.swing.JEditorPane jEditorPaneOut; public javax.swing.JScrollPane jScrollPaneErr; public javax.swing.JScrollPane jScrollPaneOut; public javax.swing.JScrollPane jScrollPaneRepl; public javax.swing.JTabbedPane jTabbedPane1; public javax.swing.JToolBar jToolBar1; public javax.swing.JToggleButton prettyPrintToggleButton; public javax.swing.JButton printStackTraceButton; public javax.swing.JToggleButton printStackTraceToggleButton; public javax.swing.JButton replHistoryButton; public javax.swing.JButton replResetButton; public javax.swing.JButton replStartupSettingsButton; public javax.swing.JToolBar replTooBar; // End of variables declaration//GEN-END:variables }