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

Configuration option for two space list indentation #324

Merged
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
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +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.

* `: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

### Runtime Options

Expand Down
72 changes: 49 additions & 23 deletions cljfmt/src/cljfmt/core.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -187,10 +187,28 @@
(count)
(dec)))

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

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

(defn- zprint-two-space-list-indent? [zloc]
(-> zloc z/leftmost* z/tag #{:token :list}))

(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)))

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

(def indent-size 2)

Expand Down Expand Up @@ -288,13 +306,27 @@
(if (and (or (nil? zloc-after-idx) (first-form-in-line? zloc-after-idx))
(> (index-of zloc) idx))
(inner-indent zloc key 0 nil context)
(list-indent zloc)))))
(list-indent zloc context)))))

(def default-indents
(merge (read-resource "cljfmt/indents/clojure.clj")
(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 All @@ -315,12 +347,12 @@

(defn- custom-indent [zloc indents context]
(if (empty? indents)
(list-indent zloc)
(list-indent zloc context)
(let [indenter (->> indents
(map #(make-indenter % context))
(apply some-fn))]
(or (indenter zloc)
(list-indent zloc)))))
(list-indent zloc context)))))

(defn- indent-amount [zloc indents context]
(let [tag (-> zloc z/up z/tag)
Expand All @@ -346,11 +378,15 @@
([form indents]
(indent form indents {}))
([form indents alias-map]
(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)]
sorted-indents (sort-by indent-order indents)
context (merge (select-keys opts [:function-arguments-indentation])
{:alias-map alias-map
:ns-name ns-name})]
(transform form edit-all should-indent?
#(indent-line % sorted-indents {:alias-map alias-map
:ns-name ns-name})))))
#(indent-line % sorted-indents context)))))

(defn- map-key? [zloc]
(and (z/map? (z/up zloc))
Expand Down Expand Up @@ -381,7 +417,9 @@
([form indents]
(indent (unindent form) indents))
([form indents alias-map]
(indent (unindent form) indents alias-map)))
(indent (unindent form) indents alias-map))
([form indents alias-map opts]
(indent (unindent form) indents alias-map opts)))

(defn final? [zloc]
(and (nil? (z/right* zloc)) (root? (z/up* zloc))))
Expand Down Expand Up @@ -486,19 +524,6 @@
(defn sort-ns-references [form]
(transform form edit-all ns-reference? sort-arguments))

(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
:indents default-indents
:extra-indents {}
:alias-map {}})

(defn reformat-form
([form]
(reformat-form form {}))
Expand All @@ -519,7 +544,8 @@
remove-multiple-non-indenting-spaces)
(cond-> (:indentation? opts)
(reindent (merge (:indents opts) (:extra-indents opts))
(:alias-map opts)))
(:alias-map opts)
opts))
(cond-> (:remove-trailing-whitespace? opts)
remove-trailing-whitespace)))))

Expand Down
10 changes: 9 additions & 1 deletion cljfmt/src/cljfmt/main.clj
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,15 @@
:id :split-keypairs-over-multiple-lines?]
[nil "--[no-]sort-ns-references"
:default (:sort-ns-references? defaults)
:id :sort-ns-references?]])
:id :sort-ns-references?]
[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
Loading
Loading