Otro Tutorial del VI Más

El siguiente documento es un tutorial/introducción al editor del textos estándar de UNIX: el vi. Está pensado para intentar que la gente que no está acostumbrada le pierda el miedo lógico de las primeras sesiones (que yo también tuve, como todo el mundo, y mírame ahora editando páginas HTML con el vi, como ahora, o consiguiendo versiones para MS-DOS y Windows para poder utilizarlo en cualquier momento)

Introducción al vi

El vi es el editor estándar de UNIX, y tiene bastantes años ya. Hay otros editores más amigables en UNIX, como por ejemplo el EMACS, pero el vi es probablemente el único que sabes que vas a tener en cualquier máquina que trabaje con UNIX. El vi se basa en órdenes, al contrario que la mayoría de los otros editores. ¿y eso qué diablos significa? te estarás preguntando si nunca lo has visto. Significa, aunque parezca extraño al principio, que cuando se pulsan teclas, éstas no se escriben, sino que son órdenes para que el editor lleve a cabo determinadas acciones.

Probablemente lo que te estarás preguntando ahora es '¿y entonces cómo escribo texto? Se supone que los editores de texto están para eso...'. Pues con una orden especial para insertar texto (en realidad hay más de una, pero para simplificar, diremos que es la 'i'). Por supuesto, como en el 99% de las utilidades UNIX, se distingue entre mayúsculas y minúsculas, así que no es lo mismo la orden i que la orden I.

Esto nos lleva a la necesidad de distinguir entre modo inserción y modo órdenes. En el modo inserción, cualquier cosa que tecleemos aparecerá en pantalla y se grabará en el fichero si finalmente salvamos los cambios, y en modo órdenes el vi estará esperando a que tecleemos órdenes, para interpretarlas y actuar en consecuencia. Para salir del modo inserción y volver al modo órdenes, tenemos que pulsar la tecla ESC. Esta tecla, en general, cancela las acciones a medias que tengamos (una orden a medias, por ejemplo). Por cierto, que a propósito de esto, es una buena costumbre pulsar ESC siempre justo después de añadir cualquier texto, ya que nos evitará confusiones y puede que algún disgusto al pulsar teclas creyendo que vamos a insertar texto, y que el vi las interprete como órdenes, por no tener claro si estábamos en modo inserción.

Esto tiene ventajas e inconvenientes: Por un lado, el tiempo de aprendizaje es mucho mayor (o, siendo radicales, hay tiempo de aprendizaje), y, por otro lado, cuando te acostumbras y te sabes una buena lista de órdenes, editas más rápido y de forma más cómoda que con cualquier otro editor, porque siempre mantienes los dedos sobre el teclado, y no los tienes que mover para llegar al ratón, las teclas de inicio, fin, etc., o al Ctrl o Alt. (aunque en realidad alguna orden que otra utiliza el Ctrl, y el clon más famoso del vi, el vim, soporta el ratón)

Primera edición: órdenes básicas

Las órdenes más importantes que hay que saber son:
	Moverse a la izquierda		- h
	Moverse a la derecha		- l
	Moverse arriba			- k
	Moverse abajo 			- j
	Insertar texto			- i
	Borrar caracter (como Supr)	- x
Bueno, vale, reconozco que en la grandísima mayoría de las terminales los cursores funcionan, pero tenía ganas de darte un pequeño susto, y además puede que te encuentres con alguna mal configurada y tengas que utilizar h, j, k, l para moverte.

En realidad con estas instrucciones podrías ingeniártelas para editarlo casi todo, aunque no podrías borrar saltos de línea (que a efectos de borrado no son caracteres en el vi, es decir, no los puedes borrar con la x*)... pero si sólo te sabes estas órdenes, te aseguro que editar con el vi puede resultar la experiencia más infernal de tu vida (sobre todo si editas código C que tiene que funcionar como sea).
* Para poder unir líneas hay una orden especial, que es la J

¡No me deja salir!

