diff --git a/org-enclojure-repl-client/src/main/clojure/org/enclojure/ide/repl/repl_panel.clj b/org-enclojure-repl-client/src/main/clojure/org/enclojure/ide/repl/repl_panel.clj index 87f9c6c..57d1dd1 100755 --- a/org-enclojure-repl-client/src/main/clojure/org/enclojure/ide/repl/repl_panel.clj +++ b/org-enclojure-repl-client/src/main/clojure/org/enclojure/ide/repl/repl_panel.clj @@ -204,6 +204,8 @@ (.setSelected (.printStackTraceToggleButton repl-pane) bv) (.setSelected (.stackTraceOnErrorMenu repl-pane) bv))) +(defn interrupt-repl [repl-id] + ((:repl-fn (org.enclojure.ide.repl.repl-manager/get-repl-config repl-id)) ":INTERRUPT")) (defn check-repl-form? ([expr repl-id] diff --git a/org-enclojure-repl-client/src/main/java/org/enclojure/ide/repl/ReplPanel.form b/org-enclojure-repl-client/src/main/java/org/enclojure/ide/repl/ReplPanel.form index 09bf82e..6023ba2 100755 --- a/org-enclojure-repl-client/src/main/java/org/enclojure/ide/repl/ReplPanel.form +++ b/org-enclojure-repl-client/src/main/java/org/enclojure/ide/repl/ReplPanel.form @@ -28,14 +28,14 @@ - + - - + + @@ -207,6 +207,21 @@ + + + + + + + + + + + + + + + diff --git a/org-enclojure-repl-client/src/main/java/org/enclojure/ide/repl/ReplPanel.java b/org-enclojure-repl-client/src/main/java/org/enclojure/ide/repl/ReplPanel.java index 28d6ce0..feaac1e 100755 --- a/org-enclojure-repl-client/src/main/java/org/enclojure/ide/repl/ReplPanel.java +++ b/org-enclojure-repl-client/src/main/java/org/enclojure/ide/repl/ReplPanel.java @@ -45,6 +45,7 @@ */ public class ReplPanel extends javax.swing.JPanel { public int _promptPos = 0; + volatile IFn _interruptReplFn = (IFn)RT.var("org.enclojure.ide.repl.repl-panel", "interrupt-repl"); 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"); @@ -387,6 +388,7 @@ private void initComponents() { clearReplHistoryButton = new javax.swing.JButton(); replStartupSettingsButton = new javax.swing.JButton(); replResetButton = new javax.swing.JButton(); + replInterruptButton = new javax.swing.JButton(); jToolBar1.setRollover(true); @@ -493,6 +495,19 @@ public void actionPerformed(java.awt.event.ActionEvent evt) { }); replTooBar.add(replResetButton); + replInterruptButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/enclojure/ide/resources/interrupt.png"))); // NOI18N + replInterruptButton.setToolTipText("Interrupt Processing"); + replInterruptButton.setFocusable(false); + replInterruptButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); + replInterruptButton.setLabel(""); + replInterruptButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); + replInterruptButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + replInterruptButtonActionPerformed(evt); + } + }); + replTooBar.add(replInterruptButton); + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); layout.setHorizontalGroup( @@ -500,12 +515,12 @@ public void actionPerformed(java.awt.event.ActionEvent evt) { .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)) + .addComponent(jTabbedPane1)) ); 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) + .addComponent(jTabbedPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 219, Short.MAX_VALUE) + .addComponent(replTooBar, javax.swing.GroupLayout.DEFAULT_SIZE, 219, Short.MAX_VALUE) ); }// //GEN-END:initComponents @@ -545,6 +560,17 @@ private void clearReplHistoryButtonActionPerformed(java.awt.event.ActionEvent ev clearReplHistoryActionPerformed(evt); }//GEN-LAST:event_clearReplHistoryButtonActionPerformed + private void replInterruptButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_replInterruptButtonActionPerformed + try + { + _interruptReplFn.invoke(this._replID); + } + catch (Exception ex) + { + Logger.getLogger(ReplPanel.class.getName()).log(Level.SEVERE, null, ex); + } + }//GEN-LAST:event_replInterruptButtonActionPerformed + // Variables declaration - do not modify//GEN-BEGIN:variables public javax.swing.JEditorPane _replErrorPane; @@ -559,6 +585,7 @@ private void clearReplHistoryButtonActionPerformed(java.awt.event.ActionEvent ev public javax.swing.JButton printStackTraceButton; public javax.swing.JToggleButton printStackTraceToggleButton; public javax.swing.JButton replHistoryButton; + public javax.swing.JButton replInterruptButton; public javax.swing.JButton replResetButton; public javax.swing.JButton replStartupSettingsButton; public javax.swing.JToolBar replTooBar; diff --git a/org-enclojure-repl-client/src/main/resources/org/enclojure/ide/resources/interrupt.png b/org-enclojure-repl-client/src/main/resources/org/enclojure/ide/resources/interrupt.png new file mode 100644 index 0000000..f8a5153 Binary files /dev/null and b/org-enclojure-repl-client/src/main/resources/org/enclojure/ide/resources/interrupt.png differ diff --git a/org-enclojure-repl-server/src/main/clojure/org/enclojure/repl/main.clj b/org-enclojure-repl-server/src/main/clojure/org/enclojure/repl/main.clj index cfcbe2c..68bb918 100755 --- a/org-enclojure-repl-server/src/main/clojure/org/enclojure/repl/main.clj +++ b/org-enclojure-repl-server/src/main/clojure/org/enclojure/repl/main.clj @@ -40,7 +40,8 @@ (:refer-clojure :exclude (with-bindings)) (:use clojure.contrib.pprint) (:require [clojure.contrib.pprint :as pprint] - [clojure.main :exclude (with-binding)]) + [clojure.main :exclude (with-binding)] + [clojure.contrib.repl-utils :as repl-utils]) (:import (java.net Socket ServerSocket) (java.util.logging Level Logger) (java.io InputStreamReader DataOutputStream DataInputStream @@ -128,6 +129,7 @@ *out* piped-out *err* (PrintWriter. *out*)] (try + (repl-utils/add-break-thread!) (clojure.main/repl :init (fn [] (in-ns 'user)) :read (fn [prompt exit] @@ -153,13 +155,11 @@ (catch java.nio.channels.ClosedByInterruptException ex)))] (.start (Thread. repl-thread-fn)) {:repl-fn (fn [cmd] - (if (= cmd ":CLOSE-REPL") - (do - (.close cmd-wtr) - (.close result-rdr)) - (do - (.write cmd-wtr cmd) - (.flush cmd-wtr)))) + (cond + (= cmd ":INTERRUPT") (sun.misc.Signal/raise (sun.misc.Signal. "INT")) + (= cmd ":CLOSE-REPL") (do (.close cmd-wtr) (.close result-rdr)) + :else (do (.write cmd-wtr cmd) (.flush cmd-wtr)))) + ;//??Using CharArrayWriter to build the string from each read of one byte ;Once there is nothing to read than this function returns the string read. ;Using partial so that CharArrayWriter is only created once and reused.