Uma Lição de VIM #15.9: Plugins – CtrlP e CtrlPFunky

(Essa é a parte em que você vai ter a impressão de estar programando em Perl, porque qualquer caractere é válido.)

O nono e penúltimo plugin (na verdade os nonos e penúltimos plugins) discutido é o CtrlP e seu plugin (sim, um plugin do plugin[1]) CtrlPFunky.

Para instalar os dois, com Vundle:

Bundle ‘kien/ctrlp.vim’
Bundle ‘tacahiroy/ctrlp-funky’ 

CtrlP é um plugin que facilita encontrar e abrir arquivos, com procura fuzzy. E, por procura fuzzy eu quero dizer que ele encontra qualquer arquivo que tenha as letras digitadas na ordem que você digitou.

ctrlp

Para acionar o CtrlP, você deve digitar, logicamente, [Ctrl]p. Ao fazer isso, uma janela parecida com a Quickfix irá aparecer, mostrando alguns arquivos e um prompt para que você digite o que quer encontrar. No exemplo acima, como que digitei “vim”, ele encontrou todos os arquivos a partir do diretório atual que começavam com “v”, tinham um “i” no meio e terminavam com “m” (seria basicamente o mesmo que pegar a lista de arquivos a partir do diretório atual e seus sub-diretórios e procurar pela regex “v.*i.*m”.)

Uma vez que você encontre o arquivo desejado na lista (ela não tem rolagem, então se você ainda não estiver vendo o arquivo, continue adicionando caracteres para que o arquivo desejado apareça na lista — uma vez lá, você pode selecioná-lo com as setas), você pode:

  • Pressionar [Enter] para abrir o arquivo na janela atual.
  • Pressionar [Ctrl]t para abrir o arquivo em outra aba.
  • Pressionar [Ctrl]s para fazer um split horizontal e abrir o arquivo no novo split.
  • Pressionar [Ctrl]v para fazer um split vertical e abrir o arquivo no novo split.

Um problema que você talvez encontre é que o CtrlP costuma listar tudo que se encaixar na expressão utilizada, inclusive arquivos binário, objetos intermediários, etc. Para remover estes arquivos da listagem, você pode usar :set wildignore, que também afeta a lista de arquivos que o VIM mostra quando você estiver usando os comandos normais de abertura de arquivo (:e, :tabe, etc).

Como a configuração do wildignore é uma lista, você pode adicionar ou remover usando += e -=. Por exemplo, para ignorar os arquivos de objetos compilados do Python e o diretório que o setup.py constuma usar para construir o pacote de distribuição do módulo, você teria:

set wildignore+=*.pyc
set wildignore+=*/build/*

ou ainda, para economizar uma linha:

set wildignore+=*.pyc,*/build/*

CtrlP tem um plugin, chamado CtrlPFunky. O que ele faz é basicamente o mesmo que o CtrlP, mas procurando funções, não arquivos.

Para ativar o CtrlPFunky, você precisa primeiro adicionar o mesmo como uma extensão do CtrlP (e, só pra avisar, isso é específico do CtrlP, não algo que funciona com todo e qualquer plugin):

let g:ctrlp_extensions = [‘funky’

Uma vez instalado, você pode usar :CtrlPFunky para mostrar a lista de funções no fonte (e a procura continua igual). O problema com CtrlPFunky é que, assim como todas as demais coisas que vínhamos vendo, ele se basea no tipo de arquivo atual (:set ft) e para arquivos em que o conteúdo e uma mistura de várias linguagens (p.ex., arquivo template com a linguagem de template, HTML, CSS e JavaScript), a listagem de funções pode não ser o que você está esperando (ou sequer vai funcionar).

Para facilitar a sua vida, você pode fazer um mapeamento do comando para um atalho de teclado. Por exemplo, eu coloquei [Ctrl]o para chamar o CtrlPFunky com

nnoremap <C-O> :CtrlPFunky<CR>

[1] “Plugin-ception” har har har[2].

[2] Eu não consigo entender porque as pessoas utilizando tanto o “ception” quando encontram um meta desta jeito. Um “inception” é a inserção de uma idéia de forma que a pessoa pense que a idéia é dela, não uma “Matrioska“.

Uma Lição de VIM #15.8: Plugins – SnipMate

(Essa é a parte que automatizamos a digitação de coisas repetidas.))

Para o oitavo plugin, iremos falar sobre SnipMate.

Como de costume, instalando pelo Vundle:

Bundle ‘msanders/snipmate.vim’

SnipMate adiciona a funcionalidade de snippets dentro do VIM. Para quem não sabe, snippets são trechos de código que são adicionados automaticamente (ou com a ação de alguma combinação de teclas) a partir de uma simples palavra.

Por exemplo, um dos snippets que já estão inclusos no pacote do SnipMate, você pode, num arquivo JavaScript, simplesmente digitar:

fun

… e, ao pressionar [Tab], o SnipMate irá adicionar, automaticamente

function function_name (argument) {
  // body…
}

… posicionando o cursor diretamente sobre function_name para que você coloque o nome da função; pressionando [Tab] irá posicionar o cursor sobre argument e pressionando [Tab] de novo, o cursor ficará sobre // body... (depois disso, [Tab] irá funcionar como tabulação, como normalmente é).

Para criar seus próprios snippets, você tem duas opções e ambas devem ficar no diretório $HOME/.vim/snippets:

A primeira forma é através de um único arquivo, com o nome do tipo de arquivo em que os snippets serão válidos (que você pode ver usando :set ft) com a extensão snippets (por exemplo, para snippets para arquivos Python, você teria um arquivo $HOME/.vim/snippets/python.snippets). Neste arquivo você deve iniciar os snippets com a palavra snippet, seguida da palavra que será utilizada para identificar o snippet, seguido pelo snippet em si, com uma tabulação na frente (quando não houver tabulação, SnipMate considera que o snippet terminou). Os pontos onde você quer que o cursor pare devem ser identificados por ${{número}:{texto}} e, se ficou confuso, é porque eu estou usando “coisas que você substituir” com {} e o próprio SnipMate usa {} para blocos, mas deve ficar mais claro com este exemplo:

snippet for
    {% for ${1:record} in ${2:list} %}
        ${3:content}
    {% endfor %}

Este snippet, para Django e Jinja, faz um loop “for”. Ao digitar “for” e pressionar [Tab], o conteúdo será adicionado, o cursor será posicionando onde ${1:record} está permitindo a alteração do mesmo, pressionando [Tab] de novo irá posicionar em ${2:list} e assim por diante.

E, caso você esteja se perguntando “E o que acontece se eu colocar o mesmo número em dois lugares diferentes?”, a resposta é: lugares com o mesmo número são alterados ao mesmo tempo. Por exemplo, o snippet:

snippet block
    {% block ${1:blockname} %}
        ${2:{% content %}}
    {% endblock $1 %}

… tem o número “1” duas vezes (uma depois de “block” e outra depois de “endblock”). Quando você colocar o nome do bloco no primeiro (do lado de “block”), o outro (depois de “endblock”) será preenchido automaticamente.

A segunda forma de adicionar snippets é através de arquivos individuais. Ao invés de ter um arquivo com o tipo de arquivo com todos os snippets dentro, você irá criar um diretório com o tipo de arquivo e cada arquivo dentro deste diretório deve ser {palavra}.snippet. Assim, como no exemplo anterior tínhamos um arquivo $HOME/.vim/snippets/htmldjango.snippets, poderíamos ter, na verdade, um diretório $HOME/.vim/snippets/htmldjango/ e, dentro deste diretório, um arquivo chamando block.snippet com o conteúdo do snippet, sem as tabulações (já que agora o SnipMate sabe exatamente onde termina o snippet: no final do arquivo).

E quando usar um ou outro? Você deve usar arquivos individuais se o SnipMate já tiver um arquivo de snippets para o tipo de arquivo especificado. Assim, se você quiser adicionar novos snippets para Python, que já tem uma série de snippets prontos incluídos no pacote do próprio SnipMate, você deve usar a segunda forma. Caso contrário, fica por preferência pessoal.

E, para concluir: Ao escrever este post, descobri que existe um fork da versão apresentada aqui. A versão do “msanders” não é atualizada a 4 anos — mas funciona perfeitamente e tenho usado sem problemas a bastante tempo. Se você quiser algo mais recente (por algum motivo), o fork está em github.com/garbas/vim-snipmate (e requer mais dependências que a versão original).

Uma Lição de VIM #15.7: Plugins – Syntastic

(Essa é a parte que o VIM ajuda você a achar o que tem de errado no seu código.)

O sétimo plugin discutido é o Syntastic. Para instalar com Vundle:

Bundle ‘scrooloose/syntastic’

Inicialmente, Syntastic não faz nada. O que ele faz é, depois de salvar o arquivo em disco, chama a função de lint para o tipo de arquivo atual e mostra os problemas encontrados no canto esquerdo do código; ao passar pela linha com problema, o erro encontrado é reportado na linha de comando.

syntastic

Para ver quais são todos os erros encontrados pelo aplicativo de lint, use :Errors, que irá abrir uma janela de quickfix com a lista de erros encontrados. Ações de janelas e de quickfix, que já vinhamos vendo, continuam valendo. É só o comando para abrir o quickfix que é diferente neste caso.

Você pode selecionar quais lints serão usados adicionado com let g:syntastic__checkers=[''] (por exemplo, para verificar arquivos Python apenas com PyLint, você deve usar let g:syntastic_python_checkers=['pylint'] mas nunca tive problemas com os lints atuais).

Uma coisa que deve ser cuidada é que o lint deve estar disponível no momento que o VIM abriu o arquivo, senão ele não será usado. Por exemplo, se você tiver pylint disponível apenas dentro de um virtualenv, chamar o VIM antes de estar no virtualenv fará com que Syntastic não encontre o pylint e, com isso, nenhum erro será reportado.

Ainda, assim como aconteceu com Commentary, Syntastic usa o tipo de arquivo atual, não o do bloco. Por exemplo, ao editar um arquivo de template de Django, que tem partes na linguagem de template do Django, HTML, CSS e JavaScript, mesmo que você tenha os lints para HTML, CSS e JavaScript instalados, estes não serão executados — porque o VIM considera o arquivo um tipo inteiro, não um conjunto de pequenos blocos de tipos diferentes.

E, por último, Airline tem suporte para mostrar os erros encontrados pelo Syntastic na barra de status. Se você adicionar

let g:airline_enable_syntastic = 1

… no seu vimrc, o canto direito da barra de status irá mostrar a primeira linha com erro e a quantidade de erros encontrados.

syntastic-airline

Uma Lição de VIM #15.6: Plugins – Auto-pairs

(Essa é a parte em que o VIM fecha as coisas pra você.)

O sexto plugin da lista de plugins que eu vou falar é Auto-Pairs. Como de costume, para instalar o plugin pelo Vundle:

Bundle ‘jiangmiao/auto-pairs’

Uma vez instalado o plugin, você verá que cada ', ", (, [ e { irá, automagicamente, gerar o seu respectivo ', ", ), ] e }. Simples assim.

Entretanto, Auto-Pairs não funciona bem com o modo visual (se você já usou TextMate ou Sublime Text, deve ter percebido que se você usar uma das combinações acima com uma área selecionada, o editor vai “circular” a área selecionada com o par indicado). O que existe é [Alt]e em modo de inserção que faz a troca rápida entre o caractere de fechamento de pair com a próxima palavra.

Por exemplo, se você tiver

auto

… com o cursor posicionado entre as duas aspas e usar [Alt]e, você irá ficar com

auto

Ainda, o Auto-pairs tem um controle para “pular” sobre os caracteres de fechamento já existentes. Se ele adicionar um “)” (que deve ficar antes do cursor), quando você pressionar “)” no seu teclado, ao invés de adicionar mais um “)”, o cursor irá pular o “)” existente.

Embora isso pareça bom, em certos casos pode ser um problema. Por exemplo, caso você tenha o seguinte trecho de código:

$(function () {
  $(‘#button’).on(‘click’function () {

})

Se você tentar fechar a função interna, o Auto-Pairs irá, na verdade, saltar para o fechamento da função externa, efetivamente “proibindo” que você feche as funções corretamente. Soluções são:

  • Fechar a função externa de novo, forçando o que era para encerrar a função externa em encerramento da função interna (depois você pode alinhar as duas novamente usando o modo visual e = em modo normal);
  • Copiar e colar o fechamento da função externa;
  • Desligar o “salto” de elementos de fechamento com :let g:AutoPairsFlyMode = 0 (e, se você realmente preferir que o salto nunca seja feito, pode adicionar esta linha no seu vimrc);
  • Desligar temporariamente o Auto-Pairs com [Alt]p em modo de inserção (usar [Alt]p novamente irá reativar o Auto-Pairs).

Uma Lição de VIM #15.5: Plugins – Tabular

(Essa é a parte em que deixamos as coisas alinhadas.)

O quinto plugin da lista de plugins é Tabular, um plugin para alinhar elementos baseados em expressões regulares (calma, não é tão complicado quando parece.)

Mais uma vez, para instalar pelo Vundle:

Bundle ‘godlygeek/tabular’

Assim como Fugitive e Commentary, Tabular não é um plugin visual, mas adiciona um novo comando :{range}Tabularize {expressão regular}.

(Apenas lembrando de {range}: são dois indicadores separados por vírgula, números são linhas, $ é a última linha do arquivo, % é igual à 1,$ (todo o arquivo), '{marcador1},'{marcador2} vai do marcador1 até o marcador2 e, se você selecionar uma região no modo visual, ao pressionar :, o prompt deve ficar '< ,'> que são os marcadores especiais de início e fim, respectivamente, da área visual. Todos os exemplos que eu vou mostrar daqui pra frente vão usar o {range} de início e fim do bloco visual, porque faz mais sentido.)

A forma mais simples de usar o Tabular é passar um único caractere, que indica qual o ponto onde os elementos serão alinhados. Por exemplo, com o seguinte trecho de código:

var pos = 1;
var element = $(this);
var i = 0;

Se você selecionar o mesmo visualmente e fizer :'< ,'>Tabularize /=, o resultado será:

var pos     = 1;
var element = $(this);
var i       = 0;

Ao contrário da pesquisa (e da substituição), Tabularize aceita um segundo parâmetro que indica como os elementos devem ser alinhados e qual o espaçamento que deve existir entre os elementos. Este parâmetro pode ser até 3 pares, no formato {alinhamento}{espaços depois do elemento} que, apesar da minha péssima descrição, não é tão complicado assim.

Por exemplo, imagine que eu tenho o seguinte pedaço de código em HTML:

<input class=‘block-size disabled’
    id=‘input-box’
    name=‘login’
    value=
    placeholder=‘Enter your login’>

No caso, eu estou quebrando cada um dos elementos para diminuir o tamanho da linha, já que ainda não coloquei minhas opções de templating e cada uma destas linhas deve ficar bem maior. Mas, como exemplo, serve.

O que eu quero é que os “=” fiquem alinhados (mais ou menos o que o Xcode faz com código Objective-C). Assim, eu posso fazer :'< ,'>Tabularize /=/r0c0l0 para obter:

   <input class=‘block-size disabled’
             id=‘input-box’
           name=‘login’
          value=
    placeholder=‘Enter your login’>

A explicação está no parámetro: o primeiro par, “r0” siginfica que o elemento antes do alinhamento deve ser alinhado à direita (“r”) com 0 espaços depois do elemento; “c0” significa que o elemento de alinhamento (no nosso caso, “=’) deve ser centralizado (“c”) também com 0 espaços depois; e finalmente “l0” significa que o elemento depois do alinhamento deve ficar à esquerda (“l”) e nenhum espaço deve ser adicionado.

Se eu quisesse que o espaço não ficasse grudado tanto na esquerda quando na direita, eu teria que fazer :'< ,'>Tabularize /=/r1c1l0 para obter:

   <input class = ‘block-size disabled’
             id = ‘input-box’
           name = ‘login’
          value = 
    placeholder = ‘Enter your login’>

Uma Lição de VIM #15.4: Plugins – Commentary

(Essa é a parte em que automatizamos a técnica de sumir código sem sumir com o código.)

O quarto plugin da lista de plugins é Commentary.

Como de costume, para instalar, você pode baixar o conteúdo do repositório acima para dentro do seu ~/.vim/ (o diretório, não o arquivo de inicialização) ou usar o Vundle:

Bundle ‘tpope/vim-commentary’

Commentary não é um plugin visual, o que significa que, mais uma vez, depois de instalado você não verá nada de novo.

O que o Commentary faz é adicionar um atalho para comentar linhas de código, baseado no tipo de arquivo atual. O atalho é \\{movimentação} ou \\\ para comentar a linha atual (ou você pode entrar em modo visual para selecionar as linhas e fazer \\ e a parte selecionada vai ficar comentada); para descomentar, basta fazer a mesma coisa (ou seja, se o pedaço selecionado não estiver comentado, ele será comentado; se já estiver comentado, o comentário será removido.)

E era isso.

A única ressalva aqui fica por conta de um comportamento padrão do VIM: O VIM tem apenas um tipo de arquivo (definido com :set filetype={sintaxe}) que vale para todo o arquivo. Assim, se você estiver usando a sintaxe de HTML, Commentary provavelmente não irá comentar seu código JavaScript corretamente. A coisa fica pior se você estiver editando um arquivo com sintaxe de template, já que o tipo de arquivo é o template, não HTML ou JavaScript ou CSS.

Ainda, aproveitando o gancho, existem sintaxes e sintaxes. Algumas sintaxes são antigas e estão definidas de uma forma que o VIM perde o contexto do código apresentado e apresenta com a coloração errada (andar no texto em direção ao começo do arquivo, com [PageUp], normalmente resolve esse problema, pois o VIM encontra um ponto onde a sintaxe volta a fazer sentido). Por exemplo, a sintaxe “htmldjango”, que funciona também para arquivos Jinja2 tem a leve tendência de se perder em arquivos muito longos; usando uma sintaxe externa para Jinja2 (usando :Bundle 'Glench/Vim-Jinja2-Syntax') esse problema não acontece.

Então lembre-se: Se a sintaxe “pirar”, voltar um pouco para o começo do arquivo deve resolver (e, depois disso, o VIM carrega o contexto a medida que você for voltando para o ponto original) e sempre verifique se não há um arquivo de sintaxe que corresponda melhor às suas necessidades.

Uma Lição de VIM #15.3: Plugins – Fugitive

(Essa é a parte que só faz sentido se você usa Git.)

O terceiro plugin que eu vou comentar é Fugitive, que adiciona comandos para gerenciar seu repositório Git dentro do VIM.

Para instalar, ou você baixa a versão do Github (no link acima) ou usa o Vundle:

Bundle ‘tpope/vim-fugitive’

(E, de novo: depois de adicionar essa linha no seu vimrc, você deve sair do VIM — ou, se não quiser fazer tudo isso, basta usar o comando acima em modo de comando — e usar :BundleInstall para instalar o plugin.)

A princípio, nada de diferente deve aparecer. Mas você agora pode usar qualquer comando do Git com :Git {comando}, como faria no shell.

Mas só adicionar um comando não é o que o Fugitive faz. Ele também adiciona outros comandos:

  • :Gwrite (ou :Gw): salva o arquivo atual e já adiciona no index para o próximo commit.
  • :Gblame: Faz um split da tela, mostrando do lado direito o fonte que já estava aberto e do lado esquerdo, o último commit (SHA1) e o autor do commit.
  • :Gread: Descarta as alterações locais e recupera o arquivo atual na sua última revisão dentro do repositório do Git (ou seja, revert).
  • :Gdiff: Mostra um diff da versão atual com a versão no repositório, com splits.
  • :Gcommit: Faz o commit dos arquivos que estão no index.
  • :Gstatus: Faz um “git status”, mas deixa que você altere os arquivos no index (usando “-” para adicionar ou remover o arquivo — leia o texto com atenção) e faça commit dos selecionados (usando “cc“) [Note que ambos os comandos devem ser usados em modo normal dentro do split aberto por :Gstatus.]

Existem outros, mas você vai usar principalmente estes. E cuide para que você esteja dentro de um repositório Git antes de tentar usar os comandos; se o VIM não estiver num diretório com um repositório válido, nenhum dos comandos do Fugitive ficarão disponíveis[1].

E, como última dica: Se você estiver usando o Airline (comentado no capítulo anterior), adicione

let g:airline_enable_branch = 1

… no seu vimrc e o branch atual será apresentando dentro do status do Airline, logo após o indicador de modo.

[1] Eu só preciso adimitir que não testei para ver o que acontece se você abrir o VIM fora de um repositório e depois usar :cd para mudar para um diretório que tem um repositório ou tentar abrir um arquivo que está dentro de um repositório para verificar se os comandos se tornam disponíveis.

Uma Lição de VIM #15.2: Plugins – Vim-Airline

(Essa é a parte em que o “laststatus” fica interessante.)

Quando estávamos falando de configurações, falamos de uma configuração chamada “laststatus”. Esta configuração tem 3 valores possíveis:

  • 0 – não apresenta a barra de status, nunca.
  • 1 – apresenta a barra de status se houver pelo menos um split.
  • 2 – sempre apresenta a barra de status.

E, conforme eu mostrei no meu arquivo de configuração, eu sempre deixo com “2”.

Acontece que a barra de status não é tããão informativa assim.

laststatus

Ela tem o básico, mas o básico não é o suficiente, sejamos honestos. É possível adicionar mais informações setando “statusline” (que eu não vou entrar em detalhes aqui, mas para configurar, você tem que usar letras únicas indicado para cada coisa que deseja apresentar tal como se faz com “guioptions”) mas, mesmo assim, certas coisas tem que vir de scripts externos (por exemplo, para mostrar o branch atual que você está) e, como eu falei, essa parte é meio chata.

Para aliviar essa confusão, existe um plugin chamado “Vim-Airline“, que tem uma apresentação mais complexa e oferece mais informações, baseados plugins que você tem instalado.

Ainda, o Airline é uma versão mais leve do Powerline, que na verdade passou de ser um simples plugin para VIM para ser um plugin para praticamente tudo (hoje eu uso o Powerline para configurar meu prompt do terminal, por exemplo) e algumas coisas ainda são usadas do Powerline (por exemplo, as fontes, mas esperem aí que eu já explico o porque o Airline usa fontes especiais.)

(Conforme formos passando a lista de plugins que eu tenho, vocês vão ver o Airline mudando de formato com o tempo.)

Como falei do Vundle como gerenciador de plugins, vamos usar o mesmo para instalar (e manter, no futuro) o Airline.

No seu vimrc, adicione o seguinte:

Bundle "bling/vim-airline"

E, revisando: :Bundle adiciona um plugin na lista de plugins gerenciados pelo Vundle (e apenas isso, nada mais); por ter uma barra no meio, estamos falando de um repositório do Github; para instalar o plugin, você precisa ou adicionar o plugin na lista manualmente (com o comando :Bundle) ou reiniciar o VIM caso você queria conferir se a configuração no seu vimrc está certa e fazer :BundleInstall.

Se nada apareceu, é porque o seu “laststatus” não está em “2”.

Se tudo deu certo, você verá o seguinte:

airline-nofonts

Não que tenha melhorado muito, mas agora você tem informações sobre qual o modo que você está atualmente (que vai mudar de cor conforme você passa para o modo de inserção ou visual), o nome do arquivo, o tipo de arquivo (que define qual a sintaxe está sendo usada), posição do cursor em relação ao todo do arquivo (em percentual) e a posição absoluta do mesmo (em linhas em colunas).

Ok, duas coisas: Ainda não é muito melhor (embora a parte de mostrar o modo ajude, acredite), mas temos alguns caracteres estranhos na barra.

É aí que entra a história do Powerline de novo: Os criadores do Powerline usaram “posições” não usadas nas fontes unicode para adicionar outros caracteres que são usados para melhorar a apresentação do status. Eles mantém um repositório com fontes já com os caracteres especiais e, caso a fonte que você queria não esteja na lista deles, eles tem um script para “patchear” a fonte desejada.

Uma vez que você tenha a fonte disponível no seu sistema, você deve adicionar no seu vimrc

let g:airline_powerline_fonts = 1

E o seu Airline, na próxima execução, deve ficar

airline-laststatus

Que é mais bonito, mas ainda continua mostrando as mesmas informações. Mais pra frente veremos ã integração com “Fugitive” (um plugin para VIM para Git) e o Syntastic (para validar o código com ferramentas externas) e como ambos são suportados pelo Airline, você terá todas as informações ao alcance do rodapé da janela.

airline-everything

Uma última nota: O Airline vem com suporte a temas, que você pode trocar usando :AirlineTheme (e um duplo [Tab] depois disso irá mostrar os temas instalados). Depois que escolher um, você pode definir

let g:airline_theme = ‘{nome do tema}’

no seu vimrc.

Uma Lição de VIM #15.1: Plugins – Vundle

(Essa é a parte em que começamos a mexer ao redor do VIM.)

Vamos começar a ver como adicionar funcionalidades no VIM com plugins. E, para isso, vamos ver Vundle, que é um gerenciador de plugins.

A pergunta que você deveria estar se fazendo agora é “E por que usar o Vundle?”. Na verdade, esta pergunta tem duas respostas:

A primeira é: Apesar de ser extremamente fácil de adicionar um plugin no VIM — normalmente é uma questão de descompactar um arquivo dentro do diretório $HOME/.vim — a parte chata é manter os scripts atualizados (e ficar preso à um arquivo compactado) e removê-los depois, se você encher o saco de um.

A segunda é: Vundle não é o único gerenciador de plugins para VIM, mas consegue instalar plugins por conta própria (Pathogen requer que você baixe os plugins manualmente, assumindo depois o controle para manter atualizado); a desvantagem é que Vundle requer que os scripts tenham uma determinada estrutura de arquivos e diretórios, mas praticamente todos os scripts hoje utilizam esta estrutura.

Então vamos lá, instalar o Vundle:

Primeiro, você deve baixar o plugin em si. Para isso, você tem que ter o Git instalado e executar:

git clone https://github.com/gmarik/vundle.git ~/.vim/bundle/vundle

Simplesmente, você está copiando o repositório do vundle para um diretório do próprio VIM. Até aqui nenhuma surpresa, exceto que o diretório de plugins é $HOME/.vim/plugin (ou ~/.vim/plugin) e a colanagem colocou no diretório ~/.vim/bundle. Ou seja, o Vundle não está ativo como um plugin do VIM (ainda). O Vundle faz isso de propósito, para que os scripts instalados com o Vundle não se misturem com os plugins instalados manualmente.

A seguir, é preciso ativar o Vundle. Para isso, nós vamos adicionar o diretório do Vundle no path do VIM e chamar o script de inicialização. Para isto, adicione as seguintes linhas no seu vimrc:

set rtp+=~/.vim/bundle/vundle/
call vundle#rc()

Explicando: “rtp” é a forma curta de “runtimepath”, que identifica os diretórios onde o VIM irá procurar scripts, se preciso. No caso, estamos adicionando o diretório do Vundle, que clonamos anteriormente. A seguir é chamado o script de inicialização do Vundle.

Pronto! Agora o Vundle está instalado.

A questão é: E agora que o Vundle está instalado, “faz o que?”

O Vundle tem mais comandos disponíveis, entre eles :Bundle "{bundle}"[1]. Este comando adiciona um bundle/plugin/script na lista de bundles/plugins/scripts gerenciados pelo Vundle. A única coisa que esse comando faz é adicionar o bundle na lista; ele não vai instalar o bundle ainda, ele não vai remover o bundle, ele não vai atualizar o bundle. Apenas adicionar na lista.

O parâmetro do comando, {bundle} pode ser:

Uma vez que você tenha a lista de plugins que você quer no sistema, você pode instalar todos usando :BundleInstall; se quiser remover um plugin, você simplesmente o deixa fora da lista de plugins desejados e executa :BundleClean; e, para atualizar os plugins que estão instalados, :BundleUpdate.

Acho que você já percebeu que o problema de se manter uma lista de plugins manualmente é meio chato: Toda vez que você quiser verificar se há atualizações dos plugins, você tem que entrar a lista inteira; se você esquecer de um plugin e fizer :BundleClean irá remover esse plugin. Para evitar essa complicação, você pode adicionar os comandos Bundle diretamente no seu vimrc[2]. Assim, cada vez que você usar qualquer comando do Vundle, você não precisa se preocupar em lembrar de todos os plugins instalados.

E, como última dica, fica o seguinte: Logo após a linha do “call vundle#rc()”, adicione

Bundle 'gmarik/vundle'

.. que nada mais é que o repositório que fizemos o clone logo no começo; desta forma, quando você fizer um :BundleUpdate, o próprio Vundle poderá ser atualizado com a última versão disponível.

[1] Lembram que eu falei que plugins poderiam adicionar novos comandos e que estes teriam pelo menos a primeira letra em maiúsculas? Pois é…

[2] Lembre-se também que o vimrc é um arquivo executado em modo Ex e o modo Ex nada mais é que o modo de comando sem precisar colocar : na frente de cada comando.

Uma Lição de VIM #14: Tags

(Essa é a parte em que você vai entender Unix um pouco.)

Eu expliquei antes que haviam dois comandos para utilizar tags, [Ctrl]] e [Ctrl]t. Existem duas coisas que eu não expliquei: O que são tags e de onde elas vem.

Primeiro, tags são qualquer palavra que o editor encontre no arquivo de tags. E o arquivo de tags pode ser definido em :set tags. Por padrão, são verificados os arquivos “./tags” (“tags” no diretório atual do editor), “./TAGS”, “tags” (arquivo “tags” em algum diretório de pesquisa” e “TAGS”.

Acontece que não é qualquer arquivo com este nome que o torna válido. Existem um formato específico em que as coisas devem estar declaradas para serem detectadas como tags. E o formato é

{tagname}{tagfile}{tagaddress}

(onde “tagname” é a tag em si, “tagfile” é o nome do arquivo onde a tag se encontra e “tagaddress” é uma expressão Ex para encontrar a tag — por exemplo, “89” para ir para linha 89).

Sim, só isso. E eu sei que manter um arquivo assim é chato horrores, e por isto existem ferramentas que já fazem isso. A mais completa de todas é Exuberant CTags e pode ser encontrada em praticamente todas as distribuições Linux atuais, gerenciadores de pacotes do OS X e ainda vem um pacote para Windows.

A grande vantagem do Exuberant é a quantidade de linguagens suportadas. Assim, se você estiver num projeto em Python e depois passar para um projeto em C, você ainda pode usar o mesmo aplicativo.

A sintaxe gerado do Exuberant é “ctags {arquivos}”, onde {arquivos} são os arquivos a serem processados (expressões como “*.py” são válidas) ou, da forma mais simples “ctags -R”, para que todos os arquivos do diretório atual e subdiretórios sejam processados.

Uma vez que este arquivo tenha sido criado, dentro do editor você pode usar [Ctrl]] para tentar achar a definição da tag (que, com o uso do Exuberant significa definição de funções ou definições de variáveis) e [Ctrl]t para retornar para a localização anterior. Se houver mais de um arquivo com uma definição válida, o VIM irá mostrar uma lista das localizações e você poderá selecionar qual deve ser acessada.

A única dica que sobra aqui é cuidar com arquivos minificados. Isso porque o Exuberant entende arquivos CSS. Não que arquivos CSS sejam um problema, mas o Exuberant coloca a expressão regular da linha onde a tag se encontra e, num arquivo minificado, a expressão acaba sendo uma linha gigantesca, que fica se repetindo em vários lugares do arquivo, deixando-o gigantesco. Se você tiver algo desse tipo, use a opção “–exclude={expressão}”, onde {expressão} é a expressão regular que define o nome dos arquivos que devem ser ignorados.