tpope / vim-fireplace

fireplace.vim: Clojure REPL support
https://www.vim.org/scripts/script.php?script_id=4978
1.75k stars 139 forks source link

Error on doc #167

Closed DAddYE closed 5 years ago

DAddYE commented 10 years ago

Hi!

thanks for this awesome plugin.

However, every time I use :Doc I get:

Error detected while processing function <SNR>50_Doc..fireplace#info..fireplace#evalparse..<SNR>50_eval:
line    6:
E716: Key not present in Dictionary: eval(a:expr, options)
E15: Invalid expression: client.eval(a:expr, options)
Press ENTER or type command to continue
tpope commented 10 years ago

Is nREPL running?

DAddYE commented 10 years ago

Yes, it is and :Connect'ed

tpope commented 10 years ago

No ClojureScript in the mix I assume? Check :echo fireplace#client() and see if it's more than an empty dictionary.

DAddYE commented 10 years ago

Yep, I was using clojurescript, that's the output:

{'status': ['eval-error', 'done'], 'ex': 'class java.lang.ClassNotFoundException', 'root-ex': 'class java.lang.ClassNo
tFoundException', 'id': 'fireplace-daddye.local-1406055206-5', 'session': ['7a24e4db-a7da-4e28-9f0f-451014ff15b3'], 'e
rr': 'ClassNotFoundException cemerick.piggieback  java.net.URLClassLoader$1.run (URLClassLoader.java:372)
', 'stacktrace': ['java.net.URLClassLoader$1.run(URLClassLoader.java:372)', 'java.net.URLClassLoader$1.run(URLClassLoa
der.java:361)', 'java.security.AccessController.doPrivileged(Native Method)', 'java.net.URLClassLoader.findClass(URLCl
assLoader.java:360)', 'clojure.lang.DynamicClassLoader.findClass(DynamicClassLoader.java:61)', 'java.lang.ClassLoader.
loadClass(ClassLoader.java:424)', 'java.lang.ClassLoader.loadClass(ClassLoader.java:357)', 'java.lang.Class.forName0(N
ative Method)', 'java.lang.Class.forName(Class.java:340)', 'clojure.lang.RT.classForName(RT.java:2065)', 'clojure.lang
.Compiler$HostExpr.maybeClass(Compiler.java:978)', 'clojure.lang.Compiler$HostExpr.access$400(Compiler.java:756)', 'cl
ojure.lang.Compiler.macroexpand1(Compiler.java:6583)', 'clojure.lang.Compiler.macroexpand(Compiler.java:6613)', 'cloju
re.lang.Compiler.eval(Compiler.java:6687)', 'clojure.lang.Compiler.eval(Compiler.java:6666)', 'clojure.core$eval.invok
e(core.clj:2927)', 'clojure.main$repl$read_eval_print__6625$fn__6628.invoke(main.clj:239)', 'clojure.main$repl$read_ev
al_print__6625.invoke(main.clj:239)', 'clojure.main$repl$fn__6634.invoke(main.clj:257)', 'clojure.main$repl.doInvoke(m
ain.clj:257)', 'clojure.lang.RestFn.invoke(RestFn.java:1096)', 'clojure.tools.nrepl.middleware.interruptible_eval$eval
uate$fn__5879.invoke(interruptible_eval.clj:56)', 'clojure.lang.AFn.applyToHelper(AFn.java:152)', 'clojure.lang.AFn.ap
plyTo(AFn.java:144)', 'clojure.core$apply.invoke(core.clj:624)', 'clojure.core$with_bindings_STAR_.doInvoke(core.clj:1
862)', 'clojure.lang.RestFn.invoke(RestFn.java:425)', 'clojure.tools.nrepl.middleware.interruptible_eval$evaluate.invo
ke(interruptible_eval.clj:41)', 'clojure.tools.nrepl.middleware.interruptible_eval$interruptible_eval$fn__5920$fn__592
3.invoke(interruptible_eval.clj:171)', 'clojure.core$comp$fn__4192.invoke(core.clj:2402)', 'clojure.tools.nrepl.middle
ware.interruptible_eval$run_next$fn__5913.invoke(interruptible_eval.clj:138)', 'clojure.lang.AFn.run(AFn.java:22)', 'j
ava.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)', 'java.util.concurrent.ThreadPoolExecu
tor$Worker.run(ThreadPoolExecutor.java:617)', 'java.lang.Thread.run(Thread.java:745)']}
tpope commented 10 years ago

Oh, looks like your ClojureScript setup is completely broken. I don't understand why it's failing this confusing way but step one of fixing it is to add piggieback to your project.

venantius commented 9 years ago

I'm hitting this issue as well, and am unclear as to what I'm doing wrong that's causing the failure. My project.clj includes the following, which should cover the Piggieback side, I think?

              :dependencies [[com.cemerick/piggieback "0.2.1"]
                             [org.clojure/tools.nrepl "0.2.10"]]
              :repl-options {:nrepl-middleware [cemerick.piggieback/wrap-cljs-repl]}
cassiomarques commented 9 years ago

I can also confirm this problem. My project.clj file looks similar to the one @venantius posted above. Could this be caused by a more recent version of vim-fireplace? Thanks!

tpope commented 9 years ago

If you are able to start a piggieback repl inside of lein repl then you should have the necessary config, yes. Next step is to determine if basic clojurescript eval is completely broken, or if it works and the issue really is :Doc.

vitvly commented 9 years ago

Can confirm this as well for arbitrary Clojurescript evals. Repl works inside of lein repl with Piggieback, but when trying to eval for instance the namespace declaration (ns c.test) from within Vim buffer i get

