Ir para a definição de função no vim


241

Como posso pular para uma definição de função usando o vim? Por exemplo, com o Visual Assist, posso digitar Alt+ gem uma função e ele abre um menu de contexto listando os arquivos com definições.

Como posso fazer algo assim no vim?


2
GNU global é melhor que ctags.
Jichao

6
@Jichao, você pode nos dar um pouco mais de insight sobre sua experiência? Com quais idiomas o gnu global funcionou melhor para você? Há mais alguma coisa sobre o contexto que você preferiu, que eu seja importante? Ou talvez você o tenha usado em muitos cenários diferentes e pareça preferir principalmente / sempre? O que você mais gosta nisso? Obrigado.
still_dreaming_1

@Jichao Transformei seu comentário em uma resposta do wiki da comunidade. Gostaria de receber suas alterações e sugestões para esta resposta.
still_dreaming_1

Respostas:


213

Use ctags. Gere um arquivo de tags e informe ao vim onde ele está usando o comando: tags. Então você pode simplesmente pular para a definição da função usando Ctrl-]

Existem mais dicas e truques de tags nesta pergunta .


2
O php é parecido com o C, para que "tags exuberantes" funcionem com ele. Não sei se ele tem um modo python.
21139 Paul Tomblin

5
Nenhuma experiência com o Cscope. O que é é?
Paul Tomblin

10
A semelhança com C não tem nada a ver com CTags suporta PHP. Ele suporta PHP, bem como Python. Dê uma olhada em ctags.sourceforge.net/languages.html para ver o suporte completo.
data

1
como faço para gerar ctags?
dwaynemac

4
seria ótimo obter uma referência de onde é melhor aprender como operar essas tags.
FZS2

137

Se tudo estiver contido em um arquivo, existe o comando gd(como em 'goto definition'), que o levará à primeira ocorrência no arquivo da palavra sob o cursor, que geralmente é a definição.


1
e se eu não tiver a palavra sob o cursor (prefiro digitá-la)?
Fuad Saud 16/01

@FuadSaud basta procurá-lo usando/
LucasB 5/14

6
/quase sempre não é preciso, pois corresponderá a todas as ocorrências. Eu descobri que você pode realmente fazer :tag <function_name>para pular para a definição via ctags.
Fuad Saud

O recurso @Faud Jump To Definition baseia-se em apontar um identificador com um cursor (em todo IDE). Digitar / pesquisar é outro recurso, você os confunde.
sangrento

101

g* faz um trabalho decente sem a criação de ctags.

Isto é, tipo g, *(ou apenas *- veja abaixo) para procurar a palavra sob o cursor (neste caso, o nome da função). Em seguida, pressione npara ir para a próxima ocorrência (ou Shift- npara a anterior).

Ele não pula diretamente para a definição, já que esse comando apenas procura a palavra sob o cursor, mas se você não deseja lidar com a configuração de ctags no momento, pode pelo menos evitar que precise -tipo o nome da função para procurar sua definição.

--Edit-- Embora eu esteja usando g * há muito tempo, descobri recentemente dois atalhos para esses atalhos!

(a) *pulará para a próxima ocorrência da palavra sob o cursor. (Não é necessário digitar o gcomando 'goto' no vi).

(b) #vai para a ocorrência anterior, de maneira semelhante.

N e n ainda funcionam, mas '#' geralmente é muito útil para iniciar a pesquisa inicialmente na direção inversa, por exemplo, ao procurar a declaração de uma variável sob o cursor.


10
A diferença entre *e g*é o limite de palavras na pesquisa. *faz uma \<keyword\>pesquisa (igual à da expressão \bkeyword\bregular regular), enquanto g*procura keywordsem limites de palavras.
Nicolai S

se você tiver cem ocorrências de uma função em um arquivo, *levará em média 50 ocorrências antes de encontrar a definição.
precisa saber é o seguinte

49

Use gdou gDenquanto coloca o cursor em qualquer variável do seu programa.

  1. gd levará você à declaração local.
  2. gD levará você à declaração global.

mais opções de navegação podem ser encontradas aqui .

