Uma gloriosa introdução ao Vim

por Caio Miranda
2010/03/04 - ? (Wërk Insch Progressen)

Uma rápida observação

Este tutorial ainda está longe de ser completo: há inconsistências na formatação, frases mal-escritas e exemplos menos-que-ideais, sem contar que faltam vários desenhos! As seções iniciais já estão boas, mas perto do fim há algumas não-terminadas ou vazias. Toda a informação aqui, porém, está (até onde eu sei) adoravelmente correta. Espero que, mesmo no atual estado, este tutorial o ajude para alguma coisa.

Introdução

Vim é um editor de texto gratuito, open source, e multiplataforma, muito popular entre usuários de sistemas *NIX por sua capacidade de editar texto de maneira extremamente veloz e pela sua longa barba. É largamente utilizado para a produção de código de computador, mas também inestimável para a escrita de texto comum. Pode ser obtido em http://www.vim.org.

Mas só isso não convém meu entusiasmo pelo Vim. Que tal isso: esse é o software mais útil e bem-desenvolvido que eu conheço. Nenhum outro programa aumentou tanto a minha produtividade quanto ele, e nenhum outro se tornou tão essencial para a minha maneira de trabalhar. Sempre que eu preciso editar texto eu o faço no Vim. Às vezes me pego tentando entrar comandos dele em outros programas. Se eu tivesse que escolher entre o Vim ou a minha mão direita, eu nunca mais poderia fazer malabarismo.

Apesar de já existirem dezenas de tutoriais para o Vim na internet, além do excelente vimtutor (o guia que vem com o próprio Vim), nunca encontrei um que me agradasse completamente (leia: um que tivesse um desenho enorme de um tubarão andando de jetpack logo no começo), então achei que poderia ser útil para alguém se escrevesse um novo.

O Vim é um programa bastante complexo, e difícil de aprender se comparado com a da maioria dos outros editores. Garanto que a recompensa será de tamanho proporcional. O Vim é como um foguete (talvez do tipo que se prende nas costas) - não é possível sair pilotando-o logo de cara, mas ele é muito mais veloz que qualquer outro veículo, e saber manejá-lo o torna mais popular entre as damas.

Assim sendo, por mais completo que venha a ser esse tutorial, você não vai aprender a utilizar todo o potencial do Vim só por aqui. Eu acredito que o melhor jeito de se aprender qualquer coisa relacionada a computadores é pesquisando em várias fontes, especialmente páginas na internet - se tiver interesse, vai absorver muita informação. Posso sugerir alguns lugares para começar, e há vários outros na seção leituras recomendadas no fim dessa página.

Mantenha uma janela do Vim aberta ao lado desse tutorial para poder experimentar enquanto lê. Experimentação é vital! Procure se familiarizar com o conteúdo de cada seção antes de seguir para a próxima. De início os comandos vão vir com certa dificuldade, mas logo sua memória muscular tomará controle e você tornar-se-á um mero escravo frente à grandiosidade de vossos dedos.

Se tiver alguma dúvida, não hesite em me mandar um email ou, se estiver nas proximidades, me procurar no Campus do Vale. Eu estou sempre disposto a conversar sobre o Vim :)

Uma nota sobre sistemas operacionais

Apesar de o Vim ter uma versão para Windows, ele é mais poderoso se utilizado em conjunto com um shell decente e uma boa coleção de programas de linha de comando, pois possui alguns métodos bem interessantes de integração com programas de linha de comando. Por exemplo, você pode passar texto por um programa externo e restaurar o resultado (para ordenar uma lista, fazer um cálculo etc.), ou compilar seu código e receber uma lista de erros do compilador, que você depois pode percorrer. Essas capacidades são muito menos aplicáveis no Windows porque sua linha de comando padrão, e os aplicativos que a acompanham, são vastamente inferiores aos de qualquer sistema *NIX. O ideal se você está no Windows seria utilizar algum setup estranho como Cygwin (na figura, ao lado), mas isso é basicamente varrer o problema para baixo da cama.

Mas não deixe isso o desencorajar de aprender Vim - eu comecei no Windows.

Uma nota sobre formatação

