Injecting global debug macros in nrepl with deps.edn

I’m just getting started with clojure and found these two awesome debugging libraries:

I would like to effectively have available everywhere the following requires:

(require '[debux.core :refer [dbg]]
         '[sc.api :refer [spy]]
         '[sc.nrepl.repl :refer [in-ep exit] :rename {exit out-ep}])

I see with lein it’s possible with :injections like here. I found

these two posts where people get effectively the same set up with deps.edn, with clojure’s basic repl. I’m using conjure on vim which uses nrepl. Nrepl’s documentation explains how to do this with leiningen (:init key in :repl-options in project.clj), but I can’t figure how to set this up without lein (I’m on an old computer where clj starts much faster than lein). Anyone know how to set this up? Or just general tips or tools for debugging clojure are also welcome :slight_smile:

One option is you can put the requires in your user namespace, which is loaded when the repl is started and store the referred vars in vars in the user namespace.

(ns user
  (require [debux.core :as debux])

(def dbg debug/dbg)
(ns some-other.ns)

user/dbg ;; refers to debug.core/dbg

There may be other (better?) ways to do this as well, but this works.

Or just general tips or tools for debugging clojure are also welcome

I like to use inline defs when debugging, as you can easily save values from the running code for experimentation at your leisure in the repl. Using inline defs with the same name as local bindings can be very helpful. See more info here: Inline def: an effective* debugging technique for Clojure.

thanks! I didn’t know about user.clj. For convenience I’d like to not have to make a separate dev/user.clj with that in every project but just have it present anytime I run nrepl. I found these instructions: How are `user.clj` files loaded? - #3 by jlesquembre
and made it work by putting in ~/.clojure/deps.edn:

{:aliases ;; Add cross-project aliases here
 {:nrepl {:extra-paths ["/home/user/.clojure"]
          :extra-deps {nrepl/nrepl       {:mvn/version "0.9.0"}
                       cider/cider-nrepl {:mvn/version "0.28.4"}
                       philoskim/debux {:mvn/version "0.8.2"}
                       vvvvalvalval/scope-capture {:mvn/version "0.3.3"}
                       vvvvalvalval/scope-capture-nrepl {:mvn/version "0.3.1"}}
          :main-opts  ["-m" "nrepl.cmdline"
                       "--middleware" "[cider.nrepl/cider-middleware sc.nrepl.middleware/wrap-letsc]"

then in ~/.clojure/user.clj:

(ns user
  (:require [debux.core :as debux]))

(defmacro dbg
  `(debux/dbg ~arg))

It doesn’t work with just (def dbg debux.core/dbg) as it’s a macro and gives a compiler error about not being able to take the value of a macro. with this clj on startup says:
WARNING: Use of :paths external to the project has been deprecated, please remove: /home/user/.clojure
So it seems making a global user.clj is not encouraged or this isn’t the way to do it.

I’m actually not really worried about getting this working properly anymore cause I switched now to emacs for clojure coding at least, cider is just more mature than what vim has at the moment. And it’s debugger and inspector and stuff takes care of most of the use for those helper macros. I was pleasantly surprised it just took like a day to set up and get somewhat comfortable with doom emacs, it’s closer to vim than any other “vim mode” outside of vim I’ve seen.

Inline def is a nice simple debugging technique for clojure! If you do it a lot def’ing large numbers of local variables maybe you’d like that scope capture library, it’s basically a macro for automating the inline defs, you just put spy at some point and it saves all the local variables at that point, and then can do defsc to def them all, which i bound a key to to make it more convenient

Glad you found something that works for you! I’m familiar with scope-capture but haven’t tried it. There’s also snitch. “It is inline-defs on steroids.” I should try one or both of those at some point.

nice, snitch looks convenient. also I’ve been playing with flowstorm which is really neat, one of the most interesting tools I’ve seen for any language

I haven’t tried it yet, but have been aware of it for some time. It looks really useful.