Error detected while processing function <SNR>20_printop..<SNR>20_opfunc:
line   35:
E716: Key not present in Dictionary: user_ns() ==# 'user'
E15: Invalid expression: fireplace#client().user_ns() ==# 'user'

Running :Eval "test" gives Vim(return):E716: Key not present in Dictionary: eval(a:expr, options).

And :echo fireplace#client() output:

{'status': ['eval-error', 'done'], 'ex': 'class clojure.lang.ArityException', 'root-ex': 'class clojure.lang.ArityException', 'id': 'fireplace-CM-1442938746-84', 'session': ['79c6b0a7-f7e7-477b-
a5a5-d2d18f5d0dd3'], 'err': 'ArityException Wrong number of args (0) passed to: piggieback/cljs-repl  clojure.lang.AFn.throwArity (AFn.java:429)
', 'stacktrace': ['clojure.lang.AFn.throwArity(AFn.java:429)', 'clojure.lang.RestFn.invoke(RestFn.java:399)', 'user$eval13976.invoke(form-init6574958625805789370.clj:1)', 'clojure.lang.Compiler.eval(Compi
ler.java:6782)', 'clojure.lang.Compiler.eval(Compiler.java:6745)', 'clojure.core$eval.invoke(core.clj:3081)', 'clojure.main$repl$read_eval_print__7099$fn__7102.invoke(main.clj:240)', 'clojure.main$repl$re
ad_eval_print__7099.invoke(main.clj:240)', 'clojure.main$repl$fn__7108.invoke(main.clj:258)', 'clojure.main$repl.doInvoke(main.clj:258)', 'clojure.lang.RestFn.invoke(RestFn.java:1523)', 'clojure.tools.nre
pl.middleware.interruptible_eval$evaluate$fn__623.invoke(interruptible_eval.clj:58)', 'clojure.lang.AFn.applyToHelper(AFn.java:152)', 'clojure.lang.AFn.applyTo(AFn.java:144)', 'clojure.core$apply.invoke(c
ore.clj:630)', 'clojure.core$with_bindings_STAR_.doInvoke(core.clj:1868)', 'clojure.lang.RestFn.invoke(RestFn.java:425)', 'clojure.tools.nrepl.middleware.interruptible_eval$evaluate.invoke(interruptible_e
val.clj:56)', 'clojure.tools.nrepl.middleware.interruptible_eval$interruptible_eval$fn__665$fn__668.invoke(interruptible_eval.clj:191)', 'clojure.tools.nrepl.middleware.interruptible_eval$run_next$fn__660
.invoke(interruptible_eval.clj:159)', 'clojure.lang.AFn.run(AFn.java:22)', 'java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)', 'java.util.concurrent.ThreadPoolExecutor$Worke
r.run(ThreadPoolExecutor.java:617)', 'java.lang.Thread.run(Thread.java:745)']}

Seems to be related to this Piggieback issue

tpope commented 9 years ago

That second output is very enlightening. cemerick.piggieback/cljs-repl used to have a sensible default for zero arguments but Wrong number of args (0) passed to: piggieback/cljs-repl suggests otherwise. I'll leave it to you to investigate what changed.

The first error is an issue with how fireplace reports that failure. I'll push up an improvement.

venantius commented 9 years ago

Here's the relevant commit and line in Piggieback that changed the arity for piggieback/cljs-repl: https://github.com/cemerick/piggieback/commit/47362bb935558db49dc906e24c5d7ba9160e4d72#diff-f31bb735cb21ecf0a8ba8ec3949a7c6aL164

TL;DR - Piggieback went from assuming that the repl-env arg should fallback to a Rhino REPL to requiring you to explicitly declare your repl-env.

tpope commented 9 years ago

https://github.com/tpope/vim-fireplace/blob/04a7f542f56cb2d932c454648e10fc39f70af345/plugin/fireplace.vim#L279-L288 is where the fix needs to go, if someone wants to figure out the specifics.

vitvly commented 9 years ago

Wow, thanks! The fix seems to be trivial, if i am not missing anything:

  if empty(a:arg)
    let arg = ' (cljs.repl.rhino/repl-env)'

and Rhino is passed as a default repl-env. The same could have been achieved with :Piggieback (cljs.repl.rhino/repl-env). I am also able to start e.g. Weasel on top of Piggieback this way with Piggieback (weasel.repl.websocket/repl-env :ip "0.0.0.0" :port 9001), if it had been already required in the lein repl.

tpope commented 9 years ago

Assuming no require is necessary that looks fine; I would just clean up my handling of that leading space while I was at it.

I would also consider a patch to favor weasel when available if a bare port is given, if that is the sort of thing people would find useful.

vitvly commented 9 years ago

So then the connection part in s:repl.piggieback() becomes

  let connection = s:conn_try(self.connection, 'clone')
  if empty(a:arg)
    let arg = ' (cljs.repl.rhino/repl-env)'
  elseif a:arg =~# '^\d\{1,5}$'
    call connection.eval("(require 'weasel.repl.websocket)")
    let port = matchstr(a:arg, '^\d\{1,5}$')
    let arg = ' (weasel.repl.websocket/repl-env :port '.port.')'
  else
    let arg = ' ' . a:arg
  endif
  let response = connection.eval('(cemerick.piggieback/cljs-repl'.arg.')')

and it works nicely, e.g. :Piggieback 9001. Just tried it with my setup. Many thanks again for directions. I would vote for including it in the patch.

vitvly commented 9 years ago

I've just created a pull request including Rhino/Weasel changes. Hopefully it is fine.