Советы и рекомендации по 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.