clojure-emacs / cider Goto Github PK
View Code? Open in Web Editor NEWThe Clojure Interactive Development Environment that Rocks for Emacs
Home Page: https://cider.mx
License: GNU General Public License v3.0
The Clojure Interactive Development Environment that Rocks for Emacs
Home Page: https://cider.mx
License: GNU General Public License v3.0
Add support for "need-input" messages from nrepl.
Reported on clojure-tools by Stuart Sierra.
Anybody else seeing this error (below) in an nREPL Emacs session? It starts
showing up after working in nREPL for a while. It's something to do with
auto-completion I think, because once it happens it repeats every time I
switch to the nrepl buffer. Only fix is restarting the Java process.
-S
clojure.lang.Compiler$CompilerException: java.lang.RuntimeException: Unable
to resolve symbol: if-let in this context, compiling:(NO_SOURCE_PATH:1)
at clojure.lang.Compiler.analyze (Compiler.java:6281)
clojure.lang.Compiler.analyze (Compiler.java:6223)
clojure.lang.Compiler$InvokeExpr.parse (Compiler.java:3497)
clojure.lang.Compiler.analyzeSeq (Compiler.java:6457)
clojure.lang.Compiler.analyze (Compiler.java:6262)
clojure.lang.Compiler.analyze (Compiler.java:6223)
clojure.lang.Compiler$BodyExpr$Parser.parse (Compiler.java:5618)
clojure.lang.Compiler$FnMethod.parse (Compiler.java:5054)
clojure.lang.Compiler$FnExpr.parse (Compiler.java:3674)
clojure.lang.Compiler.analyzeSeq (Compiler.java:6453)
clojure.lang.Compiler.analyze (Compiler.java:6262)
clojure.lang.Compiler.eval (Compiler.java:6508)
clojure.lang.Compiler.eval (Compiler.java:6477)
clojure.core$eval.invoke (core.clj:2797)
clojure.main$repl$read_eval_print__6405.invoke (main.clj:245)
clojure.main$repl$fn__6410.invoke (main.clj:266)
clojure.main$repl.doInvoke (main.clj:266)
clojure.lang.RestFn.invoke (RestFn.java:1096)
clojure.tools.nrepl.middleware.interruptible_eval$evaluate$fn__768.invoke
(interruptible_eval.clj:57)
clojure.lang.AFn.applyToHelper (AFn.java:159)
clojure.lang.AFn.applyTo (AFn.java:151)
clojure.core$apply.invoke (core.clj:601)
clojure.core$with_bindings_STAR_.doInvoke (core.clj:1771)
clojure.lang.RestFn.invoke (RestFn.java:425)
clojure.tools.nrepl.middleware.interruptible_eval$evaluate.invoke
(interruptible_eval.clj:42)
clojure.tools.nrepl.middleware.interruptible_eval$interruptible_eval$fn__809$fn__811.invoke
(interruptible_eval.clj:170)
clojure.core$comp$fn__4034.invoke (core.clj:2278)
clojure.tools.nrepl.middleware.interruptible_eval$run_next$fn__802.invoke
(interruptible_eval.clj:137)
clojure.lang.AFn.run (AFn.java:24)
java.util.concurrent.ThreadPoolExecutor$Worker.runTask
(ThreadPoolExecutor.java:886)
java.util.concurrent.ThreadPoolExecutor$Worker.run
(ThreadPoolExecutor.java:908)
java.lang.Thread.run (Thread.java:680)
Details:
Entire thread is here:
https://groups.google.com/forum/?fromgroups=#!topic/clojure-tools/RigTCB6_Ako
Currently, running M-x nrepl
multiple times opens multiple REPL buffers, but all commands use only the buffer named *nrepl*
.
nrepl.el should support working with multiple REPLs, like slime does. A simple function for switching between them should be enough.
I was using nrepl.el in the clojail project and tried to evaluate one of the testers and got this:
error in process filter: let: Wrong type argument: integer-or-marker-p, nil
error in process filter: Wrong type argument: integer-or-marker-p, nil
error in process filter: cond: Cannot decode object: 1
error in process filter: Cannot decode object: 1
To reproduce, nrepl-jack-in
to the clojail project, load clojail.testers
, and then try to evaluate secure-tester
. This prints fine in SLIME, but not in nrepl.el.
Excellent work on this btw. You're my new best friend.
I have a branch for this in my fork, but it's pretty preliminary. It does do full reloading though, which clears out the contents of the current namespace and forces all required namespaces to be reloaded, albeit by a bit of a hack.
clojure-mode
has a workaround to add paredit bindings for {
and }
when paredit is enabled, but since we have our own major mode now they don't apply any more.
Slime's tracing functionality is invaluable. Supposedly clojure.tools.trace
implements something similar; perhaps we can use that.
nREPL uses bencode by default but can also be made to work over other protocols like HTTP: https://github.com/cemerick/drawbridge/
If you wait for the display of arglists (via eldoc) your magic REPL variables get corrupted:
user> (+ 4 5) ;; wait for eldoc
9
user> *2
([] [x] [x y] [x y & more])
versus
;; type fast
(+ 1 1)
2
user> (+ 4 5)
9
user> *2
2
Don't know whether this is nrepl.el-specific.
@metajack reported this against #81. I am not sure if/now we can support this, but I am creating this issue to track it separately.
From #81:
Say you launch a thread that outputs to stdout. In slime/swank, this output appears in the swank buffer instead of the slime repl buffer. Only output from the current thread in the repl appears in the repl buffer by default. You can override this by doing alter-var-root!, but it's quite annoying, and you see people asking where their output went occasionally.
This is also the current behavior in nrepl as well, which you can see by running:
(.start (Thread. #(println "foo")))
This will print only in the nrepl-server buffer.
Hi,
after nrepl-jack-in (or connecting to an already running "lein repl"), without loading the current namespace (e.g. "testproject.core) I get an NPE when trying to complete a symbol. In this case I tried to complete "bindi" which should yield "binnding".
user=> Exception in thread "nREPL-worker-1" java.lang.NullPointerException
at clojure.core$refer.doInvoke(core.clj:3779)
at clojure.lang.RestFn.applyTo(RestFn.java:139)
at clojure.core$apply.invoke(core.clj:603)
at clojure.core$load_lib.doInvoke(core.clj:5279)
at clojure.lang.RestFn.applyTo(RestFn.java:142)
at clojure.core$apply.invoke(core.clj:603)
at clojure.core$load_libs.doInvoke(core.clj:5298)
at clojure.lang.RestFn.applyTo(RestFn.java:137)
at clojure.core$apply.invoke(core.clj:605)
at clojure.core$use.doInvoke(core.clj:5392)
at clojure.lang.RestFn.invoke(RestFn.java:408)
at clojure.main$repl.doInvoke(main.clj:259)
at clojure.lang.RestFn.invoke(RestFn.java:1096)
at clojure.tools.nrepl.middleware.interruptible_eval$evaluate$fn__1311.invoke(interruptible_eval.clj:51)
at clojure.lang.AFn.applyToHelper(AFn.java:159)
at clojure.lang.AFn.applyTo(AFn.java:151)
at clojure.core$apply.invoke(core.clj:601)
at clojure.core$with_bindings_STAR_.doInvoke(core.clj:1771)
at clojure.lang.RestFn.invoke(RestFn.java:425)
at clojure.tools.nrepl.middleware.interruptible_eval$evaluate.invoke(interruptible_eval.clj:36)
at clojure.tools.nrepl.middleware.interruptible_eval$interruptible_eval$fn__1348$fn__1350.invoke(interruptible_eval.clj:162)
at clojure.core$comp$fn__4034.invoke(core.clj:2278)
at clojure.tools.nrepl.middleware.interruptible_eval$run_next$fn__1341.invoke(interruptible_eval.clj:129)
at clojure.lang.AFn.run(AFn.java:24)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:722)
After compilation of the file (C-c C-k), everything works fine.
Regards,
Stefan
When opening an nrepl session it is convenient to have the history of previous REPL sessions.
Suggestions:
This mimics most of the things I wrote for the persistent history of SLIME ages ago :-)
Open questions:
Currently, nrepl-eval-last-expresson swallows output from evaluation. This makes it impossible to use the *nrepl*
buffer to monitor desired standard output. Following the thread linked below, it would be best to send the output to the *nrepl*
buffer, with options to hide it
https://groups.google.com/forum/#!topic/nrepl-el/3GDsRkX1IDE
This is on "GNU Emacs 24.1.1 (i686-pc-linux-gnu, GTK+ Version 2.24.10)\n of 2012-07-25 on localhost"
Using Leiningen 2.0.0-preview7 on Java 1.6.0_22 Java HotSpot(TM) Client VM
I start the repl with this:
lein2 trampoline repl :headless
I start nrepl.el with M-x nrepl RET 7777 RET.
I type this in the repl:
(cp)
Which is a little utility that is this:
(defn cp []
(clojure.string/split (System/getProperty "java.class.path") #":"))
And I get this stacktrace from emacs:
Debugger entered--Lisp error: (wrong-type-argument integer-or-marker-p nil)
goto-char(nil)
(let ((start (point)) (end (byte-to-position (+ (position-bytes (point)) (string-to-number (match-string 1)))))) (goto-char end) (buffer-substring-no-properties start end))
(cond ((looking-at "i\\([0-9]+\\)e") (goto-char (match-end 0)) (string-to-number (match-string 1))) ((looking-at "\\([0-9]+\\):") (goto-char (match-end 0)) (let ((start (point)) (end (byte-to-position (+ (position-bytes ...) (string-to-number ...))))) (goto-char end) (buffer-substring-no-properties start end))) ((looking-at "l") (goto-char (match-end 0)) (let (result item) (while (setq item (nrepl-bdecode-buffer)) (setq result (cons item result))) (nreverse result))) ((looking-at "d") (goto-char (match-end 0)) (let (dict key item) (while (setq item (nrepl-bdecode-buffer)) (if key (setq dict (cons (cons key item) dict) key nil) (unless (stringp item) (error "Dictionary keys have to be strings: %s" item)) (setq key item))) (cons (quote dict) (nreverse dict)))) ((looking-at "e") (goto-char (match-end 0)) nil) (t (error "Cannot decode object: %d" (point))))
nrepl-bdecode-buffer()
(setq item (nrepl-bdecode-buffer))
(while (setq item (nrepl-bdecode-buffer)) (if key (setq dict (cons (cons key item) dict) key nil) (unless (stringp item) (error "Dictionary keys have to be strings: %s" item)) (setq key item)))
(let (dict key item) (while (setq item (nrepl-bdecode-buffer)) (if key (setq dict (cons (cons key item) dict) key nil) (unless (stringp item) (error "Dictionary keys have to be strings: %s" item)) (setq key item))) (cons (quote dict) (nreverse dict)))
(cond ((looking-at "i\\([0-9]+\\)e") (goto-char (match-end 0)) (string-to-number (match-string 1))) ((looking-at "\\([0-9]+\\):") (goto-char (match-end 0)) (let ((start (point)) (end (byte-to-position (+ (position-bytes ...) (string-to-number ...))))) (goto-char end) (buffer-substring-no-properties start end))) ((looking-at "l") (goto-char (match-end 0)) (let (result item) (while (setq item (nrepl-bdecode-buffer)) (setq result (cons item result))) (nreverse result))) ((looking-at "d") (goto-char (match-end 0)) (let (dict key item) (while (setq item (nrepl-bdecode-buffer)) (if key (setq dict (cons (cons key item) dict) key nil) (unless (stringp item) (error "Dictionary keys have to be strings: %s" item)) (setq key item))) (cons (quote dict) (nreverse dict)))) ((looking-at "e") (goto-char (match-end 0)) nil) (t (error "Cannot decode object: %d" (point))))
nrepl-bdecode-buffer()
(cons (nrepl-bdecode-buffer) result)
(setq result (cons (nrepl-bdecode-buffer) result))
(while (not (eobp)) (setq result (cons (nrepl-bdecode-buffer) result)))
(let ((result (quote nil))) (while (not (eobp)) (setq result (cons (nrepl-bdecode-buffer) result))) (nreverse result))
(progn (save-excursion (insert str)) (let ((result (quote nil))) (while (not (eobp)) (setq result (cons (nrepl-bdecode-buffer) result))) (nreverse result)))
(unwind-protect (progn (save-excursion (insert str)) (let ((result (quote nil))) (while (not (eobp)) (setq result (cons (nrepl-bdecode-buffer) result))) (nreverse result))) (and (buffer-name temp-buffer) (kill-buffer temp-buffer)))
(save-current-buffer (set-buffer temp-buffer) (unwind-protect (progn (save-excursion (insert str)) (let ((result (quote nil))) (while (not (eobp)) (setq result (cons (nrepl-bdecode-buffer) result))) (nreverse result))) (and (buffer-name temp-buffer) (kill-buffer temp-buffer))))
(with-current-buffer temp-buffer (unwind-protect (progn (save-excursion (insert str)) (let ((result (quote nil))) (while (not (eobp)) (setq result (cons (nrepl-bdecode-buffer) result))) (nreverse result))) (and (buffer-name temp-buffer) (kill-buffer temp-buffer))))
(let ((temp-buffer (generate-new-buffer " *temp*"))) (with-current-buffer temp-buffer (unwind-protect (progn (save-excursion (insert str)) (let ((result (quote nil))) (while (not (eobp)) (setq result (cons ... result))) (nreverse result))) (and (buffer-name temp-buffer) (kill-buffer temp-buffer)))))
(with-temp-buffer (save-excursion (insert str)) (let ((result (quote nil))) (while (not (eobp)) (setq result (cons (nrepl-bdecode-buffer) result))) (nreverse result)))
nrepl-decode("d2:id1:22:ns4:user7:session36:e7b89943-dd3f-4b31-92d0-b13860cbe93b5:value4275:[\"/home/localkens/clojure/src/test-cljs3/test\" \"/home/localkens/clojure/src/test-cljs3/src\" \"/home/localkens/clojure/src/test-cljs3/dev-resources\" \"/home/localkens/clojure/src/test-cljs3/resources\" \"/home/localkens/clojure/src/test-cljs3/target/classes\" \"/home/lken/.m2/repository/org/clojure/java.classpath/0.1.0/java.classpath-0.1.0.jar\" \"/home/lken/.m2/repository/clj-stacktrace/clj-stacktrace/0.2.4/clj-stacktrace-0.2.4.jar\" \"/home/lken/.m2/repository/ring/ring/1.1.0/ring-1.1.0.jar\" \"/home/lken/.m2/repository/org/mindrot/jbcrypt/0.3m/jbcrypt-0.3m.jar\" \"/home/lken/.m2/repository/ns-tracker/ns-tracker/0.1.1/ns-tracker-0.1.1.jar\" \"/home/lken/.m2/repository/javax/servlet/servlet-api/2.5/servlet-api-2.5.jar\" \"/home/lken/.m2/repository/org/eclipse/jetty/orbit/javax.servlet/2.5.0.v201103041518/javax.servlet-2.5.0.v201103041518.jar\" \"/home/lken/.m2/repository/com/fasterxml/jackson/dataformat/jackson-dataformat-smile/2.0.0/jackson-dataformat-smile-2.0.0.jar\" \"/home/lken/.m2/repository/org/clojure/data.json/0.1.2/data.json-0.1.2.jar\" \"/home/lken/.m2/repository/ring/ring-devel/1.1.0/ring-devel-1.1.0.jar\" \"/home/lken/.m2/repository/com/fasterxml/jackson/core/jackson-core/2.0.0/jackson-core-2.0.0.jar\" \"/home/lken/.m2/repository/org/clojure/tools.nrepl/0.2.0-beta7/tools.nrepl-0.2.0-beta7.jar\" \"/home/lken/.m2/repository/clout/clout/1.0.1/clout-1.0.1.jar\" \"/home/lken/.m2/repository/org/clojure/clojure-contrib/1.2.0/clojure-contrib-1.2.0.jar\" \"/home/lken/.m2/repository/org/clojure/core.incubator/0.1.0/core.incubator-0.1.0.jar\" \"/home/lken/.m2/repository/org/apache/httpcomponents/httpclient/4.1.2/httpclient-4.1.2.jar\" \"/home/lken/.m2/repository/ring/ring-core/1.1.0/ring-core-1.1.0.jar\" \"/home/lken/.m2/repository/clj-http/clj-http/0.3.5/clj-http-0.3.5.jar\" \"/home/lken/.m2/repository/commons-logging/commons-logging/1.1.1/commons-logging-1.1.1.jar\" \"/home/lken/.m2/repository/noir/noir/1.3.0-beta8/noir-1.3.0-beta8.jar\" \"/home/lken/.m2/repository/org/apache/httpcomponents/httpcore/4.1.2/httpcore-4.1.2.jar\" \"/home/lken/.m2/repository/cheshire/cheshire/3.1.0/cheshire-3.1.0.jar\" \"/home/lken/.m2/repository/ring/ring-jetty-adapter/1.1.0/ring-jetty-adapter-1.1.0.jar\" \"/home/lken/.m2/repository/org/clojure/tools.logging/0.1.2/tools.logging-0.1.2.jar\" \"/home/lken/.m2/repository/commons-io/commons-io/2.1/commons-io-2.1.jar\" \"/home/lken/.m2/repository/org/clojure/tools.macro/0.1.1/tools.macro-0.1.1.jar\" \"/home/lken/.m2/repository/slingshot/slingshot/0.10.2/slingshot-0.10.2.jar\" \"/home/lken/.m2/repository/clj-time/clj-time/0.3.7/clj-time-0.3.7.jar\" \"/home/lken/.m2/repository/hiccup/hiccup/1.0.0/hiccup-1.0.0.jar\" \"/home/lken/.m2/repository/org/clojure/clojure/1.4.0/clojure-1.4.0.jar\" \"/home/lken/.m2/repository/clojure-complete/clojure-complete/0.2.1/clojure-complete-0.2.1.jar\" \"/home/lken/.m2/repository/org/thnetos/cd-client/0.3.4/cd-client-0.3.4.jar\" \"/home/lken/.m2/repository/org/eclipse/jetty/jetty-http/7.6.1.v20120215/jetty-http-7.6.1.v20120215.jar\" \"/home/lken/.m2/repository/utilza/utilza/0.1.0-SNAPSHOT/utilza-0.1.0-SNAPSHOT.jar\" \"/home/lken/.m2/repository/compojure/compojure/1.0.4/compojure-1.0.4.jar\" \"/home/lken/.m2/repository/commons-codec/commons-codec/1.5/commons-codec-1.5.jar\" \"/home/lken/.m2/repository/org/eclipse/jetty/jetty-util/7.6.1.v20120215/jetty-util-7.6.1.v20120215.jar\" \"/home/lken/.m2/repository/bultitude/bultitude/0.1.5/bultitude-0.1.5.jar\" \"/home/lken/.m2/repository/joda-time/joda-time/2.0/joda-time-2.0.jar\" \"/home/lken/.m2/repository/org/eclipse/jetty/jetty-server/7.6.1.v20120215/jetty-server-7.6.1.v20120215.jar\" \"/home/lken/.m2/repository/org/clojure/tools.namespace/0.1.0/tools.namespace-0.1.0.jar\" \"/home/lken/.m2/repository/org/eclipse/jetty/jetty-io/7.6.1.v20120215/jetty-io-7.6.1.v20120215.jar\" \"/home/lken/.m2/repository/org/timmc/handy/1.2.0/handy-1.2.0.jar\" \"/home/lken/.m2/repository/ring/ring-servlet/1.1.0/ring-servlet-1.1.0.jar\" \"/home/lken/.m2/repository/org/apache/httpcomponents/httpmime/4.1.2/httpmime-4.1.2.jar\" \"/home/lken/.m2/repository/common")
(let ((responses (nrepl-decode string))) (dolist (response responses) (nrepl-dispatch response)))
nrepl-filter(#<process nrepl> "d2:id1:22:ns4:user7:session36:e7b89943-dd3f-4b31-92d0-b13860cbe93b5:value4275:[\"/home/localkens/clojure/src/test-cljs3/test\" \"/home/localkens/clojure/src/test-cljs3/src\" \"/home/localkens/clojure/src/test-cljs3/dev-resources\" \"/home/localkens/clojure/src/test-cljs3/resources\" \"/home/localkens/clojure/src/test-cljs3/target/classes\" \"/home/lken/.m2/repository/org/clojure/java.classpath/0.1.0/java.classpath-0.1.0.jar\" \"/home/lken/.m2/repository/clj-stacktrace/clj-stacktrace/0.2.4/clj-stacktrace-0.2.4.jar\" \"/home/lken/.m2/repository/ring/ring/1.1.0/ring-1.1.0.jar\" \"/home/lken/.m2/repository/org/mindrot/jbcrypt/0.3m/jbcrypt-0.3m.jar\" \"/home/lken/.m2/repository/ns-tracker/ns-tracker/0.1.1/ns-tracker-0.1.1.jar\" \"/home/lken/.m2/repository/javax/servlet/servlet-api/2.5/servlet-api-2.5.jar\" \"/home/lken/.m2/repository/org/eclipse/jetty/orbit/javax.servlet/2.5.0.v201103041518/javax.servlet-2.5.0.v201103041518.jar\" \"/home/lken/.m2/repository/com/fasterxml/jackson/dataformat/jackson-dataformat-smile/2.0.0/jackson-dataformat-smile-2.0.0.jar\" \"/home/lken/.m2/repository/org/clojure/data.json/0.1.2/data.json-0.1.2.jar\" \"/home/lken/.m2/repository/ring/ring-devel/1.1.0/ring-devel-1.1.0.jar\" \"/home/lken/.m2/repository/com/fasterxml/jackson/core/jackson-core/2.0.0/jackson-core-2.0.0.jar\" \"/home/lken/.m2/repository/org/clojure/tools.nrepl/0.2.0-beta7/tools.nrepl-0.2.0-beta7.jar\" \"/home/lken/.m2/repository/clout/clout/1.0.1/clout-1.0.1.jar\" \"/home/lken/.m2/repository/org/clojure/clojure-contrib/1.2.0/clojure-contrib-1.2.0.jar\" \"/home/lken/.m2/repository/org/clojure/core.incubator/0.1.0/core.incubator-0.1.0.jar\" \"/home/lken/.m2/repository/org/apache/httpcomponents/httpclient/4.1.2/httpclient-4.1.2.jar\" \"/home/lken/.m2/repository/ring/ring-core/1.1.0/ring-core-1.1.0.jar\" \"/home/lken/.m2/repository/clj-http/clj-http/0.3.5/clj-http-0.3.5.jar\" \"/home/lken/.m2/repository/commons-logging/commons-logging/1.1.1/commons-logging-1.1.1.jar\" \"/home/lken/.m2/repository/noir/noir/1.3.0-beta8/noir-1.3.0-beta8.jar\" \"/home/lken/.m2/repository/org/apache/httpcomponents/httpcore/4.1.2/httpcore-4.1.2.jar\" \"/home/lken/.m2/repository/cheshire/cheshire/3.1.0/cheshire-3.1.0.jar\" \"/home/lken/.m2/repository/ring/ring-jetty-adapter/1.1.0/ring-jetty-adapter-1.1.0.jar\" \"/home/lken/.m2/repository/org/clojure/tools.logging/0.1.2/tools.logging-0.1.2.jar\" \"/home/lken/.m2/repository/commons-io/commons-io/2.1/commons-io-2.1.jar\" \"/home/lken/.m2/repository/org/clojure/tools.macro/0.1.1/tools.macro-0.1.1.jar\" \"/home/lken/.m2/repository/slingshot/slingshot/0.10.2/slingshot-0.10.2.jar\" \"/home/lken/.m2/repository/clj-time/clj-time/0.3.7/clj-time-0.3.7.jar\" \"/home/lken/.m2/repository/hiccup/hiccup/1.0.0/hiccup-1.0.0.jar\" \"/home/lken/.m2/repository/org/clojure/clojure/1.4.0/clojure-1.4.0.jar\" \"/home/lken/.m2/repository/clojure-complete/clojure-complete/0.2.1/clojure-complete-0.2.1.jar\" \"/home/lken/.m2/repository/org/thnetos/cd-client/0.3.4/cd-client-0.3.4.jar\" \"/home/lken/.m2/repository/org/eclipse/jetty/jetty-http/7.6.1.v20120215/jetty-http-7.6.1.v20120215.jar\" \"/home/lken/.m2/repository/utilza/utilza/0.1.0-SNAPSHOT/utilza-0.1.0-SNAPSHOT.jar\" \"/home/lken/.m2/repository/compojure/compojure/1.0.4/compojure-1.0.4.jar\" \"/home/lken/.m2/repository/commons-codec/commons-codec/1.5/commons-codec-1.5.jar\" \"/home/lken/.m2/repository/org/eclipse/jetty/jetty-util/7.6.1.v20120215/jetty-util-7.6.1.v20120215.jar\" \"/home/lken/.m2/repository/bultitude/bultitude/0.1.5/bultitude-0.1.5.jar\" \"/home/lken/.m2/repository/joda-time/joda-time/2.0/joda-time-2.0.jar\" \"/home/lken/.m2/repository/org/eclipse/jetty/jetty-server/7.6.1.v20120215/jetty-server-7.6.1.v20120215.jar\" \"/home/lken/.m2/repository/org/clojure/tools.namespace/0.1.0/tools.namespace-0.1.0.jar\" \"/home/lken/.m2/repository/org/eclipse/jetty/jetty-io/7.6.1.v20120215/jetty-io-7.6.1.v20120215.jar\" \"/home/lken/.m2/repository/org/timmc/handy/1.2.0/handy-1.2.0.jar\" \"/home/lken/.m2/repository/ring/ring-servlet/1.1.0/ring-servlet-1.1.0.jar\" \"/home/lken/.m2/repository/org/apache/httpcomponents/httpmime/4.1.2/httpmime-4.1.2.jar\" \"/home/lken/.m2/repository/common")
recursive-edit()
debug(error (error "Register doesn't contain a buffer position or configuration"))
signal(error ("Register doesn't contain a buffer position or configuration"))
error("Register doesn't contain a buffer position or configuration")
jump-to-register(109 nil)
call-interactively(jump-to-register nil nil)
However, smaller data structures do not cause nrepl.el to puke. Only these large ones do.
A network trace of the actual on-the-wire interaction between nrepl.el and lein2 is this:
ed2:id1:22:ns4:user7:session36:e7b89943-dd3f-4b31-92d0-b13860cbe93b5:value4275:["/home/localkens/clojure/src/test-cljs3/test" "/home/localkens/clojure/src/test-cljs3/src" "/home/localkens/clojure/src/test-cljs3/dev-resources" "/home/localkens/clojure/src/test-cljs3/resources" "/home/localkens/clojure/src/test-cljs3/target/classes" "/home/lken/.m2/repository/org/clojure/java.classpath/0.1.0/java.classpath-0.1.0.jar" "/home/lken/.m2/repository/clj-stacktrace/clj-stacktrace/0.2.4/clj-stacktrace-0.2.4.jar" "/home/lken/.m2/repository/ring/ring/1.1.0/ring-1.1.0.jar" "/home/lken/.m2/repository/org/mindrot/jbcrypt/0.3m/jbcrypt-0.3m.jar" "/home/lken/.m2/repository/ns-tracker/ns-tracker/0.1.1/ns-tracker-0.1.1.jar" "/home/lken/.m2/repository/javax/servlet/servlet-api/2.5/servlet-api-2.5.jar" "/home/lken/.m2/repository/org/eclipse/jetty/orbit/javax.servlet/2.5.0.v201103041518/javax.servlet-2.5.0.v201103041518.jar" "/home/lken/.m2/repository/com/fasterxml/jackson/dataformat/jackson-dataformat-smile/2.0.0/jackson-dataformat-smile-2.0.0.jar" "/home/lken/.m2/repository/org/clojure/data.json/0.1.2/data.json-0.1.2.jar" "/home/lken/.m2/repository/ring/ring-devel/1.1.0/ring-devel-1.1.0.jar" "/home/lken/.m2/repository/com/fasterxml/jackson/core/jackson-core/2.0.0/jackson-core-2.0.0.jar" "/home/lken/.m2/repository/org/clojure/tools.nrepl/0.2.0-beta7/tools.nrepl-0.2.0-beta7.jar" "/home/lken/.m2/repository/clout/clout/1.0.1/clout-1.0.1.jar" "/home/lken/.m2/repository/org/clojure/clojure-contrib/1.2.0/clojure-contrib-1.2.0.jar" "/home/lken/.m2/repository/org/clojure/core.incubator/0.1.0/core.incubator-0.1.0.jar" "/home/lken/.m2/repository/org/apache/httpcomponents/httpclient/4.1.2/httpclient-4.1.2.jar" "/home/lken/.m2/repository/ring/ring-core/1.1.0/ring-core-1.1.0.jar" "/home/lken/.m2/repository/clj-http/clj-http/0.3.5/clj-http-0.3.5.jar" "/home/lken/.m2/repository/commons-logging/commons-logging/1.1.1/commons-logging-1.1.1.jar" "/home/lken/.m2/repository/noir/noir/1.3.0-beta8/noir-1.3.0-beta8.jar" "/home/lken/.m2/repository/org/apache/httpcomponents/httpcore/4.1.2/httpcore-4.1.2.jar" "/home/lken/.m2/repository/cheshire/cheshire/3.1.0/cheshire-3.1.0.jar" "/home/lken/.m2/repository/ring/ring-jetty-adapter/1.1.0/ring-jetty-adapter-1.1.0.jar" "/home/lken/.m2/repository/org/clojure/tools.logging/0.1.2/tools.logging-0.1.2.jar" "/home/lken/.m2/repository/commons-io/commons-io/2.1/commons-io-2.1.jar" "/home/lken/.m2/repository/org/clojure/tools.macro/0.1.1/tools.macro-0.1.1.jar" "/home/lken/.m2/repository/slingshot/slingshot/0.10.2/slingshot-0.10.2.jar" "/home/lken/.m2/repository/clj-time/clj-time/0.3.7/clj-time-0.3.7.jar" "/home/lken/.m2/repository/hiccup/hiccup/1.0.0/hiccup-1.0.0.jar" "/home/lken/.m2/repository/org/clojure/clojure/1.4.0/clojure-1.4.0.jar" "/home/lken/.m2/repository/clojure-complete/clojure-complete/0.2.1/clojure-complete-0.2.1.jar" "/home/lken/.m2/repository/org/thnetos/cd-client/0.3.4/cd-client-0.3.4.jar" "/home/lken/.m2/repository/org/eclipse/jetty/jetty-http/7.6.1.v20120215/jetty-http-7.6.1.v20120215.jar" "/home/lken/.m2/repository/utilza/utilza/0.1.0-SNAPSHOT/utilza-0.1.0-SNAPSHOT.jar" "/home/lken/.m2/repository/compojure/compojure/1.0.4/compojure-1.0.4.jar" "/home/lken/.m2/repository/commons-codec/commons-codec/1.5/commons-codec-1.5.jar" "/home/lken/.m2/repository/org/eclipse/jetty/jetty-util/7.6.1.v20120215/jetty-util-7.6.1.v20120215.jar" "/home/lken/.m2/repository/bultitude/bultitude/0.1.5/bultitude-0.1.5.jar" "/home/lken/.m2/repository/joda-time/joda-time/2.0/joda-time-2.0.jar" "/home/lken/.m2/repository/org/eclipse/jetty/jetty-server/7.6.1.v20120215/jetty-server-7.6.1.v20120215.jar" "/home/lken/.m2/repository/org/clojure/tools.namespace/0.1.0/tools.namespace-0.1.0.jar" "/home/lken/.m2/repository/org/eclipse/jetty/jetty-io/7.6.1.v20120215/jetty-io-7.6.1.v20120215.jar" "/home/lken/.m2/repository/org/timmc/handy/1.2.0/handy-1.2.0.jar" "/home/lken/.m2/repository/ring/ring-servlet/1.1.0/ring-servlet-1.1.0.jar" "/home/lken/.m2/repository/org/apache/httpcomponents/httpmime/4.1.2/httpmime-4.1.2.jar" "/home/lken/.m2/repository/commons-fileupload/commons-fileupload/1.2.1/commons-fileupload-1.2.1.jar" "/home/lken/.m2/repository/com/ashafa/clutch/0.3.0/clutch-0.3.0.jar" "/home/lken/.m2/repository/org/eclipse/jetty/jetty-continuation/7.6.1.v20120215/jetty-continuation-7.6.1.v20120215.jar"]ed2:id1:27:session36:e7b89943-dd3f-4b31-92d0-b13860cbe93b6:statusl4:doneee
The same data structure does NOT crash lein2 when executed from this:
lein2 repl :connect 7777
So it seems to be a problem with nrepl.el, or perhaps with emacs itself.
Hi,
I have been using swank clojure for some time now and think that a lot of users coming from slime are used to
having all output going to the repl buffer. It would be very nice and convenient if nrepl would also allow stdout to appear in the
nrepl buffer.
Many Greetings
JOhn
When I am in the project directory (generated by leiningen 2), this works:
lein repl
(use '(incanter core stats charts))
(view (xy-plot))
If I do lein repl
(use '(incanter core stats charts))
and then use M-x nrepl from emacs,
(view (xy-plot))
also works as expected
However, when I use nrepl-jack-in in emacs
(use '(incanter core stats charts))
gives me an error that indicates (correctly) that incanter charts is not on the classpath.
Is there some way that I need to tell nrepl to reload the whole classpath?
by the way, this is the project.clj file
(defproject plot-metapop "0.1.0-SNAPSHOT"
:description "FIXME: write description"
:url "http://example.com/FIXME"
:license {:name "Eclipse Public License"
:url "http://www.eclipse.org/legal/epl-v10.html"}
:dependencies [[org.clojure/clojure "1.4.0"]
[org.clojure/tools.nrepl "0.2.0-beta9"]
[incanter/incanter-core "1.3.0"]
[incanter/incanter-charts "1.3.0"]])
I am using nrepl 0.1.3, emacs23, linux distribution is RHEL 6.3, and java version
Java(TM) SE Runtime Environment (build 1.6.0_33-b03)
Java HotSpot(TM) 64-Bit Server VM (build 20.8-b03, mixed mode)
It's now recommended to install 2.x as just lein
and leave the old one as lein1
if you still need it.
nrepl configuration based on nrepl-mode-hook
fails, as the client session is often nil at that point.
One solution may be to make nrepl-create-client-session synchronous.
Need to integrate this sucker with nrepl: https://github.com/GeorgeJahad/debug-repl/
If you kill the *nrepl-server*
buffer, it gives you a message saying the server couldn't be started.
I get a ClassNotFoundException when I try to use completion with nrepl-jack-in and full namespaces.
To reproduce the problem just:
nrepl-jack-in
clojure.core/rang<tab>
in the replI'm not skilled enough to fix this with something other than sticking (setq nrepl-server-command "lein repl")
in my init.el but I've gathered some info that should help someone:
If I start lein repl :headless
and connect to it with nrepl-el, completions continue to not work, but if I connect to the headless nrepl server with lein repl :connect <port>
, then completions in nrepl.el will start to work.
Also, I wiresharked "lein repl :connect" connecting to a :headless repl. lein repl :connect
sends a bunch of code to the nrepl server when starting up. When I ran that code into my nrepl.el session, the completion problem went away.
When using nrepl-interactive-eval
, nrepl-interactive-eval-print
from a clojure file buffer, the clojure namespace is not interpreted, and the repl namespace is used. The namespace form in the buffer should be used to interpret the buffer's namespace, so that expressions are evaluated in the correct namespace.
For those people (like myself) who do a lot of Literate Programming in Emacs using Clojure and org-babel, migrating to nrepl and nrepl.el is somewhat non-trivial. This is because the existing Clojure support in org-babel (ob-clojure.el) relies on slime and swank-clojure when running org-babel-execute-src-block (which redirects to org-babel-execute:clojure in ob-clojure.el).
So clearly this is actually an issue for both nrepl.el and ob-clojure.el, not simply one or the other. All the same, I've hacked together a simple workaround that fixes the problem and makes Literate Programming under nrepl possible once again. If there is some slick way this could be worked into nrepl.el's codebase that wouldn't break its existing behavior (as this does), I'd be excited to see it.
Here we go:
;; Patch result table rendering bug in ob-clojure (NREPL version)
(defun nrepl-send-request-sync (request)
"Send a request to the backend synchronously (discouraged).
The result is a plist with keys :value, :stderr and :stdout."
(with-current-buffer "*nrepl-connection*"
(setq nrepl-sync-response nil)
(nrepl-send-request request (nrepl-sync-request-handler (current-buffer)))
(while (not (plist-get nrepl-sync-response :done))
(accept-process-output))
nrepl-sync-response))
(defun org-babel-execute:clojure (body params)
"Execute a block of Clojure code with Babel."
(let ((result-plist (nrepl-send-string-sync (org-babel-expand-body:clojure body params) nrepl-buffer-ns))
(result-type (cdr (assoc :result-type params))))
(org-babel-script-escape
(cond ((eq result-type 'value) (plist-get result-plist :value))
((eq result-type 'output) (plist-get result-plist :value))
(t (message "Unknown :results type!"))))))
We can probably steal this straight from swank-clojure?
When compiling or load a clj file, compile errors should be highlighted and there should be a function and keybinding for navigating to the error.
I want to pull the inspector out of swank-clojure and package it up as an independent tool we can use.
When doing nrepl-jack-in or nrepl in emacs-snapshot I get an error as per this gist: https://gist.github.com/3434519.
Looking further into nrepl.el I notice switch-to-buffer-other-window returns nil which causes the error.
Trying to set up nrepl.el a short while ago, I tried running M-x nrepl-jack-in on a buffer for a file in my project. It got this error:
Debugger entered--Lisp error: (error "Could not start nREPL server: Wrong number of arguments to repl task.
Expected ([] [project])
")
signal(error ("Could not start nREPL server: Wrong number of arguments to repl task. \nExpected ([] [project])\n"))
error("Could not start nREPL server: %s" "Wrong number of arguments to repl task. \nExpected ([] [project])\n")
nrepl-server-sentinel(#<process nrepl-server> "exited abnormally with code 1\n")
The problem is that my lein command was pointing to lein1, and not lein2. Once I renamed them, nrepl-jack-in worked.
Perhaps nrepl-interaction-mode should be a major mode derived from clojure-mode instead of a minor mode. From the Elisp info pages:
A minor mode is not usually meant as a variation of a single major
mode. Usually they are general and can apply to many major modes. For
example, Auto Fill mode works with any major mode that permits text
insertion. To be general, a minor mode must be effectively independent
of the things major modes do.
Will it ever be useful to enable nrepl-interaction-mode on a non-clojure-mode buffer?
Imagine that vars are files and namespaces are directories. If you give M-.
a prefix argument (or if the point isn't on a symbol) then it should prompt for a var much like ido-find-file
. Documentation lookup should work the same way, as should all commands that operate on vars.
You should be able to write a handler that just handles value
and have default handlers for out
, err
, and done
.
I tried to install nrepl-el via marmalade few minutes after 0.1.3 release, the install didn't work until I executed M-x package-refresh-contents
.
If we intend to allow multiple active connections, then each buffer will need to be associated with a connection, and each connection should be associated with a project root.
If we don't intend to allow multiple connections, then connecting when you're already connected should close the existing connection.
It looks like the output is being broken into chunks and the chunks are being received out of order.
There's nothing like being greeted with "Take this REPL, brother; may it serve you well." when you start your hacking. We should start a thread on the Clojure mailing list taking suggestions for other phrases too.
We should have everything we need on the Clojure side from the clojure-complete
library brought in by lein repl
, but we should check to see if it's loaded first since it's possible folks could be using nrepl.el
to connect to nrepl servers embedded in other contexts.
Once completion is in place I would feel comfortable recommending nrepl.el over slime for general use. I'd love to see reload-all support, the inspector, and swank.core/break ported too, but I consider those more as nice-to-haves rather than essentials.
We should check for the presence of clj-stacktrace first and prefer that to the built-in stuff.
On windows the current buffer file name contains backslash characters. These are not properly quoted when creating the clojure form to load the file and break nrepl.el on windows.
It shouldn't create a repl buffer if it can't be used.
The idea here is that if you have a resource being loaded off the classpath (say by clojure.java.io/resource
, but it could also be by something like enlive's deftemplate
) that you should be able to jump to it with a single keystroke.
It's possible that the existing M-.
functionality could be enhanced to do this as long as there's no ambiguity. Perhaps if M-.
is invoked when the point is on a string, it could be interpreted as a classpath lookup? We'd also want it to work on namespaces I think, which would be on symbols, but maybe that's separate.
After nrepl-jack-in, some of paredit's keybindings in the clojure buffers are reset.
e.g. BACKSPACE is bound to 'paredit-backward-delete', but after nrepl-jack-in, the binding is reset to 'backward-delete-char-untabify'
When in a cljs repl using cemerick/piggieback tab completion always returns "No match".
Quoting @cemerick
it should either (a) use a different session for tooling stuff, or (b) stop using "eval" and work towards a common introspection middleware.
piggieback hijacks "eval" for cljs, so Clojure stuff sent on the same session that is running cljs/piggieback won't work
While (a) might be a good idea, I'm not sure it will let me tab complete clojurescript.
Currently (I use nrepl-20120912.248) when a code evaluated in REPL
raises an exception, a nREPL error buffer opens and becomes
focused.
A lot of times there is no need to make anything in nREPL error
buffer, the visible data is enough. Also It seems to me inconsistent
with other Emacs behaviours when an auxiliary buffer does not get
focused automatically.
Let's remove that autofocus.
Using the middleware stack from piggieback:
:injections [(require 'cemerick.piggieback)]
:nrepl-handler (-> clojure.tools.nrepl.server/unknown-op
clojure.tools.nrepl.middleware.interruptible-eval/interruptible-eval
cemerick.piggieback/wrap-cljs-repl
clojure.tools.nrepl.middleware.pr-values/pr-values
clojure.tools.nrepl.middleware.session/add-stdin
clojure.tools.nrepl.middleware.session/session)
then when in a normal clojure nrepl tab completing namespaced vars throws an exception.
clojure.core/su<tab>
throws:
java.lang.ClassNotFoundException: clojure.core
at java.net.URLClassLoader$1.run (URLClassLoader.java:217)
java.security.AccessController.doPrivileged (AccessController.java:-2)
java.net.URLClassLoader.findClass (URLClassLoader.java:205)
clojure.lang.DynamicClassLoader.findClass (DynamicClassLoader.java:61)
java.lang.ClassLoader.loadClass (ClassLoader.java:321)
java.lang.ClassLoader.loadClass (ClassLoader.java:266)
java.lang.Class.forName0 (Class.java:-2)
java.lang.Class.forName (Class.java:264)
clojure.lang.RT.classForName (RT.java:2039)
clojure.lang.Compiler.maybeResolveIn (Compiler.java:6789)
clojure.core$ns_resolve.invoke (core.clj:3883)
clojure.core$ns_resolve.invoke (core.clj:3880)
clojure.core$resolve.invoke (core.clj:3889)
complete.core$resolve_class.invoke (core.clj:83)
complete.core$eval669$fn__670.invoke (core.clj:100)
clojure.lang.MultiFn.invoke (MultiFn.java:167)
complete.core$completions.invoke (core.clj:124)
user$eval2547.invoke (NO_SOURCE_FILE:1)
clojure.lang.Compiler.eval (Compiler.java:6511)
clojure.lang.Compiler.eval (Compiler.java:6477)
clojure.core$eval.invoke (core.clj:2797)
clojure.main$repl$read_eval_print__6405.invoke (main.clj:245)
clojure.main$repl$fn__6410.invoke (main.clj:266)
clojure.main$repl.doInvoke (main.clj:266)
clojure.lang.RestFn.invoke (RestFn.java:1096)
clojure.tools.nrepl.middleware.interruptible_eval$evaluate$fn__337.invoke (interruptible_eval.clj:51)
clojure.lang.AFn.applyToHelper (AFn.java:159)
clojure.lang.AFn.applyTo (AFn.java:151)
clojure.core$apply.invoke (core.clj:601)
clojure.core$with_bindings_STAR_.doInvoke (core.clj:1771)
clojure.lang.RestFn.invoke (RestFn.java:425)
clojure.tools.nrepl.middleware.interruptible_eval$evaluate.invoke (interruptible_eval.clj:36)
clojure.tools.nrepl.middleware.interruptible_eval$interruptible_eval$fn__374$fn__376.invoke (interruptible_eval.clj:164)
clojure.core$comp$fn__4034.invoke (core.clj:2278)
clojure.tools.nrepl.middleware.interruptible_eval$run_next$fn__367.invoke (interruptible_eval.clj:131)
clojure.lang.AFn.run (AFn.java:24)
java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1110)
java.util.concurrent.ThreadPoolExecutor$Worker.run (ThreadPoolExecutor.java:603)
java.lang.Thread.run (Thread.java:679)
Is someone working with apropos? I mean specifically something on par with slime-apropos-package and slime-apropos.
I'm thinking about working on these, and was looking for some pointers as to how to proceed.
nrepl.el does not always (I actually can't grasp a full pattern here) understand what is the namespace of the buffer I'm currently in. If I evaluate *ns*
for example it returns the user
namespace. In this case I have to go to the top of the file and evaluate the ns
declaration. From that moment this buffer clearly knows its namespace and remembers it when switching buffers back and forth.
I don't know the technology behind recognizing buffer's namespace but I'll be OK with a command that changes the nrepl-interaction-mode's namespace to current buffer's one.
It would be nice if the project's init and init-ns settings were processed in the same way that REPL-y processes them.
returning the datomic database collection results in a error in process filter: Cannot decode object: 2
minimal test is:
(def uri "datomic:mem://testdb")
(create-database uri)
(db (connect uri))
completion-at-point-functions
variable was introduced in emacs 24. nrepl.el uses it now, so it seems to be broken for 23. If somebody confirms that then README should be updated (remove "support 23").
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.