Nesse tutorial, vou usar uma fonte monoespaçada para indicar comandos do Vim; às vezes esses comandos incluem teclas sem representação gráfica, como Enter ou Esc. Nesse caso, as colocarei entre < e > e em negrito (<Esc>). A tecla Enter será chamada de <CR> (abreviação de Carriage Return). Os modificadores Ctrl e Alt são representados de maneira similar: <C-w> significa segurar a tecla Ctrl, apertar a tecla w, e soltar Ctrl. Também note que há uma distinção entre, por exemplo, <A-x> e <A-X> - o primeiro significa segurar Alt e apertar x, e o segundo significa segurar Alt e Shift e apertar x. Essas representações foram escolhidas por serem as utilizadas pelo Vim.

Quando formos dar exemplos de uso que incluam informação sobre a posição do cursor, vamos usar essa notação para indicá-la no modo normal, e um caractere | piscante para indicá-la no modo de inserir*. Em coisa, o cursor está em i e estamos no modo normal; em co|usa, está entre o e u, no modo de inserir.

Para diferenciar texto literal de comandos do Vim, usaremos essa notação. Em 10iTexto.<Esc>d`[x, Texto. é uma palavra que aparecerá escrita na tela (pois será entrada no modo de inserir).

Comandos iniciados por : (como o já mencionado :help) são instruções de linha de comando, e sempre devem ser terminados por um <CR>, que vou omitir por conveniência.

* Sim, eu achei um uso semi-legítimo para a tag <blink>!

Esqueça as setinhas

Não use as setinhas!

E não ande no modo de inserir.

O Vim se propõe a permitir que o usuário realize o máximo de trabalho possível com o mínimo de esforço possível, e uma das maneiras nas quais o faz é permitindo que o usuário se mova pelo texto da maneira mais veloz possível. Para isso, temos os movimentos, comandos especiais do modo normal que colocam o cursor onde queremos muito velozmente. Logo logo vamos aprender mais sobre movimentos; até lá, seja ingênuo e confie em mim.

Então, antes de continuar, vamos combinar uma coisa: até que nos familiarizemos bastante com o Vim, vamos fingir que o mouse, as setas, o teclado numérico e as teclas auxiliares (Insert, Delete, Home, End, PgUp, PgDn) não existem. Mais tarde elas poderão ver algum uso, ainda que mínimo, mas por enquanto só irão encorajar que utilizemos o Vim sem os movimentos, do mesmo jeito que se usa qualquer outro editor. Quando vejo alguém se movendo por um documento com as setas, vejo alguém que colocou várias rodas no nosso foguete metafórico, amarrou uma dúzia de cavalos a ele e agora o dirige com um chicote!

Leitura relacionada (opcional, volte aqui se não tiver se convencido da crueldade das setinhas mais adiante): Making those Arrow Keys Work With You (or Why the Anti-Arrow-Key Propaganda is Wrong ... )

Edição modal: a alma do vim

Outra idéia que maximiza a eficiência do Vim é a sua estrutura altamente modal, o que permite que os comandos sejam muito sucintos e abrangentes. Um modo é um estado do editor; cada modo serve para realizar uma tarefa diferente, e possui comandos distintos. O conceito pode parecer contra-intuitivo de início, mas logo se torna bastante natural. Os modos que cobriremos aqui são:

Modo normal
Esse é o modo padrão do Vim. É aqui que são realizadas a maioria das tarefas de edição (e não inserção) de texto, como copiar, colar, reorganizar, etc.
Modo de inserção
Aqui podemos digitar palavras normalmente para construir belas frases. É aqui que você vai passar a maior parte do tempo quando editando textos (mas possivelmente não quando escrevendo código).
Modo visual
Nesse modo podemos selecionar uma grande quantidade de texto e lidar com ela de maneira similar ao modo normal. Existem três variações do modo visual: a comum, onde se seleciona um trecho seqüencial de texto; a de linha, onde se seleciona linhas inteiras; e a de bloco, onde se seleciona um retângulo de caracteres (essa em particular é muito legal).
Modo de linha comando
Aqui digitamos palavras mágicas para fazer várias ações complexas e configurar o editor ao seu gosto. A maioria dos comandos de processamento em massa de texto são executados a partir da linha de comando do Vim.

Não se preocupe em memorizar isso - vamos revisar tudo quando introduzirmos os modos propriamente. Há alguns outros modos e submodos além desses, alguns que resumem-se a tecnicalidades ("replace mode") e outros cujo uso é restrito demais para este tutorial.

Seus primeiros passos

Abrindo o Vim sem indicar um arquivo a ser editado, você terá um documento vazio e uma pequena introdução. Ok, agora queremos entrar algum texto. Para isso, precisamos estar no modo de inserção.

A maneira mais comum de se entrar no modo de inserção é apertando a tecla 'i', de insert. Tente: aperte i, digite algumas linhas e aperte Esc para voltar ao modo normal. Para maximizar sua velocidade e seu mojo, use o modo de inserção exclusivamente para inserir texto. Sempre que quiser apagar mais que algumas letras, movimentar-se, copiar, colar, etc., aperte Esc e utilize o modo normal.

Para movimentar o cursor uma única posição no modo normal, use as teclas h, j, k, e l. h e l andam respectivamente para a esquerda e direita. j anda para baixo (mnemônico: j parece uma seta para baixo), e k para cima. Tente andar um pouco pelo seu texto e inserir mais algumas linhas e palavras em lugares diferentes. Essas são boas teclas para movimentos básicos como esses, pois ficam todas do lado direito da home row, então são prontamente acessíveis pela saudosa mão direita.

A esse ponto já deve ter percebido que o cursor no modo normal é um retângulo que fica sobre uma letra, e não uma linha que fica entre duas letras como em outros editores. O comando i insere texto antes desse retângulo, o que o impede de inserir texto após a última posição de uma linha (a não ser que use as - brr! - setinhas). Pois bem: para inserir texto depois do retângulo, use a tecla a, de append. Há várias vantagens que vêm de ter o cursor correspondendo a uma letra específica. Descobriremos algumas delas mais adiante.

Muitas vezes uma letra maiúscula executa uma versão "maior" do comando da minúscula; I e A, por exemplo, servem para inserir texto no começo ou no fim da linha atual, não importa em que ponto dela esteja o cursor. Dois atalhos muito úteis!

Para salvar nosso arquivo, usaremos o comando :w (abreviação de :write, também válido mas de utilidade questionável). Se tentar agora, verá que o Vim reclama da falta de um destino - afinal, estamos editando um arquivo que ainda sequer existe! Para dizer onde salvar, use :w caminho/do/arquivo (por exemplo, :w ~/vimtut/teste.txt ou :w C:/vimtut/teste.txt). Note que o Vim não cria pastas automaticamente quando salvando se elas não existem. Agora vamos sair do Vim por um momento com :q (abreviação de :quit). Também há um comando que combina os dois anteriores - :wq significa write and quit. Abra o Vim novamente. O arquivo que estava editando, claro, foi embora. Para carregá-lo de volta, use :e /caminho/do/arquivo.txt (abreviação de :edit).

Outro atalho interessante, especialmente quando se editando código, é a tecla o e O (open (line)). Esses comandos, respectivamente, entram no modo de inserção em uma nova linha abaixo ou acima da atual.

Talvez seja bom observar que não é necessário sair do modo de inserção para inserir uma nova linha logo abaixo da que estava digitando; a tecla Enter funciona perfeitamente. Porém, se quisermos inserir uma linha logo acima, é mais fácil digitar <Esc>O do que <Up><End<<CR>.

Digamos agora que queiramos colocar no nosso texto vinte linhas dizendo "Oi, tudo bem?". Fazer isso em outro editor provavelmente envolveria escrever, copiar, colar e contar. Felizmente, o Vim nos fornece uma função de repetição! Preceder qualquer comando com um numeral nos permite repetí-lo aquele número de vezes. Assim, o que procuramos é 20oOi, tudo bem?<Esc>. Experimente!

Por fim, sempre que cometer algum engano, pode usar a tecla u para desfazer a última ação. <C-r> refaz.

Resumo:

  k
h   l
  j
Move o cursor.
i Entra no modo de inserir antes do cursor.
a Entra no modo de inserir depois do cursor.
I Entra no modo de inserir no começo da linha.
A Entra no modo de inserir no fim da linha.
:w Salva o arquivo atual.
:q[!] Sai do Vim [ignorando arquivos não-salvos].
:wq Salva o arquivo atual e sai do Vim.
o, O Entra no modo de inserir em uma nova linha abaixo ou acima da atual.
u Desfaz a última ação.
<C-r> Refaz a última ação.

Exercício: Qual a maneira mais rápida de entrar o seguinte texto no Vim usando o que aprendemos nessa seção?

Como vai essa força, campeão?
Bom dia, sr. presidente.
Como vai essa força, campeão? Responda!

Resposta: Uma maneira seria

2iComo vai essa força, campeão?<CR><Esc>kA Responda!<Esc>OBom dia, sr. presidente.<Esc>

Vamos analisar esse comando:

Primeiro, inserimos Como vai essa força, campeão? duas vezes, lembrando de quebrar a linha (senão ficariam as duas na mesma).
2iComo vai essa força, campeão?<CR><Esc> Como vai essa força, campeão?
Como vai essa força, campeão?
 
Depois, movemos o cursor uma linha para cima, e inserimos Responda! no final da linha atual.
kA Responda! Como vai essa força, campeão?
Como vai essa força, campeão? Responda!
Por fim, adicionamos uma linha acima, dizendo Bom dia, sr. presidente.
OBom dia, sr. presidente. Como vai essa força, campeão?
Bom dia, sr. presidente.
Como vai essa força, campeão? Responda!

Voilà! Eis um jeito - talvez não o mais intuitivo, mas é rápido e usa somente as ferramentas que conhecemos até agora. Não se sinta obrigado a usar comandos como esse - de fato, esse talvez não tenha sido um exemplo muito realista, justamente por inserir as frases de um diálogo fora de ordem, o que é estranho a não ser que tenhamos o diálogo inteiro pronto na nossa cabeça antes de escrevê-lo. No "mundo real", eu provavelmente faria dessa maneira:

iComo vai essa força, campeão?<CR>Bom dia, sr. presidente.<Esc>kyyjpA Responda!

Essa resposta usa dois comandos que ainda não entendemos, yy e p. O que eles fazem? Experimente.

Movimentação por palavras

Mover-se com hjkl pode ser conveniente para pequenas distâncias, mas há maneiras melhores de percorrer intervalos grandes. Nessa seção veremos as mais comuns, os movimentos por palavras. Mais adiante aprenderemos como nos deslocar rapidamente dentro de e entre linhas, blocos de código, etc.

O movimento mais fundamental desses é o executado pela tecla w (de word). Ela move o cursor para o próximo início de palavra, pulando sobre espaços. Quaisquer conjuntos de caracteres especiais que se encontrem entre letras são considerados palavras separadas (com algumas exceções).

Caracteres-!-)*!#($@!)-$!especiais ahoy!
wCaracteres-!-)*!#($@!)-$!especiais ahoy!
wCaracteres-!-)*!#($@!)-$!especiais ahoy!
wCaracteres-!-)*!#($@!)-$!especiais ahoy!
wCaracteres-!-)*!#($@!)-$!especiais ahoy!

Além disso, temos as teclas b e e, respectivamente beginning e end: como já deve ter adivinhado, essas se movem ao próximo começo ou fim de palavra. b é, na verdade, idêntico a w, mas se move ao contrário. A versão reversa de e é ge.

Três palavras felizes.
bTrês palavras felizes.
bTrês palavras felizes.

Três palavras felizes.
eTrês palavras felizes.
eTrês palavras felizes.

Esses quatro comandos também têm versões "maiores" em W, B, E, e gE. Elas funcionam de maneira idêntica às suas contrapartes minúsculas, mas entendem como palavras conjuntos de caracteres separados por espaços (em vez de por qualquer tipo de caractere especial). Esse tipo especial de palavra, em Vimês, chama-se WORD (em maiúsculas).

Caracteres-!-)*!#($@!)-$!especiais ahoy!
ECaracteres-!-)*!#($@!)-$!especiais ahoy!
BCaracteres-!-)*!#($@!)-$!especiais ahoy!
WCaracteres-!-)*!#($@!)-$!especiais ahoy!
gECaracteres-!-)*!#($@!)-$!especiais ahoy!

Experimente um pouco com esses comandos. Avance para a próxima seção somente quando estiver confortável com eles.

Resumo:

w Move o cursor uma palavra à frente.
b Move o cursor uma palavra para tras.
e Move o cursor para o próximo fim de palavra.
ge Move o cursor para o fim de palavra anterior.

Arrancar, deletar, colocar

Os comandos mais simples de reestruturação de texto também estão presentes no Vim, é claro: chamamos copiar de yank, recortar de delete, colocar de put.

Na verdade, eu não diria que recortar e delete são exatamente sinônimos: no Vim não temos conceitos separados para remover e recortar texto. Isso é porque todo o texto que removemos é posto em um registrador, uma área especial cujo conteúdo depois podemos resgatar. Registradores são parecidos com a área de transferência do seu sistema operacional, mas podem ser nomeados e numerados. Mais detalhes na seção *********; por agora, o resultado para você é que todo texto que apagar no modo normal pode ser colado de volta com p e P.

Colar é um processo simples, e toma vantagem do cursor retangular. p cola o conteúdo o último texto removido após o cursor, e P antes. Caso o registrador possua uma linha inteira, p irá colá-la abaixo da linha atual, e P acima.

Yank e delete são um novo tipo de comando: operadores. Diferente de movimentos, operadores não agem por si só - requerem que sua área de atuação seja delimitada por um movimento. O conceito é bastante intuitivo: d significa delete, w significa word, dw significa [delete] [word]. Similarmente, yW significa [yank] [WORD], db significa [delete] to [beginning]... se o poder dessa ainda idéia não é claro, aqui estão alguns exemplos usando movimentos mais avançados, que ainda não vimos:

Deletar até a próxima frase:

Uma frase. E mais outra.
d) E mais outra.

Deletar um bloco inteiro ("delete a Block"):

int main() {
    printf("Best editor evah");
    return 0;
}
daB int main()

Mudar o conteúdo de uma tag ("change inside tag"):

<b>Superp<a>tos</b>
cit <b>|</b>

Todos esses comandos, naturalmente, funcionam de maneira similar para yank, change, o modo visual, etc.

Nem sempre se deseja copiar ou recortar uma única palavra: freqüentemente desejamos aplicar esses comandos à linha toda. Operadores possuem sintaxe especial que facilita isso. Repetir um operador no lugar do movimento associado indica que ele deve atuar sobre a linha atual inteira. dd, assim, significa deletar toda a linha onde o cursor se encontra. Utilizar um operador maiúsculo, por outro lado, não requer um movimento, e indica que deve atuar sobre um segmento começando na posição atual do cursor e indo até o fim da linha. D significa deletar do cursor ao fim da linha.

Duas sentenças
Que têm sete sílabas
Não podem coexistir
dd Duas sentenças
Não podem coexistir
p Duas sentenças
Não podem coexistir
Que têm sete sílabas
2dw Duas sentenças
Não podem coexistir
sete sílabas

Por motivos de compatibilidade com o vi, predecessor do Vim, Y funciona da mesma maneira que yy; para fazê-lo atuar do cursor ao fim da linha, como seria mais intuitivo, use o comando :map y y$. Acho que o funcionamento desse comando é bastante evidente, mas não se preocupe - mais adiante examinaremos vários outros parecidos com bastante calma.

Também há dois comandos de menor escala: x e X. x deleta a letra sob o cursor, e X a logo atrás dele (backspace). Um dos usos dessa tecla é trocar dois caracteres de lugar:

Reposciionamento.
x Reposiionamento. Recorta o caractere abaixo do cursor...
p Reposicionamento. ...e o cola após o cursor.

Resumo:

y Copia (operador; espera um movimento).
d Apaga ("recorta") (operador; espera um movimento).
p Coloca ("cola") antes do cursor, ou na linha abaixo.
P Coloca ("cola") depois do cursor, ou na linha acima.
x Remove o caractere abaixo do cursor.
X Remove o caractere antes do cursor ("backspace").

Mudando texto

Se nossa intenção é substituir (e não somente remover) um segmento, usar d pode tornar-se cansativo. Para isso, temos alguns atalhos.

O primeiro e mais utilizado é o c, o operador change. Ele age exatamente como d, inclusive colocando o texto removido no registrador 0, mas também o coloca no modo de inserção logo após. Uma pequena diferença, mas bastante valiosa!

Há também r e R, os comandos replace. r aguarda outra tecla, mas não é um operador. Ao invés disso, vai substituir o caractere sob o cursor pela segunda tecla digitada. Mais útil do que pode parecer: por exemplo, para mudar o gênero da palavra 'gato', tendo o cursor na letra g, podemos digitar era - vai ao fim, substitui por 'a'.

gato e gato
gato ra gata

R funciona de maneira similar ao modo Insert de outros editores de texto, permitindo que insira caracteres que tomam a posição de outros.

Por fim, temos a tecla s, de substitute, uma mistura entre c e r, removendo somente o caractere atual e entrando no modo de inserção. Curiosamente, S age exatamente como cc. Use o que mais lhe convier.

Resumo:

c Deleta o texto delimitado pelo movimento e entra no modo de inserir.
s Deleta o caractere abaixo do cursor e entra no modo de inserir.
r Espera outro caractere; substitui o caractere abaixo do cursor por ele.
R Entra no modo de inserir (tecnicamente, replace mode), "atropelando" outros caracteres.

Modo visual

Quando queremos atuar sobre um segmento de texto mas não temos certeza sobre o movimento necessário para cobrí-lo (por exemplo, quando queremos deletar várias palavras ou linhas sem ter que contar uma a uma), podemos usar o modo visual do Vim. Esse modo é muito parecido com a maneira como podemos selecionar texto e movê-lo ou apagá-lo em editores convencionais.

Para entrar no modo visual normal, aperte v. Agora qualquer movimento que fizer irá alterar a seção selecionada; entrar um operador o fará atuar sobre ela. Experimente: aperte v2wd (ou vwwd!) e verá que o efeito é o mesmo de 2dw.

Também há um modo visual que atua sobre linhas inteiras; para acessá-lo, tecle V.

A terceira e última variação do modo visual, e na minha opinião a mais útil, é a que atua sobre blocos. Acesse-a teclando . Como no modo visual normal, movimentos dentro de uma linha irão expandir ou reduzir a largura da seleção; porém, movimentos verticais, ao invés de selecionar a linha inteira do ponto anterior ao atual, expandem a seleção verticalmente, mantendo o formato retangular. Aí, podemos substituir todos os caracteres selecionados com r, deletá-los com d e tudo mais como normal. Mais interessante, texto deletado no modo visual de bloco carrega informação sobre formatação. Assim, se colá-lo de volta, o formato será mantido. Experimente!

Movimentação avançada

Já aprendemos várias maneiras de se locomover pelo texto no Vim, mas há muitas mais. Aqui vou cobrir algumas das que considero mais úteis.

Freqüentemente queremos pular rapidamente para o início ou fim de um documento. No Vim, podemos fazer isso, respectivamente, com os comandos gg e G. Prefixar G com um número pula para aquela linha em vez.

Há comandos para se mover mais rapidamente dentro de uma linha. ^ pula para o início, e $ para o final; ( e ) pulam para o começo da frase anterior e da próxima. A tecla f (find) aguarda outro caractere e pula para a primeira ocorrência dele a partir do ponto atual. t funciona de maneira semelhante, mas pula para a posição logo antes do caractere. F e T fazem o mesmo, mas ao contrário. Um uso simples dessas teclas é para mudar os conteúdo de parênteses: se temos '(algum texto)', podemos usar ldt) para mudar isso para '(algum)'. Complementar operadores não é seu único uso, claro; dominar essas teclas pode aumentar consideravelmente sua velocidade de locomoção pelo texto.

Uma das maneiras mais velozes de se deslocar por um documento é usando a tecla /. Ela corresponde ao modo de localizar de outros editores; qualquer texto entre ela e um <CR> é o que queremos buscar. Apertar <Esc> cancela a busca e o retorna para onde estava. Se utilizando a opção incsearch (:set incsearch), ainda, faz a busca ser incremental, ou seja, o Vim começa a pesquisar mesmo antes de apertarmos <CR>. Após realizar a pesquisa, as teclas n e N navegam pelos resultados. ? age como /, mas no sentido oposto. Acostume-se com essa função. Ela é muito útil até para se mover dentro da mesma linha.

E lembre-se: todos esses comandos são movimentos. É perfeitamente válido digitar d15G para deletar do ponto atual até a linha 15, ou y/hello para copiar do cursor até a próxima ocorrência da palavra "hello"!

Mais alguns comandos úteis

O Vim possui vários outros comandos que, enquanto não vitais para edição de texto, podem aumentar drasticamente sua eficiência. Aqui introduzirei alguns desses comandos que não se encaixam em nenhum outro capítulo.

Às vezes queremos executar uma mesma ação várias vezes, em vários lugares diferentes (ou seja, não bastaria prefixá-la com um numeral). Para isso temos macros e o comando . (ponto). O . simplesmente repete o último comando inserido (movimentos não contam). Por exemplo, para deletar várias palavras, podemos colocar o cursor sobre a primeira, digitar dw, navegar até a próxima (com w, por exemplo), digitar ., navegar até a próxima, digitar . novamente... cada vez que apertamos ., o Vim repete dw. Uma particularidade interessante desse comando é que ele também encompassa **********; assim, se queremos adicionar a palavra "foo" ao final das quatro próximas linhas, podemos digitar Afoo<CR>j.j.j..

(J, q, ., ~, gu/U);

Interlúdio

Caso já não o tenha feito, sugiro que tome algum tempo para ler o vimtutor, um tutorial bastante compreensivo que vem com o Vim. Ele aborda mais ou menos o que vimos até aqui, mas não custa reforçar nossos conhecimentos sobre o que já vimos e adiantar algo sobre o que ainda não vimos! Em sistemas *NIX, basta digitar vimtutor em um terminal; no Windows, há um atalho no seu menu Iniciar.

Vamos lá, eu espero. Vai te tomar no máximo meia hora.

Pronto? Então vamos em frente.

Configurando o Vim e pedindo ajuda

Uma modesta introdução à linha de comando do Vim

A esse ponto já aprendemos alguns comandos iniciados com :; se tentou utilizá-los, viu que levam o cursor à parte inferior da tela, que recebe um comando e interpreta-o quando pressionamos <CR>. Essa é a linha de comando, de onde podemos, entre outras coisas, configurar o Vim, pedir ajuda sobre vários tópicos, e executar operações que agem sobre uma grande extensão de texto, inclusive encompassando vários arquivos.

A maioria dos parâmetros de configuração é controlada a partir da palavra-chave set. Alguns são booleanos, chaves que podem ser ligadas ou desligadas. Essas são ativadas com :set (depois) e desativadas com :set no(depois). Por exemplo, para ativar ou desativar a opção de busca incremental, utilizamos, respectivamente, :set incsearch ou :set noincsearch. Pode-se perguntar o valor atual de uma opção ao Vim colocando-se um ponto de interrogação após seu nome. No exemplo, :set incsearch? nos diz se a busca incremental está ativada ou não.

Algumas outras, porém, podem assumir diversos valores. Essas subdividem-se em ainda outros dois tipos. Temos as que aceitam um único valor, como history, que configura quantos comandos da linha de comando o Vim guarda; essas recebem um valor direto através do operador =; por exemplo, para mandar o Vim armazenar 100 entradas no histórico, usamos :set history=100.

O outro tipo aceita vários parâmetros: guioptions define várias preferências quanto à interface do gVim. Se pedir :set guioptions?, vai ver algo do tipo aegimrLtT. Cada uma dessas letras representa uma preferência ativada. Podemos incluir ou excluir preferências do conjunto com os operadores += e -=, ou definir exatamente quais devem estar ativos com o =. Por exemplo, para esconder o menu e a barra de ferramentas do gVim, usamos :set guioptions-=mT, pois a letra m corresponde ao menu e T à barra de ferramentas. Já se queremos uma interface mais minimalista (que, aliás, eu altamente recomendo, pois irá incentivar várias boas práticas de uso do Vim), :set guioptions=c removerá todas as opções, ficando somente com c.

Uma função extremamente útil e que você possivelmente usará com freqüência é a ajuda do Vim. Acessamos ela, como já vimos, com :help (assunto), onde (assunto) pode ser um comando, um movimento, uma instrução da linha de comando... por exemplo, :help guioptions nos mostra a lista completa de opções da interface.

Substituindo e agindo sobre várias linhas

O Vim nos fornece uma maneira muito interessante de se operar sobre várias linhas, remanescente do utilitário sed do UNIX. Não vou entrar em detalhes aqui sobre as expressões regulares que podemos usar - se quiser aprender sobre isso, e eu definitivamente recomendo que o faça, especialmente se for programador, aqui há um excelente tutorial, a maioria do qual podemos aplicar ao Vim.

Para substituir ocorrências de uma palavra ou frase por outra, usamos o comando :(faixa)s/(antes)/(depois)/(flags). (faixa) mais freqüentemente será uma linha inicial e uma final, separadas por uma vírgula, ou um %, que significa "o arquivo inteiro". Omitir a faixa faz a substituição agir somente sobre a linha atual. Em (flags) podemos colocar várias letras, cada uma correspondendo a uma opção. As mais utilizadas são g, que indica que o Vim deve considerar todas as ocorrências da palavra, e não somente a primeira ocorrência de cada linha; c, que faz o Vim pedir confirmação antes de substituir cada ocorrência; e i, que indica que a capitalização das letras não importa.

Era uma vez um garoto chamado Timmy.
Timmy usava o Vim, e por isso era conhecido por seus amigos como Vimmy.
Sua linguagem favorita era Skimmy.
:%s/immy/rogdor/g
Era uma vez um garoto chamado Trogdor.
Trogdor usava o Vim, e por isso era conhecido por seus amigos como Vrogdor.
Sua linguagem favorita era Skrogdor.
:%s/rogdor/ruman
Era uma vez um garoto chamado Truman.
Truman usava o Vim, e por isso era conhecido por seus amigos como Vrogdor.
Sua linguagem favorita era Skruman.

Substituição não é a única tarefa que podemos executar sobre várias linhas no Vim. Outra arma poderosa no nosso arsenal é o comando :global (ou só :g), que encontra linhas de acordo com uma string de busca (que também pode ser uma expressão regular) e executa qualquer comando de linha de comando sobre ela. Naturalmente isso não será útil se nos restringirmos aos comandos de definição de preferências que já conhecemos (apesar de o de substituição ter seus usos), mas há vários outros que podemos combinar.

Por exemplo, :- sobe o cursor uma linha, e :j une a linha atual com a próxima (semelhante ao comando normal J). Se queremos unir todas as linhas contendo foo com a anterior, podemos utilizar :g/foo/-j. Já se queremos substituir todas as ocorrências de foo por bar, mas somente nas linhas que contém blah, o comando :g/blah/s/foo/bar/g fará o trabalho (não se assuste - pode parecer complexo, mas é simplesmente um :g/blah/ concatenado com s/foo/bar/g).

Mas o comando que, para mim, realmente faz o :g uma das minhas ferramentas favoritas é o :normal, que simplesmente executa os comandos a seguir no modo normal. Por exemplo, :normal wdw avança uma palavra e deleta a próxima. Está vendo o uso disso? Se quisermos deletar a última palavra de todas as linhas contendo foo, podemos usar :g/foo/normal $bdw!

Trabalhando com buffers

Trabalhando com janelas

Editando código

editing code (=, >, K, ^], gd, gf);

Eu disse no começo do tutorial que não-programadores também se beneficiariam imensamente de utilizar o Vim, mas nós sabemos que, se você chegou até aqui, provavelmente é porque aprecia funções de alta ordem e um de seus passatempos é discutir big vs. little endian.

Comunicando-se com o shell

Alguns plugins úteis

a, supertab, surround...

Exemplos interessantes

Seguem alguns exemplos de coisas interessantes que fiz no Vim.

Eu estava trabalhando em um agente Jason, e decidi fazer primeiro o agente e depois implementar as funções de ambiente necessárias. O código do agente ficou um pouco grande, e eu precisava descobrir quais funções fictícias eu tinha usado para poder implementá-las.

No Jason, funções seguem o formato foo(bar); porém, há outras coisas semelhantes, como adição de objetivos ( !foo(bar) ). Eu queria fazer uma lista de todas as funções e colá-las no arquivo onde escreveria a implementação. Como fazê-lo? No final das contas foi fácil - :global ao resgate! O comando abaixo coloca todas as linhas indentadas, que não começam nem com ! nem com +, e tenham um par de parênteses.

:g/^\s\+[^!-]\+(.*);/y A

Leituras recomendadas

Eu já sugeri alguns pontos de partida na introdução, mas há várias outras páginas na Internet que podem ser úteis. Abaixo estão algumas que achei legais (e que inspiraram esse tutorial).

E agora?

Esse tutorial, espero, o ensinou o suficiente sobre o Vim para que possa aumentar consideravelmente a eficiência com a qual edita texto, mas ele não cobre todas as suas funções, e ainda há muito mais para se explorar. Quando estiver disposto, sugiro que procure colorschemes que o agradem (os que vêm com o Vim são horrendos - meu favorito é o Wombat) e plugins que pesquise sobre registradores (registers), folds, verificação ortográfica (spellchecking),

Além disso, ainda há maneiras de se criar scripts para executar as tarefas mais variadas ou escrever plugins para adicionar ou alterar funcionalidades do editor. Esse é um assunto complexo que mereceria um tutorial inteiro, então não vou abordá-lo aqui.

Além do Vim

Se fui bem-sucedido, esse tutorial o convenceu quanto à supremacia do Jeito Vim. ...(vimperator, caps lock vs. esc, awesome wm)

Esse tutorial foi escrito no Vim.

Até mais!