Dicas e truques do Vim e Ctags [fechados]

485

Acabei de instalar o Ctags (para ajudar no desenvolvimento do C ++) com o meu Vim (ou melhor, com o gVim) e gostaria de descobrir seus comandos, macros, atalhos, dicas favoritos que o acompanham ...

Compartilhe seu melhor arsenal. Quais outros complementos do Vim você recomendaria para C ++ no desenvolvimento do Vim?

EDIT Qual outro complemento você usaria em conjunto com Ctags?

EDIT2 Qual versão do gVim você usa com tags? Isso faz diferença?

EDIT3 Como você aprimora sua experiência de programação para projetos grandes e pequenos?

kenorb
fonte
15
Certifique-se de usar ctags exuberantes (uma implementação moderna) para obter melhores resultados: ctags.sourceforge.net
idbrii
17
Talvez o kev não seja construtivo?
Floyd
27
embora closed as not constructivehá quase dois anos, é tão construtivo para mim
sazary
15
Eu acho que o verdadeiro motivo para encerrar esta pergunta deveria ter sido: "Essa pergunta, apesar de ser extremamente útil, não se encaixa na política de perguntas e respostas do StackOverflow. Deixe que essa pergunta e respostas sejam movidas para o Quora e cresçam nesse site, enquanto continuamos fechando teimosamente. perguntas e respostas".
Diego Pino
2
Entendo por que essa pergunta foi encerrada, dadas as regras do SO. Mas sinalizar uma pergunta> 400 positiva com uma resposta superior a 300 para exclusão é um pouco desagradável, não é?
DevSolar

Respostas:

394

Ctrl+ ]- vá para a definição
Ctrl+ T- Volte da definição.
Ctrl+ W Ctrl+ ]- Abra a definição em uma divisão horizontal

Adicione essas linhas no vimrc
map <C-\> :tab split<CR>:exec("tag ".expand("<cword>"))<CR>
map <A-]> :vsp <CR>:exec("tag ".expand("<cword>"))<CR>

Ctrl+ \- Abra a definição em uma nova guia
Alt+ ]- Abra a definição em uma divisão vertical

Depois que as tags são geradas. Você pode usar as seguintes teclas para marcar e excluir funções:

Ctrl+ Left MouseClick- Ir para a definição
Ctrl+ Right MouseClick- Voltar para a definição

Amjith
fonte
8
C -] => (tecla de controle) e] tecla C - T => (tecla de controle) e tecla T Apenas para iniciantes com tags. Obrigado por truque novo guia
kumar
6
Da mesma forma, depois de dividir a janela, Ctrl-w C-]você pode fazer C-w T(também conhecido como Shift-t) para mudar essa divisão para uma nova guia.
dash-tom-bang
1
@ Will Se você estiver usando o vim no terminal, precisará alterar as preferências do terminal para fazer com que a tecla de opção se comporte como uma tecla alt. Se você estiver usando o MacVim, adicione esta linha ao vimrc 'set macmeta'. Existe documento para macmeta,: h macmeta.
Amjith
17
g C-]é muito útil. Abre uma caixa de diálogo rápida para selecionar uma entre várias definições.
22612 Vincenzo Pii
3
g]também é útil. Você pode posicionar o cursor sobre o nome da marca e pressionar g]para obter uma lista de marcas correspondentes.
Zeekvfu
176

Uma linha que sempre aparece no meu .vimrc:

set tags=./tags;/

Isso procurará no diretório atual "tags" e trabalhará a árvore em direção à raiz até que uma seja encontrada. IOW, você pode estar em qualquer lugar na sua árvore de origem, e não apenas na raiz dela.

uzi
fonte
37
Subir para a raiz é excessivo. Sugiro só vai até casa em vez: etiquetas + = marcas; $ HOME
gotgenes
37
As árvores de origem nas quais trabalho nem sempre estão no meu diretório pessoal ... e sendo que $ HOME tende a estar a dois diretórios da raiz ... bem, posso pagar mais duas pesquisas de diretório. :)
uzi
6
Eu concordo com uzi. Se meu cwd é / home / me / programação / foo / bar / baz / bang / bam, são apenas 8 pesquisas de diretório. Suponho que depende da sua tolerância em relação à velocidade, mas o tempo para procurar no diretório 1 não é visivelmente diferente do 8 na minha máquina.
Nate Murray
1
Depende do seu cenário, preciso usar a sugestão de gotgenes em uma das minhas máquinas, porque existem aproximadamente 8.000 diretórios em / home e isso tende a ser um pouco lento.
jkerian
1
Existe algo semelhante para cscope?
Szx 07/12/12
45

