Remote Pair Programming com Tmux e Vim

Introdução

Se você já mexeu em algum documento do Google Drive ao mesmo tempo que um colega, certamente já se perguntou se não existe nada que permita fazer o mesmo durante um processo de desenvolvimento. Principalmente, se você trabalha com TDD e tem um peer em outra localização geográfica, como é o meu caso. 
Falando especificamente de Java, tanto IntelliJ quanto Eclipse possuem plugins que permitem isso. Entre eles, podemos citar o Projeto Saros, o Floobits (que é pago e bem carinho) ou o XPairtise
Existem ainda as IDE’s cloud (que, por sinal, acredito serem o futuro), como o Cloud9 ou C9, Codenvy ou o Codeanywhere. Infelizmente, esses últimos possuem fortes limitações em suas versões gratuitas, o que pode ser um impedititivo para sua situação (como é na minha, ao menos atualmente). 
Não posso deixar de citar um projeto que considero espetacular da Eclipse, o Eclipse Che, mas esse depende de uma boa máquina disponível.

No meio de toda essa loucura de possibilidades, muitos desenvolvedores (principalmente fora do Brasil) apostam em voltar para os primórdios. É incrivel a quantidade de desenvolvedores e engenheiros de software ao redor do mundo que programam (sim, programam 100% de suas aplicações) em VIM. Basta fazer uma busca no Google por Tmux Vim para ver a quantidade de referências a “Perfect Match” (combinação perfeita).

Esse documento tenta, de forma o mais simplificada e superficial quanto possível, descrever como configurar ambos TMUX e VIM para desenvolver remotamente em pares. Mas antes, considero importante comentar as diferentes estratégias utilizadas. Caso seu interesse seja apenas o stack TMUX + VIM, pode pular direto para o capítulo Ferramentas.

Estratégias de Pareamento

Screensharing

Essa estratégia envolve a utilização de ferramentas de comunicação como o Hangouts ou o Skype. Ambos possuem compartilhamento de tela e, considerando que apenas o piloto deveria assumir o teclado, a impossibilidade de ambos mexerem no código ao mesmo tempo não deveria ser um problema. 
O que pode dificultar o processo é a impossibilidade de o piloto visualizar o ponteiro do mouse do co-piloto. Para resolver esse problema, pode ser utilizada uma aplicação dedicada de compartilhamento de tela, como o ScreenHero ou o TeamViewer, enquanto usa o Hangouts ou o Skype para comunicação. 
O problema com essa abordagem é que, normalmente, existe muita latência na comunicação e a experiência pode ser bastante prejudicada.

Collaborative Coding

Algo que poderia ajudar a resolver a questão da latência mostrada no capítulo anterior é a Codificação Colaborativa. Essa abordagem pode ser executada com ferramentas como o Cloud9 ou C9, Codenvy ou o Codeanywhere. Para quem é fiel às suas IDE’s, o Projeto Saros, o Floobits ou o XPairtise também podem ser boas saídas. 
Eu, particularmente, encontrei dois problemas para essa abordagem: 
1. No caso das IDE’s cloud, suas versões gratuitas são extretamente limitadas, e seus preços um pouco salgados para minha realidade. 
2. Os plugins para IDE’s, à exceção do Floobits, até são gratuitas, mas minha IDE de preferência é o IntelliJ Idea. Essa IDE não possui plugin para o XPairtise e a versão do Projeto Saros para IntelliJ é um projeto em andamento e ainda com muitas falhas.

Terminal Sharing

Depois de tanto pesquisar as possibilidades para meu problema, deparei-me com a questão do terminal sharing e do uso do TMUX com VIM. Confesso que nunca fui simpatizante do VIM. É uma ferramenta repelente para iniciantes. Nada intuitiva, sem nenhuma instrução aparente… Por essa razão, quando precisava fazer algo em Linux, preferia o Nano
Entretanto, de tanto ver centenas de desenvolvedores falarem mil maravilhas sobre o VIM, resolvi dar uma pesquisada mais profunda sobre a ferramenta. 
As grandes vantagens que tenho observado nesse stack são: 
1. tempo de resposta no pareamento remoto incrivelmente rápido. 
2. trabalhar sem precisar tocar no mouse, aumentando performance. 
3. integração imediata com o terminal para executar comandos Maven, Gradle entre outros.

Ferramentas

VIM

VIM é um acrônimo para VI IM proved. Ele é um editor de texto no qual podemos instalar inúmeros plugins para auxiliar no desenvolvimento. 
Usuários iniciantes costumam queixar-se do VIM em virtude da sua dificuldade à primeira vista. Sua navegação não é nada intuitiva e não possui nenhum menu ou ajuda visível. 
Toda essa dificuldade, entretanto, somente ocorre pois o VIM possui uma lógica por trás de seu funcionamento. Os criadores costumam afirmar que o método de navegação e comandos do VIM é, em verdade, uma linguagem própria, e não um simples conjunto de atalhos. 
Esse conceito pode ser visto nesse vídeo e nesse outro, ambos infelizmente em inglês. Neles, Mike Coutermarsh e Chris Toomey explicam que quando entendemos como falar essa linguagem, tudo se torna mais claro (e realmente se tornou para mim).

