sábado, 21 de março de 2009

Convertendo um arquivo com tabs para espaços

Para converter todos tabs em espaços dentro do arquivo primeiro ligue a opção:
:set expandtab

A partir de agora <Tab> irá indentar usando somente espaços.
Porém o texto original ainda tem os tabs dentro dele.
Para converte-los em espaços use:
:%retab
No entanto, todos tabs após um caractere não-branco são mantidos. Se quiser que estes sejam convertidos use:
:%retab!
Isso é um pouco perigoso, porque ele pode converter tabs
dentro de um string de código-fonte de programa.
Use :
/"[^"\t]*\t[^"]*"
para verificar se existe algum caso antes de
modificar.

É recomendado não usar hard tabs dentro de strings. Use '\t' para evitar esses problemas.

Para fazer o inverso use:
:set noexpandtab
:%retab?

Escolhendo se indenta com espaços ou com o tab

O caractere tab foi a primeira solução para espaçamento (nos teletipos e primeiras
console de computador). E com o tamanho de 8 espaços.
Os dispositivos que se seguiram mantiveram esse tamanho por questão de
compatibilidade.

No entanto, para os programadores, esse espaçamento se mostrou excessivo no
código-fonte dos programas.

Assim para conciliar esses dois fatos há 3 possibilidades:

1. Usar uma combinação de espaços e tabs. Assim se você precisa de uma indentação de 12, use um tab(8) e mais 4 espaços.
2. Dizer para o computador que o tab tem tamanho de 4 usar tab em todos lugares.
Essa é a opção não é recomendada, pois se o texto for para uma máquina com o tamanho padrão ele parecerá super-indentado.
3. Ignorar totalmente os tabs e só usar espaços para indentar.

O Vim suporta qualquer uma das 3 possibilidades.

Para usar a combinação de espaços e tabs, defina:
:set softtabstop=4
Agora, ao pressionar <Tab> o Vim irá inserir 4 espaços no primeiro nível de
indentação, um <Tab> no segundo, um <Tab> e quatro espaços no terceiro e assim
por diante.
Adicionalmente ligue a opção:
:set smarttab
Que irá inserir espaços e tabs de acordo com o valor de 'shiftwidth' no início da linha
quando for pressionado o <Tab>.

Para usar um tab com tamanho diferente (4 por exemplo) use a opção:
:set tabstop=4
o problema é que cada programa (e computador) tem seu valor para o tab.

Para ignorar o uso de tabs dentro do arquivo, ligue a opção:
:set expandtab
A partir de agora, cada <Tab> pressionado irá ser expandido para uma série de
espaços (conforme softtabstop e shiftwidth).
Note que se o arquivo já contém tabs, eles não convertidos automaticamente. Use
o comando:
:retab
para esse intento.

Inserindo e removendo indentação de texto

O Vim possui vários comandos para indentar textos.
A indentação a esquerda ou a direita é feita baseada no número de caracteres declarados em 'shiftwidth'.

No modo inserção use:
<Ctrl-T> 
insere uma indentação.
<Ctrl-D> 
deleta uma indentação.

No modo normal use para inserir uma indentação e 5 indentações:
>>
5>>
Para remover uma indentação:
<<
Como '<' e '>' são operadores, então eles podem ser combinados com objetos texto.
>i}
indenta o conteúdo de um bloco {}. Os separadores não são indentados.
>a}
faz o mesmo, mas inclui os separadores.

Indentando no estilo C alternativo

Use:
:set smartindent
Funciona com programas no formato C, mas pode também ser usados por outras linguagens.
Parece com 'cindent', porém o 'cindent' funciona melhor na maioria dos casos embora seja mais restrita.
É mais inteligente que 'autoindent'.

Normalmente, 'autoindent' deveria ser usada junto com 'smartindent'.

Uma indentação automática ocorre :
Depois de uma linha terminando com '{'.
Depois de uma linha começando com uma palavra-chave em 'cinwords'.
Antes de uma linha começando com '}'. (somente com o comando 'O').

Linhas que começam com '#' tem sua indentação removida. Isto é para que as diretivas do pré-processador comecem todas na linha 1. A indentação é restaurada na próxima linha.

Opção para customizar o estilo de indentação

O estilo default de indentação do vim atende a maioria dos casos.
Mas se quiser criar um estilo especial de indentação use a opção:
:set cinoptions
A opção afeta o modo como a opção 'cindent' re-indenta linhas em C.

