Skip to content

Commit

Permalink
Simplify two space indentation config
Browse files Browse the repository at this point in the history
- replace the two config options with a single option, `:function-arguments-indentation`, with 3 possible values: `:community`, `:cursive`, or `:zprint`
  • Loading branch information
miridius committed Nov 22, 2023
1 parent 6716c98 commit be0555d
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 89 deletions.
23 changes: 12 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -250,20 +250,21 @@ In order to load the standard configuration file from Leiningen, add the
other references in the `ns` forms at the top of your namespaces.
Defaults to false.

* `:one-space-list-indent?` -
true if cljfmt should follow the [community style recommendation][] to indent
function/macro arguments by a single space when there are no arguments on the
same line as the function name. false if two spaces should be used.
Defaults to true.

* `:one-space-list-indent-tags` -
When `:one-space-list-indent?` is false, re-enables one space indentation for
lists whose first element's [node tag][] is contained in this set.
Defaults to `#{:vector :map :list :set}`
* `:function-arguments-indentation` -
- `:community` if cljfmt should follow the [community style recommendation][]
to indent function/macro arguments by a single space when there
are no arguments on the same line as the function name.
- `:cursive` if two spaces should be used instead, unless the first
thing in the list (not counting metadata) is a data structure
literal. This should replicate Cursive's default behaviour.
- `:zprint` if two spaces should be used instead if the first thing
in the list is a symbol or keyword. This should replicate zprint's
default behaviour.

Defaults to `:community`

[indents.md]: docs/INDENTS.md
[community style recommendation]: https://guide.clojure.style/#one-space-indent
[node tag]: https://cljdoc.org/d/rewrite-clj/rewrite-clj/1.1.47/api/rewrite-clj.node#tag

### Runtime Options

Expand Down
65 changes: 33 additions & 32 deletions cljfmt/src/cljfmt/core.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -188,24 +188,27 @@
(dec)))

