Poderes vimtásticos: Ejecutando código Python sin abandonar vim

Cuando aprendí Python, hace ya muchos años, busqué un IDE que me fuera tan útil como lo había sido Eclipse cuando programaba en Java. En esa época no encontré muchas opciones, y ocupé IDLE, el que viene por defecto con Python en Windows.

Cuando poco después di el salto a Linux quise probar otras opciones y después de explorar Emacs brevemente (recuerdo con cariño que al programar en Haskell podía usar símbolos tipográficos como λ en lugar de \ en las lambdas o → para ->) y decidir que no era para mí, probé con vim. Mi primera sesión fue como la de todo el mundo, pero con el tiempo y el tutorial le agarré mejor el modo, aunque aún así no me convenció y usé Gedit por mucho tiempo. Qué ciego estaba.

Tiempo después quise agarrar Vim de nuevo, esta vez decidido a dominarlo. Aún estoy muy lejos de lograrlo, pero en este tiempo he escrito todos mis programas y mi tesis completa en ese maravilloso editor y no me arrepiento en lo absoluto. Me gustaría compartirles a través de esta sección algunas de las cosas fantásticas que he aprendido a hacer con él.

El problema

Hace unos días, me llegó en el trabajo una lista así:

Canto general
 
El perseguidor
 
La feria
 
La hojarasca
 
Conversación en La Catedral
 
Cronopios y famas

Que tenía que convertir en un archivo YAML así:

canto_general:
nombre: "Canto general"
el_perseguidor:
nombre: "El perseguidor"
la_feria:
nombre: "La feria"
la_hojarasca:
nombre: "La hojarasca"
conversacin_en_la_catedral:
nombre: "Conversación en La Catedral"
cronopios_y_famas:
nombre: "Cronopios y famas"

La solución

Como me daba flojera hacerlo a mano, escribí un poquito de Python alrededor:

#encoding: utf-8
lines = """
Canto general
 
El perseguidor
 
La feria
 
La hojarasca
 
Conversación en La Catedral
 
Cronopios y famas"""
for l in lines.split('\n\n'):
us = l.lower().replace(' ', '_')
ad = ''.join([c for c in us if 'a'<=c<='z' or c=='_'])
print '%s:\n nombre: "%s"' % (ad, l.strip())

Lo seleccioné en modo visual y escribí el comando:

:'<,'>!python

Donde '<,'< lo insertó vim automáticamente y significa "el rango seleccionado visualmente". Tras dar Enter, las líneas fueron sustituídas por:

canto_general:
nombre: "Canto general"
el_perseguidor:
nombre: "El perseguidor"
la_feria:
nombre: "La feria"
la_hojarasca:
nombre: "La hojarasca"
conversacin_en_la_catedral:
nombre: "Conversación en La Catedral"
cronopios_y_famas:
nombre: "Cronopios y famas"

Y listo.

Espera, ¿qué?

El código en Python es más o menos claro: Puse las frases en una cadena, la convertí en una lista dividiéndola cada dos saltos de línea, y cada línea la convierto a minúsculas, cambio espacios por guiones y quito los caracteres "especiales" como acentos y etcétera. Finalmente imprimo todo en el formato pertinente.

En vim, rango!comando ejecuta comando, enviándole el texto en el rango rango a través de su entrada estándar. Finalmente recoge todo lo que comando escriba a su salida estándar y lo pega en la posición actual del cursor. En este caso lo ocupé para ejecutar el intérprete de Python, que por defecto empieza a ejecutar lo que le llega por la entrada estándar.

¿Y luego?

Como supondrán, las posibilidades son amplísimas cuando se combina esta técnica con las muchas utilidades de las que se dispone en un ambiente UNIX. Por ejemplo, para ordenar una lista por órden lexicográfico basta con seleccionarla y escribir:

:'<,'>!sort

Sencillo, ¿no?. ¿Qué otras cosas se les ocurren?.

If you liked this article, say hello on Twitter

blog comments powered by Disqus