clojure-emacs / orchard

A fertile ground for Clojure tooling
Eclipse Public License 1.0
326 stars 54 forks source link

`orchard.eldoc/extract-arglists` does not handle many special forms correctly #165

Closed quanticle closed 1 year ago

quanticle commented 1 year ago

This is related to Cider bug #3307. It seems like the actual issue is that extract-arglists isn't correctly processing the forms list for many Clojure special forms. When I run

(pprint (orchard.eldoc/eldoc (cider.nrepl.middleware.info/info {:ns 'clojure.core :sym 'if})))

I get back

{:name "if",
 :eldoc (["if" "test" "then" "else?"]),
 :type "function",
 :docstring
 "Evaluates test. If not the singular values nil or false,\n  evaluates and yields then, otherwise, evaluates and yields else. If\n  else is not supplied it defaults to nil."}

Note that if is the first element of the :eldoc vector, which screws up the eldoc highlighting in emacs, because it expects the first element of the arglist to be test, not if itself.

Similarly, when I get the info for do

(pprint (orchard.eldoc/eldoc (cider.nrepl.middleware.info/info {:ns 'clojure.core :sym 'do})))

I get

{:name "do",
 :eldoc (["do" "exprs*"]),
 :type "function",
 :docstring
 "Evaluates the expressions in order and returns the value of\n  the last. If no expressions are supplied, returns nil."}

Just like with if, do is the first element of the :eldoc vector, which, once again, throws off the eldoc highlighting in emacs.

I got similar results with other special forms, such as, def and fn. The only special form I didn't get this result with was .:

(pprint (orchard.eldoc/eldoc (cider.nrepl.middleware.info/info {:ns 'clojure.core :sym '.})))

which returned

{:name ".",
 :eldoc
 ([".instanceMember" "instance" "args*"]
  [".instanceMember" "Classname" "args*"]
  ["Classname/staticMethod" "args*"]
  ["Classname/staticField"]),
 :type "function",
 :docstring
 "The instance member form works for both fields and methods.\n  They all expand into calls to the dot operator at macroexpansion time."}

So it seems like . is a special special form. I would propose that extract-arglists make a special case for ., and omit the first element when building the arglists for other special forms. I can make the change to eldoc.clj, but I wanted to raise the issue in a bug first, in order to solicit feedback on whether my suggested approach is the best one.