Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make emacs properly indent if-then-else construct in elisp

Tags:

emacs

clojure

When I indent if-then-else construct in emacs lisp, the else block doesn't indent properly. What I get is:

(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)))

where else form is not indented at the same level as the then form. Is there an obvious way to fix this?

like image 372
Mad Wombat Avatar asked Apr 15 '10 02:04

Mad Wombat


3 Answers

That is the proper indentation. A quote from the manual:

The word "else" is not written in the Lisp code; the else-part of an `if' expression comes after the then-part. In the written Lisp, the else-part is usually written to start on a line of its own and is indented less than the then-part:

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

For example, the following if expression prints the message 4 is not greater than 5! when you evaluate it in the usual way:

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

Note that the different levels of indentation make it easy to distinguish the then-part from the else-part. (GNU Emacs has several commands that automatically indent if expressions correctly. *Note GNU Emacs Helps You Type Lists: Typing Lists.)

This is a feature, not a bug :-)

like image 122
Bozhidar Batsov Avatar answered Nov 01 '22 11:11

Bozhidar Batsov


I don't have the relevant documentation handy, but this seems to do what you want:

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

Also, you misused the word "properly"; by definition, however emacs indents is "proper" :)

like image 22
offby1 Avatar answered Nov 01 '22 11:11

offby1


The default style is proper -- for Emacs Lisp. For Common Lisp and other flavors of Lisp, the "else" clause should be aligned underneath the "then" clause. To get Common Lisp indendation, you have to do something like this:

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

To get this to happen automatically, you can do something like this:

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

Note, however, that Lisp-Emacs interaction packages, like Slime, may override the indentation behavior, and in that case, the above might do nothing. The above should work in a basic Emacs.

like image 5
John V Avatar answered Nov 01 '22 11:11

John V