Uma Lição de VIM #7: Macros de teclado

(Essa é a parte em que você repete várias coisas sem repetir várias coisas.)

No capítulo #3, eu falei rapidamente do commando ., que repete o último comando completo. Mas como repetir comandos que são, na verdade, uma composição de vários outros comandos?

A resposta são macros de teclado.

Macros de teclado permitem que você grave uma execução qualquer e depois a repita quantas vezes quiser.

Para fazer uma macro de teclado, você deve, em modo normal, executar q{registrador}. Ao fazer isso, a última linha do VIM irá mostrar “recording”, indicando que o editor está agora gravandos todas as teclas pressionadas no registrador. Para encerrar a gravação pressione q novamente (desta vez, sem o registrador). Para “tocar” a macro, é necessário usar @{registrador}.

Quem prestou atenção no capítulo #5, deve ter notado que eu usei a palavra “registrador” de novo. E a base da questão é que realmente os dois são a mesma coisa: Se você copiar algo para o registrador a ("ayy, por exemplo) e depois gravar a macro a, o conteúdo copiado para a área de transferência será perdido. Em compensação, se você criar a macro no registrador a, você pode ver exatamente a sequeência de comandos usados usando "ap. Ou ainda, você pode colocar a sequência de comandos desejada num arquivo (ou no próprio arquivo), copiar para o registrador necessário e depois só “tocar” o registrador.

Como exemplo, imagine que você tem uma lista de constantes que você quer transformar em uma lista de strings. No caso, você teria que adicionar uma aspa no começo, uma aspa no final, uma vírgula e passar para a próxima linha. Se forem apenas 4 constantes, é fácil repetir os comandos em cada linha; mas se forem 100, a coisa fica diferente.

Neste caso, você faria o seguinte: Na primeira linha, executaria qaI"[Esc]A",[Esc]jq — ou seja, iniciaria a macro a, entraria em modo de inserção no primeiro caractere não branco da linha (I), colocaria uma aspa, sairia do modo de inserção, entraria novamente no modo de inserção mas desta vez movendo o cursor para o último caractere antes (A), adicionaria a aspa que encerra a string e uma vírgula, moveria para a linha de baixo e encerraria a macro de teclado. Até aqui espero que não tenha nada de surpresas. Agora você pode repetir @a 99 vezes para as próximas linhas ou simplesmente executar 99@a e deixar o VIM repetir a macro 99 vezes. No final, bastaria simplesmente remover a última vírgula.

Uma coisa a ter em mente — além da questão do registrador — é que o VIM encerra tanto a macro quanto o número de repetições se houver qualquer problema. Por exemplo, se no meio da sua macro você colocar um f. para mover o cursor para o próximo ponto, mas no meio da execução não for encontrado nenhum ponto, a macro será interrompida e qualquer execução posterior será encerrada, não importando se for a 99a. execução da macro ou a 1a. Se você perceber que a execução não terminou onde deveria, basta executar u em modo de comando para desfazer a execução da macro.

Uma Lição de VIM #6: Marcadores

(Essa é a parte em que você não vai mais precisar se lembrar da última linha que estava editando.)

Algumas vezes você precisa ficar pulando entre partes diferentes do seu arquivo. Alguns editores oferecem a funcionalidade de “bookmark” para linhas específicas e ficam “pulando” entre estes bookmarks. O VIM tem uma funcionalidade semelhante, chamada “Marcadores”. A diferença é que enquanto os demais editores só tem um estado para marcadores (ativo ou não), o VIM permite que você tenha até 26 marcadores únicos — e que podem ser acessados diretamente.

Para marcar uma linha, você deve usar m{nome do marcador} em modo normal, onde {nome do marcador} é uma letra de “a” a “z”. Para ir diretamente para um marcador, é só usar '{nome do marcador} para simplesmente mover o cursor para o primeiro caractere não branco na linha do marcador ou `{nome do marcador} para mover o cursor exatamente para a posição do marcador (ambos também em modo normal).

Como tudo no VIM, maiúsculas e minúsculas fazem diferença.

