Dejando la terminal fina con YADR: ZSH, Prezto, Solarize…

Dejando la terminal fina con YADR: ZSH, Prezto, Solarize…

Aprovechando que toca reinstalar el ordenador —gracias a todo el tiempo que ha estado abandonada la Linux Mint Debian Edition (LMDE) que tenía instalada— me he animado a personalizar la terminal que utilizo.

Obviamente, pienso seguir usando mi fiel compañero Yakuake —hay que ver lo que se farda en tutorías al mostrar como se despliega tu terminal al toque de F12— pero me apetece meterme seriamente con Zsh, así como elegir un esquema de color y fuentes adecuadas para trabajar en la terminal.

Zsh

Zsh es una shell que puede ser entendida como una extensión de una Bourne Shell (sh) en la que se han incorporado no solo elementos propios sino también características de bash, ksh y tcsh.

Aunque muchos usuarios de bash nos sentimos cómodos con Zsh, lo cierto es que no tienen un origen común. El desarrollador de Zsh, Paul Faldstad, buscaba crear una shell similar a ksh donde incorporar algunas funcionalidades de csh/tcsh. Por el contrario, bash no intenta emular a ksh, pero sí cumplir con lo que dicen estándares como POSIX.

En todo caso, tanto Zsh como bash son proyectos vivos, por lo que en estos años se han ido intercambiando algunas funcionalidades, de ahí que en algunos aspectos se note cierto parecido.

Toda shell UNIX tiene la doble función de servir tanto de intérprete de órdenes como de lenguaje de scripts con el que automatizar ciertas tareas. Lo que hace tan interesante a Zsh es que sus desarrolladores han hecho mucho hincapié en lo primero, incorporando fundamentalmente características para potenciar el uso interactivo de la misma:

  • Soporte para temas, con facilidades para mostrar información adicional en la línea de comandos.

  • Autocompletado programable de comandos.

  • Corrección ortográfica.

  • Historial compartido entre shells.

  • Comodines extendidos que permiten especificaciones de archivos complejas, sin tener que ejecutar programas externos como find.

  • Edición de comandos multilínea.

  • Módulos cargables con funcionalidades adicionales.

  • Completamente personalizable.

Supongo que en cierta medida es la flexibilidad a la hora de personalizar visualmente y de añadir nuevas funcionalidades lo que está causando tanto furor entre los usuarios. Y no hablo solo de usuarios de Linux. La mayor parte de los tutoriales que he encontrado explicando algún detalle de lo que pretendía hacer eran para Mac OS X e iTerm2.

Tema Cobalt2 para iTerm2 y Zsh en Mac OS X.

Prezto

El problema es que Zsh tiene muchas posibilidades, pero prácticamente no trae nada de serie. Cuando lo iniciamos por primera vez nos pregunta si queremos crear los ficheros de configuración necesarios. Después de eso nos quedamos en lo que parece una shell corriente y moliente. Así que ¿dónde están esos coloridos temas para la línea de comandos? ¿Y los módulos que facilitan la integración con Git, Ruby o Python?

Zsh pone la estructura necesaria para hacer cosas muy interesantes pero trae lo mínimo. Por fortuna, existe una importante comunidad dedicada a producir módulos y temas para esta shell, en su mayor parte alrededor de proyectos como Oh My Zsh y Prezto. Básicamente, ambos proveen un framework diseñado para facilitar la gestión de la configuración de Zsh. Dentro del marco de dichos frameworks, la comunidad se afana en crear nuevos temas y módulos.

A la hora de elegir uno u otro hay que tener en cuenta que Oh My Zsh tiene una comunidad inmensa, por lo que prácticamente ofrece todo lo que podríamos necesitar. Sin embargo, algunos usuarios se quejan de que enlentece demasiado la carga de la shell. Precisamente por eso existe Prezto, un fork de Oh My Zsh que ha sido reescrito usando exclusivamente sintaxis de Zsh con el objeto de ofrecer una solución más limpia y rápida.

