Skip to content

Commit

Permalink
Fix formatting when requires have metadata
Browse files Browse the repository at this point in the history
  • Loading branch information
camsaul committed Aug 21, 2024
1 parent c832761 commit 5f3b502
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 2 deletions.
37 changes: 35 additions & 2 deletions cljfmt/src/cljfmt/core.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -568,10 +568,43 @@
#?(:clj
(defn- as-zloc->alias-mapping [as-zloc]
(let [alias (some-> as-zloc z/right z/sexpr)
current-namespace (some-> as-zloc z/leftmost z/sexpr)
;; `leftmost` might be an `uneval` node e.g. in
;;
;; [#_{:clj-kondo/ignore [:x]} a.namespace :as n]
;;
;; so look for the first symbol node. The token can also have
;; metadata on it e.g.
;;
;; [^{:clj-kondo/ignore [:x]} a.namespace :as n]
;;
;; which is why we need to `skip-meta` in find.
current-namespace (some-> as-zloc
z/leftmost
(z/find #(n/symbol-node?
(z/node (skip-meta %))))
z/sexpr)
grandparent-node (some-> as-zloc z/up z/up)
;; For something like
;;
;; [a [namespace :as n]]
;;
;; `grandparent-node` points to [a [namespace :as n]]. In this case
;; `a` is the parent namespace.
;;
;; But for something like
;;
;; ^{:x true} [a.namespace :as n]
;;
;; `grandparent-node` points to a `:meta` node e.g.
;;
;; [<meta: ^{:x true} [a.namespace :as n]> ...]
;;
;; so make sure we're only looking at actual prefix forms like the
;; former by checking whether it's a list or vector
parent-namespace (when-not (ns-require-form? grandparent-node)
(first (z/child-sexprs grandparent-node)))]
(when (or (z/vector? grandparent-node)
(z/list? grandparent-node))
(first (z/child-sexprs grandparent-node))))]
(when (and (symbol? alias) (symbol? current-namespace))
{(str alias) (if parent-namespace
(format "%s.%s" parent-namespace current-namespace)
Expand Down
27 changes: 27 additions & 0 deletions cljfmt/test/cljfmt/core_test.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,33 @@
{:indents {'thing.core/defn [[:inner 0]]}
#?@(:cljs [:alias-map {"t" "thing.core"}])})
"applies custom indentation to namespaced defn")
(testing "handles metadata on or comments before forms inside ns :require list"
(doseq [ignore-str [""
"^{:clj-kondo/ignore [:discouraged-namespace]} "
"^:clj-kondo/ignore "
"^{some-symbol another-symbol} "
"#_{:clj-kondo/ignore [:discouraged-namespace]} "
"#_:clj-kondo/ignore "
"^tag "
"#_old-thing "]
ns-vec-str [(str ignore-str "[thing.core :as t]")
(str ignore-str "[thing [core :as t]]")
(str ignore-str "(thing [core :as t])")
(str "[" ignore-str "thing.core :as t]")
(str ignore-str " [" ignore-str "thing.core :as t]")]
:let [ns-str (str "(ns example (:require " ns-vec-str "))")]]
(testing ns-str
(is (reformats-to?
[ns-str
""
"(t/defn foo [x]"
"(+ x 1))"]
[ns-str
""
"(t/defn foo [x]"
" (+ x 1))"]
{:indents {'ns [[:block 1]], 'thing.core/defn [[:inner 0]]}
#?@(:cljs [:alias-map {"t" "thing.core"}])})))))
(is (reformats-to?
["(comment)"
"(ns thing.core)"
Expand Down

0 comments on commit 5f3b502

Please sign in to comment.