Bueno, en el vi, como habrás podido comprobar si ya has tenido tu primera sesión, no existen los menús (y probablemente si se te ha ocurrido preguntarle a alguien que esté acostumbrado al vi dónde o cómo se accede a ellos, le habrá entrado un ataque de risa), así que para hacer las acciones de cargar, salvar, leer otro fichero, pasar al siguiente si cargas varios a la vez... también te tienes que aprender nuevas órdenes. Todas las órdenes que no editan el texto directamente, como las típicas opciones que tendrías en menús en otros editores de texto, en vi se realizan con una orden, precedida de dos puntos ':'. Las órdenes que yo me sé son las siguientes (apréndete las que quieras):
	Salir sin grabar los cambios		- q
	Salir grabando los cambios		- x
	Salir grabando los cambios		- wq
	Salvar los cambios actuales		- w
	Salvar como fichero			- w fichero
	Insertar desde el cursor fichero	- r fichero
	Editar fichero				- e fichero
	Editar siguiente fichero		- n
	Editar anterior fichero			- prev
Cuando se ejecutan las órdenes q o e, o n o prev, y el fichero ha cambiado, el vi no nos dejará ejecutar las órdenes, pero dirá '(use ! to override)', lo que significa que si realmente queremos ejecutar la orden, perdiendo los cambios en el fichero actual, debemos escribir un '!' inmediatamente después de la orden. Así, si hacemos cambios en un fichero y queremos salir sin salvarlos, debemos escribir :q!.
Tengo que advertirte seriamente que tengas cuidado con acostumbrarte a salir con la orden :x, porque como te equivoques y escribas :X, la llevas clara. Eso grabará y saldrá, pero ¡después de encriptarlo! Antes de grabar te pide la clave de encriptación... Creo que si no pones nada no lo encriptará, pero si no es mucho lo que has escrito, yo que tu me iría a otra terminal (o utilizaría el tsm), y le haría un kill al vi, por si acaso.

Siempre, al escribir en modo órdenes el caracter ':', desplazaremos el cursor momentáneamente a la esquina inferior izquierda de la pantalla, y cuando terminemos de dar la orden volveremos a donde estuviéramos en aquel momento. Esto, en realidad, también pasa cuando buscamos texto, con la orden '/'

Algunas órdenes de movimiento más complicadas

Bueno, ya sabemos como insertar texto, y como borrar caracteres, y movernos caracter a caracter, pero moverse caracter a caracter es bastante incómodo y lento. Así que debemos aprendernos algunas órdenes de movimiento más, para que nuestro trabajo con el vi sea más rápido y cómodo. Además, como veremos más tarde, estas órdenes de desplazamiento nos servirán para movernos, sino para decirle al vi hasta dónde debe ejecutar una orden.

Una lista de órdenes más decente sería:

	Moverse hasta el fin de la línea			- $
	Moverse hasta el principio de la línea			- 0
	Moverse hasta la siguiente palabra			- w
	Moverse hasta la anterior palabra			- b
	Moverse hasta la siguiente palabra*			- W
	Moverse hasta la anterior palabra*			- B
	Moverse a la línea n***					- nG
	Moverse hasta el final de la siguiente palabra		- e
	Moverse hasta el final de la siguiente palabra* 	- E
	Encontrar el siguiente caracter c en la línea actual	- fc
	Encontrar el anterior caracter c en la línea actual	- Fc
	Llegar hasta justo antes del siguiente caracter c	- t
	Llegar hasta justo después del anterior caracter c	- T
	Encontrar el paréntesis contrario**			- %
	Moverse hasta la siguiente frase			- (
	Moverse hasta la anterior frase				- )
	Moverse hasta el anterior párrafo			- {
	Moverse hasta el siguiente párrafo			- }
	Moverse hasta la parte superior de la pantalla		- H
	Moverse hasta la parte media de la pantalla		- M
	Moverse hasta la parte inferior de la pantalla		- L
	Avanzar página						- ^F
	Retroceder página					- ^B
