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

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

我希望能够重新格式化,使其看起来像:
(defn init-globals []
   (def *board-width* 15))

我希望格式化是由智能代理完成的,它不仅使所有内容缩进固定的数量,或者仅在每行中打印一个元素,等等。这是完美的。

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,但它们并没有将输出分成多行。

我可以与emacs / elisp命令进行互操作,因此,如果有一种方法可以与emacs一起使用,那也可以。

最佳答案

如果这是您要执行的操作,那么我建议您仅打印生成的代码(或者将其写入文件),然后将cljfmt扔给它。

存在诸如bbloom的Fipp之类的工具,可以从Clojure实例内部进行类似的代码漂亮打印,但是据我所知,cljfmt可以做得更好。

我认为值得考虑一下为什么要保存宏扩展的代码,因为宏扩展的成本是名义上的,因此,按需生成代码而不是生成代码,将其保存然后再进行处理似乎是一种更好的做法。它是手写的。保留代码生成还意味着代码库更加灵活,因为您只需调整生成器并重新加载所涉及的名称空间,而不必重新生成生成的代码,然后重新格式化并重新编译即可。

09-04 18:00
查看更多