Abreviaturas en Emacs
Una de las formas de ahorrar algunas pulsaciones de teclas es utilizar abreviaturas. Ya hablé por aquí de los snippets, que serían plantillas más o menos extensas de estructuras de texto repetitivas. Las abreviaturas son sus hermanas pequeñas y consisten en algo tan sencillo como sustituir un texto corto, una abreviatura, por una expresión más larga de una o más palabras.
Para hacerlo todo más práctico, voy a mostrar dos ejemplos sencillos y de ese modo creo que será más comprensible el mecanismo de las abreviaturas. He hecho una copia de seguridad de las abreviaturas que tengo definidas para mí, y partiré de cero para no enfangar las mías con las pruebas que pueda hacer en el presente artículo.
Hay que tener en cuenta que las abreviaturas pueden ser generales y
encontrarse disponibles para todos los modos, o pueden ser locales
del modo mayor que esté activo. Aunque generalmente, programando,
suelen ser más útiles los snippets y completion
, también podemos
aprovechar la inmediatez de las abreviaturas. Los ejemplos que voy a
mostrar comprenden las dos opciones: definiré uno de manera global y
otro de manera local. Aunque, como veréis, el procedimiento es el
mismo y sólo cambia el comando invocado.
Por otro lado, también podemos decir que las abreviaturas son un modo
menor (abbrev-mode
) que nos permite utilizarlas. Más adelante
veremos que podemos usarlas sin necesidad de tener el modo activo
invocando un comando; sin embargo, la mayor parte de su potencia se
deriva de la sustitución automágica de textos mientras escribimos.
Definir abreviaturas
Imagina que tenemos un texto largo que se repite con cierta frecuencia
y queremos escribir menos, pero que el texto sea completo. No parto de
una lista completamente vacía, pues hay algunos modos como pydev
que
proporcionan sus correspondientes abreviaturas. Pero si utilizas el
comando list-abbrevs
, te aparecerá algo como lo siguiente:
Por poner un ejemplo, voy a definir una abreviatura desde el siguiente
supuesto: cuando escribo artículos es muy habitual que tenga que
escribir muchas veces la palabra Emacs
, porque es uno de mis temas
favoritos. Como me voy a dejar la yema de los dedos en el intento, voy
a escribir una abreviatura que cuando me encuentre en org-mode
, que
es el modo en el que escribo los artículos, me permita escribirlo con
un par de pulsaciones de tecla, es decir, que cuando yo escriba
em<SPC>
lo expanda a Emacs
. El procedimiento es sencillo:
- Escribo la palabra completa:
Emacs
- Después pulso
C-x a l
- Me pide una abreviatura:
em<RET>
Ya está, a partir de ahora, cuando esté activado abbrev-mode
en el
modo mayor org-mode
y yo escriba em
, Emacs escribirá toda la
palabra por mí. Para comprobarlo, veamos nuestra lista de abreviaturas
modificada:
Cuando sólo queremos expandir una palabra es sencillo. Algo más lioso
cuando queremos sustituir varias palabras, pero porque tenemos que
decirle a Emacs cuántas debe tomar con el prefijo C-u num
. Vamos a
suponer que quiero definir la abreviatura del texto siguiente:
GNU's not Unix
y quiero establecerla a gnu
. Es decir, cada vez que pulse las teclas
g
, n
, u
, <SPC>
, ─siendo éste último cualquier carácter
considerado como tal, no sólo la tecla de espacio, también la coma, el
punto, etc.─, lo sustituirá por el texto completo. Para definirlo,
hago el siguiente procedimiento:
- Escribo el texto completo: «GNU's not Unix»
- Nada más escribirlo pulso la siguiente combinación de teclas:
C-u 3 C-x a g
. Fijaos que en esta ocasión estoy utilizandoC-x a g
y por tanto la definición será global. - En la línea de estado nos pide la abreviatura:
gnu<RET>
Como he dicho antes, he cambiado el comando para hacerlo global y he
utilizado el prefijo C-u 3
para indicarle a Emacs que debe
utilizar las tres palabras anteriores a la posición del cursor.
Podemos comprobarlo también mirando la lista de abreviaturas.
Aprovecho para llamar la atención sobre la lista de abreviaciones.
Nos abre un buffer de nombre *Abbrevs*
, pero vemos que el modo es
edit-abbrevs
, lo que nos da pie a modificarlas directamente en ese
espacio. Por ejemplo, puesto que suelo escribir la palabra Emacs,
generalmente en cursiva, he aprovechado y he puesto los delimitadores
de este tipo de letra en la expresión. Tras guardar con C-x C-s
,
cada vez que escriba em
el editor lo cambiará por /Emacs/
.
Otra forma de modificar el contenido de las abreviaciones es, una vez
que lo tenemos salvado en un fichero, por defecto
~/.emacs.d/abbrev_defs
, podemos modificar el código fuente, que en
nuestro caso aparecerá del siguiente modo:
;;-*-coding: utf-8;-*- (define-abbrev-table 'global-abbrev-table '( ("gnu" "GNU's not Unix" nil :count 0) )) (define-abbrev-table 'org-mode-abbrev-table '( ("em" "/Emacs/" nil :count 5) ))
Resumen de comandos
Hay poco más que contar una vez que comprendes cómo funciona este modo. Para resumir un poco las cosas que se pueden hacer con él, voy a dar un repaso a los principales comandos, la combinación de teclas asignada y para qué sirve cada uno. Por ejemplo, para definir abreviaturas y gestionarlas se utilizan los siguientes comandos:
C-x a g
(add-global-abbrev
)- Define una abreviatura global que
estará disponible en todos los modos. Es el equivalente interactivo
al comando
M-x define-global-abbrev <RET> abrv <RET> expresión <RET>
C-x a l
(add-mode-abbrev
)- Define una abreviatura para el modo
mayor activo en ese momento. Es el equivalente interactivo al
comando
M-x define-mode-abbrev <RET> abrv <RET> expresion <RET>
. M-x kill-all-abbrevs
- Elimina todas las abreviaturas definidas.
C-x a i g
(inverse-add-global-abbrev
)- Define una palabra en el texto del buffer como una abreviatura global y solicitará su correspondiente expansión en el minibuffer.
C-x a i l
(inverse-add-mode-abbrev
)- Define una palabra del buffer como abreviatura del modo. Funciona de manera similar al anterior comando.
M-x edit-abbrevs
- Nos muestra la lista de abreviaturas definidas en un buffer y nos permite modificarlas.
M-x write-abbrev-file <RET> nombre <RET>
- Escribe en el archivo
nombre
todas las definiciones de abreviaturas activas. M-x read-abbrev-file <RET> nombre <RET>
- Lee el archivo
nombre
y carga las definiciones de abreviaturas que contiene. Hay otro comando similar,quietly-read-abbrev-file
, cuya única diferencia es que no muestra ningún mensaje en el minibuffer.
Estos dos últimos comandos son muy útiles cuando queremos mantener nuestras abreviaturas agrupadas por temática. Me explico: hay veces en que un área de nuestro trabajo necesita ciertas abreviaturas y pueden chocar con otras que tengamos definida en otras áreas. Estos comandos nos permiten tener varios archivos, que podemos activar según el tema en el que estemos trabajando.
Hay algunos otros comandos que nos permiten controlar la expansión del contenido de las abreviaturas.
C-x a e
(expand-abbrev
)- Expande la abreviatura. Es efectivo
incluso cuando
abbrev-mode
no está activo. Vamos, que normalmente, si estuviera activo, no lo necesitarás. Pero es bueno saber que si se te ha olvidado activarlo o, por algún motivo lo has desactivado, puedes seguir utilizando tus abreviaturas definidas. M-x unexpand-abbrev
- Su función es dejar la abreviatura tal cual sin expandirla, pero hablaré un poco más en el siguiente apartado.
M-x expand-region-abbrevs
- Expande todas las abreviaturas que se encuentren en la región seleccionada.
M-/
(dabbrev-expand
)- Expande la palabra en el buffer como
una abreviatura dinámica. Es decir, busca en el buffer la última
palabra que comience igual y la expande. Por ejemplo, si comenzamos
a escribir
abr
y pulsamosM-/
en este buffer, lo expandirá, posiblemente, a la palabra abreviatura. Un comando similar eshippie-expand
que si lo usamos repetidamente nos muestra varias posibles expansiones, en lugar de sólo la última, por lo que me parece más útil y os recomiendo más su uso.
También puede ocurrir que hayamos definido nosotros, o algún modo lo
haga, abreviaturas en el sistema y que por olvido o desconocimiento
estemos tecleando todo el texto. Se puede habilitar a Emacs que nos
avise de que un determinado texto tiene definida una abreviatura
activando en nuestro init.el
la variable abbrev-suggest
. De esta
manera nos advertirá de que contamos con la posibilidad de ahorrarnos
tecleos. Si nos hemos perdido algunos de esos avisos podemos utilizar
el comando abbrev-suggest-show-report
que nos hará un informe de
todas las sugerencias que nos haya hecho el sistema durante la sesión
de trabajo.
Recomendaciones
Es posible que haya ocasiones que no queramos que nos sustituya la
abreviatura por su expresión. Ya hemos visto que el comando es M-x
unexpand-abbrev
. Otra opción, que es la que uso yo, en curarnos en
salud y utilizar abreviaturas con caracteres especiales que sea raro
que se necesiten tal cual en un texto. Por ejemplo, para mis cosas
suelo utilizar de prefijo el carácter '
o el ¡
. Por hacerlo más
gráfico, mi modo usual para definir los ejemplos del principio del
artículo, hubiera sido utilizar 'g
en lugar de gnu
y 'e
en lugar
de em
para las abreviaturas. De esta forma es más raro encontrarse
el caso de tener que revertir una sustitución.
Por defecto, unexpand-abbrev
no está mapeada a ninguna tecla. Si
utilizas habitualmente las abreviaturas y lo necesitas, considera el
mapear dicha función a una combinación de teclas. En el manual
recomiendan utilizar C-q
. En mi caso, dado que utilizo el sistema
anterior, no suelo necesitarlo, pero está bien recordar que tienes la
posibilidad de hacerlo.
Como vimos en el apartado anterior hippie-expand
es un comando
también bastante más útil que el simple dabbrev-expand
y, es
posible, que quieras mapear la combinación M-/
a aquel comando en
lugar de al que viene mapeado por defecto.
Conclusiones
Mientras programo me resulta más cómodo el uso de completion
y de
snippets
que el de abreviaturas. Sin embargo, también reconozco
puede ser útil. Aunque, se me ha dado el caso que acostumbrado a
algunas abreviaturas en Emacs, al tener que cambiar de editor, se me
ha hecho la adaptación un poco pesada. Tecleaba la abreviatura y al
ver que no se expandía recordaba que no estaba en Emacs y que tenía
que teclear el texto correctamente.
Las abreviaturas pueden representar un gran ahorro de pulsaciones de teclas. Pero también significa que debes invertir tiempo en ajustar y afinar todo tu sistema de abreviaturas para que te sean útiles a largo plazo.
Comentarios