Al principio, moverte utilizando el teclado te puede hacer sentir incómodo e increíblemente lento, ¡pero no desistas! Una vez que te acostumbres, podrás moverte a cualquier parte de un archivo de manera más rápida que utilizando el ratón.
En este capítulo, aprenderás los movimientos esenciales y cómo utilizarlos de manera eficiente. Ten en mente que este capítulo **no** es todo lo que Vim puede ofrecer en cuanto a la hora de moverse por un archivo. La meta aquí es presentar los movimientos más útiles para volverte productivo rápidamente. Si necesitas aprender más, echa un vistazo a la ayuda de Vim `:h motion.txt`.
También puedes moverte con las flechas de dirección de tu teclado. Si estás empezando, sientete libre de utilizar cualquier método con el que te sientas más cómodo.
Personalmente prefiero la clásica combinación `hjkl` porque mi mano derecha permanece encima del teclado. Al hacer esto, hace que este más cerca de las teclas circundantes del teclado. Para _obligarme_ a utilizar esta combinación de teclas, he inhabilitado las flechas de dirección del teclado al usar Vim añadiendo estas líneas en el archivo `~/.vimrc`:
También hay complementos para tratar de romper ese mal hábito. Uno de ellos es [vim-hardtime](https://github.com/takac/vim-hardtime). Para mi sorpresa, solo lleva unos pocos días el habituarse al uso de `hjkl`.
Si te preguntas porque Vim utiliza la combinación de teclas `hjkl` para moverse por el texto, es debido que el terminal Lear-Siegler ADM-3A donde Bill Joy empezó a desarrollar Vi, no tenía teclas con flechas en el teclado y utilizó `hjkl` como izquierda/abajo/arriba/derecha.
¿Por qué esto puede ser útil? Esto me permite rápidamente ver cuantas a líneas de diferencia estoy desde la posición a la que quiero ir. Con esto, puedo ver fácilmente que mi objetivo está 12 líneas por debajo de mi posición actual, así que puedo ejecutar `12j`. Además, si estoy en la línea 69 y mi objetivo es desplazar el cursor a la línea 81, esto me lleva a tener que hacer un cálculo mental \(81 - 69 = 12\). Esto consume muchos recursos mentales. Cuanto menos tenga que pensar sobre donde quiero ir, mejor.
Esto es 100% una preferencia personal. Experimenta con las opciones `relativenumber` / `norelativenumber`, `number` / `nonumber` ¡y utiliza cualquier método que encuentres más útil!
Hablemos sobre el argumento "contar". Los movimientos de Vim aceptan un argumento precedente numérico. He mencionado anteriormente que puedes desplazarte 12 líneas hacia abajo en el texto mediante `12j`. El 12 en `12j` es el número que lleva la cuenta.
Puedes aplicar esto a todos tus movimientos. Si quieres moverte 9 caracteres a la derecha, en vez de presionar la tecla `l` puedes ejecutar simplemente `9l`.
Vamos a movernos por una unidad de movimiento mayor: _palabra_. Puedes moverte al comienzo de la siguiente palabra \(`w`\), al final de la siguiente palabra \(`e`\), al comienzo de la palabra anterior \(`b`\)y al final de la palabra anterior \(`ge`\).
Además de esto, también está la _PALABRA_, distinta de palabra. Puedes mover el cursor al principio de la siguiente PALABRA \(`W`\), al final de la siguiente PALABRA \(`E`\), al comienzo de la PALABRA previa \(`B`\) y al final de la PALABRA previa \(`gE`\). Para hacerlo sencillo de recordar, PALABRA utiliza las mismas letras de movimiento que palabra excepto que son en mayúsculas.
Entonces, ¿cuáles son las similitudes y diferencias entre una palabra y una PALABRA? Tanto una palabra como una PALABRA están separadas por caracteres que no son espacios en blanco. Una palabra es una secuencia de caracteres que continen _únicamente_ este grupo de caracteres `a-zA-Z0-9_`. Una PALABRA es una secuencia que incluyen todos los caracteres excepto el espacio en blanco \(cuando me refiero a espacio en blanco, esto incluye tanto un espacio, una separación por tabulador o un fin de línea\) Para aprender más, echa un vistazo a la ayuda en Vim sobre este tema con estos comandos: `:h word` o `:h WORD`.
Con el cursor al comienzo de la línea, ve al final de la línea con `l`, te llevará pulsar 21 veces la tecla. Utilizando `w`, solo te llevará pulsar 6 veces. Utilizando `W`, solo te llevará 4 pulsaciones. Tanto palabra como PALABRA son buenas opciones para mover el cursor en pequeñas distancias.
Mientras editas, a menudo necesitas navegar horizontalmente en la misma línea. Para saltar al primer caracter de la línea actual, utiliza `0`. Para ir al último caracter de la línea actual, utiliza `$`. Además, también puedes utilizar `^` para ir al primer caracter, que no sea un espacio en blanco de la línea actual y `g_` para ir al último caracter que no sea un espacio en blanco en la línea actual. Si quieres ir a la columna `n` en la línea actual, puedes utilizar `n|`, donde "n" será el número de la columna donde quieres desplazar el cursor.
También puedes realizar una búsqueda en la línea actual con `f` y `t`. La diferencia entre `f` y `t` es que `f` te lleva a la primera letra de la primera conincidencia encontrada y `t` te lleva *hasta justo* antes de la primera letra de la primera coincidencia encontrada. Así que si quieres realizar una búsqueda y que el cursor se situe sobre la letra "h", utiliza `fh`. Si quieres realizar una búsqueda de la primera "h" y quieres que el cursor se situe justo antes de esa primera coincidencia utiliza `th`. Si después quieres seguir navegando hacia la _próxima_ coincidencia de esa misma búsqueda, utiliza `;`. Para ir a la coincidencia previa de esa misma búsqueda en la línea actual, utiliza `,`.
`F` y `T` son las opciones similares a `f` y `t` pero para buscar hacia atrás en el texto. Para buscar hacia atrás una "h", ejecuta `Fh`. Para seguir buscando "h" en la misma dirección, usa `;`. Ten en cuenta que `;` después de `Fh` continua la búsqueda hacia atrás y `,` después de `fh` busca hacia adelante.
Con el curso al comienzo de la línea, puedes ir al último caracter de la línea actual \(";"\) pulsando una única tecla: `$`. Si quieres ir a la letra "w" en la palabra "world", puedes utilizar `fw`. Un buen truco para ir a cualquier punto de la línea actual es echar un vistazo a ver si existe alguna letra poco común como "w", "x" o "z" cerca de tu objetivo.
Primero vamos a hablar sobre lo que es una frase. Una frase termina con alguno de estos signos de puntuación `. ! ?` seguido por un final de línea, un espacio en blanco o una tabulación. Puedes saltar a la siguiente frase mediante `)` y a la frase previa con `(`.
Yo soy una frase. Yo soy otra frase porque termino con un punto. ¡Yo también soy una frase porque acabo con un signo de exclamación! ¿Qué pasa con el signo de interrogación? Yo no soy una frase, debido al guión - punto y coma ; o los dos puntos :
Por cierto, si tienes problemas con Vim porque no considera uan frase frases separadas por `.` seguido de una linea simple, quizás estás en el modo `'compatible'`. Añade `:set nocompatible` en vimrc. En Vi, una frase termina en `.` seguido de **dos** espacios en blanco. Deberías tener al ajuste `nocompatible` en todo momento.
Vamos a hablar sobre lo que es un párrafo. Un párrafo comienza después de cada línea vacía y también en cada conjunto de una macro de párrafo especificada por los pares de caracteres en la opción de párrafos.
Si no estás seguro de qué es un macro de párrafo, no te preocupes. Lo importante es que un párrafo comienza y termina después de una línea vacía. Esto debería ser cierto en la mayoría de las veces.
Los programadores a menudo editan archivos que continen código. Puede contener muchos paréntesis, llaves y corchetes. Te puedes perder facilmente entre ellos. Si estás dentro de uno, puedes saltar a la otra pareja \(si existe\) con `%`. También puedes utilizar esto para encontrar cualquier pareja de paréntesis, llaves o corchetes.
Echemos un vistazo a este código de ejemplo en Scheme, porque hace bastante uso de los paréntesis. Vamos a movernos con `%` dentro de los diferentes paréntesis.
Personalmente, me gusta complementar `%` utilizando complementos que añadan un indicador visual como [vim-rainbow](https://github.com/frazrepo/vim-rainbow). Para más información, echa un vistazo a la ayuda en Vim con `:h %`.
Puedes saltar a un número de línea `n` con `nG`. Por ejemplo, si quieres saltar a la línea 7, utilza `7G`. Para saltar a la primera línea del texto, puedes utilizar tanto `1G` o `gg`. Para saltar a la última línea del texto, utiliza `G`.
A menudo no sabes exactamente en qué línea está el sitio al que te quieres dirigir, pero sabes que aproximadamente se encuentra al 70% del archivo completo. En ese caso, puedes ejecutar `70%`. Para saltar a la mitad del archivo, puedes ejecutar `50%`.
Para ir rápidamente a la parte superior, central o inferior de tu _ventana_, puedes utilizar las teclas `H`, `M`, o `L`. \(_N.d.T: una regla para acordarse de estos atajos puede ser su correspondencia en inglés. `H` de High, `M` de Medium y `L` de Low_\).
También se puede pasar un número de conteo a `H` y `L`. Si utilizas `10H`, irás 10 líneas por debajo de la parte superior de la ventana. Si utilizas `3L`, se colocará el cursor 3 líneas por encima de la última línea de la ventana.
Para desplazarse por el texto \(o hacer _scroll_\), tienes 3 velocidades incrementales: Pantalla completa \(`Ctrl-F/Ctrl-B`\), media pantalla \(`Ctrl-D/Ctrl-U`\), y línea a línea \(`Ctrl-E/Ctrl-Y`\).
Muy a menudo, sabes que existe una frase concreta dentro del archivo. Puede utilizar la navegación por búsqueda para llegar hasta tu objetivo rápidamente. Para buscar una frase, puedes utilizar `/` para hacer una búsqueda hacia adelante en el texto o `?` para buscar hacia atrás. Para repetir la última búsqueda, puedes utilizar `n`. Para repetir la última búsqueda pero en dirección opuesta, puedes utilizar `N`.
Si estás buscando la cadena "let", puedes hacerlo mediante `/let`. Para buscar de nuevo "let" rápidamente, simplemente presiona `n`. Para buscar "let" de nuevo, pero esta vez en dirección contraria, hazlo mediante la tecla `N`. Si utilizas `?let` para realizar la búsqueda, buscará hacia atrás en el texto. Si usas `n`, seguirá realizando la búsqueda en esa dirección en el texto, `N` realizará ahora la búsqueda hacia adelante.
Puedes habilitar el resaltado del texto buscado mediante el ajuste `:set hlsearch`. Ahora cuando busques `/let`, resaltará _todas_ las coincidencias que haya en todo el texto. Además, puedes configurar una búsqueda incremental con `:set incsearch`. Esto resaltara el patrón de búsqueda mientras estás escribiéndolo. De manera predeterminada, la cadena buscada permanecerá resaltada, hasta que hagas otra búsqueda. Esto puede convertirse rápidamente en un inconveniente. Para inhabilitar ese reslatado, puedes ejecutar `:nohlsearch`. Como utilizo esa funcionalidad de quitar el reslatado de manera frecuente, he creado un mapedado de esa funcionalidad. Para ello he añadido la siguiente línea en el archivo .vimrc:
También puedes buscar rápidamente el texto que se encuentra bajo el cursor con `*` para buscar esa coincidencia hacia adelante en el texto, y con `#` realizará la búsqueda hacia atrás. Si tu cursor, está sobre el texto "one", pulsando `*` hará lo mismo que si hubieras escrito `/\<one\>`.
Tanto `\<` como `\>` en `/\<one\>` significa que haga una búsqueda de la palabra completa. Y que no encuentre "one" dentro de una palabra mayor. Es decir, encontrará "one" pero no "onetwo". Si tu cursor está sobre "one" y quieres buscar las coincidencias de la palabra completa o que forme parte de otras palabras más grandes, necesitas utilizar `g*` en vez de `*`.
Puedes utilizar marcas para guardar la posición actual del cursor y poder volver a esa posición más tarde. Es como un marcador para la edición de texto. Puedes establecer un marcador con `mx`, donde `x` puede ser cualquier letra del alfabeto `a-zA-Z`. Existen dos maneras de volver a la marca establecida: de manera exacta \(línea y columna\) mediante ```x`` y a la línea con `'x`.
Existe una diferencia entre establecer marcas con letras minúsculas \(a-z\) y mayúsculas \(A-Z\). Las marcas con letras minúsculas, son marcas locales y las marcas con letras mayúsculas son marcas globales \(a veces conocidas como marcas de archivo\).
Vamos a hablar sobre las marcas locales. Cada _buffer_ puede tener su propio juego de marcas locales. Si tengo dos ficheros abiertos, puedo establecer una marca "a" \(`ma`\) en el primer archivo y otra marca "a" \(`ma`\) en el segundo archivo.
A diferencia de las marcas locales con las que puedes tener un juego de marcas en cada _buffer_, solo puedes tener un juego de marcas globales. Si estableces una marca global "A" \(`mA`\) dentro de `miArchivo.txt`, la próxima vez que ejecutes `mA` en un archivo diferente, sobreescribirá la marca "A". Una ventaja de las marcas globales es que puedes saltar a cualquier marca global incluso si está dentro de un proyecto completamente diferente. Las marcas globales pueden viajar a través de los archivos.
Para ver todas las marcas establecidas puedes hacerlo mediante `:marks`. Puedes comprobar que en la lista de marcas hay más marcas que las de `a-zA-Z`. Algunas de ellas son:
Hay más marcas que las listadas aquí. No se tratarán todas aquí, porque creo que muchas no son muy comunes y se utilizan muy poco, pero si tienes curiosidad al respecto, echa un vistazo a la ayuda de Vim con: `:h marks`.
Por último, hablemos de los saltos en Vim. En Vim, puede "saltar" a un archivo diferente o a una parte diferente de un archivo con ciertos movimientos. Sin embargo, no todos los movimientos cuentan como un salto. Bajar con `j` no cuenta como un salto, incluso si bajas 10 pasos con `10j`. Ir a la línea 10 con `10G` si cuenta como un salto.
No recomiendo memorizar esta lista. Una buena regla para recordarla es, que cualquier movimiento que mueve el cursor más de una palabra o más de la línea actual, probablemente sea un salto. Vim memoriza los lugares por los que te has movido y puedes ver esto dentro de `:jumps`. Para más información echa un vistazo a la ayuda de Vim con `:h jump-motions`.
¿Por qué los saltos son útiles? Porque puedes navegar por la lista de saltos realizados mediante `Ctrl-O` para moverte hacia arriba por la lista de saltos y con `Ctrl-I` para moverte hacia abajo en la lista. También puedes saltar por diferentes archivos, lo que veremos en la siguiente parte.
Si acabas de llegar a Vim, aquí tienes mucho para aprender. No espero que nadie recuerde todo de manera inmediata. Lleva su tiempo el ejecutar estos comandos sin que tengas que parar a pensarlos.
Creo que la mejor manera de empezar es memorizar algunos comandos de movimiento esenciales. Recomiendo empezar con estos 10 movimientos: `h, j, k, l, w, b, G, /, ?, n`. Repítelos suficientemente como para usarlos sin pensar en ellos.
1. Estate alerta de acciones repetidas que realices. Si encuentras que ejecutas `l` de manera repetida, busca un movimiento que te lleve de una manera más rápida a tu destino. Encontrarás que puedes utilizar `w` para moverte entre palabras. Si descubres que ejecutas `w` de manera repetitiva, busca si hay un comando de movimiento que te lleve al final de la línea de manera inmediata. Encontrarás que puedes utilizar `$`. Si puedes describir de manera verbal lo que necesitas, hay muchas posibilidades de que Vim tenga una manera de hacer lo que necesitas.
Finalmente, no necesitas conocer cada uno de los comandos de movimiento de Vim para ser productivo. La mayoría de los usuarios de Vim no los conocen. Yo tampoco. Aprende los comandos que te ayudarán a realizar tu tarea en cada momento.