Перейти до визначення функції in vim


241

Як я можу перейти до визначення функції за допомогою vim? Наприклад, за допомогою Visual Assist я можу набрати Alt+ gпід функцією, і вона відкриє контекстне меню, в якому перераховані файли з визначеннями.

Як я можу зробити щось подібне у vim?


2
gnu global краще, ніж ctags.
Jichao

6
@Jichao, ти можеш дати нам трохи більше розуміння вашого досвіду? Якими мовами вам працювала глобальна робота? Чи є щось інше в контексті, який ви вважали за краще, щоб я був важливим? Чи, можливо, ви використовували його в багатьох різних сценаріях, і вам здається, що переважно / завжди віддають перевагу? Що вам більше подобається в цьому? Дякую.
still_dreaming_1

@Jichao Я перетворив ваш коментар у відповідь на вікі спільноти. Я вітаю ваші зміни та внесок у цю відповідь.
still_dreaming_1

Відповіді:


213

Використовуйте ctags. Створіть файл тегів та скажіть vim, де використовується команда: tags. Тоді ви можете просто перейти до визначення функції за допомогою Ctrl-]

У цьому питанні є більше хитрощів та підказок щодо тегів .


2
php схожий на C, щоб з ним працювали "Exuberant ctags". Не знаю, чи є в ньому режим пітона.
Пол Томблін

5
Немає досвіду роботи з Cscope. Що таке?
Пол Томблін

10
Схожість на C не має нічого спільного з підтримкою PHags PHP. Він підтримує PHP, а також Python. Погляньте на ctags.sourceforge.net/languages.html, щоб побачити повну підтримку.
дані

1
як я генерую теги?
dwaynemac

4
було б чудово отримати посилання на те, де найкраще навчитися керувати цими тегами.
Fzs2

137

Якщо все міститься в одному файлі, є команда gd(як у 'goto definition'), яка приведе вас до першого появи у файлі слова під курсором, що часто є визначенням.


1
що робити, якщо у мене немає курсору під курсором (я краще введу його)?
Фуад Сауд

@FuadSaud просто шукайте його, використовуючи/
LucasB

6
/майже завжди не є точним, оскільки він відповідає всім явищам. Я дізнався, що ви насправді можете зробити, :tag <function_name>щоб перейти до визначення за допомогою ctags.
Фуад Сауд

Функція @Faud Jump To Definition покладається на вказівку ідентифікатора курсором (у кожному IDE). Введення / пошук - це ще одна особливість, ви їх плутаєте.
кривавий

101

g* робить гідну роботу без встановлення ctags.

