2011-01-11 9 views
13

estoy trabajando en el Haskell y con frecuencia vienen a través de un código similar al siguiente:Emacs alinear-regexp en = == pero no

func i j | i == j = i 
     | otherwise = j 

quiero alinear en el carácter '=' usando alinear-expresión regular, pero no tengo el know-how elisp. He intentado simplemente hacer "=" sin las comillas, pero esto inserta un carácter de espacio no deseado antes de cada '='. He encontrado una solución propuesta here pero parece que no puedo hacer nada en absoluto.

Por favor, ayúdenme a escribir una función o macro codificada que me permita establecer un enlace de clave para esto.

Respuesta

17

Cu Mxalign-regexpRET\(\s-*\) =RET1RET0RETn

(nb hay un espacio después de la '=', pero no es muy obvio.)

Cuál es decir ...

Utilice un argumento de prefijo para indicarle al align-regexp que le pida más parámetros de los que tiene de manera predeterminada.

Ver C-h falign-regexp y C-h valign-rules-list para los detalles, pero en resumen:

\(\s-*\) es el 'grupo' por defecto para supresión/expansión. Agregamos nuestro patrón al final de eso: '='. (Tenga en cuenta que \s- es la sintaxis regexp de Emacs para espacios en blanco.)

1 simplemente se refiere al grupo entre paréntesis 1 (como el anterior). Este es el predeterminado.

0 para el espaciado entre las dos partes de la línea. Por defecto, esto es 1, y es por eso que terminaste con un espacio adicional.

n para no alinear ninguna coincidencia de patrón posterior después de la primera en cada línea.

de edición: En realidad, el Q & A que vincula a es casi idénticas, y me da buenos resultados en Emacs 23.2.1, por lo que este es un duplicado, pero para continuar y contestar el aspecto vinculante clave:

Puede enlazar esa (o cualquier) secuencia a través de macros de teclado. Este es el resultado final, que probablemente solo pueda agregar a su archivo init, aunque le recomiendo que realice el proceso usted mismo. Utilice lo que quiera en lugar de C-c a para la clave. C-c (letter) y F5-F9 están reservados para que los usuarios finales se vinculen a su gusto, por lo que uno de ellos estará a salvo de ser golpeado por el mapa de teclas de un modo.

(global-set-key (kbd "C-c a") (lambda (&optional arg) "Keyboard macro." (interactive "p") (kmacro-exec-ring-item (quote ([21 134217848 97 108 105 103 110 45 114 101 103 101 120 112 return 32 61 32 return return backspace 48 return 110] 0 "%d")) arg))) 

lo hice por:

  1. seleccionar el texto.
  2. F3 para comenzar a grabar.
  3. realizando el align-regexp como arriba (teniendo cuidado de escribir todo textualmente, y no usar el historial del minibúfer ni tirar).
  4. F4 para detener la grabación.
  5. C-x C-k nalign-single-equalsRET para dar el macro un nombre
  6. M-xinsert-kbd-macroRETalign-single-equalsRET para obtener el Lisp.
  7. Envolviendo la expresión (lambda) con (global-set-key) para enlazarlo. (Aunque también se podría utilizar el código (fset 'align-single-equals ...) según lo previsto, y luego obligar a la clave para ese símbolo.

Si comete un error al grabar una macro complicado, no se preocupe — Emacs proporciona una muy buen editor de macros que se puede utilizar para corregir los errores después de terminar la grabación (sólo escriba Cx Ck e), por lo que no necesita ser perfecto

edición. 2: puede también añadir un ejemplo de una función, según los comentarios.

(defun my-align-single-equals() 
    "Align on a single equals sign (with a space either side)." 
    (interactive) 
    (align-regexp 
    (region-beginning) (region-end) 
    "\\(\\s-*\\) = " 1 0 nil)) 

(global-set-key (kbd "C-c a") 'my-align-single-equals) 
+0

Gracias. Pude usar su solución pero creé una función en lugar de una macro, ya que es más fácil de leer para mí. – Karl

+0

Bueno, eso es aún mejor :) Una función es definitivamente preferible si estás contento escribiendo lisp, pero las macros son muy útiles si no lo eres. – phils

+0

un poco tarde para la fiesta, pero la manera canónica de resolver esto es agregar una regla a 'align-rules-list 'en lugar de escribir su propia función. –