Consejos y trucos de Vim y Ctags [cerrado]

485

Acabo de instalar Ctags (para ayudar con el desarrollo de C ++) con mi Vim (o más bien gVim), y me gustaría encontrar sus comandos favoritos, macros, accesos directos, consejos que lo acompañan ...

Comparte tu mejor arsenal. ¿Qué otros complementos de Vim recomendarías para C ++ en el desarrollo de Vim?

EDITAR ¿Qué otro complemento usarías junto con Ctags?

EDIT2 ¿Qué versión de gVim usas con las etiquetas? ¿Hace alguna diferencia?

EDIT3 ¿Cómo mejora su experiencia de programación para proyectos grandes y pequeños?

kenorb
fuente
15
Asegúrese de utilizar ctags exuberantes (una implementación moderna) para obtener los mejores resultados: ctags.sourceforge.net
idbrii
17
¿Quizás el kev no es constructivo?
Floyd
27
aunque hace closed as not constructivecasi dos años, es muy constructivo para mí
sazary
15
Creo que la verdadera razón para cerrar esta pregunta debería haber sido: "Esta pregunta, a pesar de ser enormemente útil, no encaja en la política de preguntas y respuestas de StackOverflow. Deje que esta pregunta y las respuestas se trasladen a Quora y hagan crecer ese sitio mientras obstinadamente seguimos cerrando útil preguntas y respuestas".
Diego Pino
2
Entiendo por qué esta pregunta se cerró, dadas las reglas de SO. Pero marcar una pregunta de> 400 votos a favor con una respuesta de> 300 votos a favor para su eliminación es un poco gruñón, ¿no?
DevSolar

Respuestas:

394

Ctrl+ ]- ir a definición
Ctrl+ T- Saltar hacia atrás desde la definición.
Ctrl+ W Ctrl+ ]- Abre la definición en una división horizontal

Agregue estas líneas en vimrc
map <C-\> :tab split<CR>:exec("tag ".expand("<cword>"))<CR>
map <A-]> :vsp <CR>:exec("tag ".expand("<cword>"))<CR>

Ctrl+ \- Abre la definición en una pestaña nueva
Alt+ ]- Abre la definición en una división vertical

Después de que se generan las etiquetas. Puede usar las siguientes teclas para etiquetar y descartar funciones:

Ctrl+ Left MouseClick- Ir a la definición
Ctrl+ Right MouseClick- Volver a la definición

Amjith
fuente
8
C -] => (tecla de control) y] tecla C - T => (tecla de control) y tecla T Solo para principiantes en ctags. Gracias por el nuevo truco de pestañas
kumar
66
Del mismo modo, después de dividir la ventana con Ctrl-w C-]usted puede hacer C-w T(también conocido como Shift-t) para cambiar esa división en una nueva pestaña.
dash-tom-bang
1
@ Will Si está utilizando vim desde el terminal, entonces tiene que cambiar las preferencias del terminal para que la tecla de opción se comporte como una tecla alt. Si está utilizando MacVim, agregue esta línea a vimrc 'set macmeta'. Hay doc para macmeta,: h macmeta.
Amjith
17
g C-]es muy útil. Abre un diálogo rápido para seleccionar uno entre múltiples definiciones.
Vincenzo Pii
3
g]También es útil. Puede colocar el cursor sobre el nombre de la etiqueta y presionar g]para obtener una lista de etiquetas coincidentes.
zeekvfu
176

Una línea que siempre va en mi .vimrc:

set tags=./tags;/

Esto buscará "etiquetas" en el directorio actual y trabajará el árbol hacia la raíz hasta encontrar uno. IOW, puedes estar en cualquier parte de tu árbol de origen en lugar de solo la raíz del mismo.

uzi
fuente
37
Subir a la raíz es excesivo. Sugiero solo ir a casa: tags + = tags; $ HOME
gotgenes
37
Los árboles de origen en los que trabajo no siempre están en mi directorio de inicio ... y dado que $ HOME tiende a estar a dos directorios de la raíz ... bueno, puedo permitirme dos búsquedas de directorios más. :)
uzi
66
Estoy de acuerdo con uzi. Si mi cwd es / home / me / programación / foo / bar / baz / bang / bam, eso es solo 8 búsquedas de directorio. Supongo que depende de su tolerancia a la velocidad, pero el tiempo para buscar 1 directorio no es notablemente diferente de 8 en mi máquina.
Nate Murray
1
Depende de su escenario, necesito usar la sugerencia de Gotgenes en una de mis máquinas porque hay aproximadamente 8,000 directorios en / home, y eso tiende a ser un poco lento.
jkerian
1
¿Hay algo similar para cscope?
szx
45

Otro complemento útil para el desarrollo de C es cscope. Así como Ctags le permite saltar a las definiciones, Cscope salta a la llamada funciones de .

