Советы и рекомендации по Vim и Ctags [закрыто]


485

Я только что установил Ctags (чтобы помочь в разработке на C ++) с моим Vim (или, скорее, с gVim) и хотел бы узнать ваши любимые команды, макросы, ярлыки, советы, которые сопровождают его ...

Поделитесь своим лучшим арсеналом. Какие еще дополнения Vim вы бы порекомендовали для C ++ при разработке Vim?

РЕДАКТИРОВАТЬ Какое еще дополнение вы бы использовали в сочетании с Ctags?

EDIT2 Какую версию gVim вы используете с тегами? Есть ли разница?

РЕДАКТИРОВАТЬ3 Как улучшить опыт программирования для больших и малых проектов?


15
Убедитесь, что вы используете exuberant ctags (современная реализация) для достижения
idbrii

17
Возможно, КЕВ не конструктивен?
Флойд

27
хотя closed as not constructiveпочти два года назад это так конструктивно для меня
сазары

15
Я думаю , что реальная причина для закрытия этого вопроса должно быть: «Этот вопрос, несмотря на огромную помощь, не вписывается в StackOverflow политики Q & A Пусть этот вопрос и ответы перейти на Quora и расти , что сайт в то время как мы упорно держать закрытие полезным. вопросы и ответы".
Диего Пино

2
Я понимаю, почему этот вопрос был закрыт, учитывая правила SO. Но пометка вопроса о> 400 ответах с ответом> 300 с ответом об удалении немного раздражает , не так ли?
DevSolar

Ответы:


394

Ctrl+ ]- перейти к определению
Ctrl+ T- отпрыгнуть из определения.
Ctrl+ W Ctrl+ ]- Открыть определение в горизонтальном разделении

Добавьте эти строки в vimrc
map <C-\> :tab split<CR>:exec("tag ".expand("<cword>"))<CR>
map <A-]> :vsp <CR>:exec("tag ".expand("<cword>"))<CR>

Ctrl+ \- Открыть определение в новой вкладке
Alt+ ]- Открыть определение по вертикали

После того, как теги генерируются. Вы можете использовать следующие клавиши для добавления и отключения функций:

Ctrl+ Left MouseClick- Перейти к определению
Ctrl+ Right MouseClick- Перейти к определению


8
C -] => (клавиша управления) и] клавиша C - T => (клавиша управления) и клавиша T Только для новичков в ctags. Спасибо за новую вкладку трюк
Кумар

6
Точно так же, после разделения окна с помощью Ctrl-w C-]вы можете сделать C-w T(иначе Shift-t), чтобы изменить это разделение на новую вкладку.
дэш-том-бэнг

1
@Will Если вы используете vim из терминала, то вам нужно изменить настройки терминала, чтобы ключ опции работал как клавиша alt. Если вы используете MacVim, добавьте эту строку в vimrc 'set macmeta'. Есть документ для Macmeta,: H Macmeta.
Амжит

17
g C-]это очень полезно. Он открывает быстрый диалог для выбора одного из нескольких определений.
Винченцо Пии

3
g]тоже полезно. Вы можете поместить курсор на имя тега и нажать, g]чтобы получить список подходящих тегов.
zeekvfu

176

Одна строка, которая всегда идет в моем .vimrc:

set tags=./tags;/

Это будет искать в текущем каталоге «теги» и обрабатывать дерево по направлению к корню, пока один из них не будет найден. Итак, вы можете быть где угодно в вашем исходном дереве, а не просто в его корне.


37
Подход к руту чрезмерен. Вместо этого я советую идти только домой: tags + = tags; $ HOME
gotgenes

37
Деревья исходных текстов, над которыми я работаю, не всегда находятся в моем домашнем каталоге ... и, поскольку $ HOME имеет тенденцию находиться в двух каталогах от корневого каталога ... хорошо, я могу позволить себе еще два поиска в каталогах. :)
узи

6
Я согласен с узи. Если мой cwd - это / home / me /рограммирование / foo / bar / baz / bang / bam, то это только 8 поисков в каталогах. Я полагаю, это зависит от вашего допуска к скорости, но время поиска в каталоге 1 заметно не отличается от 8 на моей машине.
Нейт Мюррей

1
Это зависит от вашего сценария, мне нужно использовать рекомендации gotgenes на одном из моих компьютеров, потому что в / home примерно 8000 каталогов, и это, как правило, немного вяло.
jkerian

1
Есть ли что-то подобное для cscope?
szx

45

Другой полезный плагин для разработки на C - это cscope. Подобно тому, как Ctags позволяет переходить к определениям, Cscope переходит к вызову. функциям.

Если у вас есть cscope в каталоге ~ / bin /, добавьте следующее в ваш .vimrc и используйте g ^], чтобы перейти к вызывающей функции (см .: 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

Почти забыл ... Так же, как ctags - вы должны генерировать (и периодически обновлять) базу данных. Я использую следующий скрипт

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

Где 'select_files' - это другой скрипт, который извлекает список файлов C и заголовков из файла Makefile. Таким образом, я индексирую только те файлы, которые фактически используются проектом.


В чем преимущество cscope перед ctags? Они дополняют друг друга?
Whaledawg

4
Они дополняют друг друга. Ctags находит определение символа или функции. Cscope может найти все места, вызывающие функцию. их использование делает навигацию в больших исходных деревьях очень простой.
Nimrodm

1
Тем не менее, AFAIK cscope имеет ограниченное понимание C ++.
Люк Эрмитт

Это ограничено, и не очень хорошо. Но для того, что он делает (переходя к ИСПОЛЬЗОВАНИЮ), нет лучшей альтернативы. Его главная проблема заключается в том, что когда вы хотите перейти к вызовам функций (f), вам часто нужно переходить в любое место, где вместо этого используются символы, и мысленно фильтровать результаты ...
Грег Роджерс

2
@Whaledawg Да, когда я нажимаю CTRL +], моя звуковая карта отправляет "clap.wav" в выводе :)
Patrizio Rullo

