ModoAbbrev

Un mecanismo que puede ahorrarnos muchas pulsaciones de teclas es el modo menor abbrev-mode. Su funcionamiento se basa en que cuando emacs reconoce cierta palabra mientras escribimos la sustituye por un texto que hayamos preestablecido. A la palabra que desencadena el reemplazo se la llama abreviación y el texto que se inserta expansión.

Para empezar nada mejor que un ejemplo. Escribimos foo en un buffer de emacs, con el cursor situado tras la segunda o pulsamos la combinación de teclas C-x a i g y cuando en el minibuffer nos pida Global expansión for "foo": escribimos foo bar baz.

Con esto le hemos dicho a emacs que defina una abreviación global asociando a la palabra foo (la abreviación) el texto foo bar baz (la expansión).

Si ahora escribimos foo en el buffer veremos que no ocurre nada. Para poder utilizar el abbrev-mode primero hay que activarlo, por ejemplo con M-x abbrev-mode. Si ahora escribimos foo<espacio> veremos que es reemplazado por la expansión.

referencia de comandos mas importantes

Definir abreviaciones

emacs define atajos de teclado que permiten definir abreviaciones a partir del contenido del buffer:

En ambos casos emacs pedirá el nombre de la abreviación. Estos comandos por defecto toman una única palabra del buffer para formar la expansión, pero podemos utilizar el comando prefijo (C-u) para indicar el numero de palabras.

Los dos comandos que siguen son equivalentes a los dos anteriores, pero en lugar de tomar del buffer el valor para la expansión toman el valor para la abreviación. En cierto sentido son inversos:

En ambos casos emacs pedirá el texto de la expansión. Esto comando por defecto toman como abreviación la palabra situada justo antes del punto de inserción. Con el prefijo C-u podemos indicarle que utilice una palabra anterior.

Expandir abreviaciones

Si tenemos el modo abbrev-mode activo emacs expandirá automáticamente las abreviaciones, pero en ocasiones los comandos siguientes pueden resultar útiles:

Editar abreviaciones

Con M-x edit-abbrevs se crea un buffer en el que podemos modificar las abreviaciones definidas. Para finalizar e instalar los cambios hay que pulsar C-c C-c.

Guardar/cargar abreviaciones

Para mantener las abreviaciones entre sesiones de edición podemos utilizar los comandos M-x write-abbrev-file y M-x read-abbrev-file. En ambos casos nos pedirá el nombre del fichero.

Un poco de elisp

En el buffer *scratch* podemos probar el siguiente ejemplo:

(define-abbrev lisp-interaction-mode-abbrev-table "foo" "(foo bar baz)")
  -> "foo"
foo.
(abbrev-mode)
  -> t
<foo.>>(foo bar baz).

En la linea 1 añadimos a la tabla de abreviaciones utilizada en el buffer *scratch* (lisp-interaction-mode-abbrev-table) la abreviación foo, que expandirá a (foo bar baz).

En la linea 3 vemos que al escribir foo. no se efectúa la expansión de la abreviación, esto es porque el modo menor abbrev-mode no está activo en el buffer. En la linea 4 activamos el modo abbrev-mode (puede hacerse con M-x abbrev-mode) y en la linea 6 , con ese simbolismo extraño, intento mostrar que al escribir foo. es expandido a (foo bar baz).. Observar que el carácter que ha disparado la expansión (un punto en el ejemplo) es conservado.

Lo realmente interesante de define-abbrev es que permite ejecutar una función después de expandir una abreviación. Esto posibilita definir abreviaciones cuya expansión puede variar en función del contexto. Veamos un ejemplo sencillo, como definir una abreviación cuya expansión depende de la palabra situada delante del punto de inserción.

;; función de ejemplo para ilustrar el uso de abreviaciones dinámicas
(defun crea-defun ()
  (backward-word 1)
  (insert "(defun ")
  (forward-word 1)
  (insert " () )")
  (backward-char 2))
  -> crea-defun

(define-abbrev lisp-interaction-mode-abbrev-table
               "foo"
               ""
               'crea-defun)
  -> "foo"

De la linea 1 a la 6 definimos la función crea-defun, que envuelve en un (defun ... () ) la palabra situada antes del punto de inserción. Es importante observar que la función no tiene argumentos.

De la linea 7 a la 10 definimos una abreviación. Como expansión especificamos la cadena vacía y pasamos la función como argumento.

Si en un buffer tenemos el texto hola mundo* (el asterisco representa el punto de inserción) y escribimos foo, la expansion lo convertirá en hola (defun mundo () *).

Ver tambien

Los paquetes msf-abbrev, else-mode, skeleton-mode, tempo-mode y semantic pueden resultar utiles.