Por default a opção é vazia e o estilo default do vim é usado.

Por exemplo:
:set cinoptions+={2
coloca as chaves de abertura,'{', 2 posições da indentação corrente.
if (flag) 
{
i = 8;
j = 0;
}

sexta-feira, 20 de março de 2009

Indentando linhas usando um filtro ou indentação C

Para indentar através de um programa externo (filtro) ou, se este não existir, usando a
indentação interna 'C-indenting' (default) use:
={movimento}
Exemplo:
Posicione o cursor na área a ser indentada.
=30G
indenta do cursor até a linha 30 seguinte o estilo C.

O mesmo que o '=', só que passando o número de linhas a serem indentadas:
{contagem}==
Exemplo:
5==
indenta as 5 linhas a partir do cursor.

Indentando uma seleção visual no estilo C:
VVV
=
3 linhas indentadas.

Indentando com um objeto-texto (o bloco {} corrente) com o estilo C:
=a{
Indentando o arquivo inteiro:
gg=G
Cuidado com esse comando caso você tenha indentado manualmente em certos lugares.

Benefício da indentação automática.

Além de facilitar a visualização, ela ajuda a pegar erros.

Se voce finalizar uma função com '}' e a indentação automática der mais indentação do que o esperado, existe a possibilidade de um '}' faltando.

Use o comando '%' para achar qual '{' corresponde ao que foi digitado '}'.
Um ')' e ';' pode causar indentação extra.

Indentando no estilo C

É um tipo de indentação automática estilo C (C++, Java)
Use a opção:
:set cindent
defina a quantidade de indentação mais interna com 'shiftwidth':
:set cindent shiftwidth=4
A partir disso, quando for digitando a próxima linha será indentada de acordo.

Para ativar essa indentação automaticamente coloque o seguinte no vimrc:
:filetype on
:autocmd FileType c,cpp :set cindent
O primeiro comando faz o vim detectar tipos de arquivo. O segundo ativa a
indentação se o tipo do arquivo é c ou cpp.

Essa opção é sobreposta por 'indentexpr', e sobrepõe 'autoindent' e 'smartindent'.

Redirecionando as mensagens de erro do compilador

O comando ':make' redireciona a saída do programa executado para um arquivo de erro (por default, um arquivo temporário gerado automaticamente).
Isto depende de várias coisas tais como 'shell'.

Se o comando ':make' não captura a saída, verifique as opções 'makeef' e 'shellpipe'.

Caso não consiga redirecionar a saída para um arquivo, compile o programa em uma outra janela e redirecione a saída para um arquivo.

Então, leia o arquivo com :
:cfile {filename}
O salto para os erros será o mesmo do comando ':make'.

Usando plugin de compiladores

Se estiver usando vários compiladores a definição das opções 'makeprg' e especialmente 'errorformat' pode ser difícil.
O vim oferece um método mais simples : plugin de compilador.

Por exemplo, para o compilador 'msvc' carrega o plugin com:
:compiler msvc
O vim localizará o script do compilador 'msvc' e definirá as opções apropriadas.

Vários plugins de compilador estão no diretório:
$VIMRUNTIME/compiler/*.vim

Opção para descrever o formato das mensagens de erro do compilador.

Após mudar o compilador que o vim chamará ('makeprg') é preciso dizer o formato
das mensagens de erro que ele produz.

Use:
:set errorformat={string},{string},...
para isso.
O string é uma mensagem de erro típica com o caractere '%' usado para
identificar operações especiais (como scanf do C):
%f       Nome do arquivo
%l Número da linha
%c Coluna
%t Tipo de erro (um único caractere)
%n Número do erro
%m Mensagem de erro
%r Corresponde ao resto da linha
%*{char} Corresponde (e pula) qualquer conversão scanf especificada por {char}.
%% O caractere %
Quando se está compilando um programa, você pode atravessar vários diretórios.
O programa GNU 'make' imprime uma mensagem quando ele entra e sai de um diretório.
Para obter o nome do arquivo correto, o Vim precisa estar consciente desta
mudança.
As seguintes especificações de formato são usadas para avisar o Vim sobre
mudanças de diretório:
%D Especifica uma mensagem impressa ao entrar em um diretório. 
O %f neste string indica o diretório entrado.
%X Especifica a mensagem de saída do diretório. O %f neste string especifica o
%diretório que o make passou.
Alguns compiladores, tais como o GNU GCC imprime mensagens de erro muito
verbosas.
Eis um exemplo de mensagem de uma variável não declarada:
tmp.c: In function `main’:
tmp.c:3: 'i' undeclared (first use in this function)
tmp.c:3: (Each undeclared identifier is reported only once
tmp.c:3: for each function it appears in.)
Se você usar o 'errorformat' default, isto resulta em três mensagens
de erro. Isto é realmente desagradável. Felizmente, o editor Vim reconhece
mensagens de erro multilinha.
Os códigos de formato para mensagens de erro multilinhas são:
%A   Início de uma mensagem multilinha (tipo não especificado)
%E Início de uma mensagem de erro multilinha
%W Início de uma mensagem de aviso multilinha
%C Continuação de uma mensagem multilinha
%Z Fim de uma mensagem multilinha
%G Global; útil somente em conjunto com + ou -
%O Mensagem de arquivo de uma linha: examina a parte identificada
%P Mensagem de arquivo de uma linha: coloca o arquivo %f em cima da pilha
%Q Mensagem de arquivo de uma linha: retira a última mensagem da pilha
Um + ou - pode preceder quaisquer uma das letras. Isto significa o seguinte:
%-letter   Não inclui a linha identifica em qualquer saída.
%+letter Inclui a linha inteira identificada no string de erro %m.
Eis um exemplo de definição do formato de uma mensagem de erro multilinha.

Comece definindo a mensagem inicial.
Essa mensagem corresponde à definição:
tmp.c:3: ‘i’ undeclared (first use in this function)
%E%f:%l:\ %m\ undeclared\ (first\ use\ in\ this\ function)
Note o uso de '\' para dizer ao Vim que o espaço é parte do string. Agora você
tem um problema. Se você usar esta definição, o '%m' irá identificar somente 'i'.
Você quer uma mensagem de erro mais longa. Assim você usa '+' para fazer o Vim
por a linha inteira na mensagem:
%+E%f:%l:\ %m\ undeclared\ (first\ use\ in\ this\ function)
O meio corresponde a isto:
tmp.c:3: (Each undeclared identifier is reported only once
%-C%f:%l:\ (Each\ undeclared\ identifier\ is\ reported\ only\ once
Note o uso do modificado '-' para manter a mensagem fora da lista de mensagens.

O fim do erro é o seguinte:
tmp.c:3: for each function it appears in.)
%-Z%f:%l:\ for\ each\ function\ it\ appears\ in.)
Assim você adiciona estas três linhas para o formato do erro:
%+E%f:%l:\ ‘%*\k*’\ undeclared\ (first\ use\ in\ this\ function),
%-C%f:%l:\ (Each\ undeclared\ identifier\ is\ reported\ only\ once,
%-Z%f:%l:\ for\ each\ function\ it\ appears\ in.)
Isto funciona, mas tem um pequeno problema. Quando o compilador GNU encontra a
segunda variável indefinida, ele não imprime a mensagem de 3 linhas. Ao invés,
ele só imprime a primeira linha. (ele imagina que você já viu as coisas dentro
dos parenteses, assim não tem porque imprimir de novo).

Infelizmente, sua especificação de erro tenta localizar as três linhas.
Portanto, você precisa de uma técnica diferente. A solução é dizer ao Vim para
esquecer sobre as segundas duas linhas:
%-G%f:%l:\ (Each\ undeclared\ identifier\ is\ reported\ only\ once
%-G%f:%l:\ for\ each\ function\ it\ appears\ in.)
Agora você precisa adicionar esta opção para seu arquivo vimrc. Você
adiciona-las sobre a opção 'errorformat' usando o seguinte comando:
“ Isto não irá funcionar
:set errorformat+=
\%-G%f:%l:\ (Each\ undeclared\ identifier\ is\ reported\ only\ once,
\%-G%f:%l:\ for\ each\ function\ it\ appears\ in.)
Note que no Vim, linhas de continuação começam com '\'.Além disso, você
acrescenta uma vírgula entre as mensagens de erro.
No entanto, essa técnica não funciona pois o Vim percorre a lista de strings do
'errorformat' em sequencia, parando na primeira que acha.
O string de erro do compilador GNU (%f:%l:%m) é localizado primeiro, e portanto
você não obtém as suas duas novas mensagens de erro. Você precisa por as
ocorrências mais específica (suas duas novas mensagens) no início.
Isto é realizado com:
" Isto irá funcionar
:set errorformat ^=
\%-G%f:%l:\ (Each\ undeclared\ identifier\ is\ reported\ only\ once,
\%-G%f:%l:\ for\ each\ function\ it\ appears\ in.)
Lembre, o comando set ^= irá adicionar um string no início da lista.

Abrindo uma janela de preview com uma tag automaticamente.

Esse exemplo do help do vim faz uso do evento CursorHold. Coloque o código no .vimrc e recarregue.

Após um certo tempo sem mover o cursor o comando ':ptag' é executado na palavra sob o cursor. Se não existir tag nada ocorre.
Será aberta uma janela de preview com a primeira ocorrência da palavra. A ocorrência será colorizada.

:au! CursorHold *.[ch] nested call PreviewWord()
:func PreviewWord()
: if &previewwindow " don't do this in the preview window
: return
: endif
: let w = expand("") " get the word under cursor
: if w =~ '\a' " if the word contains a letter
:
: " Delete any existing highlight before showing another tag
: silent! wincmd P " jump to preview window
: if &previewwindow " if we really get there...
: match none " delete existing highlight
: wincmd p " back to old window
: endif
:
: " Try displaying a matching tag for the word under the cursor
: try
: exe "ptag " . w
: catch
: return
: endtry
:
: silent! wincmd P " jump to preview window
: if &previewwindow " if we really get there...
: if has("folding")
: silent! .foldopen " don't want a closed fold
: endif
: call search("$", "b") " to end of previous line
: let w = substitute(w, '\\', '\\\\', "")
: call search('\<\V' . w . '\>') " position cursor on match
: " Add a match highlight to the word at this position
: hi previewWord term=bold ctermbg=green guibg=green
: exe 'match previewWord "\%' . line(".") . 'l\%' . col(".") . 'c\k*"'
: wincmd p " back to old window
: endif
: endif
:endfun

Vendo listas de erros de compilação ou grep anteriores

Se quiser ver uma lista de erros gerada por um ':make' ou ':grep' anterior use:
:colder
a lista é retornada.

Use :
:clist
:cc numero
para saltar para a linha que gerou a mensagem.

Para ir para a próxima lista de erros :
:cnewer
O vim guarda até 10 listas de erros.

Opção para definir o compilador que será chamado pelo ':make'

O comando ':make' irá chamar um compilador.

A opção:
:set makeprg
define qual comando.

O valor default é o programa de shell 'make'.

Visual C++:
: set makeprg=nmake

Usando argumentos, que deve ser escapados:
:set makeprg=nmake\ −f\ project.mak
Podem ser incluídas palavras-chave do vim, '%' expande o nome do arquivo corrente:
:set makeprg=make\ %
Se estiver editando o arquivo 'main.c', o comando ':make' com 'makeprg' default fará:
make main.c
o que não será de utilidade.

Refine o comando e use o modificador :r (root):
:set makeprg=make\ %:r.o
Agora o comando a ser executado será:
make main.o

Percorrendo as mensagens de erro do compilador dentro do Vim

Após compilar um programa dentro do Vim (usando :make) e retornado uma listagem
de erros, você pode percorrer os erros com os seguintes comandos:
Vendo a próxima mensagem de erro:
:cnext
Vendo a mensagem de erro anterior:
:cprevious
Vendo a primeira mensagem:
:cfirst
Vendo a última mensagem:
:clast
Vendo todo texto da primeira mensagem de erro:
:cc
Vendo todo texto de um mensagem de erro específica:
:cc 3
Vendo a lista de mensagens:
:clist
somente as mensagens que o vim reconhece um nome de arquivo e linha são mostradas.
Para mostrar todas mensagens (tais como erros do linker sobre uma função indefinida) use:
:clist!

Compilando um programa dentro do vim

O Vim tem um conjunto de comandos chamados de 'quick-fix mode'. Eles permitem
editar o fonte, chamar o compilador e percorrer os erros gerados para
corrigi-los tudo dentro do Vim.

O comando:
:make {argumentos}
no valor default, irá chamar o comando 'make' no shell e capturar os resultados.
Se houver erro, o vim abre o arquivo e posiciona na linha que ocorreu o primeiro erro.

O programa externo a ser usado para compilar é definido na opção:
:set makeprg
A listagem de erros é retornada para o Vim. Para ir para cada uma delas use o comando:
:cnext

quinta-feira, 19 de março de 2009

Saltando para a definição de uma variável (local) dentro do programa C

O comando '[I' pesquisa nos arquivos de include.
Para pesquisar somente dentro do arquivo corrente e saltar para a primeira ocorrência da palavra sob o cursor use:
gD
(goto Definition) Esse comando é útil para localizar uma variável ou função que foi declarada localmente ('static' em termos C).
gd
- procura somente dentro da função corrente.
O Vim tem limitado entendimento da sintaxe de C e C++, por exemplo, ele errará
se você pedir a declaração local de uma variável global. Mas, na maioria das
vezes, ele funciona bem.

Opção para definir como é uma definição de macro C

Use:
:set define={regex}
A opção define qual o regex será usado para procurar a definição. Usado por comandos como '[D'.
O default é adequado para a linguagem C:
'^\s*#\s*define'
A opção 'isident' é usada para descobrir como é o nome da macro após ser obtida uma ocorrência de 'ident'.

Para outras linguagens, a opção deve ser alterada.

Procurando definições de macros C

Use o comando:
[D
para listar todas definições da macro C debaixo do cursor.
A pesquisa começa a partir do início do arquivo.

A pesquisa usa os arquivos incluídos também.
A opção 'define' define como é um macro definição.

[d - lista somente a primeira ocorrência.
]D - lista somente itens abaixo do cursor.
]d - lista somente o primeiro item abaixo do cursor.

quarta-feira, 18 de março de 2009

Pesquisando uma palavra dentro do arquivo e nos includes

Para procurar a primeira ocorrência da palavra sob o cursor. A pesquisa começa a
partir do início do arquivo. Texto de comentários são ignorados:
[i
O mesmo que '[i', mas a partir da posição do cursor:
]i
Para listar todas ocorrências de uma palavra sob o cursor existente em includes e no arquivo corrente, mostrando somente a linha aonde ocorre.
[I
Para ver todo arquivo, anote o número da ocorrência e use:
numero[<Tab>
o vim saltará para esse item da lista.

Lembre que voce pode voltar ao ponto inicial com <Ctrl-O>.

Listando os includes achados ou não pelo vim

O vim busca os arquivos de include nos diretórios da opção 'path'.

Com o comando
:checkpath
voce obtém uma lista de arquivos que não puderam ser localizados. Incluindo arquivos incluídos por arquivos include localizados.

Note que o vim não trata os comandos condicionais de compilador (#ifdef).

Para corrigir isto adicione um diretório à opção 'path'.
Um bom local para achar isso é o Makefile, procure linhas com '-I'.

:checkpath!
lista todos includes achados e não achados no 'path' do vim.

Opção para definir como é um diretiva include

Use:
:set include=
O valor default '^\s*#\s*include' é adequado para programas C.
A opção 'isfname' é usada para reconhecer o nome do arquivo após o include.

Pesquisando por um identificador dentro de um programa e de seus includes

Você está editando um programa C e quer saber se uma variável é declarada como "int" ou "unsigned".
Um modo rápido é posicionar o cursor na palavra e usar:
[I

O vim listará todas as linhas em que a palavra aparece. Não só do arquivo corrente mais como de todos arquivos incluídos (e os arquivos incluídos dentro destes, etc).

A vantagem sobre usar tags e janelas de preview é que os arquivos incluídos são pesquisados. Na maioria dos casos resulta em achar a declaração correta. Além de evitar tags files desatualizados ou inexistentes.

Todavia, a opção 'include' deve especificar como um arquivo é incluído. O valor default funciona com C ou C++.

Para outras linguagens ele deve ser mudado.

Outros comandos de pesquisa em includes:
[i
- somente lista a primeira ocorrência.
]I
- somente lista itens abaixo do cursor.
]i
- somente lista o primeiro item abaixo do cursor.

Saltando para demarcadores de comentários C

Salta para o ínicio de um comentário C anterior:
[/ ou
[*

Salta para o fim de uma comentário C seguinte:
]/ ou
]*

Saltando para parenteses

Vai para o '(' anterior correspondente:
[(

Vai para o ')' seguinte correspondente:
])

terça-feira, 17 de março de 2009

Saltando para os delimitadores de blocos

Blocos em C são agrupados dentro de {}. Eles podem ser longos demais para serem percorridos.

Use esses comandos para saltar para os delimitadores:
Isto assume que '{' e '}' estão na coluna 1.

Salta para o '{' do bloco mais externo:
[[
Salta para o '}' do bloco mais externo:
][
Agora os blocos internos.
Salta para o '{' do bloco corrente:
[{
Salta para o '}' do bloco corrente:
]}
Em C++ ou Java, o bloco mais externo é o corpo da classe. O próximo nível é para métodos.
Em qualquer lugar dentro de uma classe use :
[m
para saltar para o início de método anterior.
]m
para saltar para o início de método posterior.

Para saltar para o delimitadores [],() e {}, delimitadores de comentários
C (/*.*/) e diretivas condicionais de macro-C (#if, #else, #endif):
%

Saltando para uma instrução condicional de pré-processador C

[# - salta para #if ou #else anterior.
]# - salta para #else ou #endif seguinte.

A janela de preview

Uma janela de preview é uma janela especial usada para mostrar outro arquivo.
É uma pequena janela usada para mostrar um include file ou uma definição de função.

Esses comandos (e outros) criam a janela de preview:
:ptag tag
ctrl-w }
:psearch /padrão

Opção para especificar a altura da janela de preview

Use:
set previewheight n
Altura default (12) da janela de preview. Usado com ':ptag' e 'Ctrl-w {'.

Usando uma janela de preview para ver definições no código-fonte

Se você estiver editando código que tem uma chamada de função, você precisa usar os argumentos corretos.
Para isso é útil olhar a definição da função.
Um modo de fazer isso é posicionando no nome da função e chamando o comando:
<Ctrl-]>
No entanto, o arquivo original desaparece pelo aparecimento do arquivo com a
definição.
O melhor jeito é usando uma janela de preview. Uma janela nova que se abre com o
comando:
:ptag nome-da-função
O vim abrirá uma janela, e salta para a definição da função. Então o Vim volta para a janela e posição original.
Assim pode continuar digitando sem necessidade de usar o comando <Ctrl-W>.

