joe di castrohttp://joedicastro.comMon, 09 Jul 2012 22:42:00 +0200Productividad & Linux: tmuxhttp://joedicastro.com/productividad-linux-tmux.html<p><a href="http://tmux.sourceforge.net/">Tmux</a> es un <strong>multiplexor</strong> de terminales. Es una herramienta básica, casi diría imprescindible, para los que trabajamos habitualmente con la consola de Linux. El termino multiplexor es empleado en electrónica para designar un dispositivo que combina múltiples entradas en una única salida. Esto es lo que hace tmux, combinar varios terminales en una sola ventana, de forma que podamos organizarlos de la forma más eficiente posible. Si lo primero que te viene a la cabeza son terminales con múltiples pestañas o paneles como <a href="https://launchpad.net/terminator/">Terminator</a>, olvídalo, tmux es un concepto diferente y más potente.</p> <p>La gran diferencia es que tmux está basado en un modelo cliente-servidor. El servidor puede albergar múltiples sesiones y cada instancia (ventana de terminal) puede estar asociado con una o más sesiones. Se pueden abrir, cerrar sesiones, moverse entre ellas, renombrarlas. Una sesión puede ser compartida por varios clientes, lo que es empleado por ejemplo para sesiones de <a href="https://es.wikipedia.org/wiki/Programaci%C3%B3n_en_pareja">pair programming</a>. Si se cierra un cliente, la sesión sigue corriendo en segundo plano, pudiéndose volver a ella cuando se desee. A su vez cada sesión puede albergar varias ventanas (el equivalente a las pestañas en otros terminales) y cada ventana puede subdividirse en varios paneles.</p> <p>Es una aplicación muy flexible y con muchas posibilidades, no voy a entrar en detalle en todas ellas porque me extendería demasiado. Es totalmente controlable desde el teclado, lo que lo hace muy ágil en su manejo. Yo lo uso a diario y es muy raro que trabaje en un terminal sin hacerlo dentro de una sesión de tmux. Tmux te permite tener perfectamente organizadas todas esas ventanas de terminal que los SysAdmins manejamos y que de otra manera se convierten en un caos. Antes de emplear tmux empleaba screen y terminator dependiendo de la tarea y el equipo a emplear, pero tmux me da lo mejor de ambas aplicaciones y aún más. Y si además los combinamos con un terminal ligero, superrápido y con soporte para UTF-8 y 256 colores como <code>rxvt-unicode</code> tenemos un entorno ideal para cualquier tarea que desarrollemos en la consola.</p> <h2 id="caracter+sticas">Características</h2> <p>Este es un resumen de las características de tmux:</p> <ul> <li>Modelo cliente/servidor</li> <li>Linea de comandos potente, consistente y fácilmente programable</li> <li>Totalmente controlable desde el teclado, aunque tiene un soporte básico de ratón</li> <li>División de las ventanas en múltiples paneles horizontales y/o verticales</li> <li>Los paneles pueden ser movidos, redimensionados y pueden reorganizarse en esquemas predefinidos</li> <li>Sincronizar paneles. Introducir el mismo texto en varios paneles a la vez</li> <li>Soporte para UTF-8 y 256 colores</li> <li>Copiar y pegar con múltiples bufferes</li> <li>Menús interactivos para seleccionar ventanas, sesiones o clientes</li> <li>Bloqueo de terminal manualmente o por cuenta atrás</li> <li>Moverse a una ventana mediante una búsqueda del texto existente dentro de ella</li> <li>Barra de estado por defecto y muy personalizable</li> <li>Fichero de configuración basado en texto plano</li> <li>Soporte para combinaciones de teclas basadas en Vim o Emacs</li> <li>Documentación bastante completa</li> </ul> <p>En esta imagen se puede ver la configuración por defecto de tmux, a primera vista no se puede apreciar toda la potencia que se esconde detrás de esta aplicación.</p> <p style="text-align:center;"><img src="pictures/tmux.png" width="700" height="481" alt="tmux" /></p> <h2 id="alternativas">Alternativas</h2> <p>La alternativa más directa es el veterano <a href="http://es.wikipedia.org/wiki/GNU_Screen">GNU Screen</a> en el que se inspira tmux. Sigue siendo una aplicación muy utilizada, pero en mi opinión tmux la ha superado hace tiempo. Otra alternativa es <a href="https://launchpad.net/byobu">Byobu</a> que no es más que un frontend para tmux o screen que los hace más amigables para los usuarios menos avanzados.</p> <h2 id="scripts">Scripts</h2> <p>Una de las posibilidades más potentes que nos permite tmux es la de la creación de scripts para iniciar una o varias sesiones con configuraciones predeterminadas. De esto modo se pueden crear sesiones predefinidas para desarrollo, web, ssh, etc. Pero crear scripts en tmux es una tarea bastante árida, por lo que se han desarrollado algunas utilidades de terceros para realizar esto de forma más cómoda y agradable:</p> <ul> <li> <p><a href="https://github.com/aziz/tmuxinator">Tmuxinator</a> es una utilidad escrita en <a href="http://www.ruby-lang.org/es/">Ruby</a> para crear y modificar sesiones de Tmux, permitiendo crear sesiones complejas de una forma muy sencilla ya que emplea ficheros de configuración en formato <a href="https://es.wikipedia.org/wiki/YAML">YAML</a> para ello.</p> </li> <li> <p><a href="https://github.com/remiprev/teamocil">teamocil</a> es una utilidad que nos permite crear esquemas de ventanas y paneles predefinidos con facilidad empleando el formato YAML. También está escrito en Ruby, en cuya comunidad de desarrolladores tmux está muy implantado.</p> </li> </ul> <p>Aquí se puede ver una ventana de tmux con mi configuración en la que se muestra la sesión <code>www</code> donde tengo agrupadas varias ventanas con aplicaciones relacionadas con la web. Se puede ver como estoy en la ventana 2 de 4 y como he personalizado la barra de estado:</p> <p style="text-align:center;"><img src="pictures/tmux_www.png" width="700" height="429" alt="tmux con una sesión para internet" /></p> <h2 id="mi_configuraci+n">Mi configuración</h2> <p>Mi configuración de tmux puede encontrarse en mi repositorio <em>dotfiles</em> en <a href="http://github.com/joedicastro/dotfiles">GitHub</a>. Mi configuración se apoya en la muchos otros usuarios que me han aportado ideas y en buena parte gracias a la lectura del libro <a href="http://pragprog.com/book/bhtmux/tmux">tmux: Productive Mouse-Free Development</a> de Brian P. Hogan.</p> <p>En esta otra imagen se puede ver una sesión de desarrollo con tmux, donde tengo abiertos tres paneles con tres aplicaciones (de izquierda a derecha y de arriba a abajo): vim, <a href="http://ipython.org/">ipython </a> y <a href="http://jonas.nitro.dk/tig/">tig</a>. Así mismo hay una ventana adicional donde tengo un shell bash. Pulsar sobre ella para ver a tamaño completo.</p> <p style="text-align:center;"><a href="pictures/tmux_develop_full.png" alt="tmux como entorno de desarrollo" title="tmux como entorno de desarrollo"><img src="pictures/tmux_develop.png" width="700" height="430" alt="tmux como entorno de desarrollo" /></a></p> <p>Voy a destacar algunos puntos reseñables de mi configuración. Lo primero que configuro es la combinación de teclas conocida como <code>Prefix</code> que es la combinación que precede a los atajos de teclado de tmux. Esto se hace de este modo para no interferir con los atajos de teclado de las aplicaciones que ejecutemos dentro de tmux. El prefijo por defecto de tmux es <strong><code>Ctrl + b</code></strong>, pero para los que estábamos acostumbrados a <strong>screen</strong> la combinación <strong><code>Ctrl + a</code></strong> es más idónea. Y también porque es más cómodo de teclear, sobre todo si como en mi caso, tienes mapeada una tecla de <strong><code>Ctrl</code></strong> adicional en lugar de <strong><code>Bloq Mays</code></strong>. Bueno, en realidad uso la tecla <strong><code>Bloq Mays</code></strong> también como tecla <strong><code>Esc</code></strong> cuando no es pulsada en combinación con otras, gracias a la maravillosa pequeña utilidad <a href="https://github.com/alols/xcape">xcape</a>, muy útil para los usuarios de Vim.</p> <div class="codehilite"><pre><span class="gp">#</span> Use C-a instead of C-b as the prefix <span class="go">set -g prefix C-a</span> <span class="go">unbind-key C-b</span> <span class="go">bind-key C-a send-prefix</span> </pre></div> <p>Para emplear 256 colores y indicarle que interprete de shell emplear, se lo indico mediante las siguientes lineas</p> <div class="codehilite"><pre><span class="gp">#</span> <span class="nb">set </span>256 colors <span class="go">set -g default-terminal &quot;screen-256color&quot;</span> <span class="gp">#</span> <span class="nb">set </span>default shell <span class="go">set -g default-command &quot;exec /bin/bash&quot;</span> </pre></div> <p>También cambio el retraso inicial después de pulsado el prefijo, para que no de problemas con otras aplicaciones como vim y para mejorar su respuesta.</p> <div class="codehilite"><pre><span class="gp">#</span> be more responsive, changing the default delay <span class="go">set -sg escape-time 1</span> </pre></div> <p>Para hacer más fácil el cambio entre ventanas y paneles a través de los números de los mismos, lo que hago es que empiecen a contar desde 1 y no desde 0</p> <div class="codehilite"><pre><span class="gp">#</span> Start numbering at 1 <span class="go">set -g base-index 1</span> <span class="go">setw -g pane-base-index 1</span> </pre></div> <p>Esto es muy útil para comprobar cambios en la configuración sobre la marcha sin necesidad de cerrar las sesiones. Este comando me permite recargar la configuración en vivo con la combinación <strong><code>prefix r</code></strong></p> <div class="codehilite"><pre><span class="gp">#</span> force a reload of the config file <span class="go">unbind r</span> <span class="go">bind r source-file ~/.tmux.conf \; display &quot;Reloaded!&quot;</span> </pre></div> <p>Para moverme entre los paneles y cambiar su tamaño empleo las teclas típicas de movimiento de vim para no tener que abandonar los dedos de la fila principal del teclado.</p> <div class="codehilite"><pre><span class="gp">#</span> moving between panes <span class="go">bind h select-pane -L</span> <span class="go">bind j select-pane -D</span> <span class="go">bind k select-pane -U</span> <span class="go">bind l select-pane -R</span> <span class="gp">#</span> Quick pane selection <span class="go">bind -r C-h select-window -t :-</span> <span class="go">bind -r C-l select-window -t :+</span> <span class="gp">#</span> Pane resizing <span class="go">bind -r H resize-pane -L 5</span> <span class="go">bind -r J resize-pane -D 5</span> <span class="go">bind -r K resize-pane -U 5</span> <span class="go">bind -r L resize-pane -R 5</span> </pre></div> <p>La barra de estado que empleo está inspirada en el plugin de Vim, <a href="https://github.com/Lokaltog/vim-powerline/">vim-powerline</a>, que le otorga una estética más lograda que la original. Es necesario emplear para ello una fuente monoespaciada parcheada especialmente, con los símbolos que emplea vim-powerline. Se pueden encontrar varias en su <a href="https://github.com/Lokaltog/vim-powerline/wiki/Patched-fonts">wiki</a>. Yo empleo mi fuente preferida que es Dejavu Sans Mono.</p> <div class="codehilite"><pre><span class="gp">#</span> Custom status bar <span class="gp">#</span> Powerline symbols: ⮂ ⮃ ⮀ ⮁ ⭤ <span class="go">set -g status-utf8 on</span> <span class="go">set -g status-left-length 32</span> <span class="go">set -g status-right-length 150</span> <span class="go">set -g status-interval 2</span> <span class="go">set -g status-left &#39;#[fg=colour15,bg=colour238,bold] #S #[fg=colour238,bg=colour234,nobold]⮀&#39;</span> <span class="go">set -g status-right &#39;#[fg=colour245]⮃ %R ⮃ %d %b #[fg=colour254,bg=colour234,nobold]⮂#[fg=colour16,bg=colour254,bold] #h &#39;</span> <span class="go">set -g window-status-format &quot;#[fg=white,bg=colour234] #I #W &quot;</span> <span class="go">set -g window-status-current-format &quot;#[fg=colour234,bg=colour39]⮀#[fg=colour16,bg=colour39,noreverse,bold] #I ⮁ #W #F #[fg=colour39,bg=colour234,nobold]⮀&quot;</span> </pre></div> <p>Por último unos atajos de teclado muy útiles que me permiten hacer un zoom temporal de un panel a ventana completa y luego regresar a la distribución original de paneles.</p> <div class="codehilite"><pre><span class="gp">#</span> Maximize and restore a pane <span class="go">unbind Up</span> <span class="go">bind Up new-window -d -n tmp \; swap-pane -s tmp.1 \; select-window -t tmp</span> <span class="go">unbind Down</span> <span class="go">bind Down last-window \; swap-pane -s tmp.1 \; kill-window -t tmp</span> </pre></div>joe di castroMon, 09 Jul 2012 22:42:00 +0200http://joedicastro.com/productividad-linux-tmux.htmlproductividadlinuxtmux