Saltar al contenido

Macros: grabar teclas y multiplicarlas

Una macro es un registro con teclas dentro, y de ahí sale todo: grabar de forma repetible, la parada por error que hace seguro escribir 999@a, añadir con qA, editarla como el texto que es, la recursión, @: y @@, y cuándo conviene :normal en su lugar.

Una macro no es magia ni una función: es un registro con teclas dentro. Entender eso —que lo grabado es texto, y que por tanto se puede pegar, corregir a mano, volver a cargar y hasta escribir sin grabar nada— es lo que separa usarlas de sufrirlas. Y hay un segundo mecanismo, que casi ningún tutorial menciona, sin el cual serían inservibles: cuando algo falla dentro de una macro, la repetición se detiene entera. Eso convierte un número inventado en una condición de parada, y es lo que te permite escribir 999@a sin mirar cuántas líneas tiene el fichero.

  • Grabar y reproducir, y reconocer el indicador recording.
  • Aplicar las tres reglas que hacen que una macro funcione en cualquier línea, no solo donde la grabaste.
  • Explicar la parada por error y usarla a propósito como condición.
  • Añadir a una macro con qA y editarla como texto sin volver a grabarla.
  • Escribir macros recursivas, y por qué qaq no es opcional.
  • Elegir entre @a, :normal! y :g/…/normal! @a según el caso.

Qué es exactamente una macro

En la lección 1.2 viste que "ayy copia una línea al registro a y que :registers te enseña el contenido de todos.

Una macro usa los mismos registros. Cuando grabas, Neovim no crea nada nuevo: mete en el registro las teclas que pulsas, como si fueran texto copiado. Puedes comprobarlo ahora mismo:

VIM
qa          " graba en el registro aciwhola<Esc>q           " para:reg a

Y :reg a te enseña, literalmente:

Texto
Type Name Content  c  "a   ciwhola^[