Se o cursor estiver sobre o nome da função, basta digitar:
<Ctrl-W>}
Para fechar a janela de preview:
:pclose
<Ctrl-W>z
Há uma série de comandos para manipular o arquivo na janela de preview.
Para fazer um ':pop' na janela de preview:
:ppop
Para abrir a janela de preview e fazer um ':tselect':
:ptselect {identificador}
Para abrir a janela de preview e fazer um ':tjump':
:ptjump {identificador}
Para fazer um ':tnext' na janela de preview:
{contagem}:ptnext
Para fazer um ':tprevious' na janela de preview:
Para edit um arquivo na janela de preview:
:pedit defs.h
útil para header files.

Para achar uma palavra no arquivo corrente e em qualquer arquivo incluído e mostrar a ocorrência na janela de preview. Isto é útil para funções de biblioteca, para as quais você não tem um tags file.

Usando Cscope para gerar tags para programas C

Cscope é como o programa ctags mas gera muito mais informações.
Ele so funciona com fontes C.

Opção para ativar pesquisa binária para tags

Use:
:set tagbsearch (é o default)
Se o tags files está ordenado, usando pesquisa binária localiza mais rapidamente as tags.
:set notagbsearch
Se o tags files não está classificado, o vim deve usar pesquisa linear.

Definindo um valor de opção específico para um janela ou buffer