(defn- skip-meta [zloc]
(when (#{:meta :meta*} (z/tag zloc))
(-> zloc z/down z/right)))
(if (#{:meta :meta*} (z/tag zloc))
(-> zloc z/down z/right)
zloc))

(defn- has-tag? [zloc tags]
(or (contains? tags (z/tag zloc))
(some-> zloc skip-meta (has-tag? tags))))
(defn- cursive-two-space-list-indent? [zloc]
(-> zloc z/leftmost* skip-meta z/tag #{:vector :map :list :set} not))

(defn- list-indent [zloc context]
(cond
(> (index-of zloc) 1)
(-> zloc z/leftmost* z/right margin)
(defn- zprint-two-space-list-indent? [zloc]
(-> zloc z/leftmost* z/tag #{:token :list}))

(or (:one-space-list-indent? context)
(has-tag? (z/leftmost* zloc) (:one-space-list-indent-tags context)))
(coll-indent zloc)
(defn two-space-list-indent? [zloc context]
(case (:function-arguments-indentation context)
:community false
:cursive (cursive-two-space-list-indent? zloc)
:zprint (zprint-two-space-list-indent? zloc)))

:else
(inc (coll-indent zloc))))
(defn- list-indent [zloc context]
(if (> (index-of zloc) 1)
(-> zloc z/leftmost* z/right margin)
(cond-> (coll-indent zloc)
(two-space-list-indent? zloc context) inc)))

(def indent-size 2)

Expand Down Expand Up @@ -310,6 +313,20 @@
(read-resource "cljfmt/indents/compojure.clj")
(read-resource "cljfmt/indents/fuzzy.clj")))

(def default-options
{:indentation? true
:insert-missing-whitespace? true
:remove-consecutive-blank-lines? true
:remove-multiple-non-indenting-spaces? false
:remove-surrounding-whitespace? true
:remove-trailing-whitespace? true
:split-keypairs-over-multiple-lines? false
:sort-ns-references? false
:function-arguments-indentation :community
:indents default-indents
:extra-indents {}
:alias-map {}})

(defmulti ^:private indenter-fn
(fn [_sym _context [type & _args]] type))

Expand Down Expand Up @@ -361,12 +378,11 @@
([form indents]
(indent form indents {}))
([form indents alias-map]
(indent form indents alias-map {:one-space-list-indent? true}))
(indent form indents alias-map default-options))
([form indents alias-map opts]
(let [ns-name (find-namespace (z/of-node form))
sorted-indents (sort-by indent-order indents)
context (merge (select-keys opts [:one-space-list-indent?
:one-space-list-indent-tags])
context (merge (select-keys opts [:function-arguments-indentation])
{:alias-map alias-map
:ns-name ns-name})]
(transform form edit-all should-indent?
Expand Down Expand Up @@ -508,21 +524,6 @@
(defn sort-ns-references [form]
(transform form edit-all ns-reference? sort-arguments))

(def default-options
{:indentation? true
:insert-missing-whitespace? true
:one-space-list-indent? true
:one-space-list-indent-tags #{:vector :map :list :set}
:remove-consecutive-blank-lines? true
:remove-multiple-non-indenting-spaces? false
:remove-surrounding-whitespace? true
:remove-trailing-whitespace? true
:split-keypairs-over-multiple-lines? false
:sort-ns-references? false
:indents default-indents
:extra-indents {}
:alias-map {}})

(defn reformat-form
([form]
(reformat-form form {}))
Expand Down
9 changes: 6 additions & 3 deletions cljfmt/src/cljfmt/main.clj
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,12 @@
[nil "--[no-]sort-ns-references"
:default (:sort-ns-references? defaults)
:id :sort-ns-references?]
[nil "--[no-]one-space-list-indent"
:default (:one-space-list-indent? defaults)
:id :one-space-list-indent?]])
[nil "--function-arguments-indentation STYLE" "STYLE may be community, cursive, or zprint"
:default (:function-arguments-indentation defaults)
:default-desc (name (:function-arguments-indentation defaults))
:parse-fn keyword
:validate [#{:community :cursive :zprint} "Must be one of community, cursive, or zprint"]
:id :function-arguments-indentation]])

(defn- abort [& msg]
(binding [*out* *err*]
Expand Down
78 changes: 35 additions & 43 deletions cljfmt/test/cljfmt/core_test.cljc
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
(ns cljfmt.core-test
(:require #?(:clj [cljfmt.test-util.clojure])
[#?@(:clj (clojure.test :refer)
:cljs (cljs.test :refer-macros)) [deftest testing is]]
:cljs (cljs.test :refer-macros)) [deftest testing is are]]
[cljfmt.core :refer [reformat-string default-line-separator
normalize-newlines find-line-separator
replace-newlines wrap-normalize-newlines]]
Expand All @@ -18,24 +18,22 @@
" baz"
" quz)"]))

(is (reformats-to?
["(foo"
"bar"
"baz)"]
["(foo"
" bar"
" baz)"])
"to first arg")

(is (reformats-to?
["(foo"
"bar"
"baz)"]
["(foo"
" bar"
" baz)"]
{:one-space-list-indent? false})
"2 spaces when `:one-space-list-indent?` is false"))
(are [fn-args-indent expected]
(reformats-to?
["(foo"
"bar"
"baz)"]
expected
{:function-arguments-indentation fn-args-indent})
:community ["(foo"
" bar"
" baz)"]
:cursive ["(foo"
" bar"
" baz)"]
:zprint ["(foo"
" bar"
" baz)"]))

(testing "block indentation"
(is (reformats-to?
Expand Down Expand Up @@ -555,7 +553,7 @@
""
" ;b"
" )"]
{:one-space-list-indent? false})))
{:function-arguments-indentation :cursive})))

(testing "empty indent blocks"
(is (reformats-to?
Expand Down Expand Up @@ -605,7 +603,7 @@
["(foo"
" )"]
{:remove-surrounding-whitespace? false
:one-space-list-indent? false}))
:function-arguments-indentation :cursive}))
(is (reformats-to?
["(foo (bar (baz)))"]
["(foo (bar (baz)))"]))
Expand Down Expand Up @@ -1049,8 +1047,8 @@
" )"
" )"]
{:remove-surrounding-whitespace? false
:one-space-list-indent? false})
"indents properly with :one-space-list-indent? set to false")))
:function-arguments-indentation :cursive})
"indents properly with :function-arguments-indentation set to :cursive")))