Outro plugin útil para o desenvolvimento de C é o cscope Assim como o Ctags permite ir para as definições, o Cscope pula para as funções de chamada .

Se você possui o cscope em seu diretório ~ / bin /, adicione o seguinte ao seu .vimrc e use g ^] para acessar a função de chamada (consulte: help cscope).

if has("cscope")
    set csprg=~/bin/cscope
    set csto=0
    set cst
    set nocsverb
    " add any database in current directory
    if filereadable("cscope.out")
        cs add cscope.out
        " else add database pointed to by environment
    elseif $CSCOPE_DB != ""
        cs add $CSCOPE_DB
    endif
endif

Quase esqueci ... Assim como ctags - você precisa gerar (e atualizar periodicamente) o banco de dados. Eu uso o seguinte script

select_files > cscope.files
ctags -L cscope.files
ctags -e -L cscope.files
cscope -ub -i cscope.files

Onde 'select_files' é outro script que extrai a lista de arquivos C e de cabeçalho do Makefile. Dessa forma, indexo apenas os arquivos realmente usados ​​pelo projeto.

nimrodm
fonte
Qual é a vantagem do cscope sobre o ctags? Eles se complementam?
Whaledawg 20/02/09
4
Eles se complementam. Ctags encontra a definição de um símbolo ou uma função. O Cscope pode encontrar todos os locais que chamam uma função. o uso de ambos facilita a navegação em grandes árvores de origem.
Nimrodm
1
No entanto, o cscope AFAIK possui uma compreensão limitada de C ++.
21711 Luc Hermitte
É limitado e não muito bom. Mas, para o que faz (saltando para USAGES), não há alternativa melhor. Seu principal problema é que quando você quer saltar para chamadas de função (F), muitas vezes você precisa ir para qualquer lugar que símbolo é utilizado (s) em vez e filtrar os resultados mentalmente ...
Greg Rogers
2
@Whaledawg Sim, quando eu pressiono CTRL +] minha placa de som envia "clap.wav" na saída :) #
Patrizio Rullo
27

Você pode adicionar diretórios à sua pesquisa ctags. Por exemplo, eu tenho um índice ctags criado para o Qt4 e tenho isso no meu .vimrc:

set tags+=/usr/local/share/ctags/qt4
strager
fonte
16

Uso ALT-esquerda e ALT-direita para abrir / enviar de / para a pilha de tags.

" Alt-right/left to navigate forward/backward in the tags stack
map <M-Left> <C-T>
map <M-Right> <C-]>

Se você usar hjklpara o movimento você pode mapear <M-h>e <M-l>em vez disso.

strager
fonte
não é o mesmo que ctrl -] e ctrl-t - acho que sua sugestão é um pouco mais limpa.
@Sha, Perdão? Não sei o que você está dizendo. = X Para observar, isso também funciona em: help.
Strager 19/02/09
2
Eu acho que isso é mais intuitivo e limpo do que o padrão.
Ayman
1
@ Ayman Mas também viola o princípio de não ter que tirar as mãos da homerow, como usar hjkl vs as teclas de seta.
TankorSmash
@TankorSmash, que princípio?
strager
10

Várias definições com o mesmo nome

<C-w>g<C-]>abra a definição em uma divisão, mas também faça o :tjumpque vai para a definição ou, se houver várias definições, apresenta uma lista de definições para você escolher.

Heikki Naski
fonte
2
Semelhante ao primeiro comando, o vim possui um :ptagcomando que abre a definição em uma janela de visualização.
Idbrii
1
A janela de visualização é boa porque você pode fechá-la com: pc a partir de qualquer outra janela, sem precisar primeiro mover o cursor para a janela de visualização.
Heikki Naski
Há também um truque simples do autocmd com ptag, no :h CursorHold-examplequal exibe a tag do item sob o cursor na janela de visualização após um tempo limite configurável.
Dash-tom-bang
+1 para: tjump eu tenho agora ligado: tjump <CR> <Cw> <CR> funciona melhor do que <C -]> imho gostariam de combinar este comportamento com: ptag
Andreas Fliesberg
:helpàs vezes é impressionante ... ver :help CTRL-W_g}e:ptjump
Andreas Fliesberg
8

