tpope / vim-fireplace

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

Connecting to the shadow-cljs REPL #322

Closed PeteW closed 6 years ago

PeteW commented 6 years ago

According to this CIDER docs:

ClojureScript support relies on the piggieback nREPL middleware being present
 in your REPL session. There's one exception to this, though -
 shadow-cljs. It has its own nREPL middleware and doesn't rely on piggieback at all.

Cool! I have a shadow-cljs setup so alls I need to do is:

> shadow-cljs watch app
shadow-cljs - config: /path/to/my/shadow-cljs.edn  
cli version: 2.6.4  node: v8.11.4
shadow-cljs - updating dependencies
shadow-cljs - starting ...
shadow-cljs - HTTP server for :app available at http://localhost:3000
shadow-cljs - server version: 2.6.4
shadow-cljs - server running at http://localhost:9630
shadow-cljs - socket REPL running on port 41066
shadow-cljs - nREPL server started on port 3333
shadow-cljs - watching build :app
[SOME CRAP]
[:app] Build completed. (190 files, 90 compiled, 2 warnings, 19.19s)

Then I launch vim and :Connect specify the nrepl protocol and localhost and port 3333 and this returns no issues.

Then I try and :<,>Eval some text (+ 1 1) whilst editing a core.cljs file And I get an exception: Fireplace: java.lang.AssertionError

Well that isnt much to go with so I edit fireplace.vim a little bit (add error and stacktrace into that vim exception on line 715, no other changes whatsoever)

function! fireplace#client(...) abort
  let buf = a:0 ? a:1 : s:buf()
  let client = fireplace#platform(buf)
  if fnamemodify(bufname(buf), ':e') ==# 'cljs'
    if !has_key(client, 'connection')
      throw 'Fireplace: no live REPL connection'
    endif
    if empty(client.piggiebacks)
      let result = client.piggieback('')
      if has_key(result, 'ex')
        let stacktracestring = join(result.stacktrace, '-=-')
        throw substitute('Fireplace: '.result.ex.' '.result.err.' '.stacktracestring,'\n', '', '')
      endif
    endif
    return client.piggiebacks[0]
  endif
  return client
endfunction

and now I see much more detail in that error message:

Fireplace: class java. lang.AssertionError AssertionError Assert failed: (keyword? repl-env) cider.
piggieback/cljs-repl (fake_piggieback04.clj cider. piggieback$cljs repl.invokeStatic :45) cider . piggieback$cljs repl . : 45) 
clojure. lang. RestFn . invoke(RestFn . java: 416) 
 clojure. lang. Var . invoke(Var. java: 381) 
 user$eva123@29.invokeStatic(Unknown Source) 
user$eva123@29.invoke(Unknown Source) 
clojure . lang. Compiler . eval (Compiler . java: 7062) 
clojure . lang. Compiler . eval (Compiler . java: 7625) 
clojure.core$eval . invokestatic(core.clj :3206) 
clojure.core$eval . invoke(core.clj 
clojure.lang.RestFn.invoke(RestFn.java: 1523) 

(side note: Pardon the malformed stack. I'm computer illiterate and didnt know how to copy from the vim error window. I took a screenshot and literally ran it through an OCR. Yes this is windows/gvim and yes I am mildly ashamed of myself)

Anyways, my impression is that fireplace is employing some sort of piggieback when I was told no piggieback is necessary. I'm still digging but wanted to see if anything obvious jumps out

PeteW commented 6 years ago

UPDATE: Some shadow-cljs devs showed me how to connect fireplace with the REPL properly. Cool stuff! I'm going to follow up on this issue with a PR that adds documentation for shadow-cljs

PeteW commented 6 years ago

Closing this issue since it doesnt seem like "make X work with vim-fireplace" sort of information has a home in the vim-fireplace docs, and that's fine. I will, for folks getting here from google, summarize with:

Say your shadow-cljs.edn looks like:

{:source-paths ["src"]
 :dependencies [[binaryage/devtools "0.9.10"]
                [cider/cider-nrepl "0.18.0"]
                [reagent "0.8.1"]]
 :nrepl        {:port 3333}
:builds
 {:app {:target :browser
        :output-dir "public/js"
        :asset-path "/js"
        :modules
        {:main
         {:entries [pete.core]}}
        :devtools
        {:after-load  pete.core/main
         :http-root   "public"
         :http-port   3000}}}}
  1. Start shadow-cljs shadow-cljs watch app
  2. Connect to the nREPL server :Connect
  3. Upgrade REPL to a CLJS REPL :Piggieback :app (converts the clojure repl to a clojurescript repl)
  4. Open web page in a web browser (or any other trick which jits the clojurescript into the app)
  5. At this point calls to Eval will work
metasoarous commented 5 years ago

@PeteW I'd beg to differ, as far as adding "make X work with vim-fireplace" to the docs/README. I brought up using vim-fireplace with Clojure CLI in #357, and @tpope seemed open to adding documentation around this if we figured out a relatively straightforward way of getting it to work. If he feels it's too much for the README though, maybe we can start some wiki pages for less frequently used (for now) setups? Then we can at least point to them from the README? It took me a while to happen upon this issue, as it did coming to the Clojure CLI solution.

tpope commented 5 years ago

Yeah I do want this sort of stuff documented, but I'm not really sure where. The README is more of a sales pitch, I don't really want any big detours. Maybe we should add a section to the help file and explain Lein, Boot, Clojure CLI, and Shadow CLJS one by one?

Wiki page is also a great solution, in the interim if not permanently.

Note that Fireplace now lets you do :CljEval (whatever/cljs-repl) to start a CLJS REPL without Piggieback, so maybe the instructions for Shadow CLJS in particular can be simplified.

tpope commented 5 years ago

Also, maybe it's time to add some sort of "jack in" functionality to spare users the trouble?

tpope commented 5 years ago

I added Clojure CLI support to salve.vim. This makes :Console into a crude first pass at a "jack in", which is good enough for now I think.

I'll do the same for Shadow CLJS if someone can figure out how to retrieve its classpath. I see a list of jar files hiding in .shadow-cljs/classpath.edn, so I would expect (or at least hope for) it to expose a way to retrieve them from the command line.

sheluchin commented 4 years ago

@tpope you might not be aware that retrieving the classpath is now possible with shadow-cljs classpath. It was added pretty recently: https://github.com/thheller/shadow-cljs/commit/d9d0002c30eaf725051a0483b248696eeb731bc8

tpope commented 3 years ago

Implemented. See the caveats in the commit message.

metasoarous commented 3 years ago

Amazing! Thanks @tpope!