¿Puedo saltar a una declaración o definición de función en un proyecto de múltiples archivos fuente C ++?

15

¿Puedo saltar a una declaración o definición de función en un proyecto de múltiples archivos fuente C ++?

Digamos que tengo un archivo de encabezado foo.hpp:

int bar();

y un archivo fuente foo.cpp:

#include "foo.hpp"
int bar() { return 42; }

y un archivo principal main.cpp:

#include "foo.hpp"
int main() { bar(); return 0; }

¿Puede vim encontrar tanto la definición como la declaración de la función a bar()partir de la mainfunción?

Allan Hasegawa
fuente

Respuestas:

15

Las etiquetas exuberantes son la forma más sencilla de lograr esto. Bajo GNU / Linux (p. Ej. Ubuntu o Debian) deberías poder hacer

sudo apt-get install exuberant-ctags

(Para OSX "$ brew install ctags" debería ser suficiente; para Windows puede visitar http://ctags.sourceforge.net/ y descargar el ejecutable independiente)

Luego navegue a la carpeta raíz de su proyecto y ejecute

ctags -R --exclude=.git .

Esto escaneará todo su proyecto y creará un archivo ./tags que vim usará automáticamente para proporcionarle la capacidad de saltar a las funciones con solo presionar una tecla. A saber:

Ctrl + ]

con el cursor colocado en la función para la que desea ver la implementación. Hay otras combinaciones y muchas funciones de modo de comando que le permiten navegar a través de su código por ctags también (por ejemplo, Ctrl+ tpara saltar a la entrada de pila de etiquetas más antigua). Consulte :help 29.1para obtener una descripción general.

Tenga en cuenta que debe volver a ejecutar ctags para cada cambio significativo en el código y dejar que vuelva a indexar su proyecto. Puede hacerlo manualmente o enseñarle a Vim a hacerlo en teclas de acceso rápido o en escritura.

Sugerencia: si hace un uso extensivo de ctags, quizás también valga la pena echar un vistazo al complemento vim-taglist ( http://vim-taglist.sourceforge.net ). Le proporciona un esquema de estilo IDE con una lista de todas las funciones para esa clase / archivo.

Rock
fuente
Dos cosas que vale la pena conocer: universal-ctags ha reemplazado de muchas maneras a exuberantes ctags. Además, cómo dejar que git sincronice sus etiquetas
D. Ben Knoble
4

Hasta ahora puedo nombrar dos soluciones al problema de encontrar la declaración o la definición de una función. Sé que hay otra solución basada en etiquetas bien conocidas, pero como no la uso, dejaré que otros te la den.

El más moderno primero: YouCompleteMe tiene un :GoToDefinitiony un :GoToDeclarationpar de comandos.

El que uso (es difícil cambiar los hábitos de 10 años). Mi plugin lh-tags tiene una forma de generar una base de datos ctags y actualizarla gradualmente. Y también ofrece una forma ( CTRL+W Meta+Down) de presentar todas las declaraciones y definiciones que coinciden con lo que está debajo del cursor (/ lo que está seleccionado). Como esta solución se basa en ctags, tampoco podrá saber qué sobrecarga está realmente relacionada con el identificador debajo del cursor. Otras soluciones basadas en ctags deberían ser tan malas (/ tan buenas) sobre este tema. Sin embargo, YCM debería ser mucho mejor aquí.

Discl .: implementé las etiquetas lh como una alternativa más ergonómica a :tselect.

(En realidad, recuerdo una tercera solución: había comenzado una bifurcación de indexador de clanes y el complemento vim relacionado que lo habría encapsulado. Pero con YCM cerca, me olvidaría de esta solución)

EDITAR: a partir de 2019, la solución más eficiente depende de los servidores LSP . Estoy usando COC + ccls para indexar, saltar y hacer muchas más cosas. Estoy recurriendo a soluciones basadas en etiquetas cuando soy demasiado vago para configurar COC para un proyecto en el que no pasaré mucho tiempo o donde no puedo instalar versiones recientes de clang y ccls.

Luc Hermitte
fuente
1
Gracias por el aporte, probará cada solución. Probé YouCompleteMe y solo GoToDeclarationfunciona con varios archivos fuente. He aquí una cita de los documentos sobre GoToDefinition: For C-family languages this only works ... when the definition of the symbol is in the current translation unit.. Además, los comandos son :YcmCompleter GoTo*.
Allan Hasegawa
Perdí esta línea. Eso significa que clang_indexer aún puede ser útil. Las otras soluciones pueden ser un poco difíciles de instalar. No dudes en enviarme un correo electrónico si es necesario.
Luc Hermitte
3

Hay pocas alternativas La primera de ellas es ctags. Si necesita un indexador más avanzado, entonces cscopees una mejor alternativa. Por ejemplo, le permitirá enumerar todas las personas que llaman de una función determinada. Estas herramientas indexarán su código sin entenderlo realmente correctamente (tienen una definición gramatical simple para saber qué significa el símbolo dado). También es relativamente fácil extender esa gramática. El taglistcomplemento es imprescindible para estos y es posible extender la gramática del indexador para mostrar los resultados en taglist.

Si necesita algo más que un indexador, entonces, como la verificación de sintaxis, YouCompleteMeprobablemente este sea el camino a seguir. Está construido en la parte superior llvmy, por lo tanto, tiene un analizador adecuado. Esto permite verificar la sintaxis y la semántica del código .

Luego, si trabaja con un código que tiene un lenguaje específico de dominio o código incrustado, a menudo terminará trabajando a través de los archivos. La alternativa es el Ackscript perl que intenta ayudar con esta tarea.

nombre
fuente
0

Creo que ctags es lo que necesitas. Vim está integrado con ctags de forma nativa y puede saltar fácilmente a las definiciones y declaraciones de funciones.

Echa un vistazo a este artículo http://andrew.stwrt.ca/posts/vim-ctags

David Carlos
fuente
Agregue un resumen de la publicación vinculada. Las respuestas de solo enlace se vuelven inútiles cuando el enlace se corta.
muru