Как сделать emacs правильно отступ, если-then-else построить в elisp

Когда я создаю indent if-then-else в emacs lisp, блок else не имеет отступ правильно. Я получаю:

(defun swank-clojure-decygwinify (path)
  "Convert path from CYGWIN UNIX style to Windows style"
  (if (swank-clojure-cygwin)
      (replace-regexp-in-string "\n" "" (shell-command-to-string (concat "cygpath -w " path)))
    (path)))

где еще форма не имеет отступов на том же уровне, что и форма then. Есть ли очевидный способ исправить это?

Ответ 1

Это правильный отступ. Цитата из руководства:

Слово "else" не записано в коде Lisp; else-часть выражение `if 'появляется после части then. В написанном Lispelse-part обычно записывается для начала на отдельной строке и с отступом меньше той части:

 (if TRUE-OR-FALSE-TEST
     ACTION-TO-CARRY-OUT-IF-THE-TEST-RETURNS-TRUE
   ACTION-TO-CARRY-OUT-IF-THE-TEST-RETURNS-FALSE)

Например, следующее выражение if печатает сообщение 4 is not greater than 5!, когда вы его оцениваете обычным способом:

 (if (> 4 5)                               ; if-part
     (message "4 falsely greater than 5!") ; then-part
   (message "4 is not greater than 5!"))   ; else-part

Обратите внимание, что различные уровни отступов облегчают отличить тогда-часть от else-части. (GNU Emacs имеет несколько команды, которые автоматически отступают выражения if. *Заметка GNU Emacs помогает вам печатать списки: списки ввода.)

Это функция, а не ошибка: -)

Ответ 2

У меня нет соответствующей документации, но это похоже на то, что вы хотите:

(put 'if 'lisp-indent-function nil)

Кроме того, вы неправильно использовали слово "правильно"; по определению, однако абзацы emacs являются "правильными":)

Ответ 3

По умолчанию используется стиль - для Emacs Lisp. Для Common Lisp и других ароматов Lisp предложение "else" должно быть выровнено под предложением "then". Чтобы получить Common Lisp indendation, вы должны сделать что-то вроде этого:

(set (make-local-variable lisp-indent-function)
     'common-lisp-indent-function)

Чтобы это произошло автоматически, вы можете сделать что-то вроде этого:

(add-hook 'lisp-mode-hook
          '(lambda ()
             (set (make-local-variable lisp-indent-function)
                  'common-lisp-indent-function))))

Обратите внимание, однако, что пакеты взаимодействия Lisp -Emacs, такие как Slime, могут переопределять поведение отступов, и в этом случае вышеуказанное может ничего не делать. Вышеупомянутое должно работать в базовом Emacs.

Ответ 4

Приведите себя к мысли, что Elisp - это схема и используйте progn. Это ограничивает выражения then и else, но отступы их в одном столбце:

(defun swank-clojure-decygwinify (path)
  "Convert path from CYGWIN UNIX style to Windows style"
  (if (swank-clojure-cygwin)
      (replace-regexp-in-string "\n" "" (shell-command-to-string (concat "cygpath -w " path)))
    (progn
      (path))))