Получите ctags в vim для перехода к определению, а не к объявлению - PullRequest
47 голосов
/ 28 июня 2009

У меня проблема с тем, что ctags в vim / gvim часто приводит меня к предварительному объявлению, а не к фактическому определению функции.

Есть ли способ обойти это?

Ответы [ 9 ]

70 голосов
/ 17 ноября 2009

Я думаю, что самый простой способ - использовать "g ctrl-]" вместо просто "ctrl-]". Если есть только один матч, он доставит вас туда. Если есть несколько совпадений, он перечислит их все, что позволит вам выбрать тот, который вы хотите, например: tselect. Лучший из двух миров. :)

9 голосов
/ 29 июня 2009

Вы можете использовать tn и tp для перехода к различным совпадающим тегам.

  • Нажмите ^], чтобы перейти к первому совпадению.
  • Если это не то соответствие, которое вы хотите, введите :tn, чтобы перейти к следующему.
  • Если вы ввели :tn слишком много раз, вы можете набрать :tp, чтобы вернуться к предыдущему.
8 голосов
/ 29 июня 2009

Я считаю, что Vim по умолчанию переходит к первому тегу в файле тегов. Вы можете выбрать другой, если хотите: используйте :tj (аналогично: tselect, но автоматический переход, если есть только одно совпадение) или Ctrl-], за которым следует :tn).

Единственный способ изменить значение по умолчанию - это изменить порядок файла тегов, но я не верю, что ctags предлагает для этого параметр командной строки.

Это не так сложно, как кажется, потому что вам нужен скрипт, который открывает файл тегов, сортирует его по типу тега и записывает обратно. «Вид» в теге - это одиночный символ, описывающий, является ли это функцией (f), прототипом функции (p), макросом, нумерованным именем и т. Д. И т. Д. И т. Д. И т. Д. Если вы используете Linux, это может быть в теории , просто:

#!/bin/sh
ctags -R -f - . | tac > tags

Поскольку tac меняет порядок строк в файле, это автоматически ставит определение на первое место. Однако, это становится немного сложнее, так как заголовок должен поддерживаться, и Vim предпочитает сортировать файл тегов, поэтому лучше просмотреть файл и отсортировать первую запись (имя тега) в прямом порядке, а затем вид в обратном порядке. Поэтому что-то более сложное может быть лучше.

Я прошу прощения за бесстыдный плагин, но я написал плагин Vim, который (косвенно) делает то, что вам нужно. Он предназначен для добавления множества дополнительных групп подсветки для таких вещей, как имена функций, макросы, перечисления и т. Д. Однако одна из других вещей, которые это делает, - это повторная сортировка файла тегов, так что реализация функции предшествует объявлению функции, тем самым достижения того, чего вы хотите (у меня была такая же потребность, как и у вас). Если вам не нужна какая-либо из функций подсветки, вы, вероятно, можете легко ее удалить: это довольно простая программа на Python и еще более простой скрипт Vim, которые доступны на my site .

2 голосов
/ 12 ноября 2013

Поздно до вечеринки, но для входящего тега vim googlers:

Я обнаружил, что использование cscope в дополнение к ctags - это путь, по крайней мере для C / C ++. Он более интеллектуален в отношении деревьев вызовов, и вы можете настроить его на ctags в случае сбоя. Просто запускайте "cscope -b" каждый раз, когда вы запускаете ctags -R. и вы будете готовы к работе. Если вы используете настройки ниже, вы сможете использовать Ctrl -] / Ctrl-T, как всегда, но вы также можете добавить изящные новые переходы, такие как переход к объявлению функции и отображение списка переходов для вызывающих функций.

" setup
if has("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
    set csverb
endif

" jump to a function declaration
nmap <silent> <C-\> :cs find s <C-R>=expand("<cword>")<CR><CR>1<CR><CR>
" show a list of where function is called
nmap <silent> <C-_> :cs find c <C-R>=expand("<cword>")<CR><CR>
1 голос
/ 03 июня 2011

Добавьте в свой файл .vimrc следующее:

noremap <c-]> 2<c-]>

Эта строка заставляет vim автоматически переходить ко второму совпадению (вместо первого), которое обычно является определением функции.

1 голос
/ 02 июня 2010

Этот вариант сработал для меня лучше

Поместите следующую строку в ваш .vimrc, и теперь вы можете использовать двойной щелчок мыши (на variable/entry в вашем файле), чтобы перейти к отмеченному местоположению. Если найдено одно совпадение, оно сразу же прыгнет. Если несколько записей совпадают, появится запрос на ввод данных пользователем.

:map <2-LeftMouse> g< c-]>
1 голос
/ 29 июня 2009
:tselect my_little_function 

и вы получите список совпадений. или если вы переходите к тегу и вас это не устраивает, введите

:tselect

И вы получите список альтернатив для последнего активного тега.

0 голосов
/ 23 октября 2014

Вы можете нажать 2 , затем CTRL + ] , это перейдет непосредственно ко второму совпадению, в Java это обычно реализация некоторого интерфейса ,

0 голосов
/ 18 августа 2014

Существует несколько способов заставить Vim напрямую перейти к тегу, если есть только одно совпадение тега, в противном случае представить список совпадений тега.

Вы можете использовать команду 'tjump' ex. Например, команда ':tjump func1' перейдет к определению func1, если оно определено только один раз. Если func1 определен несколько раз, будет представлен список совпадающих тегов.

Вы можете навести курсор на тег и нажать g Ctrl-].

Вы можете визуально выделить текст и нажать g Ctrl-], чтобы перейти или отобразить соответствующие теги.

Вы можете использовать команду ex *. Откроется соответствующий или выбранный тег из списка тегов в новом окне.

Вы можете нажать Ctrl-W g Ctrl-], чтобы выполнить: stjump.

Help: :tjump, g_Ctrl-], v_g_CTRL-], :stjump, Ctrl-W_g_Ctrl-]
...