Tempinho sem postar, a vida anda corrida demais, mas hoje tenho um assunto muito legal para falar… o VIM, editor de textos baseado no VI (para mim o melhor!). Como estou sem tempo para escrever, vou usar da fonte que eu usei para estudos, como forma de repassar isso a vocês, e ao final claro darei os devidos créditos.
Introdução
O VIM é um editor de texto baseado no “vi” (talvez o primeiro editor de texto visual), e está disponivel para a maioria dos sistemas operativos / plataformas existentes, como Linux, *BSD, Windows, BeOS, AmigaOS, MacOS, etc. Normalmente vem incluido em qualquer distribuição de Linux, podem encontrar a ultima versão em http://www.vim.org.
Uma das caracteristicas do VIM é a utilização de buffers, um buffer é uma representação do texto em memória, um ficheiro quando é aberto (tanto como parâmetro da linha de comando como com qualquer comando interno que abra um ficheiro), é “carregado” para um buffer (em memoria), e todas as alterações feitas ao texto afectam apenas o buffer e nunca o ficheiro original, até que o buffer seja gravado. Se não especificarmos o nome de um ficheiro na linha de comandos ao correr o VIM ele arranca com um buffer vazio, e sem um nome de ficheiro associado.
Outra das caracteristicas do VIM, e talvez a que faz com que um utilizador se apaixone por ele, ou fuja a sete pés, são os vários modos de funcionamento:
- O modo “insert” é usado para inserir e modificar texto, enquanto estivermos neste modo, qualquer caracter pressionado é inserido no buffer.
- O modo “visual” é usado para seleccionar texto e fazer operações sobre essa selecção, neste modo podemos usar alguns caracteres para funções especiais como ir para o principio ou fim de uma linha, apagar texto, etc.
- O modo de linha de comando serve para executar comandos do VIM ou da shell, com os comandos do VIM podemos fazer de tudo, como gravar os buffers, abrir ficheiros, procurar texto e fazer substituições usando expressões regulares, e fazer tarefas repetitivas automaticamente.
- Podemos não estar em nenhum dos modos anteriores, é assim que o VIM arranca, este modo é usado para navegar pelo buffer usando os cursores, Home/End e PageUp/PageDown ou modificar o buffer usando caracteres que correspondem a comandos do VIM.
Bases
O mais importante: sair do VIM =)
carregar em ESC para sair do modo “insert” se estiver activo
carregar em “:” para entrar no modo “linha de comandos”
carregar em “q”
carregar em ENTER
Inserir texto
posicionar o cursor onde queremos inserir o texto
carregar em “i” para entrar no modo “insert”
inserir o texto
carregar em ESC para sair do modo “insert”
Cortar / copiar texto
carregar em ESC para sair do modo “insert” se estiver activo
carregar em “v” para entrar no modo “visual”
extender a selecção com os cursores
carregar em “d” (delete) para cortar o texto (movê-lo para a memoria)
ou carregar em “y” (yank) para copiar o texto (copia-lo para a memoria)
o texto cortado ou copiado pode ser colado posteriormente.
Colar texto
carregar em ESC para sair do modo “insert” se estiver activo
posicionar o cursor
carregar em “p” para inserir o texto depois do cursor
ou carregar em “P” para inserir o texto antes do cursor
nota: a partir daqui vai usar-se uma forma mais simplificada para a representação das operações, qualquer comando ou combinação de teclas tem de ser executado depois de sair do modo “insert” usando a tecla ESC. Os comandos começam por “:”.
Ficheiros / buffers
:e ficheiro - Abre um buffer novo em ecrã completo
:buffers - Mostra a lista dos buffers
:b buffer - Salta para o buffer, usar o TAB para completar o nome
:bn - Salta para o buffer seguinte
:bp - Salta para o buffer anterior
:w ficheiro - Grava o buffer actual com o nome ficheiro
:wq - Grava o buffer (com o nome actual) e sai do VIM
:wqa - Grava todos os buffers e sai
Navegar pelo ficheiro
h - Esquerda
l - Direita
k - Cima
j - Baixo
Os 4 caracteres anteriores são equivalentes aos cursores, uma das caracteristicas de todos os editores baseados no VI é não ser necessário tirar os dedos do bloco de teclas principal para fazer seja o que fôr. A vantagem dos cursores é que podem ser usados também no modo INSERT e na linha de comandos.
gg - Move o cursor para a primeira linha do buffer
:0 - Equivalente
G - Move o cursor para a ultima linha do buffer
:$ - Equivalente
0 - Move o cursor para o principio da linha
$ - Move o cursor para o fim da linha
X G - Move o cursor para a linha X, em que X é um numero
* - Salta para a proxima ocorrencia da palavra sob o cursor
ma - Marca o caracter “a”
`a - Move o cursor para a marca “a”
‘a - Move o cursor para a linha que contém a marca “a”
“ - Volta para o caracter anterior ao ultimo salto
” - Volta para a linha anterior ao ultimo salto
Apagar texto
dd - Apaga a linha actual
d CIMA - Apaga a linha actual e a anterior
d BAIXO - Apaga a linha actual e a seguinte
d ESQUERDA - Apaga o caracter a esquerda
d DIREITA - Apaga o caracter a direita
x - Equivalente ao anterior
Exemplos:
d0 - Apaga até ao principio da linha
d$ - Apaga até ao fim da linha
dw - Apaga a palavra seguinte
db - Apaga a palavra anterior
d’a - Apaga até a linha marcada “a”
d`a - Apaga até ao caracter marcado “a”
Multiplicadores
Muitos comandos podem ser precedidos por um “multiplicador”, este é inserido antes da combinação de teclas, e só é apresentado no ecrã (ultima linha, no canto direito) se tivermos a opção “showcmd” activa (:set showcmd)
Exemplos:
20 BAIXO - Move o cursor 20 linhas para baixo
4 dd - Apaga as 4 linhas seguintes, incluindo a actual
6 d DIREITA - Apaga os 6 caracteres à direita
Encontrar uma expressão num ficheiro
“/” para procurar para a frente ou “?” para procurar para trás
inserir expressão a procurar
ENTER para ir para a primeira ocorrência
“n” para saltar para a proxima ocorrência, “N” para procurar na direcção oposta
Expressões regulares
. Representa qualquer caracter simples excepto mudança de linha.
Representa o caracter que se segue.
* Representa 0 ou mais ocorrências do caracter precedente.
[] Representa um dos caracteres incluidos.
^ O caracter seguinte tem que estar no inicio da linha.
$ Representa caracteres no fim da linha.
[^] Representa qualquer coisa excepto o que se segue a "^".
[-] Representa um intervalo de caracteres.
Exemplos:
c.pe Representa cope, cape, caper, etc
c.pe Representa c.pe, c.per, etc
sto*p Representa stp, stop, stoop, etc
car.*n Representa carton, cartoon, carmen, etc
xyz.* Representa xyz até ao fim da linha
^The Representa qualquer linha começada por The
atime$ Representa qualquer linha acabada em atime
^Only$ Representa qualquer linha que contenha unicamente Only
b[aou]rn Representa barn, born e burn
Ver[D-F] Representa VerD, VerE e VerF
Ver[^1-9] Representa Ver seguido de um não digito
the[ir][re] Representa their, theie, therr e there
[A-Za-z][A-Za-z]* Representa qualquer palavra
Substituir texto
:%s/substituir isto/por isto/g
Ao usar o caracter “%” antes de “s” estamos a substituir o texto em todo o ficheiro, desde a primeira linha até à ultima, em vez disso podemos usar um intervalo:
:linha1,linha2s/substituir isto/por isto/g
Deste modo o texto so é substituido entre a linha1 e a linha2.
Se usarmos “/gc” em vez de “/g” é pedida confirmação antes de substituir cada ocorrência.
nota: as expressões são delimitadas pelo caracter “/”, tudo o que estiver entre a 1ª e a 2ª “/” representa a expressão a procurar, tudo o que estiver entre a 2ª e a 3ª “/” representa a expressão que vai substituir a primeira. Se deixarmos a segunda expressão vazia (ver os ultimos exemplos) as ocorrências da primeira expressão são eliminadas.
Exemplos:
:1,$s/the/The/g - Substitui the por The desde a primeira linha até à ultima
:%s/the/The/g - Equivalente (% representa todo o ficheiro)
:%s/the/The/gc - Substitui the por The em todo o ficheiro pedindo confirmação
:.,5s/^.*//g - Apaga todas as linhas entre a actual e a 5º
:’a,.s/^..//g - Apaga os dois primeiros caracteres das linhas entre a marca “a” e a actual
:%s/$/ <–/g - Acrescenta ‘ <–’ ao fim de cada linha
O caracter “&” é usado para representar a expressão a procurar quando é usado na segunda expressão, de modo a podermos inclui-la nas substituções.
Exemplos:
:%s/help/&ing/g - Substitui help por helping
:%s/ */&&/g - Duplica o numero de espaços entre as palavras
:%s/and/\&/g - Para inserir o práprio caracter “&” usamos “\&”
Registos
Os registos podem ser usados para automatizar algumas tarefas repetitivas, eu comecei a usá-los para acrescentar e modificar “tags” em ficheiros HTML. Usam-se da seguinte forma:
Sair do modo “insert” pressionando ESC, pressionar “q” e a seguir o caracter (que vai ser o nome do registo) no qual queremos guardar as acções, por exemplo “a”, para não termos de deslocar muito o dedo =), mas pode ser um qualquer. Depois disso deve aparecer “recording” na ultima linha do terminal, agora tudo o que fizermos vai ser gravado no registo “a”, para acabar de gravar saimos do modo “insert” e pressionamos “q” outravez, “recording” deve desaparecer da ultima linha do terminal. Para executar o registo pressionamos “@” e depois o caracter correspondente ao registo, neste exemplo é o “a”.
“q” caracter - Tudo o que for feito a seguir fica gravado no registo caracter
“@” caracter - Executa o registo caracter
Todas as teclas pressionadas ficam gravadas no registo, por exemplo, se gravarmos a sequência de teclas “Home, Delete, Baixo”, cada vez que executamos o registo é apagado o primeiro caracter da linha e posicionado o cursor no inicio da linha seguinte, se executarmos o registo 5 vezes seguidas (pode ser feito automaticamente usando um multiplicador, teclando o número antes de executar o registo) removemos o primeiro caracter de 5 linhas seguidas.
Os registos não servem apenas para gravar acções, quando apagamos, cortamos e copiamos texto o VIM está a usar registos especiais, podemos especificar que registo usar em cada caso, bastando para isso indicar qual o registo a usar. Referimo-nos a um registo usando o caracter ‘”‘, assim para nos referirmos ao registo ‘a’, usamos ‘”a’.
Exemplos:
“ay - Copia para o registo ‘a’ o texto seleccionado (modo visual)
“ad - Remove o texto selecionado e coloca-o no registo ‘a’
“ap - Cola o conteudo do registo ‘a’ depois do cursor
Janelas
:sp - Cria uma janela nova com o mesmo buffer
:sp ficheiro - Abre uma nova janela com um buffer novo
:q - Fecha a janela actual, não sai se for a unica janela do buffer e este não tiver sido gravado
:q! - Fecha a janela actual mesmo q seja a unica janela do buffer e este não tenha sido gravado
:qa - Fecha todas as janelas e sai, pede confirmação
CTRL “ww” - Salta para a janela seguinte
gvim
O gvim (é apenas um link para o vim e é equivalente ao comando “vim -g”, só existe se o VIM foi compilado com suporte para GUI) corre em modo grafico, isto é, com menus, scrollbars, etc, numa janela própria com menus totalmente configuráveis, os que vêm por defeito são de facil utilização, têm opções para gravar e abrir ficheiros, sair, procurar e substituir texto, etc.
Outra vantagem é o maior numero de cores disponiveis, são muito uteis para editar código (usando syntax highlighting).
O gvim usa, para além do ~/.vimrc, o ~/.gvimrc, onde definimos as fontes, cores, menus, mapeamento de teclas, etc.
Linux
As ultimas versões (a partir da 5.6) usam as widgets GTK+, ao suportar os themes de GTK integra-se perfeitamente no GNOME. A maioria das opções da versão GTK são usadas a partir de caixas de diálogo, podendo assim evitar-se a utilização da linha de comandos (algo impensável para um utilizador experiente =). Podemos usar todas as cores do X (contra as 16 de um terminal), tanto usando os nomes presentes no ficheiro /root/usr/X11R6/lib/X11/rgb.txt (no Debian) como valores em hexadecimal com qualquer numero de bits (#000, #000000) e decimal (rgb:0/0/0, rgb:00/00/00).
Este é o ~/.gvimrc que uso no Linux, depende do ~/.vimrc.
BeOS
Na versão para BeOS não existem caixas de diálogo, é tudo feito através da linha de comando. As cores têm de ser definidas como valores em hexadecimal da forma #000000, tanto os nomes (embora estejam definidos em /etc/rgb.txt) como valores com outro numero de bits ou no formato decimal são ignorados. Além disso é usada a fonte fixa definida para o sistema, não sendo possivel especificar outra.
Se abrirmos o executavel do VIM com o programa QuickRes (disponivel no bebits.com) e alterarmos as duas primeiras opções para “Single Launch” apenas uma copia do programa pode correr de cada vez, deste modo, quando corremos o gvim com um ficheiro como parâmetro ele abre a janela com o ficheiro, qualquer chamada posterior ao vim ou gvim com um ficheiro como parâmetro faz com que este seja aberto num novo buffer na janela já existente, assim todos os ficheiros são abertos na mesma janela, quer seja a partir do Tracker, do Terminal, etc. Caso a janela esteja num Desktop diferente vamos parar lá automaticamente.
Este é o ~/.gvimrc que uso no BeOS, depende do ~/.vimrc.
Menus
Os menus que acompanham o gvim usam os diálogos em GTK, eu fiz uns que usam apenas a linha de comandos, têm um menu “Extra” com comandos para abrir outros menus guardados em ficheiros separados (HTML por enquanto, com alguns caracteres especiais e o código que uso mais), foram testados na versão GTK em Linux e na versão para BeOS. Os menus estão incluidos nas minhas configurações.
Configurações
A configuração do vim é muito importante, algumas opções podem tornar a sua utilização muito mais agradável.
Estas são algumas das opções que eu uso:
set nocompatible
set incsearch " procura texto em tempo real, enquanto é teclado
set magic " usa 'magia' ao procurar texto =)
set backspace=2 " permite apagar qualquer coisa em modo insert
set textwidth=78 " muda de linha automaticamente ao chegar a esta coluna
set laststatus=2 " mostra sempre a statusbar com o nome do ficheiro
set ruler " mostra a linha e coluna na statusbar
set title " mostra o nome do ficheiro no titulo do terminal
set smarttab
set wildmode=longest,list " mostra completacoes ao usar o TAB
set showmode
set showcmd " mostra comando incomletos (marcar caracter, etc)
set shortmess=atI " mensagens abreviadas
set autoindent
syntax on " activa as cores para varios tipos de ficheiros
Qualquer destes comandos pode ser introduido na linha de comandos (util para o testar) ou colocado no ficheiro de arranque do vim (~/.vimrc). Podem ver aqui um exemplo mais completo de um ficheiro de configuração, ou puxar as minhas configurações actuais (que têm uma organização um pouco mais complexa =), as quais incluem ficheiros de configuração para o vim e gvim, menus para o ultimo, e mappings para substituição automática de caracteres acentuados pelos códigos HTML equivalentes, usado ao editar ficheiros HTML e PHP.