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.
@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-]
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.
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.
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.
gd levará você à declaração local.
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.
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.
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.
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:
instale o vim-plug para gerenciar seus plug-ins VIM
adicione COC e (opcionalmente) Vimspector na parte superior de ~/.vimrc:
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:
deoplete - aciona a conclusão enquanto você digita
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:
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`
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:
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.
Respostas:
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 .
fonte
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.fonte
/
/
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.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
g
comando '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.
fonte
*
eg*
é o limite de palavras na pesquisa.*
faz uma\<keyword\>
pesquisa (igual à da expressão\bkeyword\b
regular regular), enquantog*
procurakeyword
sem limites de palavras.*
levará em média 50 ocorrências antes de encontrar a definição.Use
gd
ougD
enquanto coloca o cursor em qualquer variável do seu programa.gd
levará você à declaração local.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.
fonte
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
fonte
Detailed description
seção de#2507
script está quebrado. Você pode fornecer outro, por favor?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.
A função acima pode ser encontrada
/^main
dentro do arquivo ou:grep -r '^main' *.c
em 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.
fonte
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:
~/.vimrc
::source $MYVIMRC | PlugInstall
para baixar plug-ins do VIMvim
e ligue:CocInstall coc-marketplace
para obter acesso fácil às extensões COC:CocList marketplace
e pesquise servidores de idiomas, por exemplo:python
para encontrarcoc-jedi
,php
para encontrarcoc-phpls
, etc.install_gadget.py --help
para 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:A comunicação com os servidores de idiomas ocorre através do LSP ( Language Server Protocol ). Ambos
nvim
evim8
(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:
Você pode pesquisar no Google cada um para ver o que eles fazem.
fonte
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:
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:
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
(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, usectrl+o
(fonte: https://stackoverflow.com/a/53929/226255 )fonte
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:
fonte
Instale
cscope
. Funciona muito parecido com,ctags
mas 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.fonte
Depois de gerar ctags, você também pode usar o seguinte no vim:
Acima o levará à definição de função.
fonte