Trasteando con yasnippets
Hace poco, por Mastodon, el amigo Giorgio habló de yasnippets
y de
cómo le habían servido para ser más productivo en su trabajo... he
de confesaros que las uso poco, o casi nada, para ser sinceros. Con
Python
las utilicé, porque elpy
las usa, pero para el resto de
modos, normalmente, ni las tengo instaladas. No porque no sean útiles,
sino porque yo no suelo utilizarlas. Sin embargo, entiendo que cada
uno tiene sus costumbres y su flujo de trabajo y que, yasnippet
,
puede ser muy útil a otra gente. Por esto, en este artículo contaré
cómo instalar y configurar el paquete y cómo crear nuestros propios
snippets
para adecuarlo a nuestras necesidades. Incluso, quizá
hablándome de ello a mí mismo, termine por cogerle el gusto.
Como digo, utilicé snippets
programando en Python
con Emacs.
Con elpy
los snippets
vienen de serie... a todo ésto creo que
todos sabemos lo que es un snippet
(al menos los que programan un
poco), pero es posible que haya quien no, o está de más tirar de la
definición en la Wikipedia:
Snippet es un término del idioma inglés utilizado en programación para referirse a pequeñas partes reusables de código fuente, código máquina o texto. Comúnmente son definidas como unidades o métodos funcionales que se pueden integrar fácilmente en módulos mucho más grandes, aportando funcionalidad.
Wikipedia
Por expresarlo más rápidamente o de forma más directa: son pequeñas
plantillas de código que nos ahorran tecleos. En Emacs la gestión de
estos bloques de código la podemos realizar con yasnippet
(que
significa, según su página, «Yet Another Snippet» extension for
Emacs).
No utilizando elpy
lo tenía muy abandonado, porque no lo suelo usar,
el funcionamiento es muy útil, especialmente para programar, aunque no
sólo para esa actividad: hay snippets
que sirven para muchas otras
cosas. Por poner un ejemplo, si tenemos activos los snippets
en
org-mode
y queremos introducir una línea con la fecha pulso la
combinación C-c & C-s
(luego veremos cómo configurar las teclas).
Paso 1: tecleo
C-c & C-s
Paso 2: tecleo
date <RET>
Paso 3: tecleo
2022 <TAB>
Paso 4: tecleo
02 <TAB>
Resultado: tecleo
09 <TAB>
Vemos que los snippets
no sólo introducen texto por nosotros sino
que también nos proporcionan paradas de tabulador que nos permiten
introducir opciones simplemente avanzando con el tabulador (y
retrocediendo con S-<TAB>
).
Muy bonito, ¿ahora cómo hacemos para que nuestro Emacs haga estas cosas?
Instalación de los paquetes necesarios
En un principio, instalando el paquete yasnippet
sería suficiente.
Sin embargo, recomiendo instalar algunos paquetes auxiliares que nos
facilitarán el uso de snippets
:
yasnippet
, proporciona la funcionalidad principal.yasnippet-snippets
, proporciona una larga lista de snippets para multitud de modos y lenguajes de programación.ivy-yassnipet
, proporciona integración deyasnippet
conivy
. También existe un paquetehelm-yasnippet
, si utilizashelm
para proporcionarte menús interactivos.
La instalación de los paquetes es la habitual. Por ejemplo, para el
principal de yasnippet
:
M-x package-install <RET> yasnippet
Con eso ya tendríamos toda la funcionalidad de los snippets
, pero no
adelantamos nada si no tenemos plantillas que utilizar. Tenemos que
crearlas, lo que puede ser un trabajo arduo y aburrido haciéndolo
desde cero. Para ahorrarnos ese tedioso trabajo, el paquete
yasnippet-snippets
nos proporciona decenas (si no, cientos), de
plantillas ya preparadas y revisadas para multitud de modos. Incluso,
para aquellos que no utilizas, por lo que el paquete ocupará más
espacio en disco del estrictamente necesario, aunque no tanto como
para que te debas preocupar por ello.
En cualquier momento, podemos consultar qué snippets
tenemos
disponibles según el modo en el que estemos con el comando
M-x yas-describe-tables
No es necesario que nos aprendamos toda la tabla, pero si trabajamos
habitualmente con este sistema podemos aprendernos el key
del
snippet
y luego utilizar el comando yas-expand
(que yo lo tengo
mapeado a la combinación s-y
, luego explicaré cómo). Con eso sólo,
es decir, tecleando el key
y una combinación de teclas nos expandirá
toda la plantilla. Nos podremos mover por los puntos de tabulador
pulsando <TAB>
para ir hacia adelante y <S-TAB>
para ir
hacia atrás, como ya vimos antes.
Ahora que tenemos instalado el modo, vamos a configurarlo un poco.
Configuración de los snippets
El primer paso que hay que hacer es decidir si lo vas a utilizar
siempre. Es decir, si quieres que automáticamente se cargue esta
funcionalidad en tu Emacs cada vez que inicia. Esto enlentecerá el
arranque del editor porque revisará todos los snippets
para tenerlos
a mano. Recuerda que Emacs no es el editor más rápido de arrancar.
O simplemente no quieres ocupar memoria con algo que no vas a
utilizar. Por ejemplo, en mi caso, sólo los suelo usar programando,
por lo que por defecto no los tengo activados.
En el manual del modo yasnippet
recomiendan (cómo no) tenerlo
permanentemente activado. Su configuración es sencilla:
(require 'yasnippet) (yas-global-mode t)
En mi caso, como no lo quiero cargado continuamente lo he retocado un
poco y he acomodado las combinaciones de teclas a mi gusto. El retoque
del código de configuración se debe principalmente a que utilizo
use-package
.
(use-package yasnippet :defer t) (global-set-key (kbd "C-c x") 'ivy-yasnippet) (global-set-key (kbd "C-c y") 'yas-minor-mode) (global-set-key (kbd "s-y") 'yas-expand)
Con esas tres teclas y otras tres que define el modo yasnippet
en su
código, tenemos configurada casi toda la funcionalidad que se necesita.
Combinación | Comando | Significado |
---|---|---|
C-c & C-s |
yas-insert-snippet |
Insertar un snippet por nombre |
C-c & C-v |
yas-visit-snippet-file |
Editar un snippet |
C-c & C-n |
yas-new-snippet |
Crear un nuevo snippet |
C-c y |
yas-minor-mode |
Activar el modo |
C-c x |
ivy-yasnippet |
Abrir lista de snippets en ivy |
s-y |
yas-expand |
Expandir un snippet por su clave |
Explico un poco más detalladamente las tres últimas combinaciones, que son las configuraciones de tecla que he añadido yo y las otras, que son las propias del modo, las veremos en el siguiente epígrafe:
yas-minor-mode
: es la función para activar el modo menor deyasnippet
que nos permite utilizarlo. Lo activo con configuración de teclas incluida porque al no abrirse universalmente, activarlo sólo afecta al buffer donde lo activas. Para trabajar con Python no hace falta, porqueelpy
lo activa automáticamente al abrir un fichero.py
. Si quieres activarlo siempre para un modo concreto siempre puedes poner un hook. Por ejemplo, si quisiéramos que se activara siempre que editamos un archivoorg
añadiríamos:(add-hook 'org-mode-hook 'yas-minor-mode)
ivy-yasnippet
: nos muestra enivy
la lista desnippets
disponibles para el modo mayor del buffer desde el que la llamamos. Cuando comenzamos a teclear un nombre, la lista filtra aquellos nombres que coincidan con lo que vamos escribiendo. Si no estamos seguros de cuál es elsnippet
que necesitamos podemos recorrer la lista que muestra y el contenido delsnippet
nos lo va mostrando en el punto del cursor en el buffer.yas-expand
: lo que hace es expandir unsnippet
a partir de su clavekey
. Cuando llevas un tiempo utilizando esta herramienta, terminas, a fuerza de verlas, aprendiéndote esas claves. Sobre todo, si es unsnippet
que utilizas con asiduidad, lo más rápido es aprenderse lakey
y expandirla sin buscar por la lista. Además, en este caso, he utilizado una combinación de tecla poco habitual. Normalmente en Emacs se utilizan <control> (C
) y <meta> (M
), con o sin <shift> (S
), sin embargo utilizo <super> (s
), la que algunos llaman tecla windows y otros la tapamos con una pegatina de un pingüino.
Estas funcionalidades son comodidades, si lo queréis llamar así,
porque en realidad, lo mínimo que necesitas para trabajar con
snippets
es crearlos, modificarlos y llamarlos. Esa funcionalidad
básica la detallo en el siguiente punto poniendo un pequeño ejemplo de
creación de snippet
.
Crear nuestros snippets
Al activar el modo yasnippet
por defecto nos activa tres
combinaciones de teclas para lanzar sus comandos principales. Figuran
en la tabla del apartado anterior. Esos tres comandos son:
- Crear un
snippet
(C-c & C-n
) - Editar un
snippet
que ya existe (C-c & C-v
) - Insertar en el buffer de edición un
snippet
(C-c & C-s
)
Por supuesto, si utilizas estas funciones de manera habitual, sería
buena idea cambiar la combinación de teclas por algo más sencillo y
rápido de teclear. En mi caso las he dejado así porque normalmente
utilizo la funcionalidad de ivy-yasnippet
o la expansión directa de
la clave (las pocas que me sé).
Vamos a ver cómo es un snippet
por dentro par hacernos una idea. Por
ejemplo, si tecleamos:
C-c & C-v current-date
nos abrirá un buffer con el siguiente contenido
# -*- mode: snippet -*- # name: current-date # key: dd # contributor : Kristof Molnar-Tatai <kristof.mlnr@gmail.com> # -- `(format-time-string "%Y-%m-%d")`
De ese código podemos extraer alguna información interesante:
- Los ficheros que guardan los
snippets
se suelen guardar sin extensión, por eso se añade la primera línea demode
seguida de la cabecera del mismo que está dividida en etiquetas o campos. - La cabecera se separa del texto del
snippet
mediante la línea# --
- Se pueden introducir formas lisp que devuelvan una cadena.
Para ilustrarlo mejor, vamos a crear un nuevo snippet
. Imagina que
tienes que hacer muchos informes psicológicos, como puede ser mi caso,
sobre los tests que van haciendo los clientes y el encabezado de
todos ellos es muy similar o repetitivo, por lo que decides crear una
plantilla de encabezado para incrustarla cuando escribes tus informes
con Emacs.
Al pulsar C-c & C-n
nos abrirá un buffer con el siguiente
contenido:
# -*- mode: snippet -*- # name: # key: # --
El cursor aparece en la línea # name:
. Atentos, porque lo que hace
es crear un buffer y añadir un snippet
con la estructura del
mismo. Lo único que tenemos que hacer es rellenar los datos y avanzar
pulsando <TAB>
.
Para no liarme mucho más con las explicaciones muestro el contenido final y luego lo explicamos:
# -*- mode: snippet -*- # name: informe-cabecera # key: inf-cab # -- INFORME que realiza /D. Fulanito de Tal/ con D.N.I. nº 123456789Z sobre los resultados obtenidos en la prueba ${1:test psicológico} por D/ña. ${2:Menganito de Cual}, con D.N.I. nº ${3:987654321A}, a petición del interesado.
El texto es lo de menos, puede ser cualquier otro, lo importante es
que nos fijemos dónde lo guarda yasnippet
. Por defecto, al hacerlo
nos sugerirá un directorio llamado:
~/.emacs.d/snippets/[nombre-del-modo]
En el caso anterior, lo queremos para hacer es tener un snipper
para
insertar una cabecera. En la mayoría de los casos lo único que
cambiará será el test que se pasó y los datos, el nombre y el DNI,
del cliente:
${1:test psicológico}
${2:Menganito de Cual}
${3:987654321A}
Como se puede apreciar, las paradas de tabulador se denotan por
${...}
. En este caso se han tenido en cuenta textos por defecto,
pero los campos podrían haber sido, por ejemplo ${1:}
. No hay
necesidad de incluir ese texto, con los números es suficiente para
establecer las paradas, pero puede venir muy bien cuando además hay
algún contenido frecuente, para ahorrar aún más tecleos.
Por último, si ya tenemos nuestro snippet
creado y lo que queremos
es cambiar o corregir algún aspecto de él, utilizaremos la combinación
C-c & C-v
o utilizaremos el comando M-x yas-visit-snippet-file
para modificarlo.
Conclusiones
Esta es una entrada cortita, porque esta herramienta es muy sencilla de utilizar, pero con una gran utilidad, especialmente para programación. Nos ahorrará bastante trabajo de escritura repetitiva, aparte de evitar errores tontos como meter «;» donde corresponde «:» en una expresión y que el programa tarde un poco más en compilar, dándonos de cabezazos hasta descubrir el sutil error de tecleo.
Para otros menesteres nos viene bien para introducir algunos tipos de
información repetitiva en textos. No lo suelo utilizar en org-mode
,
pero sí me es muy útil en html
para no olvidarme de cerrar ninguna
etiqueta. Cada uno decidirá cómo puede adecuar la herramienta a su
modo de trabajar, cuándo le es útil y cuando no.
Comentarios