O comando que estou usando mais é C-], que salta para a definição da função sob o cursor. Você pode usá-lo com mais frequência para acompanhar mais chamadas. Depois disso, Co trará de volta um nível, Ci se aprofundará novamente.

raimue
fonte
16
Ct volta um nível na pilha C-], enquanto Co volta à posição anterior do cursor após um movimento. Portanto, se você C-] em uma função e, em seguida, pagina para baixo, Ct retornará imediatamente enquanto Co retornará ao início da função e, em seguida , retornará à chamada.
22711 Greg Hewgill
6

Encontrei o plug-in de lista de tags obrigatório. Ele lista todas as tags que conhece (arquivos que você abriu) em uma janela separada e facilita a navegação por arquivos maiores.

Eu o uso principalmente para desenvolvimento em Python, mas só pode ser melhor para C / C ++.

Walter
fonte
5

Encapsulei a manipulação de tags em um plugin experimental meu.

Com relação ao desenvolvimento de C ++ no vim, eu já respondi : eu uso meu próprio conjunto e alguns outros plugins.

Luc Hermitte
fonte
4

Coloquei o seguinte no meu arquivo .gvimrc, que procura na árvore a partir de qualquer ponto um arquivo de tags quando o gvim é iniciado:

function SetTags()
    let curdir = getcwd()

    while !filereadable("tags") && getcwd() != "/"
        cd ..
    endwhile

    if filereadable("tags")
        execute "set tags=" . getcwd() . "/tags"
    endif

    execute "cd " . curdir
endfunction

call SetTags()

Em seguida, regenero periodicamente um arquivo de tags na parte superior da minha árvore de origem com um script parecido com:

#!/bin/bash

find . -regex ".*\.\(c\|h\|hpp\|cc\|cpp\)" -print | ctags --totals --recurse --extra="+qf" --fields="+i" -L -
alanwj
fonte
7
Você acabou de reinventar a pesquisa ascendente. Veja: h procura de arquivos. Veja também stackoverflow.com/questions/563616/vimctags-tips-and-tricks/…
gotgenes
2

Eu uso o vim no macos, e as ctags originais não funcionam bem, então faço o download do mais novo e configurei o make make install. Eu instalo o ctgas em / usr / local / bin / ctags (para manter o original)

"taglist
let Tlist_Ctags_Cmd = "/usr/local/bin/ctags"
let Tlist_WinWidth = 50
map <leader>ta :TlistToggle<cr>
map <leader>bta :!/usr/local/bin/ctags -R .<CR>
set tags=tags;/
map <M-j> <C-]>
map <M-k> <C-T>
Zhenyu Li
fonte
1

Adaptei a função de pesquisa SetTags () acima (que deve ser substituída pelo equivalente set tags+=./tags;/) para trabalhar no cscope. Parece funcionar!

"cscope file-searching alternative
function SetCscope()
    let curdir = getcwd()

    while !filereadable("cscope.out") && getcwd() != "/"
            cd ..
                endwhile

    if filereadable("cscope.out")
            execute "cs add " . getcwd() . "/cscope.out"
                endif

    execute "cd " . curdir
    endfunction

call SetCscope()
dergachev
fonte
3
Como disse a gotgenes, você acabou de reinventar a pesquisa ascendente. Veja: h procura de arquivos. Veja este plugin para um exemplo relevante.
Idbrii
1

Outra iteração na função SetCscope () acima. Isso define o pré-caminho do cscope para obter correspondências sem estar no diretório em que "cscope.out" é:

function s:FindFile(file)
    let curdir = getcwd()
    let found = curdir
    while !filereadable(a:file) && found != "/"
        cd ..
        let found = getcwd()
    endwhile
    execute "cd " . curdir
    return found
endfunction

if has('cscope')    
    let $CSCOPE_DIR=s:FindFile("cscope.out")
    let $CSCOPE_DB=$CSCOPE_DIR."/cscope.out"
    if filereadable($CSCOPE_DB)
        cscope add $CSCOPE_DB $CSCOPE_DIR
    endif

    command -nargs=0 Cscope !cscope -ub -R &
endif
saoret.one
fonte
3
Como disse a gotgenes, você acabou de reinventar a pesquisa ascendente. Veja: h procura de arquivos. Veja este plugin para um exemplo relevante.
Idbrii 24/11