Use:
:setlocal ...

É igual a ':set' exceto que define somente o valor localmente para uma janela ou buffer. Nem todas opções tem valor local, nesse caso o valor global é definido.

:setlocal all
mostra todos valores das opções locais.

:setlocal
mostra todos valores das opções locais que são diferentes do default.

segunda-feira, 16 de março de 2009

Criando um browser de tags

Como o comando 'ctrl-]' leva para a definição de um identificador sobre o cursor, pode-se fazer uma lista de identificadores como se fosse um índice.

Primeiro crie a lista de identificadores com o programa ctags:
ctags -R --c-kinds=f -f functions *.c
serão geradas tags para funções C e o tags file irá para o arquivo 'functions'.

Agora inicie o vim sem arquivo, e edite o arquivo functions no vim, em uma janela dividida verticalmente:
vim
:vsplit functions
A janela contém uma lista de todas funções. Existe outras coisas que podem ser ignoradas.
Faça um ':setlocal ts=90' para limpar um pouco.

Defina um mapeamento nesta janela:
:nnoremap <buffer> <CR> 0ye<C-W>w:tag <C-R>"<CR>
Agora pressionando <enter> sobre uma tag (nome de função) fará o vim saltar para outra janela com a definição da função.

Autocompletando uma tag

Use o autocompletar da linha de comando:
:tag write_<tab>
Aparece a primeira ocorrência. Se tiver com a opção 'wildmenu' ligada as tags seguintes aparecem rodapé da tela.
Repita até encontrar a tag.