TMUX

Tmux é uma aplicação para *nix que permite a criação de sessões virtuais dentro do console. Isso significa que você pode, em uma única janela de terminal, criar abas/janelas para utilização simultânea, permitindo trabalhar com atalhos similares a ALT+TAB ou mesmo dividir a tela vertical e horizontalmente.

Instalação

Linux

Dependendo da distribuição, o instalador pode ser o yum ou apt. Assumindo que seu instalador é o apt, segue o comando a ser inserido:

sudo apt-get install curl git vim tmux

Windows

No Windows, recomendo utilizar uma aplicação chamada Cygwin. Ele cria um terminal com comandos linux, e permite a instalação de inúmeras ferramentas também presentes nessas distribuições (dentre elas, o VIM e o TMUX). 
Durante o processo de instalação do Cygwin, ele pergunta se o usuário deseja instalar pacotes adicionais. Utilize o campo de busca para buscar pelos pacotes abaixo e finalize a instalação: 
* curl 
* git 
* vim 
* tmux

Configuração

TMUX

Existe apenas uma configuração recomendada para o TMUX. Siga os comandos listados abaixo: 
cd ~ 
echo "set -g mouse on" > .tmux.conf

VIM

O VIM exige mais passos, então listo abaixo para referência:

1. Instalar o gerenciador de plugins:

curl -fLo ~/.vim/autoload/plug.vim --create-dirs \ 
https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim

2. Inserir configurações e plugins no VIM

Entre na pasta do usuário ~/ e crie um arquivo chamado .vimrc. Abaixo, passo as configurações que utilizo pessoalmente com o VIM. Nesse arquivo, cole o seguinte conteúdo:

" Encoding
set encoding=utf-8
set fileencoding=utf-8
" Enabling colorful status bar
set t_Co=256
set laststatus=2
" Syntax Highlighting
syntax enable
" Auto reload file on external change
set autoread
" Indentation
set backspace=indent,eol,start
set complete-=i
set smarttab
set smartindent
set autoindent
set shiftwidth=4
set tabstop=4
" Some visual options
set scrolloff=1
set sidescrolloff=5
set display+=lastline
set backspace=indent,eol,start
set listchars=tab:>\ ,trail:-,extends:>,precedes:<,nbsp:+
set title
set background=dark
" Split defaults
set splitbelow
set splitright
" Searching options
set smartcase
" Show line numbers
set number
" set relativenumber
" Enable mouse
set mouse=a

" Load plugins
call plug#begin('~/.vim/plugged')
Plug 'vim-syntastic/syntastic'
Plug 'flazz/vim-colorschemes'
Plug 'wincent/ferret'
Plug 'kien/ctrlp.vim'
Plug 'itchyny/lightline.vim'
Plug 'scrooloose/nerdtree'
Plug 'tpope/vim-fugitive'
Plug 'tpope/vim-surround'
Plug 'townk/vim-autoclose'
Plug 'airblade/vim-gitgutter'
call plug#end()

" Plugins configuration
map <C-t> :NERDTreeToggle<CR>
autocmd bufenter * if (winnr("$") == 1 && exists("b:NERDTree") && b:NERDTree.isTabTree()) | q | endif
nnoremap <C-r> :set norelativenumber!<CR>

3. Aplicar plugins

Abra o arquivo de configuração com VIM usando a sequência de comandos abaixo:

cd ~
vim .vimrc

Com o arquivo aberto, digite no teclado: 
:PlugInstall

Uma aba será aberta do lado esquerdo, mostrando o progresso de instalação dos plugins. 
Quando tudo tiver terminado, saia do VIM com o comando: 
:q! 
Obs: talvez seja necessário inserir esse comando duas vezes, uma para cada aba aberta.

Pareando

Para aprender a usar o Tmux, recomendo a leitura deste artigo (em inglês). 
Para que seja possível o pareamento, é necessário que um dos participantes se conecte na máquina do outro através de SSH (não comentarei sobre os passos necessários para tal, mas é super fácil encontrar no Google). 
Assim que um esteja conectado via SSH na máquina do outro, é necessário que cada um crie a sua sessão com o Tmux, utilizando o comando abaixo: 
tmux -uS /tmp/shared new -s nome-da-sessao 
onde nome-da-sessao poderia ser o nome do usuário, por exemplo (é como eu costumo usar, mas é indiferente o nome utilizado). 
Feito isso, caso os dois usuários estejam conectados na mesma aba, será possível um ver o que o outro digita em tempo de execução, com baixíssima latência. 
As abas se tornam compartilhadas, mas ambos podem mudar de aba de forma independente, ou seja, cada um escolhe em qual aba quer trabalhar.

Depois disso, é só abrir o VIM e ser feliz.

Leitura Recomendada