Eso es la macro entera: siete caracteres y un ^[, que es Esc. No hay nada más. Una macro es texto, y de ahí sale todo lo que puedes hacerle.

Grabar es un interruptor

q seguido de una letra empieza a grabar. q a secas para. La misma tecla hace las dos cosas, y por eso mientras grabas no puedes usar q para nada más.

Mientras grabas, Neovim escribe recording @a abajo a la izquierda. Si alguna vez el editor «se comporta raro» y ves eso ahí, es que empezaste a grabar sin querer: pulsa q y sigue.

Tecla Qué hace
q{reg} empieza a grabar en ese registro
q para de grabar
@{reg} reproduce
@@ repite la última macro reproducida
{n}@{reg} la reproduce n veces
@: repite el último comando de dos puntos
:reg {reg} enseña qué hay dentro

Grabar para que sirva en cualquier línea

Grabar es fácil. Grabar algo repetible tiene tres reglas, y son la diferencia entre una macro que funciona y una que destroza el fichero.

Empieza desde una posición conocida

La macro se reproducirá con el cursor en un sitio que hoy no puedes prever. Arranca siempre con 0 o ^ para colocarte tú, en vez de depender de dónde te dejen.

Usa complementos, no cuentas de teclas

ciw funciona en una palabra de cuatro letras y en una de veinte. 4l funciona solo hoy. Todo lo que aprendiste en la gramática —objetos de texto, f{x}, t{x}, /patrón— existe precisamente para esto.

Termina moviéndote a la siguiente unidad

Si la macro edita una línea, que acabe con j. Si edita un bloque, que acabe en el siguiente. Así reproducirla otra vez continúa donde lo dejó, y 99@a recorre el fichero solo.

Un ejemplo completo. Partimos de una lista y queremos convertirla en un array de cadenas:

Texto
manzana          "manzana",pera        →    "pera",platano          "platano",
Texto
qa          empieza a grabar en 'a'0           al principio de la línea       (regla 1)i"<Esc>     abre comillasA",<Esc>    cierra y añade la coma          (regla 2: A no depende del largo)j           siguiente línea                 (regla 3)q           para

Y ahora 99@a.

La parada por error

Acabas de escribir 99 sobre un fichero que a lo mejor tiene doce líneas. Nadie te ha dicho cuántas veces repetir, y aun así no pasa nada:

Cuando un comando dentro de una macro falla, la macro se aborta y la repetición se detiene entera.

Al llegar a la última línea, la j final no puede bajar más. Falla. La macro para, y las ochenta y siete repeticiones que quedaban no se ejecutan. El fichero queda exactamente como querías.

El fallo como condición de parada

Deja de leer 99@a como «hazlo noventa y nueve veces» y empieza a leerlo como «hazlo hasta que ya no se pueda». El número solo tiene que ser mayor que el trabajo real, y por eso nadie lo calcula: se escribe un número grande y ya está.

Lo interesante es la inversión conceptual que hay debajo. Un bucle normal necesita que le digas cuándo parar, y para eso necesitas saber de antemano cuántas unidades hay: contar las líneas, mirar el tamaño de la lista, comprobar una condición en cada vuelta. Aquí no se cuenta nada. La condición de parada no la escribes tú: la aporta el propio trabajo, que en algún momento deja de ser posible.

Ese patrón —el error no es una excepción al flujo, es el flujo— es más común de lo que parece en cuanto le pones nombre. Es exactamente lo que hace un iterador de Python cuando lanza StopIteration para terminar un for: el bucle no pregunta «¿quedan elementos?», intenta coger uno y se para cuando la respuesta es una excepción. Es lo que hace un bucle de lectura que termina al recibir fin de fichero, en vez de haber medido antes cuántos bytes había. Es el while (read(...) > 0) de C. Y es la razón de que en muchos sitios sea idiomático «pedir perdón en vez de pedir permiso»: intentarlo y manejar el fallo, en lugar de comprobar antes si se puede —comprobación que además puede quedarse obsoleta entre que preguntas y actúas—.

Y tiene un uso deliberado que conviene aprender: puedes meter un fallo a propósito. Si tu macro empieza con f, y la línea que toca no tiene coma, la macro se detiene ahí sola en vez de hacer un estropicio en el resto del fichero. Acabas de darle un if a algo que no tiene condicionales, usando como guarda una moción que falla donde no debe aplicarse. Por eso conviene grabar con f, t y / en lugar de con l repetidas: además de ser independientes del texto, fallan cuando el patrón no está, y ese fallo te protege.

Y el reverso: deshacer 99 repeticiones cuesta 99 u

Cada iteración de la macro es un cambio independiente en el árbol de deshacer. Si 99@a hace lo que no querías, un u deshace una sola repetición.

La salida no es aporrear u: es :earlier 1f, que devuelve el buffer a como estaba la última vez que lo guardaste, de un golpe. Lo verás a fondo en la lección 1.8. De momento quédate con la costumbre de guardar antes de lanzar una macro larga, que convierte cualquier desastre en un comando.

Añadir a una macro sin volver a empezar

Grabaste, la probaste, y te faltaba un paso al final. No hay que rehacerla: la letra en mayúscula añade en vez de reemplazar.

Texto
qA          sigue grabando SOBRE lo que ya tiene 'a'=$          lo que faltabaq           para

Es el mismo comportamiento que ya conoces de los registros: "ayy reemplaza, "Ayy añade.

Editar una macro como el texto que es

Cuando lo que falta está en medio, añadir no sirve. Pero como una macro es texto, se puede pegar, corregir a mano y volver a cargar.

Pégala en una línea vacía

"ap vuelca el contenido del registro a en el buffer. Vas a ver algo como 0i"^[A",^[j — con el ^[ como un carácter, no como dos.

Corrígela como cualquier otra línea

Es texto normal: edítalo con lo que ya sabes. Para escribir un Esc literal, pulsa Ctrl-v y luego Esc; para un Enter literal, Ctrl-v y luego Enter.

Cárgala de vuelta

Con el cursor en esa línea: 0"ay$.

No uses yy para recargarla

"ayy copia la línea con su salto de línea final. Ese salto entra en el registro, así que la macro recargada ejecuta un Enter de más al terminar — y en modo Normal, Enter baja una línea. La macro hará algo distinto de lo que acabas de corregir, y de forma sutil: no falla, solo se desplaza una línea por iteración.

0"ay$ copia desde el principio de la línea hasta el último carácter, sin el salto. Es exactamente la diferencia entre una moción de línea y una de caracteres, de la lección 0.4, y es el detalle que hace que este truco funcione o no.

También puedes escribirla sin grabar nada:

VIM
:let @a = '0i"' . "\<Esc>" . 'A",' . "\<Esc>" . 'j'

Entre comillas dobles, \<Esc> se convierte en la tecla de verdad —el mismo mecanismo de :execute que viste en la lección anterior—. Es menos cómodo de leer y es lo que usas cuando quieres dejar una macro escrita en tu configuración.

Tus macros sobreviven a cerrar el editor

Los registros se guardan en el shada, y una macro es un registro. Eso significa que la que grabaste esta mañana en a sigue ahí mañana, aunque hayas cerrado Neovim.

Tiene dos consecuencias prácticas. Una buena: puedes reservar un par de letras para macros que uses a menudo y no volver a grabarlas. Y una que explica un misterio: si alguna vez pulsas @a sin haber grabado nada y pasa algo inesperado, es la macro de la semana pasada.

Macros recursivas

Si tu macro se llama a sí misma al final, se ejecuta hasta que algo falla. Es un bucle sin escribir un bucle:

Texto
qaq         PRIMERO: vacía el registro aqa          empieza a grabar0i"<Esc>A",<Esc>j@a          se llama a sí mismaq           para

Ahora @a solo, sin número, recorre el fichero entero y se detiene al final por la parada por error.

El qaq del principio no es un adorno

@a dentro de la grabación se ejecuta mientras grabas. Si el registro a tuviera algo de antes, ese algo correría en ese momento y además quedaría dentro de la macro nueva.

qaq es grabar cero teclas en a: lo deja vacío. Un @a sobre un registro vacío no hace nada, así que la grabación continúa limpia. Es un truco raro de leer y sin él la recursión no se puede grabar.

En la práctica, la recursiva y 999@a resuelven lo mismo, y la segunda se escribe más rápido. La recursiva gana cuando no quieres pensar ni un número, y cuando vas a reutilizar la macro muchas veces.

@: y los registros que no grabaste

El registro : guarda el último comando de dos puntos que ejecutaste, y se reproduce igual que una macro:

VIM
:m+1        " mueve la línea una abajo@:          " otra vez@@          " y otra

No lo grabaste tú: Neovim lo mantiene solo. Lo mismo con "/ —la última búsqueda— y ". —el último texto insertado—. Son registros de solo lectura que puedes reproducir o pegar, y @: en particular convierte cualquier comando complejo en algo repetible sin haber previsto que lo ibas a repetir.

Macro contra :normal

Los dos ejecutan teclas de modo Normal. La diferencia es quién decide dónde.

Macro @a :{rango}normal! {teclas}
Dónde empieza donde esté el cursor al principio de cada línea del rango
Cuántas veces las que pidas, hasta que falle una por línea del rango
Si falla se detiene todo esa línea se aborta, sigue con la siguiente
Cómo eliges el conjunto con un número con un rango o con :g
Deshacer un u por iteración un u por línea

Fíjate en la tercera fila, porque es la que decide en la práctica. Si quieres que un fallo detenga la operación entera —porque significa que algo no era como creías—, quieres la macro. Si quieres que las líneas problemáticas se salten y las demás se procesen, quieres :normal!.

VIM
:%normal! A;                 " punto y coma al final de TODAS las líneas:'<,'>normal! I- "           " guion delante de cada línea de la selección

:normal es mejor cuando el conjunto se describe —«todas», «de la 10 a la 40», «las que digan TODO»— y la edición es corta. La macro es mejor cuando la edición es larga o tiene que empezar en un punto que no es el principio de la línea.

Y como en la lección anterior: la exclamación no es opcional. :normal sin ella respeta tus mapeos, con lo que el mismo comando hace cosas distintas en máquinas distintas.

Las tres piezas juntas

VIM
:g/TODO/normal! @a           " la macro, solo en las líneas que casan:'<,'>normal! @a             " la macro, solo en la selección

Programar el editor sin escribir un programa

Ahí tienes las tres piezas: un patrón que dice sobre qué, una macro que dice qué hacer, y :g o un rango que las une. Sin abrir un fichero de configuración, sin escribir Lua, sin instalar nada.

Y fíjate en lo que es cada pieza por separado, porque ninguna se diseñó para esto. El patrón es el motor de búsqueda. La macro es un registro, el mismo sitio donde guardas lo que copias. :normal es un puente entre la línea de comandos y el modo Normal. Tres mecanismos independientes, con tres propósitos distintos, que combinados dan un lenguaje de transformación de texto que no aparece en ninguna lista de funcionalidades porque nadie lo implementó: emerge.

Es la misma economía de la lección 0.4, un nivel más arriba. Allí eran operadores por complementos; aquí son conjuntos por transformaciones. Y el efecto práctico también es el mismo: cada pieza nueva que aprendas se multiplica por las que ya tienes. El día que aprendas la quickfix, en la lección siguiente, tendrás una cuarta forma de describir el conjunto —los sitios que encontró una herramienta externa— y funcionará con todo lo demás sin que nadie lo haya conectado.

Es también el motivo de que valga la pena grabar bien. Una macro con 0 al principio y objetos de texto en medio se puede aplicar a un fichero, a una selección o a las trescientas cuarenta líneas que casan con un patrón. Una macro grabada con lll solo sirve donde se grabó.

La j del final falla en la última línea y detiene la repetición sola: por eso el 99 no hace daño con solo tres líneas. Mira el HUD durante la reproducción: ahí está la grabación entera.

Mayúscula = añadir. No hay que volver a grabarla entera.

Es texto. Se pega, se edita y se recarga. Con y$, no con yy.

Con un rango y una edición corta, :normal! es más directo que grabar.

:g elige el conjunto; la macro hace el trabajo.

Cada iteración es un cambio, así que u deshace una sola. :earlier 1f vuelve al último guardado de golpe.

Grábala, rómpela, arréglala

  1. Coge un fichero con una lista de palabras y graba una macro que envuelva cada línea en comillas y le añada una coma. Aplícala con 99@a y comprueba que se detiene sola al final.
  2. Mira lo que grabaste con :reg a. Localiza el ^[ y cuenta los caracteres: no hay nada más que eso.
  3. Pégala con "ap, cámbiale algo, y recárgala con 0"ay$. Comprueba que hace lo nuevo.
  4. Vuelve a cargarla, esta vez a propósito con "ayy, y observa el desplazamiento de más. Ese es el fallo del que te avisa esta lección.
  5. Graba la versión recursiva con qaq delante y lánzala con un solo @a.
  6. Provoca la parada a propósito: graba una macro que empiece con f, y lánzala con 99@ sobre un bloque donde algunas líneas no tengan coma. Observa dónde se detiene.
  7. Ejecuta la macro solo sobre las líneas que contengan una palabra concreta, con :g/palabra/normal! @a.
  8. Guarda el fichero, lanza una macro que haga estropicios, y recupéralo con :earlier 1f en vez de con veinte u.
  9. Cierra Neovim, ábrelo otra vez y ejecuta :reg a. Tu macro sigue ahí, porque un registro es un registro.