Se for necessário use um regexp, por exemplo, para achar tags com a palavra 'block' em qualquer parte da palavra:
:tag /block<tab>
irá listar todas tags com 'block'.
:tselect /^block<tab>
localiza todas tags que começam com 'block'.

Listando as tags de uma palavra

Use:
:tselect {palavra}
mostra a lista de ocorrências de tags de uma palavra.
Se for omitida a palavra, o última taga saltada (a última da pilha de tags) é usada.
A palavra pode ser uma regexp, bastando prefixar com '/'.

Digite o número da tag para saltar para lá.
Para fazer um ':tselect' com a palavra sob o cursor use:
g]
Para listas as tags como ':tselect', porém saltar automaticamente caso haja
apenas uma use:
:tjump
Para fazer o mesmo com a palavra sob o cursor use:
g <CTRL-]> 

Criando um tags file único

Se o vim tiver que procurar tags files em diversos diretórios, a pesquisa poderá ficar lenta devido ao intenso acesso ao disco.
Neste caso, é melhor gerar um único tags file englobando todo sub-diretórios.
Use :
cd ~/proj
ctags -R .
Se a geração demorar, rode de madrugada.

Agora diga ao vim para usar aonde está o tags file:
:set tags=~/proj/tags

Opção para definir quais diretórios o Vim deve buscar arquivos de tag

