Hace ya algún tiempo que quiero recopilar todas las configuraciones de vim que tengo repartidas en un montón de cuentas con la intención de centralizarlas de alguna forma y hacerlo todo mantenible que pudiese y ha llegado el momento. Era una de esas cosas que procastinaba constantemente pese al uso bastante intensivo que hago de vim. Y lo peor es que no había pensado completamente en la forma de hacerlo. Tenía claro que quería usar versionado y git tenía muchas papeletas en vista de todo lo que he visto, aprendido y gozado con este DSCM, pero poco más.
La solución ha llegado tras ver este post en vimcasts.com (recomiendo encarecidamente ver el screencast) que me ha parecido tan sencillo y tan potente. En este primer post voy a explicar este método y en el siguiente contaré cuál es mi configuración actual (aunque irá evolucionando, pero bueno, que sirva de ayuda).
La idea es muy sencilla: crear un repositorio de git (que centralizaremos en github.com) que clonaremos en nuestro directorio ~/.vim y, gracias a un par de trucos, extenderlo a todas las cuentas que tengamos de forma sencilla. Nadie nos quita tener que actualizar cada una de nuestras cuentas, pero bueno, podemos tirar de un cron que lo haga automáticamente 🙂
Usando pathogen
Este plugin para vim es un must-have si usas muchos plugins o, aunque uses únicamente uno, para poder tener todo bien organizado. Cada plugin de vim, en función de sus necesidades, puede estar repartido en múltiples carpetas dentro del raíz de nuestro ~/.vim. Es decir, un plugin nos puede obligar a esta estructura de directorios:
- ~/.vim
- doc/
- plugin.txt
- plugin/
- plugin.vim
- syntax/
- plugin-syntax.vim
- doc/
Si multiplicamos esto por varios plugins, teniendo en cuenta que hay más directorios posibles, añadir o quitar plugins es un engorro. Gracias a pathogen, en vez de tener repartidos los ficheros de cada plugin, podremos tenerlos todos juntos, los del mismo plugin en una carpeta, algo que es tremendamente cómodo ya que añadir o quitar un plugin es cuestión de añadir o quitar una carpeta. Muy sencillo.
Con el ejemplo anterior, nos quedaría:
- ~/.vim
- bundle/
- nombre-plugin/
- doc/
- plugin.txt
- plugin/
- plugin.vim
- syntax/
- plugin-syntax.vim
- doc/
- nombre-plugin/
- bundle/
Lo único que tenemos que hacer es descargarnos pathogen.vim y colocarlo en la carpeta ~/.vim/autoload/ (comprobar lo que dice el autor, es posible que esto cambie en el futuro) y añadir estas dos líneas en nuestro ~/.vimrc:
call pathogen#runtime_append_all_bundles()
call pathogen#helptags()
Enlazar ~/.vimrc
Como he explicado al principio, la principal idea es versionar el directorio ~/.vim/. Entonces, ¿qué pasa con ~/.vimrc? Efectivamente, este fichero (y ~/.gvimrc si usas gvim) se quedarían fuera y no los podríamos versionar, teniendo el gran inconveniente de que no podríamos guardar toda nuestra configuración.
Para solucionar este problema, lo que se propone en vimcasts.com es renombrar este fichero a ~/.vim/vimrc (atentos que no se llamaría .vimrc sino vimrc y, por lo tanto, sería visible) y crear un enlace simbólico. Es decir:
mv ~/.vimrc ~/.vim/vimrc
ln -s ~/.vim/vimrc ~/.vimrc
Esto nos permite versionar también este fichero con el punto extra añadido que volvemos al fichero visible y más cómodo de localizar.
Submodules en git
Por último, y no menos importante, trabajar con submodules de git en un repositorio. Partiendo de un repositorio de git ya creado, con los submodules podemos indicar a ese repositorio que los datos de un directorio se extraen de un repositorio git externo a ese. En subversion, sería el hermano mayor de svn:external.
Muchos de los plugins de vim se han ido migrando a git y no sólo eso, sino que también los repositorios mantienen la estructura necesaria del plugin dentro de la carpeta ~/.vim y, por lo tanto como he explicado, gracias a pathogen podremos agrupar ese plugin en una carpeta muy fácilmente.
Vamos a dividir en dos partes. La primera en la que le decimos a nuestro repositorio cuál es el plugin externo (vía submodule) y hacemos el commit & push y la segunda en la que clonamos nuestro repositorio en otra máquina e inicializamos y actualizamos los submodules.
Definiendo el repositorio externo
Supongamos que queremos instalar NerdTree que se encuentra git://github.com/scrooloose/nerdtree.git y ponerlo en bundle/nerdtree
git submodule add git://github.com/scrooloose/nerdtree.git bundle/nerdtree
git add .
git commit -m "Install NerdTree.vim as submodule."
git push origin master
Notar que tendremos que estar en el directorio donde se encuentra el directorio .git/ y que la configuración del submodule se guarda en .gitmodules (al mismo nivel que .git/)
Clonando y actualizando
Suponiendo que nuestro repositorio se encuentra en git://github.com/tatai/vim.git, lo que haremos primero será clonar el repositorio en nuestra carpeta ~/.vim y posteriormente inicializar y actualizar los submodules:
cd ~
git clone git://github.com/tatai/vim.git ~/.vim
cd ~/.vim
git submodule init
git submodule update
Si todo ha ido bien, si entramos en vim tendremos disponible toda nuestra configuración y plugins que hallamos subido.
A partir de este momento, si queremos actualizar uno de los submodules, tendremos que ir a su directorio y usar git pull. Por ejemplo, usando el ejemplo anterior de nerdtree:
cd ~/.vim/bundle/nerdtree
git pull
Ventaja de usar git
Una de las ventajas añadidas que tiene usar git es que, en cualquier momento, puedes crear tu propia versión de un plugin sin perder de vista el código original ni que nuestras configuraciones pierdan sincronización.
Voy a poner un ejemplo concreto con snipmate del que hablaré en el siguiente post más tranquilamente. Resumiendo, este plugin permite que, en función de ciertas palabras clave, definir snippets. Es una gran utilidad y todas las plantillas se encuentran en la misma carpeta del plugin.
¿Qué ocurriría si queremos añadir más snippets o cambiar el formato de alguno de ellos, por ejemplo porque no se adapta a nuestro estilo de programar? Evidentemente, si usamos el código original del autor sólo podremos enviarle un patch-request que aceptará si quieres o no.
Lo que podemos hacer en estos casos es hacer un fork, como por ejemplo he hecho yo en http://github.com/tatai/snipmate.vim. Un fork nos permite tener una versión propia del repositorio de otro usuario, considerándola como una fuente más de nuestro código, lo que nos permite no sólo reportar errores o mejoras al autor, sino también añadir lo que nosotros creamos más conveniente.
Así pues, a la hora de añadir el submodule, en vez de usar el repositorio original del autor:
git submodule add git://github.com/msanders/snipmate.vim bundle/snipmate
Usaremos como origen el nuestro propio:
git submodule add git://github.com/tatai/snipmate.vim bundle/snipmate
Esto claramente nos añade un paso más, ya que no bastará con actualizar los nuestros directorios ~/.vim sino también mantener este otro repositorio.
Genial, estoy empezando a aprender vim y una introducción tan buena de cómo empezar a personalizarlo me viene de perlas 🙂 Un par de cosillas (las digo sin haber probado), para actualizar los submodulos, en lugar de meterte en cada uno y hacer un git pull, puedes actualizar de golpe en el raiz con git submodule update. Y la otra, si quieres personalizar un plugin como snipmate sólo para añadir nuevos snippets, podrías utilizar .gitignore para que no se tengan en cuenta tus nuevos archivos y así poder actualizar el plugin normalmente, no?