Programando en C con ViM

Álvaro Uría (Fermat - fermat00 AT euskalnet DOT net)

    De todos los lenguajes de programación que he ido (y que sigo) aprendiendo, me quedo con ariel, digo C. No sé ahora mismo por qué razón. Quizás porque UNIX y la mayoría de software libre para GNU/Linux que conozco se programó en este lenguaje, y es el que más utilizo. O quizás porque es completamente libre (no como las clases y librerías de Java). No sé. Para no condicionar a nadie, una reflexión de qué lenguaje utilizar. Pero C rlz! };-)

    Por otro lado, entre los editores de texto que conozco, el más interesante que me ha parecido hasta el momento es ViM, por su ligereza y a la vez, claridad, con opciones como colorear textos reconocidos, como palabras reservadas de lenguajes de programación (yaaa.. emacs tb, pero en fin). Si quieres saber más sobre vi y emacs, busca en google. Y recuerda, yo soy un dibujo animado O;-)

    Con esto, ya tengo los ingredientes para empezar este documento, basado totalmente en C editing with VIM HOWTO de Siddharth Heroor.

    Nota: es bastante probable que este documento lo puedas reutilizar para programación en algún otro lenguaje, como Java.

Índice

Introducción

    Soy consciente de que al principio, VI puede resultar un verdadero infierno. Resulta muy geek al principio no tener que usar el ratón para nada y con 4 teclas poder modificar todo un fichero.

    Pero de veras, ViM es bastante más sencillo y más claro que VI. Esto no pretender ser un manual de manejo de ViM en absoluto (los hay en varios idiomas y muy buenos por la red), sino ver como podemos perder menos tiempo repasando y mejorando, o lo que fuere, nuestro código o el de otro programador :-)

Un simple ejemplo,
	#include <stdio.h>

	int main ( int argc, char ** argv )
	{
		printf ("Hola Mundo\n");
		return 0;
	}

Moviéndonos por el código

'w', 'e' y 'b'

    Si queremos movernos carácter a carácter podemos utilizar las flechas del teclado, o incluso la 'h' y la 'l'. Pero si lo que queremos es ir saltando palabra a palabra, podemos utilizar la 'w' (nos deja a principio de palabra) y la 'e' (nos deja al final de la palabra) para ir hacia delante, y la 'b' (nos deja al principio de la palabra) para ir hacia atrás.

    Si lo que queremos es subir y bajar en el código, podemos utilizar las flechas del teclado, o o también, 'RePág.' y 'Av.Pág.'. La 'H' y la 'L' nos sube y baja a la primera y última línea del código que se nos muestre en pantalla en ese momento.

Por ejemplo,

	if ( (fich == NULL) && (y > z) )

'{', '}', '[[', ']]', '[]' y ']['

    Para movernos de párrafo en párrafo, usaremos '{' (hacia arriba) y '}'. Esta opción es muy interesante para movernos entre funciones, sin tener que pasar por el código de cada una de ellas.

    Ahora bien, si queremos posicionarnos en el anterior o siguiente comienzo de función (en el '{'), utilizaremos '[[' y ']]', respectivamente (en modo comando, después de pulsar la tecla 'Esc.'). Del mismo modo si queremos subir al '{' de la función anterior a la anterior, utilizaremos el comando '2[[', y así sucesivamente.

    Si queremos posicionarnos en el final de función (en el '}') utilizaremos, para la anterior el comando '[]' y para el siguiente, '][', cabiendo la posibilidad de usar los números antes de estos comandos (i.e. '4[]' subiríamos hasta el final de la 4 función hacia arriba).

'%'

    Esto simplemente es una genialidad. En C todo lo que empieza tiene que acabar. Es decir, después del '{' de un if, tiene que haber por algún lado un '}'. Si nos posicionamos con el cursor encima del '{' y pulsamos en modo comando '%', el cursor se pondrá encima del '}' correspondiente.

    Pero ATENCIÓN, si el '}' correspondiente falta, el cursor irá a una posición indeterminada, o más bien, al primer '}' que encuentre libre, como por ejemplo, el de final de función.

    Esta forma de explicar con un ejemplo espero que no lleve a error. El símbolo '%' en modo comando también nos permite relacionar '#ifndef', '(' y demás. También relaciona de forma inversa. Es decir, si nos ponemos en un '}', nos llevará al '{'. Lo dicho, una genialidad O:-)

Saltándo por el código

ctags

    Cuando estamos recorriendo una función y nos encontramos con una llamada a otra, es muy probable que queramos saber qué hace esa función. Para ello está pensado ctags.

En Debian GNU/Linux, el paquete se llama,

	~$ apt-cache search exuberant-ctags
	exuberant-ctags - build tag file indexes of source code definitions
.. y después de instalarlo, lo pasamos al fichero (o los ficheros) .c que tengamos,
	~$ ctags-exuberant *.c
