cider icon indicating copy to clipboard operation
cider copied to clipboard

No comment syntax is defined

Open jimka2001 opened this issue 5 years ago • 2 comments

This issue reports a problem which was discussed in the clojurians forum. I often get the following confusing message when debugging clojure macros in cider.

screenshot_2020-09-29_at_15 45 55

The basic problem is that when I'm debugging a clojure macro, the code within defmacro might very well throw an exception. Sometimes emacs ends up in a state where it is asking me for a comment character. I doubt this is information the user should be being asked.

To reproduce this, I've prepared a more-than-minimum working example. You can download the repo,

git clone https://gitlab.lrde.epita.fr/jnewton/clojure-rte.git
cd clojure-rte
git checkout c2b73731462393540a254c7ed7f1b1cf01a72a1b

You'll find a project.clj file in the top level directory.

Start up cider. In the REPL paste the following but don't press ENTER>

(destructuring-case
   args
   [[] {}]
   (throw (IllegalArgumentException. 
           "destructuring-fn, empty argument list not supported"))

   [[name & others] {name (not (or (satisfies symbol?)
                                   (= nil))) }]
   `(destructuring-fn nil ~@args)

   [[name] {}]
   (throw (IllegalArgumentException. 
           "destructuring-fn, invalid function body or clauses clauses"))

   [[name lambda-list & others] {lambda-list (satisfies vector?)}]
   `(destructuring-fn-many
     ~@(if name (list name) nil) ;; either name or nothing
     (~lambda-list
      ~@others))
   
   [[name & clauses] {clauses (and (satisfies list?)
                                   (not (= ()))
                                   (rte (:* (:cat (satisfies vector?) (:* :sigma)))))}]
   `(destructuring-fn-many
     ~@(if name (list name) nil) ;; either name or nothing
     ~@clauses)

   [[& others] {}]
   (throw (IllegalArgumentException. 
           (cl-format false
                      "destructuring-fn, invalid argument list: ~A"
                      args))))

With the cursor at the end of the expression, press C-c C-m, to open a new buffer cider-macroexpansion containing the following: (let [...] (rte-case ...))

(let [v15697 args]
  (rte-case
    v15697
    (:cat)
    (let [[] v15697]
      (throw
        (IllegalArgumentException.
          "destructuring-fn, empty argument list not supported")))
    (:cat (not (or (satisfies symbol?) (= nil))) (:* :sigma))
    (let [[name & others] v15697]
      (seq (concat (list 'destructuring-fn) (list 'nil) args)))
    (:cat :sigma)
    (let [[name] v15697]
      (throw
        (IllegalArgumentException.
          "destructuring-fn, invalid function body or clauses clauses")))
    (:cat :sigma (satisfies vector?) (:* :sigma))
    (let [[name lambda-list & others] v15697]
      (seq
        (concat
          (list 'destructuring-fn-many)
          (if name (list name) nil)
          (list (seq (concat (list lambda-list) others))))))
    (:cat
      :sigma
      (:*
        (and
          (satisfies list?)
          (not (= ()))
          (rte (:* (:cat (satisfies vector?) (:* :sigma)))))))
    (let [[name & clauses] v15697]
      (seq
        (concat
          (list 'destructuring-fn-many)
          (if name (list name) nil)
          clauses)))
    (:cat (:* :sigma))
    (let [[& others] v15697]
      (throw
        (IllegalArgumentException.
          (cl-format
            false
            "destructuring-fn, invalid argument list: ~A"
            args))))
    (:* :sigma)
    nil))

Navigate the cursor to the close paren of (rte-case ...), i.e. between the final and penultimate parens as shown here: Screenshot 2020-10-01 at 09 49 31

Now press m

You should now find yourself in the state where emacs is asking for a comment character Screenshot 2020-10-01 at 09 51 17

Environment & Version information

CIDER version information

;; CIDER 0.26.1 (Nesebar), nREPL 0.8.0
;; Clojure 1.10.0, Java 11.0.7

Emacs version

Screenshot 2020-10-01 at 09 53 41

Operating system

Screenshot 2020-10-01 at 09 55 36

jimka2001 avatar Oct 01 '20 07:10 jimka2001

I've followed those steps to reproduce the problem, and in my case (emacs 27, all cider related projects updated from git, using an emacs launched from eldev) it does'n appear the "No comment syntax defined" error, but there is an exception now:

ERROR: Unhandled REPL handler exception processing message {:op macroexpand, :expander macroexpand-1, :code (rte-case
    v6974
    (:cat)
    (let [[] v6974]
      (throw
        (IllegalArgumentException.
          "destructuring-fn, empty argument list not supported")))
    (:cat (not (or (satisfies symbol?) (= nil))) (:* :sigma))
    (let [[name & others] v6974]
      (seq (concat (list 'destructuring-fn) (list 'nil) args)))
    (:cat :sigma)
    (let [[name] v6974]
      (throw
        (IllegalArgumentException.
          "destructuring-fn, invalid function body or clauses clauses")))
    (:cat :sigma (satisfies vector?) (:* :sigma))
    (let [[name lambda-list & others] v6974]
      (seq
        (concat
          (list 'destructuring-fn-many)
          (if name (list name) nil)
          (list (seq (concat (list lambda-list) others))))))
    (:cat
      :sigma
      (:*
        (and
          (satisfies list?)
          (not (= ()))
          (rte (:* (:cat (satisfies vector?) (:* :sigma)))))))
    (let [[name & clauses] v6974]
      (seq
        (concat
          (list 'destructuring-fn-many)
          (if name (list name) nil)
          clauses)))
    (:cat (:* :sigma))
    (let [[& others] v6974]
      (throw
        (IllegalArgumentException.
          (cl-format
            false
            "destructuring-fn, invalid argument list: ~A"
            args))))
    (:* :sigma)
    nil), :ns clojure-rte.core, :display-namespaces tidy, :session 28f2cea5-6c9b-4732-b838-7b728ff0a1ba, :id 11}
java.lang.NullPointerException: Cannot invoke "clojure.lang.IFn.invoke(Object, Object)" because "this.print_fn" is null
	at cider.nrepl.middleware.stacktrace$analyze_cause$pprint_str__6374.invoke(stacktrace.clj:286)
	at cider.nrepl.middleware.stacktrace$analyze_cause.invokeStatic(stacktrace.clj:298)
	at cider.nrepl.middleware.stacktrace$analyze_cause.invoke(stacktrace.clj:281)
	at cider.nrepl.middleware.stacktrace$analyze_causes$fn__6381.invoke(stacktrace.clj:315)
	at clojure.core$map$fn__5847$fn__5848.invoke(core.clj:2742)
	at clojure.core$take_while$fn__5898$fn__5899.invoke(core.clj:2901)
	at clojure.lang.Iterate.reduce(Iterate.java:81)
	at clojure.core$transduce.invokeStatic(core.clj:6883)
	at clojure.core$into.invokeStatic(core.clj:6899)
	at clojure.core$into.invoke(core.clj:6887)
	at cider.nrepl.middleware.stacktrace$analyze_causes.invokeStatic(stacktrace.clj:314)
	at cider.nrepl.middleware.stacktrace$analyze_causes.invoke(stacktrace.clj:306)
	at clojure.lang.Var.invoke(Var.java:388)
	at cider.nrepl.middkleware.util.error_handling$pp_stacktrace.invokeStatic(error_handling.clj:44)
	at cider.nrepl.middleware.util.error_handling$pp_stacktrace.invoke(error_handling.clj:39)
	at cider.nrepl.middleware.util.error_handling$base_error_response.invokeStatic(error_handling.clj:54)
	at cider.nrepl.middleware.util.error_handling$base_error_response.doInvoke(error_handling.clj:46)
	at clojure.lang.RestFn.invoke(RestFn.java:425)
	at cider.nrepl.middleware.util.error_handling$eval4568$fn__4569.invoke(error_handling.clj:129)
	at clojure.lang.MultiFn.invoke(MultiFn.java:239)
	at cider.nrepl.middleware.util.error_handling$eval4580$fn__4581.invoke(error_handling.clj:140)
	at clojure.lang.MultiFn.invoke(MultiFn.java:239)
	at cider.nrepl.middleware.macroexpand$handle_macroexpand.invokeStatic(macroexpand.clj:225)
	at cider.nrepl.middleware.macroexpand$handle_macroexpand.invoke(macroexpand.clj:224)
	at clojure.lang.Var.invoke(Var.java:388)
	at cider.nrepl$wrap_macroexpand$fn__4273.invoke(nrepl.clj:272)
	at nrepl.middleware$wrap_conj_descriptor$fn__2800.invoke(middleware.clj:16)
	at cider.nrepl$wrap_version$fn__4371.invoke(nrepl.clj:486)
	at nrepl.middleware$wrap_conj_descriptor$fn__2800.invoke(middleware.clj:16)
	at cider.nrepl$wrap_tracker$fn__4353.invoke(nrepl.clj:467)
	at nrepl.middleware$wrap_conj_descriptor$fn__2800.invoke(middleware.clj:16)
	at cider.nrepl$wrap_info$fn__4255.invoke(nrepl.clj:203)
	at nrepl.middleware$wrap_conj_descriptor$fn__2800.invoke(middleware.clj:16)
	at nrepl.middleware.sideloader$wrap_sideloader$fn__3684.invoke(sideloader.clj:104)
	at nrepl.middleware$wrap_conj_descriptor$fn__2800.invoke(middleware.clj:16)
	at nrepl.middleware.session$session$fn__3233.invoke(session.clj:309)
	at nrepl.middleware$wrap_conj_descriptor$fn__2800.invoke(middleware.clj:16)
	at nrepl.server$default_handler$fn__3728.invoke(server.clj:130)
	at nrepl.server$handle_STAR_.invokeStatic(server.clj:22)
	at nrepl.server$handle_STAR_.invoke(server.clj:19)
	at nrepl.server$handle$fn__3699.invoke(server.clj:39)
	at clojure.core$binding_conveyor_fn$fn__5739.invoke(core.clj:2030)
	at clojure.lang.AFn.call(AFn.java:18)
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
	at java.base/java.lang.Thread.run(Thread.java:832)

As far as I can tell, the NPE is caused because there should be a print-fn function that is nil. Said function should have been retrieved from the ::print/print-fn key from the message in error_handling.clj:54, but the msg map doesn't carry it. Maybe the nrepl.middleware.print isn't being executed? I'd need some more info to investigate further.

fvides avatar Jan 30 '21 23:01 fvides

This is still happening with CIDER 1.1.0

tried on this on a plain lein new macroerror project

(cond
  (= 1 0) :bad
  :else   :ok)

First macroexpand produces

(if (= 1 0) :bad (cond :else :ok))

Pressing m for further macro expand cond you get the same error screen with: No comment syntax is defined. Use:

image

BrunoBonacci avatar Jun 27 '21 10:06 BrunoBonacci

Fix available in CIDER 1.8.3 + clojure-mode 5.18.0 (both are necessary)

vemv avatar Oct 18 '23 19:10 vemv