我正在寻找一个正确的编辑/命令行程序(IMHO)缩进Clojure代码,将第三个和后续元素与第二个元素对齐:
(let [foo (fun arg1
arg2)
bar (doto (Baz.)
(.setProp abc123))
[v1 v2] (fun2)
[v3 v4] (fun3)]
(xyzzy 42))
我已尝试使用“通过第二个元素对齐Clojure表单”(由第二个元素对齐),VimClojure,emacs(混淆了[v3 v4]
部分的缩进),然后使用了对于IntelliJ的La Clojure,Enclojure在Netbeans中(不与第二个元素对齐),在Eclipse中逆时针(不与第二个元素对齐)。在每种情况下,我都在使用最新版本的软件。
如果需要,我可以在编辑器外部(在命令行上)运行一个美化器。
以下是Aquamacs的输出。请注意“级联”(make-day-panel)调用:
(defn make-mainframe [build-number project-version]
"Create the mainframe.
@param build-number the current build number
@param project-version the Maven project version
@returns the reified JFrame"
(let [[^JToggleButton day-sheets-button
^JToggleButton summaries-button]
(let [day-sheets-button
(doto (JToggleButton. "Day Sheets")
(.setToolTipText
"Switch to the Day Sheets view"))
summaries-button
(doto (JToggleButton. "Summaries")
(.setToolTipText "Switch to the Summaries view"))]
(doto (ButtonGroup.)
(.add day-sheets-button)
(.add summaries-button))
(.setSelected day-sheets-button true)
[day-sheets-button summaries-button])
[^JPanel monday-panel
monday-button
monday-vacation-check
monday-arrive-text-field
monday-depart-text-field] (make-day-panel "Monday")
[^JPanel tuesday-panel
tuesday-button
tuesday-vacation-check
tuesday-arrive-text-field
tuesday-depart-text-field] (make-day-panel "Tuesday")
[^JPanel wednesday-panel
wednesday-button
wednesday-vacation-check
wednesday-arrive-text-field
wednesday-depart-text-field] (make-day-panel "Wednesday")
[^JPanel thursday-panel
thursday-button
thursday-vacation-check
thursday-arrive-text-field
thursday-depart-text-field] (make-day-panel "Thursday")
[^JPanel friday-panel
friday-button
friday-vacation-check
friday-arrive-text-field
friday-depart-text-field] (make-day-panel "Friday")
[^JPanel saturday-panel
saturday-button
saturday-vacation-check
saturday-arrive-text-field
saturday-depart-text-field] (make-day-panel "Saturday")
[^JPanel sunday-panel
sunday-button
sunday-vacation-check
sunday-arrive-text-field
sunday-depart-text-field] (make-day-panel "Sunday")
#_ [week-selector-panel week-selector-combobox week-selector-today-button]
#_ (make-week-selector)
north-panel
(let [^JPanel panel (JPanel.)]
(doto panel
(.setLayout (BoxLayout. panel BoxLayout/X_AXIS))
(.add day-sheets-button)
(.add (Box/createHorizontalStrut 5))
(.add summaries-button)
(.add (Box/createHorizontalGlue))
#_ (.add week-selector-panel)))
^JToggleButton mail-button
(make-button "Mail Report"
(make-icon "email-32x32-plain.png")
"Generate and send a weekly report for the currently selected week")
^JToggleButton report-button
(make-button "Report"
(make-icon "history2-32x32-plain.png")
"Generate a weekly report for the currently selected week")
day-sheet-panel
(let [panel (JPanel. (BorderLayout.))
north-panel (grid-bag-container (JPanel. (GridBagLayout.))
{:insets (Insets. 2 2 2 2)}
[[(doto (JPanel. (GridLayout. 1 0))
(.add report-button)
(.add mail-button))]
[(Box/createHorizontalGlue)
:weightx 1.0 :fill :HORIZONTAL ]
[(doto (JPanel. (GridLayout. 1 0))
(.add monday-panel)
(.add tuesday-panel)
(.add wednesday-panel)
(.add thursday-panel)
(.add friday-panel)
(.add saturday-panel)
(.add sunday-panel))]])]
(doto panel
(.add north-panel BorderLayout/NORTH)
(.setBorder (BorderFactory/createRaisedBevelBorder))))
summaries-panel (let [panel (JPanel.)]
(doto panel))
card-panel (let [panel (JPanel. (CardLayout.))]
(doto panel
(.add day-sheet-panel day-sheet-panel-key)
(.add summaries-panel summaries-panel-key)))
main-panel (doto (JPanel. (BorderLayout.))
(.setBorder
(BorderFactory/createEmptyBorder default-border default-border
default-border default-border))
(.add north-panel BorderLayout/NORTH)
(.add card-panel))
frame (doto (JFrame. (str "SpareTime (version " project-version ", build "
build-number ")"))
(.setDefaultCloseOperation JFrame/EXIT_ON_CLOSE)
(.add main-panel))]
(reify mainview-methods
(frame-add-component-listener [_ listener] (.addComponentListener frame listener))
(frame-center [_] (.setLocationRelativeTo frame nil))
(frame-get-location [_] (.getLocation frame))
(frame-get-size [_] (.getSize frame))
(frame-set-location [_ x y] (.setLocation frame x y))
(frame-set-size [_ width height] (.setSize frame (Dimension. width height)))
(frame-set-visible [_ visible] (.setVisible frame visible)))))
答案 0 :(得分:2)
据我所知,当前的clojure-mode缩进就像你想要的那样,只是它把doto处理为特殊的(也就是说,它从第三个表单开始缩进以制作“目标”的立场更多)。
使用来自橘子酱的clojure-mode在我的emacs 24上输出indent-sexp
:
(let [foo (fun arg1
arg2)
bar (doto (Baz.)
(.setProp abc123))
[v1 v2] (fun2)
[v3 v4] (fun3)]
(xyzzy 42))
我认为你要么破坏了clojure模式,要么aquamacs又变得困难了。我真的建议在OSX上使用标准的Gnu emacs - 只要你将meta映射到命令以外的东西,你就可以在标准的emacs中使用大多数简单的标准osx密钥组合(command-c,command-v,command-s等)
附录:该大型代码块的输出(请注意make-day-panel调用的正确位置):
(defn make-mainframe [build-number project-version]
"Create the mainframe.
@param build-number the current build number
@param project-version the Maven project version
@returns the reified JFrame"
(let [[^JToggleButton day-sheets-button
^JToggleButton summaries-button]
(let [day-sheets-button
(doto (JToggleButton. "Day Sheets")
(.setToolTipText
"Switch to the Day Sheets view"))
summaries-button
(doto (JToggleButton. "Summaries")
(.setToolTipText "Switch to the Summaries view"))]
(doto (ButtonGroup.)
(.add day-sheets-button)
(.add summaries-button))
(.setSelected day-sheets-button true)
[day-sheets-button summaries-button])
[^JPanel monday-panel
monday-button
monday-vacation-check
monday-arrive-text-field
monday-depart-text-field] (make-day-panel "Monday")
[^JPanel tuesday-panel
tuesday-button
tuesday-vacation-check
tuesday-arrive-text-field
tuesday-depart-text-field] (make-day-panel "Tuesday")
[^JPanel wednesday-panel
wednesday-button
wednesday-vacation-check
wednesday-arrive-text-field
wednesday-depart-text-field] (make-day-panel "Wednesday")
[^JPanel thursday-panel
thursday-button
thursday-vacation-check
thursday-arrive-text-field
thursday-depart-text-field] (make-day-panel "Thursday")
[^JPanel friday-panel
friday-button
friday-vacation-check
friday-arrive-text-field
friday-depart-text-field] (make-day-panel "Friday")
[^JPanel saturday-panel
saturday-button
saturday-vacation-check
saturday-arrive-text-field
saturday-depart-text-field] (make-day-panel "Saturday")
[^JPanel sunday-panel
sunday-button
sunday-vacation-check
sunday-arrive-text-field
sunday-depart-text-field] (make-day-panel "Sunday")
#_ [week-selector-panel week-selector-combobox week-selector-today-button]
#_ (make-week-selector)
north-panel
(let [^JPanel panel (JPanel.)]
(doto panel
(.setLayout (BoxLayout. panel BoxLayout/X_AXIS))
(.add day-sheets-button)
(.add (Box/createHorizontalStrut 5))
(.add summaries-button)
(.add (Box/createHorizontalGlue))
#_ (.add week-selector-panel)))
^JToggleButton mail-button
(make-button "Mail Report"
(make-icon "email-32x32-plain.png")
"Generate and send a weekly report for the currently selected week")
^JToggleButton report-button
(make-button "Report"
(make-icon "history2-32x32-plain.png")
"Generate a weekly report for the currently selected week")
day-sheet-panel
(let [panel (JPanel. (BorderLayout.))
north-panel (grid-bag-container (JPanel. (GridBagLayout.))
{:insets (Insets. 2 2 2 2)}
[[(doto (JPanel. (GridLayout. 1 0))
(.add report-button)
(.add mail-button))]
[(Box/createHorizontalGlue)
:weightx 1.0 :fill :HORIZONTAL ]
[(doto (JPanel. (GridLayout. 1 0))
(.add monday-panel)
(.add tuesday-panel)
(.add wednesday-panel)
(.add thursday-panel)
(.add friday-panel)
(.add saturday-panel)
(.add sunday-panel))]])]
(doto panel
(.add north-panel BorderLayout/NORTH)
(.setBorder (BorderFactory/createRaisedBevelBorder))))
summaries-panel (let [panel (JPanel.)]
(doto panel))
card-panel (let [panel (JPanel. (CardLayout.))]
(doto panel
(.add day-sheet-panel day-sheet-panel-key)
(.add summaries-panel summaries-panel-key)))
main-panel (doto (JPanel. (BorderLayout.))
(.setBorder
(BorderFactory/createEmptyBorder default-border default-border
default-border default-border))
(.add north-panel BorderLayout/NORTH)
(.add card-panel))
frame (doto (JFrame. (str "SpareTime (version " project-version ", build "
build-number ")"))
(.setDefaultCloseOperation JFrame/EXIT_ON_CLOSE)
(.add main-panel))]
(reify mainview-methods
(frame-add-component-listener [_ listener] (.addComponentListener frame listener))
(frame-center [_] (.setLocationRelativeTo frame nil))
(frame-get-location [_] (.getLocation frame))
(frame-get-size [_] (.getSize frame))
(frame-set-location [_ x y] (.setLocation frame x y))
(frame-set-size [_ width height] (.setSize frame (Dimension. width height)))
(frame-set-visible [_ visible] (.setVisible frame visible)))))
答案 1 :(得分:1)
据我所知,如果你在同一行开始一个全新的性别与缩进的延续,Emacs压头不明白发生了什么,这就是你let
以上所做的事情。你看到了与
(if (< 1 (- 3
1) 3
4))
当然,开头写的不是很好的风格,所以也许Emacs可以原谅。正如你所指出的那样,这样形状的代码更有可能出现在Clojure的let
或cond
中,并且风格也不错 - 但是Emacs压头是为其他lisps设计的,这需要每对都是用括号括起来:
(let [([x
y
z] (foo))
([a
b
c] (bar))]
...)
正如你所看到的那样,缩进很好。因此,我认为在某些时候有人必须弄清楚如何更新Emacs压头以适应这种情况,并且这比让其他编辑器达到Emacs的水平更容易。也许那个人应该是你,如果它困扰你 - 我想是开源的魔力和负担。
答案 2 :(得分:1)
当您从doto
移除lispwords
时,VimClojure将缩进您想要的方式(如果我理解您的示例正确)。
setlocal lispwords-=doto
答案 3 :(得分:0)
LightTable在Joost的帖子中以与Emacs相同的方式缩进它:
(let [foo (fun arg1
arg2)
bar (doto (Baz.)
(.setProp abc123))
[v1 v2] (fun2)
[v3 v4] (fun3)]
(xyzzy 42))
如果你问我,那就太好了。根据我的经验,它比IDEA,Sublime Text或Netbeans更好。如果你不是Vim / Emacs用户,值得一试。它仍然处于早期阶段,但显示出很多希望。它的设计考虑了Clojure。