clojure社区是否有相同的perltidy?

时间:2015-03-12 05:14:50

标签: emacs clojure

我有一个像这样的函数定义:

(defn init-globals [] (def *board-width* 15))

我希望能够重新格式化,使其看起来像:

(defn init-globals []
   (def *board-width* 15))

我希望格式化是由一个智能代理完成的,它不仅会缩减固定数量的所有内容,或者只是每行打印一个元素等等。这是perltidy所做的事情。

perltidy采用如下代码:

sub foo {
my $args = shift;    $a = $args->{a}; $long_var = $args->{b}; }

并将其变为:

sub foo {
    my $args = shift;
    $a        = $args->{a};
    $long_var = $args->{b};
}

注意它如何将“sub”定义视为一个整体,甚至最后两个赋值中的“=”排成一行。虽然我不一定需要这种级别的格式化,但我想要一些列表(或更准确地说,一个表单),这是一个带有args和子表达式的函数,并使其尽可能具有人类可读性。

我的函数定义是单行的原因是因为它是从宏生成的。我不想用格式化指令来混淆宏(如果我确实可以在不生成字符串而不是列表的情况下这样做),因为宏很难实现。虽然我可以将列表评估到我的REPL中,但我还想将生成的代码写入文件,就好像它是手动输入的那样,即可以检查源代码控制的内容。

我看过像(clojure.pprint / pp)这样的东西,并使用emacs的indent-sexp和smartparen的'sp-indent-defun,但他们不会将输出分成多行等等。 / p>

我可以与emacs / elisp命令互操作,所以如果有办法用emacs做,那也可以。

2 个答案:

答案 0 :(得分:4)

如果这是您想要做的,那么我建议您只是打印生成的代码(或者您想将其写入文件),然后向其投掷cljfmt

有一些工具,比如bbloom' Fipp,它可以在Clojure实例中进行类似的代码打印,但据我所知,cljfmt做得更好。

我认为值得考虑为什么你试图保存宏扩展代码,因为宏扩展的代价是名义上的,并且根据需要生成代码被认为是更好的做法而不是生成代码,保存它,然后处理它,就像它是手写的一样。保留代码生成也意味着您的代码库更加灵活,您只需调整生成器并重新加载所涉及的命名空间,而不必重新生成生成的代码,然后重新格式化并重新编译它。

答案 1 :(得分:2)

lispy - 我的扩展程序包含一般的短绑定 LISP编程。

它支持任何LISP,甚至还有Clojure内联eval,内联args,内联doc和goto-symbol via 苹果酒。

它还有一个天真的多线程快捷方式,可以完全满足您的需求 特别的功能。

启用lispy-mode后,您需要将光标放在defn之前或之后的paren上 线路末端的线路。然后按 M 将表达式格式化为多个 线。

要将其格式化为单行,请按 O

改进格式错误的表达式,如下所示:

(defn init-globals[](def *board-width* 15
                      )
  )

导航到正确的paren并按 i

如果您对特定 M 的结果不满意, 可以使用 h j k l 手动快速修复它 f d for by-paren navigation。