Tema Powerline para Prezto.

Dotfiles

Vim, Git o Zsh, entre muchos otros, son programas que solemos utilizar en la terminal. Para que la experiencia de largas horas de trabajo sea satisfactoria es conveniente haberlos configurado según nuestras preferencias. Para preservar estas configuraciones —lo que, al menos la primera vez, pueden llevar varias horas— controlar las versiones, compartirlas de forma sencilla entre los distintos equipos que usamos y —¿por qué no?— ponerlas a disposición del resto de la comunidad, es muy común subirlas a GitHub.

Si no me crees, solo tienes que visitar GitHub y buscar repositorios de nombre dotfiles. Verás la cantidad ingente de usuarios que están compartiendo sus archivos de configuración, lo que es de agradecer si no tiene mucho tiempo para configurar los programas por ti mismo.

De entre todos esos repositorios yo voy a destacar YADR, una completa solución que trae configuraciones para:

  • Zsh usando Prezto.

  • Git y GitHub.

  • Diversos comandos para facilitar la gestión de los alias. Por ejemplo el comando ae que permite editar todos los alias de forma sencilla.

  • Ruby Gem.

  • Tmux.

  • Vim y vimificación de otras utilidades de línea de comandos. Por ejemplo mysql o irb.

En general, el proyecto está muy orientado a Ruby y Mac OS X, por lo que también incluye temas de color para iTerm2 e intenta instalar algunos paquetes con Homebrew. En cualquier caso, yo no me he encontrado muchos problemas al intentar utlizar YADR en Linux.

Solarized

Una de las cosas que trae YADR es un tema de colores para iTerm2 basado en Solarized. En parte porque dicho esquema de colores para la terminal es muy recomendado por algunos temas para Zsh.

Solarized es una paleta de 16 colores diseñada para ser utilizada en aplicaciones, tanto gráficas como en la terminal. Su autor afirma que tiene propiedades únicas y que ha sido probada ampliamente en el mundo real, tanto en monitores calibrados como no calibrados y en distintas condiciones de iluminación.

Solarized Yin Yang.

El proyecto Solarized ofrece esquemas de color y temas en los formatos requeridos por una amplia variedad de aplicaciones. Por ejemplo Mutt, Qt Creator, IntelliJ IDEA, Gedit, Netbeans, Emacs. Texmate, Putty y muchas más. Aunque parece que no ofrecen esquemas para ninguna aplicación de KDE, esto no es un problema porque ya vienen de serie con Konsole los esquemas de color Solarized Light y Dark.

Instalación de YADR

El instalador de YADR usa Rake y Git —al analizar el proyecto con algo más de profundidad es fácil darse cuenta de que el autor tiene cierta predilección por Ruby— y también necesitamos un Vim con soporte para Lua, ya que algunos complementos instalados lo necesitan. Así que eso será lo primero que haremos:

sudo apt-get install rake git vim-nox

Después descargamos el instalador propiamente dicho para ejecutarlo. Por ejemplo así:

wget https://raw.githubusercontent.com/skwp/dotfiles/master/install.sh
chmod +x install.sh
./install.sh

Se puede ejecutar install.sh -s ask si queremos que el instalador nos pregunte sobre cada uno de los componentes que puede instalar. Sin embargo, aunque no soy desarrollador de Ruby y sé que muchas de esos componentes no los voy a aprovechar, no me pareció buena idea hacerlo de esa manera. En mi opinión es un una pérdida de tiempo porque son muchísimos componentes. Nunca se sabe si al final los acabarás necesitando y, en todo caso, apenas ocupan espacio.

Al final del proceso de instalación es normal que pida la contraseña del usuario actual para activar Zsh como tu shell por defecto. Si el instalador no lo hace, siempre lo podemos hacer nosotros mismos a mano:

chsh -s /bin/zsh

Obviamente, este cambio surtirá efecto en el siguiente inicio de sesión.

Configuración del entorno