Тобто, типу g, *(або просто *- дивіться нижче) , щоб знайти слово під курсором (в даному випадку, ім'я функції). Потім натисніть, nщоб перейти до наступного (або Shift- nдля попереднього) явища.

Він не переходить безпосередньо до визначення, враховуючи, що ця команда просто шукає слово під курсором, але якщо ви зараз не хочете мати справу з налаштуванням тегів, ви можете принаймні врятувати себе від необхідності повторного -введіть ім'я функції для пошуку її визначення.

- редагуйте. Хоча я довго використовую g *, нещодавно я виявив два ярлики для цих ярликів!

(а) *перейде до наступного появи слова під курсором. (Не потрібно вводити команду g"goto" in vi).

(b) #подібним чином переходить до попереднього явища.

N і n все ще працюють, але "#" часто дуже корисно починати пошук спочатку у зворотному напрямку, наприклад, під час пошуку декларації змінної під курсором.


10
Різниця між *і g*- це межі слів у пошуку. *здійснює \<keyword\>пошук (такий же, як \bkeyword\bу звичайному регулярному вираженні), g*шукаючи keywordбез меж слова.
Nicolai S

якщо у вас є сто вторгнень функції у файлі, *перед вами знайдеться в середньому 50 звернень.
naught101

49

Використовуйте курсор gdабо gDпід час розміщення курсору на будь-якій змінній вашої програми.

  1. gd переведе вас до місцевої декларації.
  2. gD переведе вас до глобальної декларації.

більше варіантів навігації можна знайти тут .

Використовуйте cscope для перехресного посилання на великий проект, такий як ядро ​​Linux.


14

Як згадував Пол Томблін, ви повинні використовувати ctags . Ви також можете використати плагіни для вибору відповідного або для попереднього перегляду визначення функції під курсором. Без плагінів у вас буде головний біль, намагаючись вибрати один із сотень перевантажених методів "doAction", вбудованих у підтримку ctags, не враховуючи контекст - лише ім'я.

Також ви можете скористатися cscope та його функцією "знайти глобальний символ". Але ваш vim має бути зібраний із підтримкою + cscope, що не є типовим варіантом збірки.

Якщо ви знаєте, що функція визначена в поточному файлі, ви можете використовувати клавіші 'gD' у звичайному режимі, щоб перейти до визначення символу під курсором.

Ось найбільш завантажений плагін для навігації
http://www.vim.org/scripts/script.php?script_id=273

Ось один я написав для вибору контексту під час переходу до тегу
http://www.vim.org/scripts/script.php?script_id=2507


Привіт @ mykola-golubyev, посилання, надане вами у Detailed descriptionрозділі #2507сценарію, порушено. Чи можете ви надати ще одну, будь ласка?
FelikZ

12

Ще одна поширена методика - розмістити ім'я функції в першому стовпчику. Це дозволяє визначити визначення за допомогою простого пошуку.

int
main(int argc, char *argv[])
{
    ...
}

Вищеописану функцію можна було знайти /^mainу файлі або за допомогою:grep -r '^main' *.c в каталозі. Поки код належним чином з відступом, єдиний раз, коли ідентифікатор виникне на початку рядка, - це визначення функції.

Звичайно, якщо ви не використовуєте ctags з цього моменту, вам повинно бути соромно за себе! Однак я вважаю цей стандарт кодування також корисним доповненням.


13
Мені завжди було цікаво, чому деякі кодери так пишуть свої підписи!
Тарраш

Крім того, коли ви пишете підписи своїх функцій, включаючи '{' в першому стовпці, ви можете швидко переміщатися до кожної функції, натискаючи]], щоб перейти у файл і [[повернутися назад.
BentChainRing

12

TL; DR:

Сучасний спосіб полягає у використанні COC для інтелінгенс-подібного завершення та одного або декількох мовних серверів (LS) для переходу до визначення (і набагато більше). Для ще більшої функціональності (але вона не потрібна для переходу до визначення) ви можете встановити один або кілька налагоджувачів і отримати повноцінний досвід IDE. Швидкий старт:

  1. встановіть vim-plug для управління вашими плагінами VIM
  2. додайте COC та (необов'язково) Vimspector вгорі ~/.vimrc:
    call plug#begin()
    Plug 'neoclide/coc.nvim', {'branch': 'release'}
    Plug 'puremourning/vimspector'
    call plug#end()
    
  3. заклик :source $MYVIMRC | PlugInstallдля завантаження плагінів VIM
  4. перезапустіть vimі зателефонуйте, :CocInstall coc-marketplaceщоб отримати легкий доступ до розширень COC
  5. виклик :CocList marketplaceта пошук мовних серверів, наприклад:
    • введіть, pythonщоб знайти coc-jedi,
    • тип php щоб знайти coc-phplsтощо.
  6. (необов'язково) див. install_gadget.py --helpдоступні відладчики, наприклад:
    • ./install_gadget.py --enable-python,
    • ./install_gadget.py --force-enable-phpтощо.

Повна відповідь:

Мовний сервер (LS) - це окремий окремий додаток (по одному для кожної мови програмування), який працює у фоновому режимі та аналізує весь ваш проект у режимі реального часу, відкриваючи додаткові можливості вашому редактору (будь-який редактор, не тількиvim ). Ви отримуєте такі речі, як:

  • заповнення тегу відомості про простір імен
  • перейти до визначення
  • перейти до наступної / попередньої помилки
  • знайти всі посилання на об'єкт
  • знайти всі реалізації інтерфейсу
  • перейменувати весь проект
  • документація на наведення
  • фрагменти, дії коду, форматування, зв'язування та багато іншого ...

Спілкування з мовними серверами відбувається через протокол мовного сервера (LSP). І nvimта vim8(і вище) підтримують LSP за допомогою плагінів, найпопулярнішим з яких є Conquer of Completion (COC).

Список активно розроблених мовних серверів та їх можливостей розміщено на веб-сайті Lang Server . Не всі з них надаються розширеннями КОК. Якщо ви хочете скористатись одним із таких, ви можете самостійно написати розширення COC або встановити LS вручну та використовувати комбінацію наступних плагінів VIM як альтернативу COC:

  • LanguageClient - обробляє LSP
  • deoplete - запускає завершення під час введення

Спілкування з налагоджувачами відбувається через протокол адаптера налагодження (DAP). Найпопулярніший плагін DAP для VIM - це Vimspector .

Протокол мовного сервера (LSP) був створений корпорацією Microsoft для коду Visual Studio і був випущений як проект з відкритим кодом з дозвільною ліцензією MIT (стандартизована співпрацею з Red Hat та Codenvy). Пізніше Microsoft також випустила протокол адаптера налагодження (DAP). Будь-яка мова, що підтримується VSCode, підтримується у VIM.

Я особисто рекомендую використовувати мовні сервери COC +, надані розширеннями COC + ALE, для додаткового зв’язування (але з відключеною підтримкою LSP, щоб уникнути конфліктів з COC) + Vimspector + відладчики, що надаються Vimspector (звані "гаджетами") + наступні плагіни VIM:

call plug#begin()
Plug 'neoclide/coc.nvim'
Plug 'dense-analysis/ale'
Plug 'puremourning/vimspector'
Plug 'scrooloose/nerdtree'
Plug 'scrooloose/nerdcommenter'
Plug 'sheerun/vim-polyglot'
Plug 'yggdroot/indentline'
Plug 'tpope/vim-surround'
Plug 'kana/vim-textobj-user'
  \| Plug 'glts/vim-textobj-comment'
Plug 'janko/vim-test'
Plug 'vim-scripts/vcscommand.vim'
Plug 'mhinz/vim-signify'
call plug#end()

Ви можете перейти в Google, щоб побачити, що вони роблять.


11

1- встановити буйні коти. Якщо ви використовуєте osx, ця стаття показує невелику хитрість: http://www.runtime-era.com/2012/05/exuberant-ctags-in-osx-107.html

2- Якщо ви хочете включити лише каталоги для файлів у свій каталог, запустіть цю команду у своєму каталозі:

ctags -R

Це створить для вас файл "тегів".

3- Якщо ви використовуєте Ruby і хочете включити ctags для ваших дорогоцінних каменів (це було дуже корисно для мене з RubyMotion та локальними дорогоцінними каменями, які я розробив), зробіть наступне:

ctags --exclude=.git --exclude='*.log' -R * `bundle show --paths`

Кредит: https://coderwall.com/p/lv1qww (Зверніть увагу, що я пропустив опцію -e, яка генерує теги для emacs замість vim)

4- Додайте наступний рядок до ~ / .vimrc

set autochdir 
set tags+=./tags;

(Чому напівкрапка: http://vim.wikia.com/wiki/Single_tags_file_for_a_source_tree )

5- Перейдіть до слова, яке ви хочете слідувати, і натисніть ctrl + ]; якщо ви хочете повернутися назад, скористайтеся ctrl+o(джерело: https://stackoverflow.com/a/53929/226255 )


Посилання на згадану статтю Mac порушено. Ось оновлене посилання: runtime-era.blogspot.com/2012/05/… Ваша найкраща ставка - встановити ctags з таким інструментом, як Homebrew
ZaydH

6

На другу відповідь Павла: так, ctags (особливо exuberant-ctags ( http://ctags.sourceforge.net/ )) є чудовим. Я також додав це до свого vimrc, тому я можу використовувати один файл тегів для всього проекту:

set tags=tags;/

2

Встановити cscope. Це дуже схоже, ctagsале потужніше. Щоб перейти до визначення, замість Ctrl+ ], зробіть Ctrl+ \+ g. Звичайно, ви можете використовувати обидва одночасно. Але з великим проектом (скажімо, ядром Linux) cscope на милі вперед.


1

Після генерації ctags ви також можете використовувати наступні програми vim:

:tag <f_name>

Наведене вище допоможе вам визначити функцію.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.