Quando os arquivos-fonte estão em vários diretórios, você pode criar um tags file em cada um deles.
O Vim será capaz de saltar somente para as tags que estão dentro deles.

Para usar múltiplos tags file use a opção 'tags':
:set tags=./tags,./../tags,./*/tags
isso fará o Vim procurar tags files no mesmo diretório do arquivo corrente, no diretório acima e em todos subdiretórios.

Isso não pode ser suficiente, se por exemplo precisar de um tags file que está em um diretório ("~/proj/sub/tags") que não é sub-diretório do diretório corrente ("~/proj/src").
Se ambos tiverem mesmo pai ("~/proj") pode-se dizer ao vim para pesquisar a árvore inteira de diretórios:
:set tags=~/proj/**/tags

domingo, 15 de março de 2009

Saltando para uma tag e criando um nova janela

Se quiser ver tanto o uso de uma função como a definição (tag) divida a tela usando:
:stag nome-da-tag
ou:
ctrl-w ]

Mostrando a lista de tags que foram saltadas

Use:
:tags

Saltando para uma tag

Após criar um tag file, você pode saltar para a primeira da tag da palavra:
:tag palavra

Ou se a palavra está sobre o cursor use:
<Ctrl-]>
Pode haver mais ocorrências, salte com para elas com ':tnext, tprevious, etc'.

Se e {palavra} for precedida de um '/' é um regexp, caso contrário é tratado literalmente.
O comando irá descobrir a função mesmo que ela esteja em outro arquivo.

Criando tags para localizar identificadores dentro de programas

Uma tag é um local aonde um identificador é definido. Por exemplo uma definição de uma função em C ou C++.

Uma lista de tags é mantida em um arquivo de tags (tags file).
Isto pode ser usado pelo vim para saltar para o local aonde a tag aponta, por exemplo , na definiçao da função.

Para gerar o tags file para todos arquivos C no diretório corrente, use no terminal:
ctags *.c
'ctags' é um programa separado que a maioria das distribuições unix tem.
O arquivo gerado, tags file, deverá estar em um dos diretórios da opção 'tags'.
Instale no Ubuntu com:
apt-get install exuberant-ctags
Se não estiver no repositório ou a versão nao é mais a rencente baixe o programa Exuberant Ctags daqui:
http://ctags.sf.net
O ctags reconhece vários tipos de arquivo além do C ou C++ (Eiffel, scripts vim, etc).