Hey all, is there any working example of "Formatting Code with cljfmt" ? The example here: https://docs.cider.mx/cider/usage/misc_features.html#formatting-code-with-cljfmt doesn't work with the same error I see with this configuration
(require 'package)
(package-initialize)
(use-package clojure-mode)
(use-package lsp-mode)
(use-package cider)
(setq cider-format-code-options '(("indents" ((".*" (("inner" 0)))))))
I'll include the error in the thread.Thank you for investigating this, and @iarenaza for providing the solution! https://github.com/clojure-emacs/cider/pull/3848
Nice catch! //cc @alexyakushev
Looks like it fails on something you are not sharing.
There is no map here and there is a hint about a macro named my-custom-indentation
My bad, this error was for the full namespace before I reduced it
(ns clojure-sample.foo
(:require
[clojure.string]
[clojure.core.cache]))
(defn some-function []
(concat (str (+ 1 2) "-foo")))
(some-function)
(some-function)
(some-function)
(defmacro my-custom-indentation [& _body])
(my-custom-indentation []
1)
I'll reduce it and retryRedone with minimal code
(ns clojure-sample.foo
(:require
[clojure.string]
[clojure.core.cache]))
Debugger entered--Lisp error: (error "An even number of KEY-VALS is needed to build a dict object")
error("An even number of KEY-VALS is needed to build a dict object")
nrepl-dict(("indents" (dict ".*" (("inner" 0)))))
cider--nrepl-format-code-request-options((("indents" ((".*" (("inner" 0)))))))
cider-sync-request:format-code("(ns clojure-sample.foo\n (:require\n [clojure.string]\n [clojure.core.cache]))\n" (("indents" ((".*" (("inner" 0)))))))
#<subr F616e6f6e796d6f75732d6c616d626461_anonymous_lambda_13>("(ns clojure-sample.foo\n (:require\n [clojure.string]\n [clojure.core.cache]))\n")
cider--format-region(1 82 #<subr F616e6f6e796d6f75732d6c616d626461_anonymous_lambda_13>)
cider--format-buffer(#<subr F616e6f6e796d6f75732d6c616d626461_anonymous_lambda_13>)
cider-format-buffer()
funcall-interactively(cider-format-buffer)
command-execute(cider-format-buffer record)
#<subr execute-extended-command>(nil "cider-format-buffer" nil)
ad-Advice-execute-extended-command(#<subr execute-extended-command> nil "cider-format-buffer" nil)
apply(ad-Advice-execute-extended-command #<subr execute-extended-command> (nil "cider-format-buffer" nil))
execute-extended-command(nil "cider-format-buffer" nil)
funcall-interactively(execute-extended-command nil "cider-format-buffer" nil)
command-execute(execute-extended-command)
Is this more helpful @hkjels ?Hmm. Looks like cider--nrepl-format-code-request-options is adding an additional list structure. Try:
(setq cider-format-code-options '("indents" ((".*" (("inner" 0))))))I haven't set this in my configuration, and I see that the documentation says to write it like you have it. So this might be a bug in cider
That's if my suggested solution actually works 🙂
Thank you for the suggestion, similar error
Debugger entered--Lisp error: (error "An even number of KEY-VALS is needed to build a dict object")
error("An even number of KEY-VALS is needed to build a dict object")
nrepl-dict(nil)
cider--nrepl-format-code-request-options(("indents" ((".*" (("inner" 0))))))
cider-sync-request:format-code("(ns clojure-sample.foo\n (:require\n [clojure.string]\n [clojure.core.cache]))\n" ("indents" ((".*" (("inner" 0))))))
#<subr F616e6f6e796d6f75732d6c616d626461_anonymous_lambda_13>("(ns clojure-sample.foo\n (:require\n [clojure.string]\n [clojure.core.cache]))\n")
cider--format-region(1 84 #<subr F616e6f6e796d6f75732d6c616d626461_anonymous_lambda_13>)
cider--format-buffer(#<subr F616e6f6e796d6f75732d6c616d626461_anonymous_lambda_13>)
cider-format-buffer()
funcall-interactively(cider-format-buffer)
command-execute(cider-format-buffer record)
#<subr execute-extended-command>(nil "cider-format-buffer" nil)
ad-Advice-execute-extended-command(#<subr execute-extended-command> nil "cider-format-buffer" nil)
apply(ad-Advice-execute-extended-command #<subr execute-extended-command> (nil "cider-format-buffer" nil))
execute-extended-command(nil "cider-format-buffer" nil)
funcall-interactively(execute-extended-command nil "cider-format-buffer" nil)
command-execute(execute-extended-command)
I tried the following variants, all failing
(setq cider-format-code-options '(("indents" ((".*" (("inner" 0)))))))
(setq cider-format-code-options '(("indents" ((".*" ("inner" 0))))))
(setq cider-format-code-options '(("indents" (".*" ("inner" 0)))))
(setq cider-format-code-options '(("indents" ((".*" . (("inner" . 0)))))))
(setq cider-format-code-options '(("indents" . ((".*" . (("inner" . 0)))))))
(setq cider-format-code-options '(("indents" (".*" (("inner" 0))))))
(setq cider-format-code-options '(("indents" (".*" (("inner" 0))))))
(setq cider-format-code-options '(("indents" ((".*" (("inner" (0))))))))
(setq cider-format-code-options '(("indents" ((".*" (("inner" (0))))))))
(setq cider-format-code-options '(("indents" ((".*" . (("inner" . 0)))))))
(setq cider-format-code-options '(("indents" ((".*" . ("inner" 0))))))
(setq cider-format-code-options '(("indents" . ((".*" . (("inner" . 0)))))))Documentation says to do it like this: '(("indents" (("http://org.me/foo" (("inner" 0))))) ("alias-map" (("me" "http://org.me")))) which I believe aligns with what you posted prior
> So this might be a bug in cider How to report that? The official example
(setq cider-format-code-options
'(("indents" (("" (("inner" 0)))))
("alias-map" (("me" "")))))
Also fails with similar messageThe issue must be elsewhere then
I can't really spot the issue. Maybe search github for cider-format-code-options and see if anyone does something similar.
I found this: https://github.com/clojure-emacs/cider/issues/3209 looks to be related
@adham.rasoul While the issue that you reference may impose extra limitations on what you can do with cider-format-buffer et al, the error you are getting is happening before we even send the request to the CIDER nrepl-server.
I was involved in the implementation of initial support for the feature (https://github.com/clojure-emacs/cider/issues/2907) and it proved tricky to represent those kind of maps and vectors in the required nrepl-dict format that CIDER uses to send the requests.
It worked at the time (April 2021), but maybe later changes in other places have changed something along the call chain to that function. Very few people seem to use this feature (I no longer use it myself), so it's easy not to notice if you break it. While there are unit tests for the nrepl-dict encoding machinery, there are no (as far as I know) "end-to-end" tests for this particular use case (from cider-format-buffer formatting options down to nrepl-dict encoding of those options).
If you could tell me what exact CIDER version you are using, I could have a look at it and see if I can find where it breaks and why.
Hey @iarenaza, thank you for your work and taking the time to look at this
I'm on CIDER 1.20.0-snapshot (package: with nREPL 1.4.0
@adham.rasoul It seems commit https://github.com/clojure-emacs/cider/commit/ee35c30d58bffe08dab080ec5135e23b9dfcf508 broke the creation of the "nrepl-dict" needed to send the request to the Cider nrepl middleware. If you change the lines: https://github.com/clojure-emacs/cider/blob/28b7ecdb3d3d893a3c7fccbb6a1506d664900caf/cider-client.el#L280-L284 from:
(nrepl-dict
`(,@(when indents-dict
`("indents" ,indents-dict))
,@(when alias-map-dict
`("alias-map" ,alias-map-dict))))
to
(apply #'nrepl-dict
`(,@(when indents-dict
`("indents" ,indents-dict))
,@(when alias-map-dict
`("alias-map" ,alias-map-dict))))
it should work. Can you confirm it, please?Debugger entered--Lisp error: (error "An even number of KEY-VALS is needed to build a dict object")
error("An even number of KEY-VALS is needed to build a dict object")
nrepl-dict(("indents" (dict ".*" (("inner" 0)))))
cider--nrepl-format-code-request-options((("indents" ((".*" (("inner" 0)))))))
cider-sync-request:format-code("(ns clojure-sample.foo\n (:require\n [clojure.string]\n [clojure.core.cache]))\n\n(defn some-function []\n (concat (str (+ 1 2) \"-foo\")))\n\n(some-function)\n\n(some-function)\n\n(some-function)\n\n(defmacro my-custom-indentation [& _body])\n\n(my-custom-indentation []\n 1)\n" (("indents" ((".*" (("inner" 0)))))))
#("(ns clojure-sample.foo\n (:require\n [clojure.string]\n [clojure.core.cache]))\n\n(defn some-function []\n (concat (str (+ 1 2) \"-foo\")))\n\n(some-function)\n\n(some-function)\n\n(some-function)\n\n(defmacro my-custom-indentation [& _body])\n\n(my-custom-indentation []\n 1)\n")
cider--format-region(1 287 #)
cider--format-buffer(#)
cider-format-buffer()
funcall-interactively(cider-format-buffer)
command-execute(cider-format-buffer record)
#(nil "cider-format-buffer" "cider-format-b")
ad-Advice-execute-extended-command(# nil "cider-format-buffer" "cider-format-b")
apply(ad-Advice-execute-extended-command # (nil "cider-format-buffer" "cider-format-b"))
execute-extended-command(nil "cider-format-buffer" "cider-format-b")
funcall-interactively(execute-extended-command nil "cider-format-buffer" "cider-format-b")
command-execute(execute-extended-command) Thank you!
The code I wanted to format
(ns clojure-sample.foo
(:require
[clojure.string]
[clojure.core.cache]))
With expected result being
(ns clojure-sample.foo
(:require
[clojure.string]
[clojure.core.cache]))