Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions cljfmt/resources/cljfmt/indents/clojure.clj
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
{alt! [[:block 0]]
{-> [[:thread] [:block 0]]
alt! [[:block 0]]
alt!! [[:block 0]]
are [[:block 2]]
as-> [[:block 2]]
as-> [[:thread 3] [:block 2]]
binding [[:block 1]]
bound-fn [[:inner 0]]
case [[:block 1]]
catch [[:block 2]]
comment [[:block 0]]
cond [[:block 0]]
condp [[:block 2]]
cond-> [[:block 1]]
cond-> [[:thread :odd] [:block 1]]
cond->> [[:block 1]]
def [[:inner 0]]
defmacro [[:inner 0]]
Expand Down Expand Up @@ -50,6 +51,7 @@
ns [[:block 1]]
proxy [[:block 2] [:inner 1]]
reify [[:inner 0] [:inner 1]]
some-> [[:thread] [:block 0]]
struct-map [[:block 1]]
testing [[:block 1]]
thread [[:block 0]]
Expand Down
54 changes: 46 additions & 8 deletions cljfmt/src/cljfmt/core.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -275,15 +275,41 @@
(symbol? key) (= key sym)
(pattern? key) (re-find key (str sym)))))

(defn form-matches-key? [zloc key context]
(defn- form-symbol-matches? [zloc pred context]
(let [possible-sym (form-symbol zloc)]
(or (symbol-matches-key? (fully-qualified-symbol possible-sym context) key)
(symbol-matches-key? (remove-namespace possible-sym) key))))
(or (pred (fully-qualified-symbol possible-sym context))
(pred (remove-namespace possible-sym)))))

(defn- form-matches-key? [zloc key context]
(form-symbol-matches? zloc #(symbol-matches-key? % key) context))

(defn- form-matches-thread-macro? [zloc context]
(form-symbol-matches? zloc (:threads context) context))

(defn- get-zipper-position [zloc]
(loop [idx 0
loop-zloc (z/leftmost zloc)]
(cond
(= zloc loop-zloc) idx
(= loop-zloc (z/rightmost zloc)) nil
:else (recur (inc idx) (z/right loop-zloc)))))

(defn- in-thread-macro? [zloc context]
(when (= zloc (z/root zloc))
(when-some [idx (form-matches-thread-macro? zloc context)]
(let [position (cond-> (get-zipper-position (z/up zloc))
(in-thread-macro? (z/up (z/up zloc)) context) inc)]
(cond
(< position 2) false
(= idx :odd) (odd? position)
(= idx :even) (even? position)
:else (<= idx position))))))

(defn- inner-indent [zloc key depth idx context]
(let [top (nth (iterate z/up zloc) depth)]
(let [top (nth (iterate z/up zloc) depth)
adjusted-idx (cond-> idx (in-thread-macro? zloc context) (some-> dec))]
(when (and (form-matches-key? top key context)
(or (nil? idx) (index-matches-top-argument? zloc depth idx)))
(or (nil? idx) (index-matches-top-argument? zloc depth adjusted-idx)))
(let [zup (z/up zloc)]
(+ (margin zup) (indent-width zup))))))

Expand All @@ -302,9 +328,10 @@

(defn- block-indent [zloc key idx context]
(when (form-matches-key? zloc key context)
(let [zloc-after-idx (some-> zloc (nth-form (inc idx)))]
(let [adjusted-idx (cond-> idx (in-thread-macro? zloc context) (some-> dec (max 0)))
zloc-after-idx (some-> zloc (nth-form (inc adjusted-idx)))]
(if (and (or (nil? zloc-after-idx) (first-form-in-line? zloc-after-idx))
(> (index-of zloc) idx))
(> (index-of zloc) adjusted-idx))
(inner-indent zloc key 0 nil context)
(list-indent zloc context)))))

Expand Down Expand Up @@ -336,6 +363,9 @@
(defmethod indenter-fn :block [sym context [_ idx]]
(fn [zloc] (block-indent zloc sym idx context)))

(defmethod indenter-fn :thread [_ _ _]
(constantly nil))

(defn- make-indenter [[key opts] context]
(apply some-fn (map (partial indenter-fn key context) opts)))

Expand Down Expand Up @@ -372,6 +402,13 @@
(defn- find-namespace [zloc]
(some-> zloc root z/down (z/find z/right ns-form?) z/down z/next z/sexpr))

(defn- get-thread-indents [indents]
(->> indents
(keep (fn [[k v]]
(when-first [[_ idx] (filter (fn [[rule]] (= rule :thread)) v)]
[k (or idx 2)])))
(into {})))

(defn indent
([form]
(indent form default-indents {}))
Expand All @@ -384,7 +421,8 @@
sorted-indents (sort-by indent-order indents)
context (merge (select-keys opts [:function-arguments-indentation])
{:alias-map alias-map
:ns-name ns-name})]
:ns-name ns-name
:threads (get-thread-indents indents)})]
(transform form edit-all should-indent?
#(indent-line % sorted-indents context)))))

Expand Down
43 changes: 42 additions & 1 deletion cljfmt/test/cljfmt/core_test.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -692,7 +692,48 @@
["#:clj {:a :b"
":c :d}"]
["#:clj {:a :b"
" :c :d}"]))))
" :c :d}"])))

(testing "thread first"
(is (reformats-to?
["(-> v"
"(cond-> a b"
"c d))"]
["(-> v"
" (cond-> a b"
" c d))"]))
(is (reformats-to?
["(cond-> v"
"a b"
"c d)"]
["(cond-> v"
" a b"
" c d)"]))
(is (reformats-to?
["(-> v"
"(cond-> a b"
"c d))"]
["(-> v"
" (cond-> a b"
" c d))"]))
(is (reformats-to?
["(-> (cond-> a"
"odd? inc)"
"inc)"]
["(-> (cond-> a"
" odd? inc)"
" inc)"]))
(is (reformats-to?
["(cond-> a"
"(cond-> 1
odd? inc)
(cond-> a b
c d))"]
["(cond-> a"
" (cond-> 1"
" odd? inc)"
" (cond-> a b"
" c d))"]))))

(deftest test-remove-multiple-non-indenting-spaces
(let [opts {:remove-multiple-non-indenting-spaces? true}]
Expand Down