【问题标题】:How to pprint a clojure file?如何打印clojure文件?
【发布时间】:2017-07-23 04:57:57
【问题描述】:

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

【问题讨论】:

    标签: clojure formatting pretty-print


    【解决方案1】:

    您可以使用lein-zprint,它将在您的源文件上运行zprint 库。如果你是引导用户,你可以使用 boot-fmt 来处理你的文件,它也使用 zprint。

    zprint 库将从头开始完全重新格式化您的源代码,使其尽可能漂亮,因为它知道如何制作它。它实际上在每个级别尝试了几件事,以查看哪个“更好”,并内置了许多启发式方法来尝试生成在垂直空间中尽可能多的信息,同时仍然看起来“漂亮”的东西。 它很多了解 Clojure(和 Clojurescript)源代码,并且知道哪些函数需要不同类型的处理以及处理新的 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!")])))))
    

    【讨论】:

      【解决方案2】:

      你可以使用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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-11-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多