Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Comparing changes

Choose two branches to see what's changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
base fork: technomancy/swank-clojure
...
head fork: technomancy/swank-clojure
Checking mergeability… Don't worry, you can still create the pull request.
  • 9 commits
  • 10 files changed
  • 0 commit comments
  • 2 contributors
Commits on Mar 24, 2012
@tobias tobias Add function to cleanly shutdown a running swank server.
This adds (stop-server), which shuts down the threads and sockets
created by (start-server).
6317401
@tobias tobias Add option to disable calling System/exit on quit. 9507401
@technomancy Eliminate reflection.
Conflicts:

	src/swank/util/sys.clj
7c46f64
@technomancy Release 1.4.1. 1357fe8
Commits on Mar 25, 2012
@tobias tobias Restore java.io imports in sys.clj
This breaks swank-clojure 1.4.1.
0089cde
@technomancy Merge pull request #117 from tobias/sys-imports
Restore java.io imports in sys.clj
6cd7a39
@technomancy Release 1.4.2. ed5c8ba
Commits on Nov 29, 2012
@tobias tobias Make swank-clojure work under clojure 1.5.0.
The constructor for clojure.lang.Compiler$CompilerException takes an
additional column argument under 1.5.0. This patch handles the
different arities, and always sets the column to 0 under 1.5.0.
0a0640c
@tobias tobias Release 1.4.3. bc545af
View
4 README.md
@@ -12,7 +12,7 @@ using [Leiningen](http://github.com/technomancy/leiningen):
* Install `clojure-mode` either from
[Marmalade](http://marmalade-repo.org) or from
[git](http://github.com/technomancy/clojure-mode).
-* `lein plugin install swank-clojure 1.4.0`
+* `lein plugin install swank-clojure 1.4.2`
* From an Emacs buffer inside a project, invoke `M-x clojure-jack-in`
That's all it takes; there are no extra install steps beyond
@@ -58,7 +58,7 @@ If you just want a standalone swank server with no third-party
libraries, you can use the shell wrapper that Leiningen installs for
you:
- $ lein plugin install swank-clojure 1.4.0
+ $ lein plugin install swank-clojure 1.4.2
$ ~/.lein/bin/swank-clojure
M-x slime-connect
View
2  project.clj
@@ -1,4 +1,4 @@
-(defproject swank-clojure "1.4.0"
+(defproject swank-clojure "1.4.3"
:description "Swank server connecting Clojure to Emacs SLIME"
:url "http://github.com/technomancy/swank-clojure"
:dependencies [[org.clojure/clojure "1.2.1"]
View
14 src/swank/commands/basic.clj
@@ -30,7 +30,8 @@
:version ~(deref protocol-version)))
(defslimefn quit-lisp []
- (System/exit 0))
+ (and @exit-on-quit?
+ (System/exit 0)))
(defslimefn toggle-debug-on-swank-error []
(alter-var-root #'swank.core/debug-swank-clojure not))
@@ -110,7 +111,7 @@
;;;; Compiler / Execution
-(def compiler-exception-location-re #"Exception:.*\(([^:]+):([0-9]+)\)")
+(def compiler-exception-location-re #"Exception:.*\(([^:]+):([0-9]+)(:[0-9]+)?\)")
(defn- guess-compiler-exception-location [#^Throwable t]
(when (instance? clojure.lang.Compiler$CompilerException t)
(let [[match file line] (re-find compiler-exception-location-re (str t))]
@@ -174,12 +175,19 @@
(.getLineNumber f))
(catch Exception e 1)))
+(defmacro compiler-exception [directory line ex]
+ `(eval (if (>= (:minor *clojure-version*) 5)
+ '(clojure.lang.Compiler$CompilerException.
+ ~directory ~line 0 ~ex)
+ '(clojure.lang.Compiler$CompilerException.
+ ~directory ~line ~ex))))
+
(defslimefn compile-string-for-emacs [string buffer position directory debug]
(let [start (System/nanoTime)
line (line-at-position directory position)
ret (with-emacs-package
(when-not (= (name (ns-name *ns*)) *current-package*)
- (throw (clojure.lang.Compiler$CompilerException.
+ (throw (compiler-exception
directory line
(Exception. (str "No such namespace: "
*current-package*)))))
View
2  src/swank/core.clj
@@ -21,6 +21,8 @@
(def color-support? (atom false))
+(def exit-on-quit? (atom true))
+
(def sldb-stepping-p nil)
(def sldb-initial-frames 10)
(def #^{:dynamic true} #^{:doc "The current level of recursive debugging."}
View
4 src/swank/core/cdt_utils.clj
@@ -90,8 +90,8 @@
(defn get-system-thread-groups [] @system-thread-groups)
(def system-thread-names
- #{#"^CDT Event Handler$" #"^Swank Control Thread$" #"^Read Loop Thread$"
- #"^Socket Server \[\d*\]$"})
+ #{#"^CDT Event Handler$" #"^Swank Control Thread$" #"^Swank Read Loop Thread$"
+ #"^Swank Socket Server \[\d*\]$"})
(defn system-thread? [t]
(some #(re-find % (.name t)) system-thread-names))
View
63 src/swank/swank.clj
@@ -1,5 +1,5 @@
(ns swank.swank
- (:use [swank.core]
+ (:use [swank core util]
[swank.core connection server]
[swank.util.concurrent thread]
[swank.util.net sockets]
@@ -12,6 +12,8 @@
[java.io File])
(:gen-class))
+(def current-server (atom nil))
+
(defn ignore-protocol-version [version]
(reset! protocol-version version))
@@ -22,21 +24,23 @@
(try
(control-loop conn)
(catch Exception e
- (.println System/err "exception in control loop")
- (.printStackTrace e)
+ (when-not @shutting-down?
+ (.println System/err "exception in control loop")
+ (.printStackTrace e))
nil))
(close-socket! (conn :socket)))
read
(dothread-swank
- (thread-set-name "Read Loop Thread")
+ (thread-set-name "Swank Read Loop Thread")
(try
(read-loop conn control)
(catch Exception e
;; This could be put somewhere better
- (.println System/err "exception in read loop")
- (.printStackTrace e)
- (.interrupt control)
- (dosync (alter connections (partial remove #{conn}))))))]
+ (when-not @shutting-down?
+ (.println System/err "exception in read loop")
+ (.printStackTrace e)
+ (.interrupt control)
+ (dosync (alter connections (partial remove #{conn})))))))]
(dosync
(ref-set (conn :control-thread) control)
(ref-set (conn :read-thread) read))))
@@ -52,17 +56,38 @@
"Start the server and write the listen port number to
PORT-FILE. This is the entry point for Emacs."
[& opts]
- (let [opts (apply hash-map opts)]
- (reset! color-support? (:colors? opts false))
- (when (:load-cdt-on-startup opts)
- (load-cdt-with-dynamic-classloader))
- (setup-server (get opts :port 0)
- simple-announce
- connection-serve
- opts)
- (when (:block opts)
- (doseq [#^Thread t (get-thread-list)]
- (.join t)))))
+ (if @current-server
+ (println System/err "Swank server already running")
+ (do
+ (reset! shutting-down? false)
+ (let [opts (apply hash-map opts)]
+ (reset! color-support? (:colors? opts false))
+ (reset! exit-on-quit? (:exit-on-quit opts true))
+ (when (:load-cdt-on-startup opts)
+ (load-cdt-with-dynamic-classloader))
+ (reset! current-server
+ (setup-server (get opts :port 0)
+ simple-announce
+ connection-serve
+ opts))
+ (when (:block opts)
+ (doseq [#^Thread t (get-thread-list)]
+ (.join t)))))))
+
+(defn stop-server
+ "Stop the currently running server, shutdown its threads, and release the port."
+ []
+ (if @current-server
+ (do
+ (reset! shutting-down? true)
+ (doseq [c @connections]
+ (doseq [t [:control-thread :read-thread :repl-thread]]
+ (when-let [^Thread thread @(c t)]
+ (.interrupt thread))))
+ (close-server-socket! @current-server)
+ (dosync (ref-set connections []))
+ (reset! current-server nil))
+ (println System/err "Swank server not running")))
(defn start-repl
"Start the server wrapped in a repl. Use this to embed swank in your code."
View
4 src/swank/util.clj
@@ -2,6 +2,8 @@
(:import (java.io StringReader)
(clojure.lang LineNumberingPushbackReader)))
+(def shutting-down? (atom false))
+
(defmacro one-of?
"Short circuiting value comparison."
([val & possible]
@@ -64,7 +66,7 @@
(apply ~f args#))))))
(defmacro continuously [& body]
- `(loop [] ~@body (recur)))
+ `(loop [] ~@body (when-not @shutting-down? (recur))))
(defmacro failing-gracefully [& body]
`(try
View
8 src/swank/util/net/sockets.clj
@@ -36,10 +36,14 @@
server to close."
([server-socket handle-socket]
(dothread-keeping-clj nil
- (thread-set-name (str "Socket Server [" (thread-id) "]"))
+ (thread-set-name (str "Swank Socket Server [" (thread-id) "]"))
(with-open [#^ServerSocket server server-socket]
(while (not (.isClosed server))
- (handle-socket (.accept server)))))))
+ (try
+ (handle-socket (.accept server))
+ (catch SocketException e
+ (when-not @shutting-down?
+ (throw e)))))))))
(defn close-socket!
"Cleanly shutdown and close a java.net.Socket. This will not affect
View
25 src/swank/util/sys.clj
@@ -1,4 +1,5 @@
-(ns swank.util.sys)
+(ns swank.util.sys
+ (:import (java.io BufferedReader InputStreamReader)))
(defn get-pid
"Returns the PID of the JVM. This is largely a hack and may or may
@@ -9,5 +10,27 @@
(System/getProperty "pid")))
{:tag String})
+(defn #^java.lang.Process cmd [p]
+ (.. Runtime getRuntime (exec (str p))))
+
+(defn cmdout [^Process o]
+ (let [r (BufferedReader.
+ (InputStreamReader. (.getInputStream o)))]
+ (line-seq r)))
+
+;; would prefer (= (System/getenv "OSTYPE") "cygwin")
+;; but clojure's java not in cygwin env
+(defn is-cygwin? []
+ (not= nil (try (cmdout (cmd "cygpath c:\\")) (catch Exception e))))
+
+(defn universal-path [path]
+ (if (is-cygwin?)
+ (first (cmdout (cmd (str "cygpath " path))))
+ path))
+
+(defn preferred-user-home-path []
+ (or (System/getenv "HOME")
+ (System/getProperty "user.home")))
+
(defn user-home-path []
(System/getProperty "user.home"))
View
4 test/swank/test_swank/commands/basic.clj
@@ -22,9 +22,9 @@ list, Alan Dipert and MeikelBrandmeyer."
(deftest guess-compiler-exception-location-test
(is (= '(:location (:file "a.clj") (:line 1) nil)
(guess-compiler-exception-location
- (clojure.lang.Compiler$CompilerException. "a.clj" 1 (Exception. "err"))))))
+ (compiler-exception "a.clj" 1 (Exception. "err"))))))
(deftest exception-location-test
(is (= '(:location (:file "a.clj") (:line 1) nil)
(exception-location
- (clojure.lang.Compiler$CompilerException. "a.clj" 1 (Exception. "err")))))))
+ (compiler-exception "a.clj" 1 (Exception. "err")))))))

No commit comments for this range

Something went wrong with that request. Please try again.