* La diferencia está en que se guía por los blancos sólo, no por los signos de puntuación. El movimiento como w lo hacen los procesadores de texto como el Word, y el tipo W lo hacen editores como el bloc de notas
** Encuentra el paréntesis, corchete o llave que "concuerde" con el paréntesis, etc. sobre el que estemos
*** Si sólo se pulsa G, iremos al final del fichero

Estas órdenes están más o menos en orden de importancia (al menos teniendo en cuenta la frecuencia con las que yo las uso), pero míralas y apréndete las que creas conveniente.

Órdenes de movimiento e inserción

Una vez sepas moverte y sepas insertar (no me entiendas mal lo de moverse e insertar, todavía estoy hablando de editar texto), quizás empieces a considerar útil algunas órdenes que hagan las dos cosas a la vez. Pues bien, las hay, aunque no muchas (que yo me sepa), pero son bastante útiles:
	Insertar después del caracter actual			- a
	Insertar al final de la línea				- A
	Insertar antes del primer caracter blanco de la línea	- I
	Añadir línea por debajo e insertar texto		- o
	Añadir línea por arriba e insertar texto		- O
Quizás ya hayas adivinado la I si tenías el Bloq. Mayús puesto. Puede que no te lo parezca si no tienes mucha experiencia con el vi, pero las órdenes o y O están probablemente entre las cinco órdenes que más utilizo, en especial para escribir programas.

Aspectos generales de las órdenes

Las órdenes del vi tienen por lo general algo en común, y eso es que admiten un número antes de la orden para indicar el número de veces que se ha de ejecutar.
Así, si pulsamos un número antes de dar una orden de inserción, el vi repetirá el texto tantas veces como hallamos especificado, después de pulsar el ESC. Si pulsamos un número antes de borrar un caraacter, borrará n caracteres. Si ponemos un número antes de la orden de moverse una palabra hacia la derecha, nos moveremos n palabras a la derecha, etc.

Algunas órdenes versátiles

vi tiene algunas órdenes que hacen cosas desde donde estés en ese momento hasta donde tú especifiques, lo que hace que sea necesario saberse algunas órdenes de desplazamiento antes de poder utilizarlas (a esto me refería antes). Estas órdenes son:
	Borrar (delete)		- d
	Cambiar (change)	- c
	Copiar (yank)		- y
Es importante el hecho de que borrar no sólo borra, sino que mantiene lo último borrado en un búfer temporal, que servirá para pegarlo en otro sitio (es decir, para cortar). Esto lo veremos en el siguiente apartado.
Todas estas órdenes tienen algo en común:
  1. Necesitan una orden de desplazamiento después de la orden, para saber hasta cuándo realizar el trabajo.
  2. Si se pulsa la tecla en mayúscula, hace su trabajo hasta el final de la línea, es decir, que equivale a orden$. En esto, no sé por qué y es una excepción ya que copia la línea entera
  3. Si se pulsa la tecla dos veces seguidas, hace lo propio con la línea actual entera. Es decir, que yy y Y hacen lo mismo, y dd borra la línea actual, y cc (además de compilar :) cambia la línea actual, es decir, la borra y entra en modo inserción
Las órdenes de desplazamiento más útiles para usarlas con estas tres órdenes son w y W, b y B, f y F, t y T, y {, } (es decir, las órdenes de moverse entre palabras, buscar caracteres y las de moverse entre párrafos),
Exite otra orden, no tan versátil, pero versátil al fin y al cabo, que es la orden (o mejor dicho la pareja de órdenes) de añadir o quitar "indentación" (espacio al principio de la línea). Estas órdenes son < y >.
Su versatilidad consiste en que hay que dar una orden de desplazamiento después de la orden en sí, para indicar hasta qué línea hay que añadir o quitar indentación. Si se pulsa dos veces la misma orden, sólo hará efecto en la línea actual, y si pulsamos un número antes de dar la orden para una sola línea, entonces la orden se ejecutará para n líneas. Para esta pareja de órdenes es muy útil la orden de desplazamiento al siguiente párrafo, la }.

Copiar, cortar y pegar

