Modificación de la sangría de algunos formularios Emacs Lisp

8

Me gustaría que algunas formas de Emacs Lisp tengan sangría como Common Lisp. Por ejemplo, en Emacs Lisp, ifse sangra así:

(if COND
    THEN
  ELSE)

mientras que lo preferiría así:

(if COND
    THEN
    ELSE)

Yo podría hacer esto:

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

Pero esto afecta a todas las formas, rompiendo así la sangría de las macros de Emacs Lisp, como cl-letfy cualquier macro definida por el usuario.

Elena
fuente

Respuestas:

17

Responder:

Los símbolos para funciones y macros tienen una lisp-indent-functionpropiedad que puede establecer con declareo en su caso, ya ifque ya está definida, puede usarla put.

Puede leer sobre los posibles valores de propiedad aquí:

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

ifLa configuración predeterminada es lo 2que significa que el segundo formulario recibe un tratamiento especial y está compensado.

Puede cambiar el valor de la propiedad a 'defuny todas las formas del cuerpo se alinearán.

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

Mejores prácticas:

Es importante tener en cuenta que hay una razón para el estilo de sangría. ifen Elisp NO es como ifen Common Lisp.

Tenga en cuenta las diferentes firmas:

Lisp común: (if TEST THEN &OPTIONAL ELSE)

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

En Emacs lisp, puede tener tantas formas después de la condición como desee, pero solo la primera forma es la cláusula ENTONCES, todas las demás formas son parte de la cláusula ELSE.

Este es un ifformulario válido de Elisp que no es válido en CL:

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

Esto muestra por qué es importante que la cláusula ENTONCES tenga más sangría, es para que se destaque contra todas las formas ELSE.

Además de que la sangría es importante para la capacidad de los usuarios de analizar el código, también iría en contra de los patrones de estilo aceptados de elisp. El 99.99999% (calculado cuidadosamente) del código elisp que encuentre utilizará exactamente el mismo esquema de sangría predeterminado. Cambiar la sangría ifpara su propio uso hará que le resulte difícil trabajar en otras personas y evitar que otros trabajen en la suya.

Jordon Biondo
fuente
2

De hecho, uso la sangría Common Lisp, con la sangría Elisp para if. Puedes personalizar un código similar al mío:

(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
fuente
Gracias, pero esto también requeriría que arregle la sangría de todas las macros definidas por el usuario. Prefiero seguir la ruta opuesta y arreglar solo la sangría de ifcomo lo realiza lisp-indent-function.
Elena
He tenido esta configuración durante años. Hay cero otras macros que necesitaba "arreglar". Solo recuerde poner una declaredeclaración en cada nueva macro, lo cual es bueno en cualquier caso.
abo-abo