(deftest test-options
(is (reformats-to?
Expand Down Expand Up @@ -1113,8 +1111,8 @@
" foo"
" bar)"]
{:indents {}
:one-space-list-indent? false})
"can clear all indents rules with :one-space-list-indent? set to false")
:function-arguments-indentation :cursive})
"can clear all indents rules with :function-arguments-indentation :cursive")
(is (reformats-to?
["(do"
"foo"
Expand Down Expand Up @@ -1154,7 +1152,7 @@
" )"]
{:remove-surrounding-whitespace? false
:remove-trailing-whitespace? false
:one-space-list-indent? false}))
:function-arguments-indentation :cursive}))
(is (reformats-to?
["( "
"foo"
Expand All @@ -1173,7 +1171,7 @@
" )"]
{:remove-surrounding-whitespace? false
:remove-trailing-whitespace? false
:one-space-list-indent? false}))
:function-arguments-indentation :cursive}))
(is (reformats-to?
["(foo"
" bar "
Expand All @@ -1192,7 +1190,7 @@
" )"]
{:remove-surrounding-whitespace? false
:remove-trailing-whitespace? false
:one-space-list-indent? false}))
:function-arguments-indentation :cursive}))
(is (reformats-to?
["{:one two :three four}"]
["{:one two"
Expand Down Expand Up @@ -1305,7 +1303,7 @@
" 3 4)"]
{:alias-map {"other" "another.lib"}
:sort-ns-references? true
:one-space-list-indent? false
:function-arguments-indentation :cursive
:indents {'block1 [[:block 1]]
'other.lib/overridden [[:block 2]] ;; This one is ignored
'another.lib/overridden [[:block 1]] ;; As this one overrides.
Expand Down Expand Up @@ -1335,7 +1333,7 @@
"bar)"]
["#_(foo"
" bar)"]
{:one-space-list-indent? false}))
{:function-arguments-indentation :cursive}))
(is (reformats-to?
["(juxt +' -')"]
["(juxt +' -')"]))
Expand Down Expand Up @@ -1476,7 +1474,7 @@
" b"
" [c]))"]
{:sort-ns-references? true
:one-space-list-indent? false}))
:function-arguments-indentation :cursive}))
(is (reformats-to?
["(ns foo.bar"
" (:require"
Expand Down Expand Up @@ -1505,9 +1503,9 @@
" ^{:x 1} b"
" [c]))"]
{:sort-ns-references? true
:one-space-list-indent? false})))
:function-arguments-indentation :cursive})))

(deftest one-space-list-indent-tags
(deftest cursive-and-zprint-function-argument-indents-depend-on-first-element
(let [input ["(foo"
"bar)"
"(:foo"
Expand Down Expand Up @@ -1564,7 +1562,7 @@
"bar)"
"(#:foo{:bar 1}"
"baz)"]]
(testing "matches Cursive style by default"
(testing ":cursive style uses two spaces unless starting with a collection"
(is (reformats-to?
input
["(foo"
Expand Down Expand Up @@ -1623,8 +1621,8 @@
" bar)"
"(#:foo{:bar 1}"
" baz)"]
{:one-space-list-indent? false})))
(testing "can also match zprint style"
{:function-arguments-indentation :cursive})))
(testing ":zprint uses two spaces when starting with a symbol, keyword, or list"
(is (reformats-to?
input
["(foo"
Expand Down Expand Up @@ -1683,10 +1681,4 @@
" bar)"
"(#:foo{:bar 1}"
" baz)"]
{:one-space-list-indent? false
;; everything except :token and :list
:one-space-list-indent-tags #{:meta :meta* :vector :map
:eval :uneval :fn
:set :deref :reader-macro :unquote
:var :quote :syntax-quote :unquote-splicing
:namespaced-map}})))))
{:function-arguments-indentation :zprint})))))

0 comments on commit be0555d

Please sign in to comment.