En el apartado anterior ya vimos algunas ideas sobre copiar, cortar y pegar, pero aún no hemos visto realmente algo consistente con lo que poder empezar a hacer experimentos destrozando código fuente :)
Lo primero de todo, decir que no es lo mismo cortar o copiar a nivel de caracteres que a nivel de líneas. Cuando la orden que borrar (para cortar) o copiar la damos con una orden que trabaja con líneas, el pegado se realizará a nivel de líneas, añadiéndolas por encima o por debajo del texto actual (dependiendo de la orden exacta que empleemos para pegar). Análogamente, si la orden que damos de borrado o copia la damos a nivel de caracteres, el texto a pegar se pegará antes o después del cursor.
Esto a primera vista puede que no tenga ningún interés o importancia, pero por ejemplo es importante saberlo cuando queremos cortar o copiar una línea entera dentro de otra línea. Para ello no podremos cortar la línea con dd, sino que tendremos que ponernos al principio de la línea y cortar con D (lo que es bastante incómodo).
También es importante notar, en este sentido, que las órdenes que cortar o copian más de una línea siempre trabajan a nivel de líneas. Lo que significa que si queremos borrar desde la mitad de una línea hasta el final del fichero, no lo podremos hacer con dG, sino que tendremos que ir a la línea de abajo, ejecutar dG, y borrar la mitad de la línea con una segunda orden, como por ejemplo D.
Respecto a que el vi no puede borrar saltos de línea, es muy importante saber de la existencia de una orden, la J, que une la línea siguiente a la actual.

Múltiples búfers de copia

En vi, cuando se borra o se copia, se utiliza un búfer general. Esto tiene una desventaja, y es que cuando tienes una cosa que quieres copiar, pero borras algo, entonces ya te quedas con el búfer conteniendo lo último que borraste.
Esto en vi tiene una sencilla solución, que es utilizar los otros búfers de copia. Estos se cambian con la orden ", que tiene que ir seguida del nombre del búfer. A la hora de poner algo en el búfer, se pueden utilizar todas las letras. A la hora de coger algo del búfer, se pueden utilizar tanto las letras como los números.
¿Y para qué sirve coger de un búfer en el que no puedes escribir? te preguntarás. Pues bien, esos búfers los rellena vi automáticamente, con el contenido del búfer general, desplazando hacia "la derecha" los resultados que ya estuvieran en los búfers. Así, en el ejemplo anterior, lo que podríamos haber hecho sería pegar el búfer 0, en vez de repetir la operación de copiado. Pero en realidad yo no me fío mucho de estos búfers numerados, así que prácticamente no los utilizo. Nunca estoy seguro de en qué búfer tendría que estar cada cosa, y termino pegando tres o cuatro cosas que no me interesan y tengo que volver a borrar...
Bueno, como iba diciendo, para utilizar los búfers, hay que utilizar esta instrucción antes de copiar/borrar/pegar algo, ya que sólo funciona para la siguiente orden de pegado. Esta orden puede ir justo despuás del cambio o también puedes ejecutar algunas órdenes antes de pegar finalmente, pero es una buena costumbre cambiar justo antes de pegar, por lo que pueda pasar...

Otras órdenes útiles (y no tan útiles)

	Deshacer el último cambio				- u
	Deshacer todos los cambios de la línea actual		- U
	Redibujar la pantalla					- ^L
	Ver información del archivo actual			- ^G
	Reemplazar un caracter					- r
	Sobreescribir texto					- R
	Borrar el caracter actual y entrar en modo inserción	- s
	Cambiar la línea actual*				- S
	Cambiar entre mayúsculas y minúsculas			- ~
	Borrar texto (como el BackSpace)			- X
	(Sólo en vim) marcar bloque				- v, V, ^V
	Buscar texto						- /texto
	Repetir última búsqueda					- n
	Repetir última búsqueda en dirección contraria		- N
	Repetir última búsqueda hacia abajo			- /
	Repetir última búsqueda hacia arriba			- ?
	Repetir último cambio					- .
	Siguiente palabra (Modo inserción) **			- ^N
	Anterior palabra (Modo inserción) **			- ^P
	Indentación inteligente					- :set si