27

Вы можете добавить каталоги в свой поиск ctags. Например, у меня есть индекс ctags, созданный для Qt4, и он есть в моем .vimrc:

set tags+=/usr/local/share/ctags/qt4

23

Все вышеперечисленное и ...

code_complete: параметр функции завершен, фрагменты кода и многое другое.

taglist.vim: браузер исходного кода (поддерживает C / C ++, Java, Perl, Python, Tcl, SQL, PHP и т. д.)


5
Я думаю, что было бы хорошо добавить, что taglist.vim является наиболее загружаемым плагином vim.
Амит

16

Я использую ALT-влево и ALT-вправо для извлечения / перемещения из / в стек тегов.

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

Если вы используете hjklдля движения, вы можете отобразить <M-h>и <M-l>вместо этого.


не то же самое, что ctrl -] и ctrl-t - я думаю, ваше предложение немного чище.

@ Саша, простите? Не знаю, что ты говоришь. = X Обратите внимание, это также работает в: help.
Страгер

2
Я думаю, что это более интуитивно и чище, чем по умолчанию.
Айман

1
@Ayman Но также нарушает принцип отсутствия необходимости снимать руки с homerow, как, например, использование hjkl против клавиш со стрелками.
TankorSmash

@TankorSmash, какой принцип?
Страж

10

Несколько определений с тем же именем

<C-w>g<C-]>откройте определение в разбиении, но также сделайте, :tjumpчто либо идет к определению, либо, если есть несколько определений, предоставляет вам список определений на выбор.


2
Как и в первой команде, vim имеет :ptagкоманду, которая открывает определение в окне предварительного просмотра.
idbrii

1
Окно предварительного просмотра приятно, потому что вы можете закрыть его с помощью: pc из любого другого окна, без необходимости сначала перемещать курсор в окно предварительного просмотра.
Хейкки Наски

Есть также аккуратный трюк autocmd с ptag, при :h CursorHold-exampleкотором после настраиваемого тайм-аута отображается тег для элемента под курсором в окне предварительного просмотра.
dash-tom-bang

+1 за: tjump, который я сейчас связал: tjump <Cr> <Cw> <CR> работает лучше, чем <C -]> imho Хотел бы объединить это поведение с: ptag
Andreas Fliesberg

:helpэто круто иногда ... увидеть :help CTRL-W_g}и:ptjump
Андреас Флисберг

8

Команда, которую я использую чаще всего, это C-], которая переходит к определению функции под курсором. Вы можете использовать его чаще, чтобы отслеживать больше звонков. После этого Ко вернет вас на один уровень, Си снова углубится.


16
Ct возвращается на один уровень в стеке C-], а Co возвращается к предыдущей позиции курсора после перемещения. Поэтому, если вы переходите к функции, а затем переходите на страницу вниз, Ct немедленно вернется назад, а Co вернется к началу функции, а затем к вызову.
Грег Хьюгилл

6

Я нашел плагин taglist, который обязательно нужно иметь. В нем перечислены все известные ему теги (файлы, которые вы открыли) в отдельном окне и очень легко перемещаться по большим файлам.

Я использую его в основном для разработки на Python, но может быть лучше только для C / C ++.




4

Я поместил следующее в мой файл .gvimrc, который ищет дерево тегов в любой точке для файла тегов при запуске 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()

Затем я периодически обновляю файл тегов в верхней части дерева исходных текстов с помощью скрипта, который выглядит следующим образом:

#!/bin/bash

find . -regex ".*\.\(c\|h\|hpp\|cc\|cpp\)" -print | ctags --totals --recurse --extra="+qf" --fields="+i" -L -

7
Вы только что заново изобрели поиски вверх. Смотрите: h поиск файлов. См. Также stackoverflow.com/questions/563616/vimctags-tips-and-tricks/…
gotgenes

2

Я использую vim в macos, и оригинальные ctags не работают должным образом, поэтому я загружаю самые новые и настраиваю make make install. Я устанавливаю ctgas в / usr / local / bin / ctags (чтобы сохранить оригинал)

"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>

1

Я приспособил функцию поиска SetTags () выше (которая должна быть заменена эквивалентной set tags+=./tags;/) для работы в cscope. Кажется, работает!

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

3
Как сказал Готген, ты просто заново изобрел поиск наверх. Смотрите: h поиск файлов. Смотрите этот плагин для соответствующего примера.
idbrii

1

Еще одна итерация функции SetCscope () выше. Это устанавливает предварительный путь cscope для получения совпадений, не находясь в директории, где "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

3
Как сказал Готген, ты просто заново изобрел поиск наверх. Смотрите: h поиск файлов. Смотрите этот плагин для соответствующего примера.
idbrii
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.