Como he comentado, YADR trae Prezto. Así que antes de seguir vamos a ver como debemos gestionar a partir de ahora la configuración de Zsh.

Zsh

Estos son los archivos de configuración utilizados por cualquier instalación de Zsh:

  • ~/.zlogin
    Su contenido solo se incluye en shells* de login* —siempre después del de .zshrc— por lo que debemos incluir aquí cosas que queremos que se ejecuten solo cuando nos autenticamos.

  • ~/.zlogout
    Su contenido solamente se incluye cuando una shell de login termina y, por tanto, vamos a abandonar la sesión actual.

  • ~/.zprofile
    Es similar a .zlogin —únicamente se incluye en shells de login— pero se incluye siempre antes que el contenido de .zshrc.

  • ~/.zshrc
    Se usa para la configuración de shell interactivas. Por lo tanto, aquí es donde se deben cargar módulos, activar o desactivar las distintas opciones interactivas de Zsh, configurar el historial, cambiar el aspecto visual de la línea de comandos, configurar el autocompletado, etc.

  • ~/.zshenv
    Siempre es incluido y debe contener las variables de entorno que debe estar disponibles para todos los programas. Por ejemplo $PATH, $EDITOR, o $PAGER, entre muchas otras.

Prezto toma el control de esos archivos poniendo sus propias versiones para, por ejemplo, ejecutarse a través de .zshrc en cualquier shell interactiva que iniciemos —si hemos instalado Prezto sin la ayuda de YADR y queremos modificar algunos de los archivos anteriores, el desarrollador del proyecto nos anima a hacerle un fork en GitHub y usar nuestro nuevo repositorio para subir los cambios que hagamos a los archivos de configuración, evitando que podamos perderlos—.

Prezto

Prezto introduce un nuevo archivo de configuración específico para sus opciones de configuración:

  • ~/.zpreztorc
    Se usa para indicar las opciones específicas de Prezto. Por ejemplo los módulos que queremos utilizar —el listado completo de módulos se puede visitar en la web del proyecto en GitHub— o el tema de la línea de comandos o prompt que más nos gusta. Sin embargo no utilizaremos .zpreztorc para esto último, si no que lo haremos de la manera propuesta por YADR.

En mi caso me gusta editar el archivo .zpreztorc para activar el módulo python y desactivar ruby y osx. Así que la configuración, en parte, debe quedar tal que así:

# Set the Prezto modules to load (browse modules).
# The order matters.
zstyle ':prezto:load' pmodule \
  'environment' \
  'terminal' \
  'editor' \
  'history' \
  'directory' \
  'spectrum' \
  'utility' \
  'completion' \
  'archive' \
  'fasd' \
  'git' \
  'python' \
  'syntax-highlighting' \
  'history-substring-search' \
  'ssh' \
  'prompt'

Como se puede observar, también he dejado activado el módulo ssh, que es muy cómodo porque, aparte de incorporar algunos alias, cargar nuestras identidades SSH en ssh-agent. Si nos molesta que nos pida las contraseñas que protegen nuestras identidades la primera vez que abrimos una terminal podemos:

  • Quitarles la contraseña, lo que es muy poco recomendable por motivos de seguridad.

  • Desactivar el módulo ssh, que es lo mejor si no se entiende que problema resuelve.

  • Instalar libpam-ssh y asegurarnos de que la contraseña de dichas identidades es la misma que la de nuestro sistema. libpam-ssh permite que se use la contraseña de nuestra cuenta en el sistema para descifrar automáticamente las identidades SSH y cargarlas en ssh-agent.

Si optamos por esta última opción solo tendremos que ejecutar:

sudo apt-get install libpam-ssh
sudo pam-auth-update

asegurándonos de que en la Configuración de PAM está marcado Authenticate using SSH keys and start ssh-agent.

Diálogo de configuración de PAM.

YADR

Finalmente, YADR ofrece una serie de ubicaciones adicionales pensadas para evitar en lo posible que toquemos los archivos de configuración anteriores:

~/.zsh.before
Es un directorio donde podemos colocar archivos para personalizar cosas antes de que se apliquen las configuraciones incluidas en YADR. Nos sirve para indicar qué módulos se cargan y cuáles no porque eso ocurre mucho antes, cuando Prezto se inicia desde .zshrc y lee .zpreztorc. Por eso siempre tenemos que configurar los módulos en ese archivo.

~/.zsh.after
Es un directorio donde podemos colocar archivos para personalizar cosas después de que se apliquen las configuraciones incluidas en YADR.

~/.zsh.prompts
Es un directorio donde podemos colocar archivos con nuestros propios temas de línea de comandos.

Algo similar hace YADR con los otros programas que personaliza. Por ejemplo toma el control de ~/.gitconfig, por lo que se recomienda que las personalizaciones de Git —como las credenciales de usuario— se incluyan en ~/.gitconfig.user. O las personalizaciones de Vim, que deben indicarse en los archivos ~/.vimrc.before o ~/vimrc.after.

El comando prompt nos permite obtener una lista de los temas de línea de comandos actualmente disponibles:

$ prompt -l
Currently available prompt themes:
agnoster cloud damoekri giddie kylewest minimal nicoulaj paradox peepcode powerline pure skwp smiley sorin steeef adam1 adam2 bart bigfade clint elite2 elite fade fire off oliver pws redhat suse walters zefram steeef_simplified

Podemos tener una vista previa de alguno que nos interese:

prompt -p agnoster

Podemos activarlo para la sesión actual:

prompt agnoster

O configurarlo como tema por defecto de futuras sesiones:

echo 'prompt agnoster' > ~/.zsh.after/prompt.zsh

En mi caso particular utilizo una versión del tema *agnoster* que utiliza el módulo python de Presto para mostrar el nombre del entorno virtual de Python activo en cada momento. Para usarlo solo hay que descargar el archivo agnoster.zsh-theme del tema en ~/.zsh.prompts/prompt_agnoster-aplatanado_setup y activarlo tal y como he comentado anteriormente:

echo 'prompt agnoster-aplatanado' > ~/.zsh.after/prompt.zsh

Y este sería el resultado final en la terminal Yakuake con el esquema de color Solarized Dark.

Resultado final en la terminal Yakuake con el esquema de color Solarized Dark

Fuentes y colores

Muchos temas usan caracteres especiales que requieren de una fuente parcheada con powerline. Afortunadamente, YADR ya las incorpora, así que solamente tenemos que escoger una de dichas fuentes como fuente monoespaciada por defecto del sistema. Por ejemplo en KDE podemos ir a Preferencias del sistema > Tipos de letra > Anchura fija y escoger Menlo for Powerline.

Como he comentado, algunos temas recomiendan Solarized como esquema de color de la terminal. De este modo lo hago yo y suelo escoger la versión oscura. Además, también aprovecho para ajustar otras herramientas con las que trabajo con cierta frecuencia, como Qt Creator o IntelliJ IDEA. En el primer IDE utilizo la versión oscura y en el segundo la versión clara —puesto que no he terminado de sentirme cómodo con la oscura— y fuente Menlo para que todo mi entorno de trabajo tenga más o menos el mismo estilo.

Finalmente, aunque todo parezca estar bien, lo cierto es que algunas personalizaciones requieren que la terminal informe adecuadamente de sus capacidades. En concreto, Konsole y Yakuake informan ser de tipo xterm, cuando para que todo funcione correctamente debería ser xterm-256color. Esto hace que, por ejemplo, no funcione correctamente el marcado del modo visual de Vim. Esto se puede cambiar, tanto en Konsole como en Yakuake, yendo a Gestionar perfiles > Editar perfil: Intérprete de órdenes... > Entorno: Editar... e indicar:

TERM=xterm-256color

Y ya tenemos nuestra terminal en perfecto, completo y precioso funcionamiento. Ahora a usarla y mucho cuidado con acabar rompiendo algo ;)