Criar um marcador com um nome em minúsculas signifca que o marcador é valido somente dentro do arquivo. O marcador a do arquivo “arquivo1” não é o mesmo marcador a do arquivo “arquivo2”. Quando um marcador é criado em maiúsculas, ele se torna global: Se você fizer mA no arquivo “arquivo1” e abrir o arquivo “arquivo2”, `A irá voltar para o arquivo “arquivo1” (na posição do marcador, obviamente).

E como tudo no VIM, sempre existem os comandos mágicos.

`` ou ''
Retorna para a última posição onde foi feito um “pulo”. Por exemplo, se você está na linha 100 do arquivo atual, e fizer um pulo para o marcador a (com `a, por exemplo), `` irá retorna para a linha 100. Note que isso não gera um marcador per se, já que fazer `` de novo irá retornar para a posição do marcador a (pois foi lá que aconteceu o último pulo).
`. ou '.
Retorna para a última posição onde houve alteração de texto. O exemplo que eu posso pensar neste caso é quando você está digitando um comando e não se lembra se fez o #include ou import necessário. Neste caso, você simplesmente termina de digitar o comando, usa gg para ir para o começo do arquivo para verificar se o include/import está lá e, se tiver, usa `. para retornar para a posição original.
`[ ou '[ e `] ou ']
Retorna para a posição onde o texto foi copiado (“yanked”) para a área de transferência (qualquer área de transferência). [ irá mover para o primeiro caractere copiado e ] para o último.
`" ou '"
Move para a última posição do arquivo quando o arquivo foi fechado. Isto normalmente é controlado pelo arquivo de inicialização, que veremos mais a frente.

E, para ver onde estão as marcas atuais, você só precisa usar :marks no modo de comando.

Uma Lição de VIM #5: Registradores

(Essa é a parte que o VIM fica melhor que os outros editores.)

No capítulo anterior eu mencionei que o VIM tem uma área de transferência própria e que ela não se comunica diretamente com a área de transferência do sistema operacional, apenas através de registradores.

A forma mais simples de pensar em registradores é: são marcadores para áreas de transferência com nomes[1].

Enquanto você estava vendo yank’n’paste do VIM, o VIM estava guardando o texto numa área de transferência apontanda pelo “registrador sem nome”. E eu não estou brincando aqui: O próprio help do VIM chama este registrador de “registrador sem nome”.

Para acessar os registradores, você deve usar "{nome do registrador}, onde {nome do registrador} é uma letra apenas. Assim, para copiar texto para um registrador, é utilizado "{registrador}y{movimento}; para retirar depois este texto do registrador, é utilizado "{registrador}p.

Enquanto você estava utilizando yank’n’paste sem um registrador específico, o VIM estava copiando o texto para o “registrador sem nome” (sem brincandeira, o próprio help do VIM chama este registrador de “registrador sem nome”). O nome do registrador sem nome é " (ou seja, ""yy e yy ambos irão copiar a linha atual para o registrador sem nome).

Números são registradores especiais. 0 contém o último texto copiado para área de transferência; de 1 a 9 ficam os textos excluídos, em forma de pilha (o mais recente no registrador 1, o anterior a este no 2 e assim por diante; e quando mais texto é excluído, o conteúdo vai para o registrador 1, o conteúdo do registrador 1 vai para o registrador 2 e assim por diante).

- é um registrador que guarda qualquer coisa excluída que for menor que uma linha inteira.

Registradores com letras de a a z funcionam exatamente como esperado: "ayy irá copiar a linha atual para o registrador a enquanto que "bp irá colar o conteúdo do registrador b.

Note que até agora eu chamei os registradores normais com minúsculas. O motivo é que, ao copiar algo para um registrador, o conteúdo anterior é removido, a não ser que você passe o nome do registrado em maiúsculas. Neste caso, o conteúdo movido para a área de transferência do registrador é adicionado ao conteúdo já existente. Assim, você pode copiar linhas não-contíguas usando "ayy para a primeira linha, "Ayy para as demais e depois colar com "ap (para o paste não há diferença entre maiúsculas e minúsculas).

Outros registradores especiais são:

=
Registrador de expressões. Você pode entrar fórmulas e depois colar o resultado no conteúdo com p. Uma coisa a cuidar aqui é que não é possível fazer "=p; o VIM irá imediatamente abrir espaço para entrar a fórmula ao digitar "=; ainda, o conteúdo é perdido se depois de digitar a fórmula você utilizar qualquer comando que não seja p (incluindo os comandos de movimentação).
_
Registrador “buraco negro” (de novo, eu não estou brincando, o help do VIM chama esse registrador de “buraco negro”). Qualquer coisa enviada para este registrador é perdida; paste deste registrador retorna nada. Útil quando você quer excluir algum texto sem mexer no registrador sem nome.
+
Registrador da área de transferência do sistema operacional. Somente disponível para aplicações GUI, já que estas tem acesso direto ao sistema (no caso do VIM console em Linux, o “sistema operacional” seria o próprio shell, que não tem uma área de transferência — se você pensar nas bibliotecas envolvidas, a coisa faz sentido).

[1] Registradores também são usados para outras coisas, mas veremos isso mais pra frente.

Uma Lição de VIM #4: Recortar, Copiar e Colar

(Essa é a parte que você não deve fazer muitas vezes quando estiver programando.)

Assim como outros editores, o VIM tem um sistema de copiar e colar. E, como vimos vendo desde o começo, o VIM tem seu modo peculiar de lidar com isso.

Toda a parte de copiar-e-colar do VIM é feita em modo normal. E sem que você soubesse, você já stava vendo a parte de recordar textos desde a parte de comandos do modo normal: Qualquer comando que exclua texto imediatamente transfere a parte excluído para a área de transferência do VIM. A única parte que ficou faltando foi como você “cola” estes textos de volta.

E, para colar, você usa p (de “paste”, veja só!).

E, obviamente, existe o [Shift]+p também. E a diferença é facilmente explicada se voltarmos para o capítulo #2.2.

Quando falamos do cursor, eu disse que o cursor encontra-se na parte inferior esquerda do bloco do cursor. O colar do VIM é feito depois do cursor. Assim, ao pressionar p, o texto irá aparecer depois do caractere sob o cursor; se for pressionado [Shift]+p, o texto será colado antes do caractere atual, empurrando o mesmo pra frente.

O funcionamento muda um pouco se você recortar o texto usando o modo visual de linha (ou recortar usando algum movimento que desconsidere a coluna atual). Nestes casos, o VIM entende que você quer colar uma linha inteira e, ao invés de mover o conteúdo da linha atual, o texto é colado abaixo da linha atual, desconsiderando a posição do cursor. [Shift]+p irá colar o texto antes da linha atual.

(Embora pareça complicado, a medida que você for se aclimatando com o copiar-e-colar do VIM, você verá que não é tão diferente dos demais editores — com a exceção que os outros editores tentam adivinhar quando você quer fazer copia de linhas inteiras ou apenas pedaços, enquanto que o VIM deixa você mesmo decidir quando fazer isso.)

A única coisa que ficou faltando agora foi como copiar o texto sem remover o mesmo antes — porque, vamos admitir, recortar e colar de novo seria muita burrice.

O comando para copiar é y{movimentação}. Normalmente, ele é chamado de “yank” (arrancar) e por isso muitos chamam o sistema de “copy’n’paste” do VIM de “yank’n’paste”.

Para copiar a linha inteira, você pode usar yy. Isto copia toda a linha, incluindo o marcador de nova linha, e o VIM vai entender que, na hora de colar, você quer colar a linha inteira, seguindo as mesmas regras que eu expliquei acima sobre o modo visual de linha.

Assim como outros editores, o VIM mantém a área de transferência entre arquivos (com isso, você pode abrir um arquivo, copiar um texto, abrir outro arquivo e colar a parte selecionada do primeiro) e, normalmente, o VIM ainda consegue manter a área de transferência entre execuções. Entretanto, uma coisa que você pode não gostar é que a área de transferência pertence e é gerenciada exclusivamente pelo VIM — ou seja, ele não usa a área de transferência do sistema operacional[1]. Assim, você não vai conseguir copiar do VIM e colar no seu browser ou vice-versa.

… a não ser que você use registradores, que nós vamos ver a seguir.

[1] E não, o “botão do meio dentro do X” não é a mesma coisa a área de transferência.

Uma Lição de VIM #3: Outros Comandos

(Esta é a parte em que eu comento alguns comandos que você vai usar esporadicamente.)

Neste ponto você deve estar entendendo como os modos do VIM funcionam, para que cada um funciona e tento uma idéia básica de como editar arquivos. Como eu falei já duas vezes, a quantidade de comandos disponíveis é gigantesca, então vamos aproveitar esse pequeno momento em que as coisas começam a fazer sentido para ver mais alguns comandos.

[Shift]+j (Modo normal)

“Junta” a linha abaixo do cursor com a atual. Pode não parecer muito, mas o VIM irá colocar um espaço no final da linha atual[1] antes de juntar com a linha abaixo e removerá todo caractere branco da linha de baixo antes de juntar as duas linhas.

x (Modo normal)

Apaga o caractere sob o cursor. O mesmo que [Del].

gq (Modo normal)

Reformata o parágrafo. Não faz muito sentido para código, mas se você tiver configurado a coluna máxima (vou explicar como fazer isso na parte de configuração do VIM), você pode selecionar um comentário em modo visual e usar gq para que o VIM alinhe o comentário no espaço definido. Também serve para quando você estiver editando arquivos de markup (MarkDown, reSTRUCTURED text, HTML, etc).

gg e G (Modo normal)

gg move o cursor para o início do arquivo e G move o cursor para o fim do arquivo. Efetivamente, fazer ggdG (mover o cursor para o início do arquivo, remover tudo até o final do arquivo) irá remover todo o conteúdo do arquivo.

= (Modo normal)

Reidenta o código usando a sintaxe atual.

u e [Ctrl]+r (Modo normal)

Undo e redo, respectivamente.

[Ctrl]+y e [Ctrl]+e (Modo normal e Modo de inserção)

Dois comandos que funcionam de forma diferente se executados em modo normal ou modo de inserção.

No modo normal, [Ctrl]+y irá rolar o conteúdo do texto para baixo, mantendo o cursor na mesma posição enquanto que [Ctrl]+e irá rolar o conteúdo para cima, ainda mantendo o cursor na mesma posição. Se você abusar destes comandos, movendo a linha onde o cursor se encontra para fora da área visível, o cursor irá se mover.

No modo de inserção, no entanto, [Ctrl]+y irá copiar o caractere da linha de cima na mesma coluna na posição atual; [Ctrl]+e faz o mesmo, mas com a linha de baixo.

. (Modo normal)

Repete o último comando. Note que . irá repetir o último comando completo. Por exemplo, quando eu falei sobre ggdG, estamos falando, na verdade, de dois comandos completos: gg e d{movimentação}. ., neste caso, irá repetir o comando dG. Mais adiante veremos como criar “macros de teclado” e efetivamente permitir a execução de coleções de comandos.

:e e :files (Modo de comando)

Edita um arquivo. Se não for passado o nome do arquivo depois do comando, o mesmo arquivo é recarregado do disco (em outras palavras, o buffer é atualizado com o conteúdo do arquivo). :e# recarrega o último arquivo aberto (por exemplo, se você estiver com o arquivo “arquivo” aberto e fizer :e arquivo2, usar :e# irá recarregar “arquivo” para o editor; usando :e# de novo, “arquivo2” será apresentado).

Você pode ver os últimos arquivos abertos na sessão atual do VIM com :files. Se quiser recarregar algum destes arquivos de novo, basta usar :e#{número}, onde {número} é o número do arquivo na lista.

:sh (Modo de comando)

Abre um shell dentro do VIM. Para retornar ao VIM, basta encerrar o shell.

:{número} (Modo de comando)

Pula para a linha indicada. Por exemplo, :100 irá para a centésima linha do arquivo.

[Ctrl]+] e [Ctrl]+t (Modo normal)

[Ctrl]+] pula para a tag sob o cursor e [Ctrl]+t retorna. Mais adiante veremos como criar um arquivo de tags para que o VIM consiga navegar pelo código. A mesma idéia é usada no help do VIM: se você digitar :help irá ver a primeira página de ajuda do editor; para navegar entre os tópicos apresentados (marcados de forma diferente, dependendo do esquema de cor utilizado), é utilizado [Ctrl]+] para avançar e [Ctrl]+t para retornar para a página anterior.

~ (Modo normal)

Altera o caractere sob o cursor para maiúscula se for minúscula e vice-versa e move o cursor uma posição pra frente.

gu{movimentação}, gU{movimentação} e g~{movimentação} (Modo normal)

gu{movimentação} altera todos os caracteres em {movimentação} para minúsculas.

gU{movimentação} altera todos os caracteres em {movimentação} mara maiúsculas.

g~{movimentação} faz ~ nos caracteres em {movimentação} (ou seja, os caracteres da posição do cursor até movimentação ficarão em maiúsculas se estiverem em minúsculas e vice-versa).

[Ctrl]+p e [Ctrl]+n (Modo de inserção)

Auto-complete. [Ctrl]+p tenta completar a palavra antes do cursor voltando no texto enquanto que [Ctrl]+n tenta completar com palavras mais a frente no texto.

[Ctrl]+a e [Ctrl]+x (Modo normal)

Incrementa ([Ctrl]+a) ou decrementa ([Ctrl]+x) o número sob o cursor. O VIM automaticamente detecta se o número está em decimal, octal ou hexa.

Edit: E MAIS!

w (Modo normal)

Move o cursor para o começo da próxima palavra.

e (Modo normal)

Move o cursor para o fim da próxima palavra.

b (Modo normal)

Move o cursor para o começo da palavra anterior.

ge (Modo normal)

Move o cursor para o fim da palavra anterior.

[1] … a não ser que o primeiro caractere (não branco) da linha de baixo seja um ); neste caso, o VIM não adiciona o espaço.

Uma Lição de VIM #2.5: Mudando de Modos – Modo de Comando

(Essa é a parte onde você vai aprender a fazer as coisas que precisavam de um menu para serem feitas.)

Existem três “iniciadores” de comandos no modo de… erm… comando:

:
Inicia um comando de edição.
/
Comando de pesquisa.
!
Comando de filtro externo.

Comandos de Edição

Assim como os comandos do modo normal, a quantidade de comandos de edição é grande demais para cobrir de uma vez só. Então vamos dar uma olhada nos mais utilizados:

:q
Sai do VIM. Esse deve ser o comando mais infame da história do editor — pelo menos, para os não iniciados.
:w
Salva o arquivo atual em disco. Edit: Esqueci de mencionar: Você pode passar o nome do arquivo a ser salvo neste ponto. :w, por exemplo, irá salvar o conteúdo com o nome atual; :w outro-nome irá salvar o conteúdo no arquivo “outro-nome”.
:wall
Salva todos os arquivos arquivos. Mais adiante veremos como ter vários arquivos abertos ao mesmo tempo.
:wq
Salva o arquivo atual e o fecha.
:help
Abre o help do VIM no tópico indicado. Por exemplo, :help :w irá apresentar as opções existentes para o comando :w; :help c irá mostrar as opções do comando c do modo normal e assim por diante.
:set
Configura (ou apresenta) alguma configuração do VIM. Mais a frente veremos como configurar o VIM e veremos as opções este comando.
:r
(Ou :read) Não é muito comum, mas permite carregar o conteúdo de outro arquivo para dentro do arquivo atual. sem precisar fazer todo o processo de copiar-e-colar (que veremos mais adiante). Um fato interessante de :r é que se o nome do arquivo a ser carregado começar com !, o VIM irá tentar executar o comando ao invés de carregar o conteúdo. Por exemplo, :r date irá carregar o conteúdo do arquivo date para dentro do arquivo atual enquanto que :r !date irá carregar o resultado do comando date para dentro do arquivo atual.
:noh
(Ou :nohighlight) Desliga a marcação sobre elementos de pesquisa. A seguir nós vamos ver sobre o comando de pesquisa; ao fazer uma, o VIM irá colocar um “realce” (ou “highlight”) sobre as palavras encontradas. Para desligar esses realces no texto, você pode usar :noh.

Aqui eu preciso abrir três parenteses:

  • Quando o vim se recusar a executar um comando, você pode forçá-lo a executar o mesmo de qualquer forma adicionando uma exclamação ! no final do comando. Por exemplo, se o VIM se recusar a sair porque você tem alterações em um arquivo não salvo, :q! irá forçar o editor fechar, perdendo as alterações feitas; se o arquivo não tiver permissão de escrita, :w! irá fazer com que o VIM altere as permissão do arquivo para poder escrever (e, no final, esta alteração das permissões é revertida)[1].
  • Uma coisa que você vai encontrar frequentemente são referências a “buffer” e “arquivo”. Entenda assim: buffer é a representação do arquivo na memória enquanto que o arquivo é a representação do conteúdo no disco. Ao abrir um arquivo, o VIM cria um buffer com o conteúdo do arquivo e o mantém em memória; se o arquivo sumir, o buffer ainda existirá e poderá ser salvo ainda; vários comandos internos do VIM — se você se aventurar a escrever um plugin, por exemplo — fazem referência ao buffer e não ao arquivo, mas existem funções que retornam o buffer de um arquivo com o nome indicado. Em todo esse tempo usando VIM, a distinção entre ambos nunca me pareceu importante e considerar, simplesmente, que “buffer” é o arquivo em memória é o suficiente.
  • Todos os comandos internos do VIM iniciam com uma letra minuscula e plugins, quando adicionam comandos a mais, adicionam com letras maicúlas[2]. Ainda, boa parte dos comandos não precisa ser digitada completa; quando não há mais redundâncias, o comando é aceito. Por exemplo, se houverem os comandos “:Gblame” e “:Gbork“, “:Gb” não será aceito, mas “:Gba” será porque não há mais nenhum outro comando que comece com “:Gba” (por isso que “:noh” funciona como atalho para “:nohighlight“).

Comando de Pesquisa

O comando de pesquisa é, simplesmente, /. Uma vez pressionado, você verá o cursor indo para a última linha da tela esperando a pesquisa. Uma coisa a ter em mente é que o VIM utiliza expressões regulares — então algumas coisas que você procurar não irão funcionar exatamente como você está esperando. “.“, por exemplo. Eu não vou entrar em detalhes sobre expressões regulares porque há pilhas de informações sobre elas na internet — e há praticamente mais sobre elas do que essa série tem (e terá) sobre VIM.

Dois comandos do modo normal que eu não mencionei antes por estarem ligados ao comando de pesquisa são n e N. n irá mover o cursor para a próxima ocorrência da pesquisa, enquanto que N move o cursor para a anterior. Note que eu falei “move o cursor”; isso quer dizer que n e N são comandos de movimentação e, portanto, podem ser usados com outros comandos do modo normal que utilizam movimentação. Por exemplo, procurar por “olá” e, em modo normal, executar cn irá remover tudo da posição do cursor até a próxima ocorrência de “olá” (e entrará em modo de edição).

Comando de Filtro

O comando de filtro pega o conteúdo no editor e passa para outro programa. Por exemplo, se você tiver o aplicativo “rot13”, ao executar !rot13, todo o conteúdo do arquivo será convertido para ROT13. Se você digitar !!rot13, no entanto, o conteúdo ainda será passado para o filtro e o resultado irá substituir o conteúdo do buffer atual.

Não parece ser interessante, mas um dos aplicativos que normalmente vem com o VIM é “xxd”, que converte o conteúdo para sua representação hexadecimal. Ao executar “!xxd”, você verá todo o conteúdo do seu arquivo com os valores hexadecimais de cada caracter.

[1] Não confunda “Não ter permissão de escrita” com “O arquivo pertence ao root”. No primeiro caso, o usuário tem permissão de ler o arquivo e trocar as permissões enquanto que no segundo o editor teria que ter permissões especiais de execução para poder trocar as permissões. O VIM só consegue responder ao :w! se ele próprio — e, no caso, o próprio usuário — tiver permissões suficientes sem requisitar outro aplicativo.

[2] Na verdade, o VIM vem sim com comandos que inicial com letra maíuscula: São os comandos de exploração de diretório :Explore, :Rexplore, :Vexplore e o famigerado :Sexplore, que o pessoal costuma encurtar para :Sex.

Uma Lição de VIM #2.4: Mudando de Modos – Modo Visual

(Esta é a parte em que VIM deixa de ser um editor tão alienígena.)

Na nota de rodapé do primeiro capítulo eu comentei que a maior parte dos comandos do modo visual podem ser feitos no modo de comando. Como já vimos o modo de comando, fica mais fácil entender o modo visual.

Em suma, o modo visual é a versão do VIM para o “Shift+Direcionais” dos demais editores: Vai selecionando texto, deixando visível o que está sendo selecionado. A diferença é que não é preciso ficar segurando o Shift o tempo todo. E todos os demais comandos de movimentação ainda são válidos.

Para entrar no modo visual, você usa, em modo normal, v — e, de novo, você não precisa pressionar ou ficar segurando nenhuma tecla: o modo ficará ativo até que você cancele o modo visual (voltando para o modo normal com [Esc]) ou seja utilizado algum comando de alteração de texto (como s).

Uma vez que a região fique selecionada, você pode usar qualquer comando de alteração de textos para executar somente naquela região. Assim, ao invés de ficar contando quantos tempos a linha tem para chegar no número certo de saltos para o commando f, você pode facilmente ativar o modo visual, navegar a bel prazer, usado qualquer combinação de comandos de movimentação (incluindo repetir f a vontade) até chegar no ponto que quiser e executar o comando somente naquela região.

Além de v, existem outros dois outros comandos para entrar em modo visual: [Shift]+v e [Ctrl]+v.

[Shift]+v é chamado de “modo visual de linha” porque, bem, são selecionadas linhas inteiras neste modo, incluíndo o caracter de nova linha de cada uma das linhas selecionadas. Neste modo, não é possível selecionar apenas parte de uma linha, somente linhas inteiras — que é útil quando se quer remover aquela função inteira[1].

[Ctrl]+v é chamado de “modo visual de bloco” e faz algo que poucos outros editores conseguem: seleção de regiões retangulares. A pergunta que você deve estar se fazendo agora é: e como é que o VIM junta as linhas se eu apagar um bloco inteiro? Resposta indireta: O modo visual de bloco funciona como se várias seleções fossem feitas ao mesmo tempo, o que significa que cada linha é uma seleção diferente e que cada comando de alteração de texto é executado individualmente em cada linha. Assim, se você iniciar o modo visual de bloco, selecionar várias linhas mas apenas uma coluna, e executar o comando c,[Esc], o que vai acontecer é que o VIM irá substituir o caracter na coluna indicada por vírgula em cada uma das linhas. Ou seja, respondendo a pergunta feita logo no começo deste parágrafo: o VIM irá juntar as linhas como se você tivesse ido na primeira linha, executado o comando, retornado a coluna inicial, ido para a linha seguinte, repetido o comando e passado para a próxima linha.

[1] Ou copiar para outro arquivo, que nós vamos ver mais pra frente.

Uma Lição de VIM #2.3: Mudando de Modos – Modo de Inserção

(Esta é a parte em que você vai finalmente começar a editar o texto.)

Agora que você sabe que existe mais de um modo de edição e como o cursor funciona, podemos finalmente começar a ver como se passa de um modo para o outro — e, no processo, entender como editar um texto no VIM.

Primeiro, é preciso saber que o Modo Normal é o ponto central para todos os outros modos — o jeito mais fácil de passar de um modo para o outro é através do Modo Normal. E, de qualquer modo[1], para ir para o modo normal basta pressionar Esc.

Lembre-se: Esc irá sempre voltar para o modo normal para que você possa passar para os demais modos. Esc em modo normal irá continuar em modo normal.

Para passar do modo normal para o modo de inserção, você deve usar o seguinte:

i
Vai para o modo de inserção na posição do cursor (lembre-se do capítulo anterior: o cursor está no canto inferior esquerdo do cursor, logo qualquer coisa que você digitar vai aparecer antes da letra onde o cursor se encontrava antes de pressionar i).
I
Move o cursor para o primeiro caracter que não seja espaço ou tabulação na linha e entra em modo de inserção (semelhante à _i).
a
Move o cursor uma posição pra frente e entra em modo de inserção (ou o mesmo que li).
A
Move o cursor para o fim da linha e entra em modo de inserção (Seria quase um $i, só que $ pára no último não branco da linha — se considerarmos o caracter de quebra de linha um caracter “branco” — e i ficará antes desse não-branco).
o
Insere uma linha em branco depois do cursor e entra em modo de inserção.
O
Insere uma linha em branco acima do cursor e entra em modo de inserção.
R
Entra em modo de inserção, mas substitui as letras atuais ao invés de adicionar mais. Sim, é um modo de substituição (“replace”), mas ainda é considerado um modo de inserção.

Ok, pequena pausa para acertar os ponteiros agora: Uma coisa que eu comentei anteriormente foi que, no modo normal é possível definir o número de vezes que um comando será repetido. Por mais estranho que isso possa parecer, todos os comandos acima também aceitam um número de repetições. Por exemplo, 20A-[Esc] irá repetir o comando A- 20 vezes, efetivamente colocando 20 “-” na linha atual; 20Oolá[Esc] irá adicionar 20 linhas de olá no seu texto, a partir da posição do cursor.

Sua vida acabou de mudar.

Sua vida acabou de mudar.

Quem estava prestando atenção deve ter notado que eu pulei r como opção de modo de inserção e todos os demais comandos tem uma versão em minúsculas e maiúsculas. O motivo é que r tem um funcionamento, digamos, peculiar.

r, por si só, espera por uma tecla para substituir o caracter sob o cursor. Seria o equivalente a fazer R, pressionar uma tecla e, na sequência, pressionar [Esc] para sair do modo de inserção. O estranho, no entando, é quando é definido um número de vezes que r deve ser executado: Neste caso, o caracter sob o cursor é alterado para o caracter indicado, o cursor é movido para o próximo caracter e o processo se repete até o número de vezes indicado (ou seja alcançado o final da linha). 20r-[Esc] irá, efetivametne, substituir os 20 próximos caracteres por - — que não seria o mesmo que digitar, manualmente, r- 20 vezes.

Existem ainda outros dois comandos para entrar em modo de inserção: c e s. Existem algumas diferenças configuráveis entre ambos, mas o funcionamento é o mesmo: Removem os caracteres indicados pela movimentação e passam para o modo de inserção.

Como assim "movimentação"?!?

Como assim “movimentação”?!?

De novo, pausa para acertar os ponteiros: no capítulo #2.2, eu falei sobre comandos do modo normal que movimentam o cursor. Aqui, c e s não vão entrar em modo de inserção até que você adicione uma sequência de movimentação. Assim: s$ irá remover tudo da posição de cursor até o final da linha e entrará em modo de inserção, s% irá remover tudo da posição do cursor até o próximo elemento que “fecha” o elemento atual (aspas, parênteses, colchetes, etc) e entrará em modo de inserção, c2f. irá remover tudo da posição do cursor até o segundo ponto na linha e entrará em modo de inserção e assim por diante.

A ficha finalmente caiu.

A ficha finalmente caiu.

Embora c e s funcionam de forma semelhante, C e S não: C irá apagar tudo da posição do cursor até o final da linha enquanto que S irá remover todo o conteúdo da linha, não importando a posição do cursor. Logicamente, depois de fazerem isso, ambos entram em modo de inserção. Com um número de repetições, no entanto, ambos funcionam da mesma forma — tanto 20S quanto 20C irão remover a linha atual e mais 19 e entrar em modo de edição.

E, só pra lembrar: Pressionar [Esc] irá voltar para o modo normal.

[1] … exceto o modo Ex, mas como eu falei antes, não é um modo muito útil hoje em dia e, portanto, eu estou ignorando ele daqui pra frente.

Nota: Todas as imagens são copyright (C) seus respectivos donos.

Uma Lição de VIM #2.2: Entendendo o Cursor

(Esta é a parte em que você vai lembrar quando o texto não parar exatamente onde você pensava que ele iria parar.)

Antes de passar para comandos do modo normal que realmente alteram o texto, é preciso entender como o VIM entende o cursor, porque o funcionamento pode parecer um pouco diferente dos demais editores.

Para todos os efeitos, considere que o cursor está sempre na parte inferior esquerda do bloco do cursor.

Screenshot from 2013-10-22 08:50:35

Mais uma foto de você, nesse exato momento.

Mais uma foto de você, nesse exato momento.

Porque é importante ter isso em mente?

Porque a maior parte dos editores trata as coisas um pouco diferentes: Por exemplo, se houver uma linha inteira no clipboard, o VIM irá inserir (com o comando padrão de colar, que vamos ver mais adiante) a nova linha abaixo na linha atual — a maior parte dos outros editores cola a nova linha no lugar da linha atual e move a antiga linha uma posição abaixo.

Apenas tenha isso em mente agora que vamos começar a mudar de modo e alguns comandos consideram a posição do cursor desta forma e tem uma “contraparte” para ações antes do cursor — e por isso o próximo capítulo parece ter comandos repetidos.

Nota: Todas as imagens são copyright (C) seus respectivos donos.

Uma Lição de VIM #2.1: O Modo Normal

(Esta é a parte em que você ainda vai precisar de um arquivo pronto para ver as coisas funcionando.)

Como vimos antes, o modo normal é o modo em que o VIM inicia e que, como padrão, oculta qualquer coisa que você esteja digitando.

A apresentação mais clássica do modo normal são todas as demais explicações que você vai achar por aí que dizem que é preciso usar h, j, k e l para mover o cursor na tela. Tirando o fato que isso é uma balela sem tamanho e que o VIM suporta movimentação com as teclas direcionais e que você não precisa ficar pensando em mnemônicos como “j tem uma perna pra baixo, k tem uma perna pra cima” e outras absurdices, estes são comandos normais válidos: ao pressionar k, o cursor irá mover para a linha de cima, j moverá o cursor para a linha de baixo e assim por diante.

Nem todos os comandos são acionados com apenas uma tecla. Alguns iniciam um comando, mas ficam esperando mais informações para saber o que fazer ou onde fazer. Assim, temos comandos que são de movimentação e outros de ação.

Comandos de Movimentação

Comandos de movimentação são comandos que movem o cursor no texto. Como já vimos, h, j, k e l são comandos de movimentação. Além destes temos[1]:

f[letra]
Posiciona o cursor na próxima [letra] na linha. Se [letra] não existir, não move o cursor. Por exemplo, fa irá mover o cursor para o próximo “a” na linha.
F[letra]
O mesmo que f[letra], mas voltando na linha ao invés de ir pra frente.
t[letra]
Posiciona o cursor uma posição antes de [letra] na linha. Praticamente o mesmo que f[letra], mas uma posição antes.
T[letra]
Assim como F““ faz o mesmo que t““, mas voltando na linha.
0
Move o cursor para a coluna 0.
_
Move o cursor para a primeira letra que não seja espaço ou tabulação na linha.
$
Move o cursor para o final da linha.
%
Move o cursor para o outro elemento do par (por exemplo, % quando cursor estiver sobre um “(” irá mover o cursor para o “)” correspondente).

Até aqui eu acredito que você esteja pensando “nada que mude minha vida”. Bom, então aqui vem a primeira grande dica:

Se você digitar um número antes de fazer um comando, VIM irá repetir o comando quantas vezes o número indicar.

Mind-Blown

Ok, talvez não tenha sido a revelação do século, mas isso quer dizer que se você digitar 3f., VIM irá mover o cursor para o terceiro ponto na linha atual. E isso também pode não parecer importante, mas daqui pra frente isso vai fazer sentido.

[1] De forma alguma, esta é uma lista completa de todos os comandos de movimentação existentes, apenas os mais interessantes.

Nota: Todas as imagens são copyright (C) seus respectivos donos.