rgm / experiments

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Get piggieback running via vim

rgm opened this issue · comments

Goal

Have sample/core.cljs open in Vim (with fireplace) and be able to cpp at L23, or :Eval (js/alert "hi from editor via piggieback") and actually see an alert. This indicates we have a live connection and can eg. send re-frame events, look up docs, jump to definitions ... all the good repl-connected editor niceties.

Expected

cpp in vim should show a browser alert after starting Piggieback.

Observed

I seem to get a Nashorn repl, not a browser repl. (Evidence: nashorn_code_cache directory appears). Step 5 below shows in vim:

Execution error (IllegalArgumentException) at cljs.repl/fn$G (repl.cljc:116).
No implementation of method: :-repl-options of protocol: #'cljs.repl/IReplEnvOption
s found for class: nil
Prompt will show when REPL connects to evaluation environment (i.e. a REPL hosting
webpage)
Figwheel Main Controls:
          (figwheel.main/stop-builds id ...)  ;; stops Figwheel autobuilder for ids

          (figwheel.main/start-builds id ...) ;; starts autobuilder focused on ids
          (figwheel.main/reset)               ;; stops, cleans, reloads config, and
 starts autobuilder
          (figwheel.main/build-once id ...)   ;; builds source one time
          (figwheel.main/clean id ...)        ;; deletes compiled cljs target files

          (figwheel.main/status)              ;; displays current state of system
Figwheel REPL Controls:
          (figwheel.repl/conns)               ;; displays the current connections
          (figwheel.repl/focus session-name)  ;; choose which session name to focus
 on
In the cljs.user ns, controls can be called without ns ie. (conns) instead of (figw
heel.repl/conns)
    Docs: (doc function-name-here)
    Exit: :cljs/quit
 Results: Stored in vars *1, *2, *3, *e holds last exception object
Open URL http://localhost:9500
To quit, type: :cljs/quit
Press ENTER or type command to continue

Step 6 below shows in the repl terminal (not vim):

Exception in thread "nRepl-session-b6eb8830-39ac-4122-8c8a-07aa4fec1c91" java.lang.IllegalArgumentException: No implementation of method: :send of protocol: #'nrepl.transport/Transport found for class: nil
	at clojure.core$_cache_protocol_fn.invokeStatic(core_deftype.clj:583)
	at clojure.core$_cache_protocol_fn.invoke(core_deftype.clj:575)
	at nrepl.transport$eval8304$fn__8305$G__8295__8312.invoke(transport.clj:16)
	at nrepl.middleware.print$replying_PrintWriter$fn__8761.invoke(print.clj:115)
	at nrepl.middleware.print.proxy$java.io.Writer$ff19274a.write(Unknown Source)
	at java.io.BufferedWriter.flushBuffer(BufferedWriter.java:129)
	at java.io.BufferedWriter.flush(BufferedWriter.java:253)
	at java.io.PrintWriter.flush(PrintWriter.java:320)
	at clojure.core$flush.invokeStatic(core.clj:3711)
	at clojure.core$flush.invoke(core.clj:3705)
	at cljs.repl$repl_caught.invokeStatic(repl.cljc:996)
	at cljs.repl$repl_caught.invoke(repl.cljc:980)
	at cider.piggieback$repl_caught.invokeStatic(piggieback.clj:105)
	at cider.piggieback$repl_caught.invoke(piggieback.clj:98)
	at cider.piggieback$do_eval.invokeStatic(piggieback.clj:265)
	at cider.piggieback$do_eval.invoke(piggieback.clj:227)
	at cider.piggieback$evaluate.invokeStatic(piggieback.clj:273)
	at cider.piggieback$evaluate.invoke(piggieback.clj:271)
	at clojure.lang.Var.invoke(Var.java:384)
	at cider.piggieback$wrap_cljs_repl$fn__9317$fn__9320$fn__9321.invoke(piggieback.clj:305)
	at cider.piggieback$enqueue$fn__9289.invoke(piggieback.clj:195)
	at clojure.lang.AFn.run(AFn.java:22)
	at nrepl.middleware.session$session_exec$main_loop__8996$fn__9000.invoke(session.clj:171)
	at nrepl.middleware.session$session_exec$main_loop__8996.invoke(session.clj:170)
	at clojure.lang.AFn.run(AFn.java:22)
	at java.lang.Thread.run(Thread.java:748)

Steps to reproduce

  1. Check out the minimal-piggieback branch
  2. make distclean to clear build products, node modules and start fresh
  3. make repl to start a JVM repl
  4. Once the rebel CLI prompt is showing, type (go) to start nrepl and figwheel running
  5. Open src/cljs/sample/core.cljs in vim w/ fireplace installed
  6. :Piggieback (figwheel.main.api/repl-env "config/dev") ... wait for control to return
  7. cpp on L23 or :Eval pretty much any form