Si tiene cscope en su directorio ~ / bin /, agregue lo siguiente a su .vimrc y use g ^] para ir a la función de llamada (consulte: ayuda 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

Casi lo olvido ... Al igual que ctags, debe generar (y actualizar periódicamente) la base de datos. Yo uso el siguiente script

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

Donde 'select_files' es otro script que extrae la lista de archivos C y de encabezado del Makefile. De esta manera indexo solo los archivos realmente utilizados por el proyecto.

nimrodm
fuente
¿Cuál es la ventaja de cscope sobre ctags? ¿Se complementan entre sí?
Whaledawg
44
Se complementan entre sí. Ctags encuentra la definición de un símbolo o una función. Cscope puede encontrar todos los lugares que llaman a una función. El uso de ambos hace que la navegación en grandes árboles de origen sea muy fácil.
nimrodm
1
Sin embargo, AFAIK cscope tiene una comprensión limitada de C ++.
Luc Hermitte
Es limitado y no muy bueno. Pero por lo que hace (saltar a USAGES), no hay otra alternativa mejor. Su principal problema es que cuando desea saltar a las llamadas de función (f), a menudo necesita saltar a cualquier lugar donde se use ese símbolo y filtrar los resultados mentalmente ...
Greg Rogers
2
@Whaledawg Sí, cuando presiono CTRL +] mi tarjeta de sonido envía "clap.wav" en la salida :)
Patrizio Rullo
27

Puede agregar directorios a su búsqueda de ctags. Por ejemplo, tengo un índice ctags creado para Qt4, y tengo esto en mi .vimrc:

set tags+=/usr/local/share/ctags/qt4
extraño
fuente
16

Uso ALT-izquierda y ALT-derecha para hacer estallar / empujar desde / a la pila de etiquetas.

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

Si usas hjklpara movimiento puedes mapear <M-h>y en su <M-l>lugar.

extraño
fuente
no es lo mismo que ctrl -] y ctrl-t - Supongo que su sugerencia es un poco más limpia.
@ Sasha, perdón? No sé lo que dices = X Para tener en cuenta, esto también funciona en: ayuda.
extraño
2
Creo que esto es más intuitivo y más limpio que el predeterminado.
Ayman
1
@Ayman Pero también viola el principio de no tener que mover las manos fuera del jonrón, como usar hjkl contra las teclas de flecha.
TankorSmash
@TankorSmash, ¿qué principio?
extraño
10

Varias definiciones del mismo nombre.

<C-w>g<C-]>abra la definición en una división, pero también haga lo :tjumpque va a la definición o, si hay varias definiciones, le presenta una lista de definiciones para elegir.

Heikki Naski
fuente
2
Similar al primer comando, vim tiene un :ptagcomando que abre la definición en una ventana de vista previa.
idbrii
1
La ventana de vista previa es agradable porque puede cerrarla con: pc desde cualquier otra ventana, sin tener que mover primero el cursor a la ventana de vista previa.
Heikki Naski
También hay un ingenioso truco de autocmd con ptag en el :h CursorHold-exampleque se muestra la etiqueta del elemento debajo del cursor en la ventana de vista previa después de un tiempo de espera configurable.
dash-tom-bang
+1 para: tjump ahora he vinculado: tjump <Cr><Cw> <CR> funciona mejor que <C -]> imho Me encantaría combinar este comportamiento con: ptag
Andreas Fliesberg
:helpes impresionante a veces ... ver :help CTRL-W_g}y:ptjump
Andreas Fliesberg
8

El comando que más uso es C-], que salta a la definición de la función debajo del cursor. Puede usarlo con más frecuencia para seguir más llamadas. Después de eso, Co te traerá de vuelta un nivel, Ci profundiza nuevamente.

raimue
fuente
16
Ct retrocede un nivel en la pila C-], mientras que Co vuelve a una posición anterior del cursor después de un movimiento. Entonces, si C-] a una función, luego retrocede una página, Ct volverá inmediatamente mientras que Co volverá al inicio de la función, luego volverá a la llamada.
Greg Hewgill
6

He encontrado que el complemento de taglist es imprescindible. Enumera todas las etiquetas que conoce (archivos que ha abierto) en una ventana separada y facilita la navegación por archivos más grandes.

Lo uso principalmente para el desarrollo de Python, pero solo puede ser mejor para C / C ++.

Walter
fuente
5

He encapsulado la manipulación de etiquetas en un complemento experimental mío.

Con respecto al desarrollo de C ++ en vim, ya he respondido allí : uso mi propia suite y algunos otros complementos.

Luc Hermitte
fuente
4

Puse lo siguiente en mi archivo .gvimrc, que busca en el árbol desde cualquier punto un archivo de etiquetas cuando se inicia gvim:

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()

Luego regenero periódicamente un archivo de etiquetas en la parte superior de mi árbol de origen con un script que se ve así:

#!/bin/bash

find . -regex ".*\.\(c\|h\|hpp\|cc\|cpp\)" -print | ctags --totals --recurse --extra="+qf" --fields="+i" -L -
alanwj
fuente
77
Acabas de reinventar la búsqueda ascendente. Ver: h búsqueda de archivos. Ver también stackoverflow.com/questions/563616/vimctags-tips-and-tricks/…
gotgenes
2

Uso vim en macos, y los ctags originales no funcionan bien, así que descargo los más nuevos y configuro make make install. Instalo ctgas en / usr / local / bin / ctags (para mantener el 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
fuente
1

Adapté la función de búsqueda SetTags () anterior (que debería ser reemplazada por el equivalente set tags+=./tags;/) para trabajar para 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
fuente
3
Como dijo Gotgenes: Acabas de reinventar la búsqueda ascendente. Ver: h búsqueda de archivos. Vea este complemento para un ejemplo relevante.
idbrii
1

Otra iteración en la función SetCscope () anterior. Eso establece la ruta previa de cscope para obtener coincidencias sin estar en el directorio donde "cscope.out" es:

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
fuente
3
Como dijo Gotgenes: Acabas de reinventar la búsqueda ascendente. Ver: h búsqueda de archivos. Vea este complemento para un ejemplo relevante.
idbrii