Indentando seus arquivos automaticamente e em massa com o VIM.

Heya pessoal.

Depois de longo tempo sem postar, mas sempre coletando idéias (vem por ai um how-to de como usar controle de playstation adaptado a porta serial para jogar no linux).

A dica de hoje abrange uma área delicada, indentação de código. Por todo o mundo existem códigos mal indentados (exceto em python :]), e no meu trabalho, este é um caso extremamente comum com as ferramentas que dou manutenção, e literalmente é um pé no saco. No dia 06 de Setembro deste mês, de tão saco cheio que estava dos códigos mal indentados e sempre usando uma mapping (1) do VIM para indentar uma página, com o problema sério que quando ia dar um svn diff ou coisa do genêro quase toda a página vinha no diff, senão toda ela, resolvi verificar se o VIM não tinha um “BATCH mode”, assim com o top, para usar em um loop para passar nos arquivos.

Pois bem, depois de uma meia hora batendo papo no #vim da irc.freenode.net, o pessoal me fala de uma opção ‘-c’ do VIM, que eu jurava não ter visto no manual do VIM. É dai que surge a dica de hoje :).

Para indentar os arquivos, podes usar os seguintes comandos (segue abaixo a explicação dos comandos para ninguém ficar boiando):



1. cd diretorio/com/arquivos/a/serem/indentados
2. find -type f | egrep ".html$|.php$|.inc$|.tpl$" > lista_arquivos
3. for arquivo in $( < lista_arquivos );
4. do
5.     echo "$(date +'%d/%m/%Y %H:%M:%S') - iniciando indentação  de '$arquivo'" >> log_indentacao
6.     vim -c ":normal gg=G" -c :w! -c :q! -- $arquivo &&
7.         echo "$(date +'%d/%m/%Y %H:%M:%S') - finalizando indentação  de '$arquivo'" >> log_indentacao ||
8.         echo "$(date +'%d/%m/%Y %H:%M:%S') - falhou indentação  de '$arquivo'" >> log_indentacao
9. done

Explicando as linhas:

  • Linha 2: Procurando por arquivos a serem indentados, este comando
    pega todos os arquivos .html, .php, .inc e .tpl do diretório e
    subdiretórios. Se houver problemas com espaços, você pode usar da
    seguinte forma:

    
    find -type f -name '*.php' -or -name '*.html' -or -name '*.inc' -or -name '*.tpl' -exec vim -c ':normal gg=G' -c :w! -c :q! -- "{}" ;
    

    Com isto, ele irá fazer a mesma coisa que o for faz.

  • Linhas 3 e 4: Inicia o for. $(<lista_arquivos) faz o bash fazer um ‘eval’ do arquivo lista_arquivos, mandando seu conteúdo como paramêtros para o for.
  • Linhas 5, 7 e 8: Logando para melhor acompanhamento.
  • Linha 6: O comando propriamente dito, a opção -c envia comandos ao VIM. Uma explicação melhor sobre o comando de indentação pode ser achada digitando ‘:help =’ no próprio VIM, existem dezenas de configurações que podem ser setadas e existem também dezenas de arquivos de identação prontos, da uma olhadinha em /usr/share/vim/vim71/indent :].
  • Linha 9: Finaliza o for.

Com esta dica, se salve dos arquivos não indentados! Os comandos passados ao vim também pode ser para tirar quebras de linha DOS, outra dor de cabeça absurda que costumo ter, e qualquer outra coisa do VIM.

(1) Sobre o mapping do vim, para indentar seus arquivos abertos, podes usar os seguintes comandos no seu .vimrc:

" map <F8> to reindent file
noremap <F8> mzd19m04gg=G`z
inoremap <F8> <ESC>mzgg=G`z<Insert>

Apertar a tecla = com um bloco de texto selecionado também faz o mesmo trabalho :)

Realmente espero que aproveitem!

Abraços!


About this entry