Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix #45: Thread first changes the indentation of the inner forms #344

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
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
21 changes: 17 additions & 4 deletions cljfmt/src/cljfmt/core.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -280,10 +280,22 @@
(or (symbol-matches-key? (fully-qualified-symbol possible-sym context) key)
(symbol-matches-key? (remove-namespace possible-sym) key))))

(defn- parent-is-thread-first? [zloc context]
(some #(form-matches-key? zloc % context) #{'-> 'as-> 'some-> 'cond->}))
lambdank marked this conversation as resolved.
Show resolved Hide resolved

(defn- is-first-parameter? [zloc]
(= (z/right (z/leftmost zloc)) zloc))
lambdank marked this conversation as resolved.
Show resolved Hide resolved

(defn- adjust-idx [zloc idx context]
(cond-> idx
(and (parent-is-thread-first? zloc context) (not (is-first-parameter? zloc)))
(some-> dec (max 0))))
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of adjust-idx which doesn't convey why the index is being adjusted, perhaps instead we just split out the predicate:

(defn- in-thread-macro? [zloc context]
  (and (form-matches-thread-macro? zloc) (not (first-argument? zloc))))

Then we could write:

(cond-> idx (in-thread-macro? zloc context) dec)

I'm unsure why you have (some-> dec (max 0)) instead of just dec. Under what circumstances would the index be less than or equal to zero?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't idx be zero in this case, if I configured {cond-> [[:block 0]]}?
There is a check for (nil? idx) in inner-indent already. Isn't it nil when there is no indentation rule, like (-> x foo bar)?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The index is the position of the child in the parent form, IIRC. So, come to thing about it, we could change (not (first-argument? zloc)) to (> idx 1).

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't the index come from the :indents as specified here?
So for :block it uses default indenting until we reach the index. So if we are in a thread, we should basically hit that index one spot before (ie. decrease the index). If the index is 0, we should keep it at 0.
For :inner when index is set, it is restricted to that particular index. So that should also occur one spot earlier (ie. decrease the index). If the index is 0, then we should avoid using this indentation rule, since the spot it was meant for is not present.

I also oversaw the depth argument of inner. Here we should check whether the parent of the top zloc is wrapped in a thread. I'll commit a fix.

Hope it makes sense.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, yes, I believe you're right. I need to refresh myself on the indentation logic as it's been a while since I've looked at it.


(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 (adjust-idx (z/up zloc) idx context)]
(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 +314,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 (adjust-idx (z/up zloc) idx context)
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
34 changes: 33 additions & 1 deletion cljfmt/test/cljfmt/core_test.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -692,7 +692,39 @@
["#: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)"]))))

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