Notes

I've also seen an issue where I seem to get further than this, but end up on a "Can't find react.cljs" error. I don't seem to be able to reproduce this (might have been an older piggieback or nrepl dep), but I'm guessing that somehow Figwheel or Nashorn isn't being made aware that target/public/js-out is where it can find this, since for that error I also had an out directory show up. My understanding is that that's the cljs compiler's default.

Interesting ... dropping to nrepl 0.5.3 and cider 0.20.0 gives the same

Execution error (IllegalArgumentException) at cljs.repl/fn$G (repl.cljc:116).
No implementation of method: :-repl-options of protocol: #'cljs.repl/IReplEnvOption
s found for class: nil

<figwheel repl startup messages snipped>

as before on first connect, and then an attempt at cljs eval ends in

internal/modules/cjs/loader.js:611
    throw err;
    ^

Error: Cannot find module '@cljs-oss/module-deps'
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:609:15)
    at Function.Module._load (internal/modules/cjs/loader.js:535:25)
    at Module.require (internal/modules/cjs/loader.js:663:17)
    at require (internal/modules/cjs/helpers.js:20:18)
    at [eval]:8:13
    at Script.runInThisContext (vm.js:123:20)
    at Object.runInThisContext (vm.js:312:38)
    at Object.<anonymous> ([eval]-wrapper:6:22)
    at Module._compile (internal/modules/cjs/loader.js:734:30)
    at evalScript (internal/process/execution.js:56:25)

Execution error () at (<cljs repl>:1).
null
Press ENTER or type command to continue

This usually doesn't show if the Clojurescript compiler options :install-deps false :npm-deps false are in place (which they are in config/dev.cljs.edn , and ... yep, Fireplace is still starting Nashorn with default compiler options (or, at the least, creating a nashorn_code_cache directory).

Huh, ok, finally got a working piggieback connection into the browser.

Steps:

  1. Bump deps to cider/piggieback {:mvn/version 0.4.1-SNAPSHOT}
  2. make repl, then (user/go) to start up nrepl and figwheel from the terminal REPL. Figwheel will open a browser window.
  3. (user/cljs-repl) in the terminal repl to start a figwheel REPL, wait for the browser websocket to connect. (There's a suggestion in the docstring for figwheel.main.api/repl-env that this is an inferior/subordinate REPL to one started with figwheel.main.api/cljs-repl ... I take that to mean the terminal one is somehow dominant over vim's secondary one, since we're going to use the return value of figwheel.main.api/repl-env to get Piggieback going, and I hadn't done this step before).
  4. Patch fireplace.vim to prime the connection ... see cichli's workaround suggestion per https://clojurians-log.clojureverse.org/nrepl/2019-02-22/1550861250.019000
  5. This one's weird: Patch fireplace.vim to kill the default Nashorn repl env and instead ask for Figwheel's repl env. For reasons that are not clear to me, Fireplace seems to ignore the argument in :Piggieback (figwheel.main.api/repl-env "config/dev") and ends up booting Nashorn. With an arg, L321 should take effect but it doesn't. This hack is OK for my purposes, but is curious.

The fireplace diff is

diff --git a/plugin/fireplace.vim b/plugin/fireplace.vim
index a6531b9..d7ab75b 100644
--- a/plugin/fireplace.vim
+++ b/plugin/fireplace.vim
@@ -306,9 +306,9 @@ function! s:repl.piggieback(arg, ...) abort
   endif

   let connection = s:conn_try(self.connection, 'clone')
+  call connection.eval("nil")
   if empty(a:arg)
-    call connection.eval("(require 'cljs.repl.nashorn)")
-    let arg = '(cljs.repl.nashorn/repl-env)'
+    let arg = '(figwheel.main.api/repl-env "config/dev")'
   elseif a:arg =~# '^\d\{1,5}$'
     let replns = 'weasel.repl.websocket'
     if has_key(connection.eval("(require '" . replns . ")"), 'ex')
  1. Start vim and do an :Eval within a clj namespace just to confirm that Fireplace is connecting properly to nrepl on the JVM side.
  2. Open a Clojurescript namespace in a vim buffer, and run :Piggieback to connect (no arg needed, since I've forced fireplace to make sure it uses the right repl-env). No nashorn_code_cache shows up: a positive sign.
  3. :Eval (js/alert "hi from piggieback) in Vim.

Result: An alert shows up in the right browser window.

(Whew!)

Just one thing to note: the Fireplace patch shouldn't be necessary with [cider/piggieback "0.4.1-SNAPSHOT"]. If it is, that's a bug in piggieback. It might be worth keeping in as a workaround for compatibility with older versions (maybe a comment noting this would be in order).