Clojure индентор, который работает - PullRequest
2 голосов
/ 18 октября 2011

Я ищу программу редактора / командной строки, которая правильно (ИМХО) делает отступ в коде Clojure, выравнивая третий и последующие элементы со вторым элементом:

(let [foo (fun arg1
               arg2)

      bar (doto (Baz.)
                (.setProp abc123))

      [v1 v2] (fun2)

      [v3 v4] (fun3)]
  (xyzzy 42))

Я пробовал La Clojure для IntelliJ с «Выровнять формы Clojure по второму элементу» (не выравнивает по второму элементу), VimClojure, emacs (испортил отступ для части [v3 v4]), Enclojure в Netbeans (не выравнивается по второму элементу) и против часовой стрелки в Eclipse (не выравнивается по второму элементу). В каждом случае я использую последнюю версию программного обеспечения.

При необходимости я могу запустить beautifier за пределами редактора (в командной строке).

Вот вывод 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)))))

Ответы [ 4 ]

2 голосов
/ 18 октября 2011

Насколько я могу судить, текущие отступы в режиме clojure, как вы хотите, за исключением того, что он обрабатывает doto как особый (то есть он отступает от формы третья и далее, чтобы выделить "цель" больше).

Вывод для indent-sexp на моем emacs 24 с clojure-mode из мармелада:

(let [foo (fun arg1
               arg2)

      bar (doto (Baz.)
            (.setProp abc123))

      [v1 v2] (fun2)

      [v3 v4] (fun3)]
  (xyzzy 42))

Я думаю, что у вас либо сломан режим clojure, либо aquamacs снова становится другим и трудным. Я действительно рекомендую использовать стандартный emacs Gnu в OSX - если вы сопоставляете мета с чем-то, кроме команды, вы можете использовать большинство стандартных комбинаций клавиш osx (command-c, command-v, command-s и т. Д.) В стандартных emacs .

Добавление: вывод для этого большого блока кода (обратите внимание на правильное размещение вызовов панели make-day):

(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 голос
/ 19 октября 2011

VimClojure будет отступать так, как вы хотите (если я правильно понимаю ваш пример), когда вы удаляете doto из lispwords.

setlocal lispwords-=doto
1 голос
/ 18 октября 2011

Насколько я могу судить, индентор Emacs не понимает, что происходит, если вы запускаете совершенно новый sexp в той же строке, что и отступ с отступом, что и делает ваш let выше.Вы видите похожую проблему с

(if (< 1 (- 3
            1) 3
            4))

Конечно, писать, что для начала это не очень хороший стиль, поэтому, возможно, Emacs может быть извинен.Как вы заметили, код, подобный этому, с большей вероятностью будет отображаться в let или cond в Clojure, и это не плохой стиль - но индентор Emacs был разработан для других строк, которые требуют, чтобы каждая пара заключалась в скобки:

(let [([x
        y
        z] (foo))
      ([a
        b
        c] (bar))]
  ...)

И, как вы видите, эти отступы в порядке.Поэтому я думаю, что в какой-то момент кому-то придется выяснить, как обновить индентор Emacs для этого случая, и что это будет намного проще, чем получить какой-либо другой редактор до уровня Emacs.Возможно, этот человек должен быть вами, если вас это беспокоит - я полагаю, магия и бремя открытого исходного кода.

0 голосов
/ 16 июня 2013

LightTable отступает так же, как 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.

...