Use cscope para fazer referência cruzada a projetos grandes, como o kernel do linux.


14

Como Paul Tomblin mencionou, você deve usar ctags . Você também pode considerar o uso de plug - ins para selecionar um apropriado ou para visualizar a definição da função no cursor. Sem os plugins, você terá dor de cabeça ao tentar selecionar um dos métodos 'doAction' sobrecarregados, pois o suporte a ctags não leva em consideração o contexto - apenas um nome.

Além disso, você pode usar o cscope e sua função 'find global symbol'. Mas seu vim precisa ser compilado com o suporte do + cscope, que não é o padrão para uma opção de compilação.

Se você souber que a função está definida no arquivo atual, poderá pressionar as teclas 'gD' no modo normal para pular para a definição do símbolo sob o cursor.

Aqui está o plug-in mais baixado para navegação
http://www.vim.org/scripts/script.php?script_id=273

Aqui está um que eu escrevi para selecionar o contexto enquanto pula para tag
http://www.vim.org/scripts/script.php?script_id=2507


Olá @ mykola-golubyev, o link fornecido na Detailed descriptionseção de #2507script está quebrado. Você pode fornecer outro, por favor?
FelikZ #

12

Outra técnica comum é colocar o nome da função na primeira coluna. Isso permite que a definição seja encontrada com uma pesquisa simples.

int
main(int argc, char *argv[])
{
    ...
}

A função acima pode ser encontrada /^maindentro do arquivo ou :grep -r '^main' *.cem um diretório. Desde que o código seja recuado adequadamente, a única vez que o identificador ocorrerá no início de uma linha será na definição da função.

Claro, se você não estiver usando ctags a partir deste ponto, você deve ter vergonha de si mesmo! No entanto, acho esse padrão de codificação uma adição útil também.


13
Eu sempre me perguntei por que alguns codificadores escrevem suas assinaturas dessa maneira!
Tarrasch