La órden de deshacer funciona de distinta manera en vi original que en vim. En el primero, sólo deshace la última acción, y si se vuelve a pulsar hace un redo (rehacer, es decir, deshace la orden de deshacer)
En vim, la orden u es un deshacer multinivel, por lo que deshace acciones mientras ejecutes esa orden. Para rehacer acciones, existe otra orden, que es Ctrl-R. La orden de redibujado está muy bien en sistemas UNIX, y sirve por ejemplo cuando te llega la salida estándar de un programa que estaba en segundo plano, cuando alguien escribe en tu terminal, o cuando te llega el mensaje de que tienes nuevo correo.
* Que yo sepa, orden totalmente análoga a cc
** Que encaje con la subristra que está antes del cursor

vim (Vi IMproved)

El vim es un clon del editor vi, que está disponible para una gran variedad de sistemas operativos y arquitecturas. Es el editor por defecto en la mayoría de las distribuciones que yo he tenido, así que cuando escribes:
	$ vi
desde la línea de órdenes, en realidad estás llamando al vim. El vim tiene muchas características interesantes, como por ejemplo el soporte de ratón, la ayuda en línea, coloreado de sintaxis, en su última versión (poco probable que la tengas en casa, tendrás que conseguirla por tu cuenta), posibilidad de marcar bloque, deshacer multinivel, partir la ventana para ver varios archivos a la vez, etc. Tiene también otras características que hacen que el trabajo con vim sea más fácil que con el vi "plano". La lista de las órdenes propias del vim más relevantes (de las que yo me sé, ojo) es:
	Marcar bloque visual					- v
	Marcar bloque visual (por líneas completas)		- V
	Marcar bloque visual (un bloque rectangular)		- ^V
	Ir a la primera línea					- gg
	Formatear párrafo[*]					- gqorden
	Buscar una palabra (en la ayuda, o en el man)[**] 	- K
	Deshacer (ahora es multinivel)				- u
	Rehacer							- ^R
* Esto de formatear párrafo quiere decir ajustar las palabras a líneas de como máximo 80 (es configurable) caracteres. Así, cuando tienes, por ejemplo, un párrafo en una sola línea, o cuando tienes unas líneas más largas que otras, se puede utilizar esta orden y todo queda como nuevo. La orden es una orden de desplazamiento, al igual que con las órdenes y, d y c.
** La palabra buscada es la que está debajo del cursor en ese momento. Si se quiere especificar el número de la sección, se pulsa el número y luego la K. La orden con la que se busca la palabra es definible por el usuario, aunque por defecto es man. Empíricamente me he dado cuenta de que en ambas versiones de Win32 (la versión gráfica de ventanas, y la de línea de órdenes) la acción por defecto no es llamar a una orden exterior, sino llamar al propio sistema de ayuda del vim.

Actualmente el vim puede conseguirse del sitio vim.org.

Final

Bueno, en realidad no hemos visto todo lo que se puede hacer con el vi (ni mucho menos). Faltan todas las opciones para la personalización del vi (y créeme que son muchísimas), marcar un texto, para poder volver justo allí en cualquier momento, llamadas a programas exteriores, para que procesen parte del texto y lo reemplazen con la salida estándar, y un larguísimo etc... (bueno, puede que no queden muchas cosas más, pero es que sólo las opciones de configuración explicadas probablemente podrían ocupar un documento entero, y ni me las sé ni tengo ganas de escribir sobre ello).
Como siempre, si quieres más información, consulta los manuales, que para eso están, o pregúntame a mí, si son dudas particulares, o busca más cosillas en InterNet, que haberlas haylas. Por ejemplo, tienes un sitio FTP muy bueno con cosas sobre el vi y el ex. De ahí me conseguí yo hojas de referencia, otros tutoriales y un documento sobre cómo escribir macros.
Cualquier cosa que no quede clara en el documento, nuevas órdenes, correcciones... ya sabes



Última revisión: 28-XII-98
© Esteban Manchado 'ZoSo'