.. y ya se nos habrá creado un fichero tags que es el que nos va ayudar cuando accedamos a los .c

    La idea es poner el cursor encima de la llamada a la función, pulsar CTRL+] y apareceremos al comienzo de la implementación de la función (aunque esté en otro fichero .c, que también tiene que estar descrito en el fichero tags). Para volver al lugar donde estaba dicha llamada a función, pulsaremos CTRL+T (ambas opciones en modo comando).

'm'

    'm' es el comando utilizado para crear marcas a lo largo del código para volver a ellas en cualquier momento.

    Lo primero, una marca sirve para volver a una línea en cualquier momento. Es decir, si tenemos la primera línea de una función donde declaramos las variables, y a medida que vamos creando código iremos añadiendo variables en esa zona de dicha función, podríamos dejar una marca en esa línea para volver en cualquier momento. Y ya de paso, dejaríamos otra temporal en la línea donde paramos de escribir para declarar la variable.

    Los pasos serían tal que así..

	int juas ( int num )
	{
		static short int raspando; /* creo marca pulsando mv */
		char *s[] = {"raspando","mil"};
		
		if ( (num >= 0) && (num < 2) ) {
			raspando = 1;
			printf ("%s\n", s[num]); /* creo marca pulsando m' y vuelvo a las variables pulsando 'v */
			return 0;
		}
		else
			return -1;
	}

    Las marcas pueden guardarse en buffers, desde [a-z], [A-Z] y [0-9]. Es decir, ma sería una marca a la que se vuelve pulsando 'a

    NOTA: las marcas se olvidan al cerrar el fichero.

'gd'

    Ésta es otra genialidad. Al poner el cursor encima de una variable podemos ir directamente a la línea donde se declaró, sólo con pulsar en modo comando gd.

    Si la variable está declarada como local y global, podremos ir a la declaración como global pulsando gD.

AutoCompletition

    Quienes usamos el shell en sistemas GNU/Linux, o incluso el iRC, estamos acostumbrados a vaguear, no escribiendo comandos, nombres (de fichero, etc.), nicks completamente. Ahora los móviles llevan estas cosas también, o eso creo.

    Bueno, pues esta tecnología también está en ViM X-D

    En el caso de palabras reservadas de C, hay que ser muy vago para no escribir int o double. Pero si tenemos un montón de funciones, algunas larguísimas que explican lo que hace la función, y no queremos escribirla continuamente, podríamos utilizar en modo editar, CTRL+P (o CTRL+p) para completar. Pulsando esto de forma reiterada, navegaremos por las coincidencias. Para navegar en sentido contrario, usaremos CTRL+N.

    NOTA: Para ver más modos, pulsa CTRL+X.

Formateo del código

Restringiendo ancho de columna

    Esto se hace en vim con..
	:set textwidth=80
	:set wrapwidth=60
    Puedes añadirlo a tu .vimrc para no tener que introducirlo cada vez :-)

Indentación

    Esto se hace en vim con..
	:set cindent

Comentarios

    Cuando escribimos comentarios en nuestro programa, queremos, generalmente, que al saltar de línea siga siendo un comentario.

Por ejemplo..

	/*
	* esto es GPL
	*/
Se hace con..
	:set comments=sl:/*,mb:*,elx:*/
lo que traducido a lenguaje natural..
	:set comments=sl:ComoEmpieza,mb:SimboloAlSaltarDeLinea,elx:ComoAcaba
entonces sí ajustamos..
	:set comments=sl:/*,mb:**,elx:*/
entonces quedará..
	/*
	** esto tb es GPL
	*/

Editando múltiples ficheros

    Si abrimos varios ficheros..
	fermat@uritech:~$ vim juas lol
podemos movernos entre ellos con
	:n
y volver atrás con
	:e#

    También podemos visualizar varios ficheros a la vez.

	:split
	:vsplit
	:e fichero
    Y nos movemos entre ellos con CTRL+W, e incluso puedes hacer una parte más amplia que la otra, etc. . Pero esto no forma parte de este documento ;-)

Compilando

    Después de compilar nuestro código, nos podría salir un churro tal que...
	fermat@uritech:~$ gcc holaMundo.c
	holaMundo.c: En la función `main':
	holaMundo.c:4: error: error sintáctico before '}' token
    Si esto lo guardamos en un fichero tal que..
	fermat@uritech:~$ gcc holaMundo.c &> fuck.err
    Podremos ir directamente al primer error en el fichero con el código, con..
	fermat@uritech:~$ vim -q fuck.err
    Por otro lado, y para no sufrir saliendo de vim para compilar con gcc y volviendo a la línea con error..
	fermat@uritech:~$ vi +4 holaMundo.c
.. tenemos 2 opciones: crear un Makefile y usar..
	:make
.. o bien, configurar la variable..
	:set makeprg=gcc\ holaMundo.c\ -o\ aupi
.. y luego ejecutar..
	:make
    Para ir al siguiente error, si es que hay, usaremos
	:cn
y para ir hacia atrás,
	:cN

 Este documento ha sido escrito por un miembro de e-GHOST y su contenido es libre de ser reproducido en otros medios bajo las condiciones de la Licencia FDL (GNU Free Documentation License).