Além disso, quando você escreve suas assinaturas de funções, incluindo '{' na primeira coluna, você pode mover-se rapidamente para cada função pressionando]] para avançar no arquivo e [[para retroceder.
BentChainRing 23/03

12

TL; DR:

A maneira moderna é usar o COC para conclusão do tipo intellisense e um ou mais servidores de linguagem (LS) para salto para definição (e muito mais). Para ainda mais funcionalidades (mas não é necessário para a definição de salto), você pode instalar um ou mais depuradores e obter uma experiência IDE completa. Começo rápido:

  1. instale o vim-plug para gerenciar seus plug-ins VIM
  2. adicione COC e (opcionalmente) Vimspector na parte superior de ~/.vimrc:
    call plug#begin()
    Plug 'neoclide/coc.nvim', {'branch': 'release'}
    Plug 'puremourning/vimspector'
    call plug#end()
    
  3. ligue :source $MYVIMRC | PlugInstallpara baixar plug-ins do VIM
  4. reinicie vime ligue :CocInstall coc-marketplacepara obter acesso fácil às extensões COC
  5. ligue :CocList marketplacee pesquise servidores de idiomas, por exemplo:
    • digite pythonpara encontrar coc-jedi,
    • digite phppara encontrar coc-phpls, etc.
  6. (opcionalmente) veja install_gadget.py --helppara depuradores disponíveis, por exemplo:
    • ./install_gadget.py --enable-python,
    • ./install_gadget.py --force-enable-php, etc.

Resposta completa:

O servidor de idiomas (LS) é um aplicativo independente separado (um para cada linguagem de programação) que é executado em segundo plano e analisa todo o seu projeto em tempo real, expondo recursos extras ao seu editor (qualquer editor, não apenas vim). Você obtém coisas como:

  • conclusão de marca com reconhecimento de namespace
  • pule para a definição
  • pule para o erro seguinte / anterior
  • encontre todas as referências a um objeto
  • encontre todas as implementações de interface
  • renomear em todo o projeto
  • documentação em foco
  • snippets, ações de código, formatação, fiapos e muito mais ...

A comunicação com os servidores de idiomas ocorre através do LSP ( Language Server Protocol ). Ambos nvime vim8(ou superior) suportam LSP através de plug-ins, sendo o mais popular o Conquer of Completion (COC).

A lista de servidores de idiomas desenvolvidos ativamente e seus recursos está disponível no site do Lang Server . Nem todos são fornecidos por extensões COC. Se você deseja usar um desses, você pode escrever uma extensão do COC ou instalar o LS manualmente e usar a combinação dos seguintes plug-ins do VIM como alternativa ao COC:

A comunicação com depuradores ocorre através do DAP ( Debug Adapter Protocol ). O plug-in DAP mais popular para o VIM é o Vimspector .

O LSP ( Language Server Protocol ) foi criado pela Microsoft para o Visual Studio Code e lançado como um projeto de código aberto com uma licença MIT permissiva (padronizada pela colaboração da Red Hat e Codenvy). Mais tarde, a Microsoft lançou também o DAP ( Debug Adapter Protocol ). Qualquer idioma suportado pelo VSCode é suportado no VIM.

Eu, pessoalmente, recomendo o uso de servidores de idiomas COC + fornecidos pelas extensões COC + ALE para obter dicas extras (mas com o suporte LSP desativado para evitar conflitos com o COC) + Vimspector + depuradores fornecidos pelo Vimspector (chamados "gadgets") + seguintes plug-ins do VIM:

call plug#begin()
Plug 'neoclide/coc.nvim'
Plug 'dense-analysis/ale'
Plug 'puremourning/vimspector'
Plug 'scrooloose/nerdtree'
Plug 'scrooloose/nerdcommenter'
Plug 'sheerun/vim-polyglot'
Plug 'yggdroot/indentline'
Plug 'tpope/vim-surround'
Plug 'kana/vim-textobj-user'
  \| Plug 'glts/vim-textobj-comment'
Plug 'janko/vim-test'
Plug 'vim-scripts/vcscommand.vim'
Plug 'mhinz/vim-signify'
call plug#end()

Você pode pesquisar no Google cada um para ver o que eles fazem.


11

1- instale ctags exuberantes. Se você estiver usando osx, este artigo mostra um pequeno truque: http://www.runtime-era.com/2012/05/exuberant-ctags-in-osx-107.html

2- Se você deseja incluir apenas as ctags dos arquivos no seu diretório, execute este comando no seu diretório:

ctags -R

Isso criará um arquivo "tags" para você.

3- Se você estiver usando Ruby e desejar incluir as ctags para suas gemas (isso foi realmente útil para mim com RubyMotion e gemas locais que desenvolvi), faça o seguinte:

ctags --exclude=.git --exclude='*.log' -R * `bundle show --paths`

credit: https://coderwall.com/p/lv1qww (Observe que eu omiti a opção -e que gera tags para o emacs em vez do vim)

4- Adicione a seguinte linha ao seu ~ / .vimrc

set autochdir 
set tags+=./tags;

(Por que o ponto e vírgula: http://vim.wikia.com/wiki/Single_tags_file_for_a_source_tree )

5- Vá para a palavra que você deseja seguir e pressione ctrl + ]; se você quiser voltar, use ctrl+o(fonte: https://stackoverflow.com/a/53929/226255 )


O link para o artigo do Mac mencionado está quebrado. Aqui está o link atualizado: runtime-era.blogspot.com/2012/05/… Sua melhor aposta é instalar ctags com uma ferramenta como Homebrew
ZaydH 02 /

6

Para responder à resposta de Paulo: sim, ctags (especialmente exuberant-ctags ( http://ctags.sourceforge.net/ )) é ótimo. Também adicionei isso ao meu vimrc, para que eu possa usar um arquivo de tags para um projeto inteiro:

set tags=tags;/

2

Instale cscope. Funciona muito parecido com, ctagsmas mais poderoso. Para ir para a definição, em vez de Ctrl+ ], faça Ctrl+ \+ g. Claro que você pode usar os dois simultaneamente. Mas com um grande projeto (por exemplo, kernel do Linux), o cscope está a quilômetros de distância.


1

Depois de gerar ctags, você também pode usar o seguinte no vim:

:tag <f_name>

Acima o levará à definição de função.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.