如何打印一个clojure文件?

时间:2017-03-03 07:14:11

标签: clojure formatting pretty-print

我希望能够将整个clojure文件格式化以使其看起来不错。我找到的最好的东西是clojures pprint。它在正确的位置进行缩进和换行。然而,它只能阅读clojure litterals。 Clojure文件作为字符串读入。 read-string将只接受字符串的第一个括号。在整个序列上映射read-string有很多我遇到的问题。有人知道一种使clojure文件看起来漂亮的自动方法吗?不只是缩进它吗?

2 个答案:

答案 0 :(得分:3)

您可以使用lein-zprint对您的源文件运行zprint库。如果您是启动用户,则可以使用boot-fmt处理文件,该文件也使用zprint。

zprint库将从头开始完全重新格式化您的源代码,使其与它知道如何制作它一样漂亮。它实际上尝试了每个级别的几个东西,看看哪个是“更好”,并且内置了许多启发式方法,试图在垂直空间中生成尽可能多的信息,同时仍然看起来“漂亮”。 它知道关于Clojure(和Clojurescript)源代码的 lot ,并且知道哪些函数需要不同类型的处理以及处理新的clojure.spec(cljs.spec)文件。

这几乎是荒谬的可配置,所以通过一些工作,你可以调整它以你想要的方式输出代码。但即使没有任何配置,它通常也能很好地使您的代码看起来不错。

将它与lein-zprint一起使用非常简单。 将[lein-zprint "0.1.16"]放入project.clj:

的:plugins向量中

:plugins [[lein-zprint "0.1.16"]]

然后,要格式化源文件,只需在该文件上调用lein zprint:

$ lein zprint src/<project>/<file-name>.clj

除非你另外告诉它(在你的project.clj中这很简单),它会将现有文件重命名为<file-name>.clj.old,以便你在尝试时将它们进行比较。

这是一个例子(显然格式不佳):

(defn apply-style-x
  "Given an existing-map and a new-map, if the new-map specifies a   
  style, apply it if it exists.  Otherwise do nothing. Return   
  [updated-map new-doc-map error-string]"
  [doc-string doc-map existing-map new-map] (let [style-name
  (get new-map :style :not-specified) ] (if
  (= style-name :not-specified) [existing-map doc-map nil]
  (let [style-map ( if (= style-name :default) 
  (get-default-options) (get-in existing-map [:style-map style-name]))]
  (cond (nil? style-name)
  [existing-map doc-map "Can't specify a style of nil!"] 
  style-map [(merge-deep existing-map style-map) (when doc-map 
  (diff-deep-doc (str doc-string " specified :style " style-name)
  doc-map existing-map style-map)) nil] :else
  [existing-map doc-map (str "Style '" style-name "' not found!")])))))
$lein zprint 70 src/example/apply.clj格式化之后

将其格式化为70列,以使其更适合这个答案:

(defn apply-style-x
  "Given an existing-map and a new-map, if the new-map specifies a   
  style, apply it if it exists.  Otherwise do nothing. Return   
  [updated-map new-doc-map error-string]"
  [doc-string doc-map existing-map new-map]
  (let [style-name (get new-map :style :not-specified)]
    (if (= style-name :not-specified)
      [existing-map doc-map nil]
      (let [style-map (if (= style-name :default)
                        (get-default-options)
                        (get-in existing-map
                                [:style-map style-name]))]
        (cond
          (nil? style-name) [existing-map doc-map
                             "Can't specify a style of nil!"]
          style-map
            [(merge-deep existing-map style-map)
             (when doc-map
               (diff-deep-doc
                 (str doc-string " specified :style " style-name)
                 doc-map
                 existing-map
                 style-map)) nil]
          :else [existing-map doc-map
                 (str "Style '" style-name "' not found!")])))))

答案 1 :(得分:1)

您可以使用weavejester/cljfmt

$ boot -d cljfmt:0.5.6 repl

boot.user=> (require '[cljfmt.core :as cljfmt])
nil

boot.user=> (println (cljfmt/reformat-string
       #_=> "( let [x 3
       #_=>   y 4]
       #_=>   (+ (* x x
       #_=>   )(* y y)
       #_=>  ))"))

(let [x 3
      y 4]
  (+ (* x x) (* y y)))
nil

检查其README for the supported formatting options