Modification de l'indentation de certaines formes Emacs Lisp

8

Je voudrais que certaines formes Emacs Lisp soient en retrait comme Common Lisp. Par exemple, dans Emacs Lisp, ifest en retrait comme ceci:

(if COND
    THEN
  ELSE)

alors que je le préfère comme ceci:

(if COND
    THEN
    ELSE)

Je pourrais faire ça:

(setq lisp-indent-function #'common-lisp-indent-function)

Mais cela a un impact sur toutes les formes, rompant ainsi l'indentation des macros Emacs Lisp, comme cl-letfet de toute macro définie par l'utilisateur.

Elena
la source

Réponses:

17

Réponse:

Les symboles pour les fonctions et les macros ont une lisp-indent-functionpropriété que vous pouvez définir avec declareou dans votre cas, car ifétant déjà défini, vous pouvez simplement l'utiliser put.

Vous pouvez lire sur les valeurs de propriété possibles ici:

M-: (info "(elisp) Indenting Macros") return

ifLe paramètre par défaut de ce paramètre 2signifie que le traitement spécial du deuxième formulaire get est compensé.

Vous pouvez remplacer la valeur de la propriété par 'defunet toutes les formes du corps s'aligneront.

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

Meilleur entrainement:

Il est important de noter qu'il existe une raison pour le style d'indentation. ifdans Elisp n'est PAS comme ifdans Common Lisp.

Notez les différentes signatures:

Lisp commun: (if TEST THEN &OPTIONAL ELSE)

Emacs Lisp: (if COND THEN ELSE...)

Dans Emacs lisp, vous pouvez avoir autant de formulaires après la condition que vous le souhaitez, mais seul le premier formulaire est la clause THEN, tous les autres formulaires font partie de la clause ELSE.

Il s'agit d'un ifformulaire Elisp valide qui n'est pas valide dans CL:

(if something
    (message "THEN")
  (message "all")
  (message "these")
  (message "run")
  (message "on")
  (message "ELSE"))

Cela montre pourquoi il est important que la clause THEN soit plus en retrait, c'est pour la faire ressortir de toutes les formes ELSE.

En plus de l'indentation étant importante pour la capacité des utilisateurs à analyser le code, cela irait également à l'encontre des modèles de style acceptés d'Elisp. 99,99999% (calculé avec prudence) du code elisp que vous rencontrez utilisera exactement le même schéma d'indentation par défaut. Changer l'indentation de ifpour votre propre usage, il sera difficile pour vous de travailler sur d'autres peuples élisp et rendra difficile pour les autres de travailler sur le vôtre.

Jordon Biondo
la source
2

J'utilise en fait le retrait Common Lisp, avec le retrait Elisp pour if. Vous pouvez personnaliser un code similaire au mien:

(setq lisp-indent-function 'common-lisp-indent-function)
(eval-after-load 'cl-indent
  `(progn
     (put 'cl-flet 'common-lisp-indent-function
          (get 'flet 'common-lisp-indent-function))
     (put 'cl-labels 'common-lisp-indent-function
          (get 'labels 'common-lisp-indent-function))
     (put 'if 'common-lisp-indent-function 2)))
abo-abo
la source
Merci, mais cela nécessiterait que je corrige également l'indentation de toutes les macros définies par l'utilisateur. Je préfère suivre la route opposée et corriger uniquement l'indentation de ifcomme effectuée par lisp-indent-function.
Elena
J'ai cette configuration depuis des années. Il n'y a aucune autre macro que je devais "corriger". N'oubliez pas de mettre une declaredéclaration dans chaque nouvelle macro, ce qui est bon dans tous les cas.
abo-abo