На днях я искал решение этой проблемы и наткнулся на отличный пост Рэя Грассо от апреля 2015 года. Я рекомендую прочитать пост, чтобы узнать о его решении; Я просто немного его изменил. Он также ссылается на свои точечные файлы, которые включают обновления с момента публикации сообщения.

О ctags

Много лет назад я познакомился с базовыми ctags функциями в vim. Но ctags сам по себе гораздо более гибкий и может использоваться большинством редакторов. Я настоятельно рекомендую вам посетить веб-сайт ctags, а также плагины для популярных редакторов, таких как vscode, atom и sublime text.

По сути, ctags будет сканировать все файлы, которые вы его запрашиваете, и искать то, что он понимает как определения символов. Это классы, функции, имена переменных и так далее. ctags имеет большой список известных языков, но поддержка JavaScript пока не самая лучшая.

Для начала убедитесь, что у вас установлено exuberant-ctags, а не обычные теги ctags. Например, вы можете brew install ctags на компьютере с macOS, на котором будет установлена ​​последняя версия exuberant-ctags.

Внутри vim

Создание ctags

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

Переход к определению под курсором

Во время чтения кода, когда курсор находится над известным символом, нажатие Ctrl+] приведет к переходу к этому определению.

Поиск доступных тегов

Если вы знаете, какой тег вам нужен, но не знаете его, вы можете :tag <tagname> перейти к его определению. Команда :tag поддерживает завершение табуляции; Я часто использую :tag поиск, чтобы перейти к определениям классов или констант.

Навигация по нескольким совпадениям

Любой из этих способов перехода к определению может привести к совпадению нескольких тегов. Вы можете перемещаться по стеку тегов с помощью :tnext (кратко, :tn) или :tprevious (:tp). Если вы хотите увидеть список определений, найденных для любого данного тега, вы можете :tselect (:tsel).

Включение других пакетов в созданный файл тегов

Хотя это может занять слишком много времени в зависимости от размера вашего графа зависимостей, я счел полезным в некоторых случаях включить мой каталог node_modules в мой файл tags. В то время как я обычно включаю только базовые каталоги, такие как app, config и lib, бывают случаи, когда мне нужно проверить источник модуля в том же сеансе, что и код моего приложения. Одним из примеров может быть случай, когда я впервые использую библиотечный модуль, и я не уверен, как все работает под прикрытием, или почему то, что я ожидаю, просто не так.

Ваш новый файл .ctags

После небольшой обрезки и изучения эта часть моего ~/.ctags файла, относящаяся к JavaScript, выглядит так:

--exclude=node_modules
--exclude=gulp
--languages=-javascript
--langdef=js
--langmap=js:.js
--langmap=js:+.jsx
--regex-js=/[ \t.]([A-Z][A-Z0-9._$]+)[ \t]*[=:][ \t]*([0-9"'\[\{]|null)/\1/n,constant/
--regex-js=/\.([A-Za-z0-9._$]+)[ \t]*=[ \t]*\{/\1/o,object/
--regex-js=/['"]*([A-Za-z0-9_$]+)['"]*[ \t]*:[ \t]*\{/\1/o,object/
--regex-js=/([A-Za-z0-9._$]+)\[["']([A-Za-z0-9_$]+)["']\][ \t]*=[ \t]*\{/\1\.\2/o,object/
--regex-js=/([A-Za-z0-9._$]+)[ \t]*=[ \t]*\(function\(\)/\1/c,class/
--regex-js=/['"]*([A-Za-z0-9_$]+)['"]*:[ \t]*\(function\(\)/\1/c,class/
--regex-js=/class[ \t]+([A-Za-z0-9._$]+)[ \t]*/\1/c,class/
--regex-js=/([A-Za-z$][A-Za-z0-9_$()]+)[ \t]*=[ \t]*[Rr]eact.createClass[ \t]*\(/\1/c,class/
--regex-js=/([A-Z][A-Za-z0-9_$]+)[ \t]*=[ \t]*[A-Za-z0-9_$]*[ \t]*[{(]/\1/c,class/
--regex-js=/([A-Z][A-Za-z0-9_$]+)[ \t]*:[ \t]*[A-Za-z0-9_$]*[ \t]*[{(]/\1/c,class/
--regex-js=/([A-Za-z$][A-Za-z0-9_$]+)[ \t]*=[ \t]*function[ \t]*\(/\1/f,function/
--regex-js=/(function)*[ \t]*([A-Za-z$_][A-Za-z0-9_$]+)[ \t]*\([^)]*\)[ \t]*\{/\2/f,function/
--regex-js=/['"]*([A-Za-z$][A-Za-z0-9_$]+)['"]*:[ \t]*function[ \t]*\(/\1/m,method/
--regex-js=/([A-Za-z0-9_$]+)\[["']([A-Za-z0-9_$]+)["']\][ \t]*=[ \t]*function[ \t]*\(/\2/m,method/
--langdef=typescript
--langmap=typescript:.ts
--regex-typescript=/^[ \t]*(export)?[ \t]*class[ \t]+([a-zA-Z0-9_]+)/\2/c,classes/
--regex-typescript=/^[ \t]*(export)?[ \t]*module[ \t]+([a-zA-Z0-9_]+)/\2/n,modules/
--regex-typescript=/^[ \t]*(export)?[ \t]*function[ \t]+([a-zA-Z0-9_]+)/\2/f,functions/
--regex-typescript=/^[ \t]*export[ \t]+var[ \t]+([a-zA-Z0-9_]+)/\1/v,variables/
--regex-typescript=/^[ \t]*var[ \t]+([a-zA-Z0-9_]+)[ \t]*=[ \t]*function[ \t]*\(\)/\1/v,varlambdas/
--regex-typescript=/^[ \t]*(export)?[ \t]*(public|private)[ \t]+(static)?[ \t]*([a-zA-Z0-9_]+)/\4/m,members/
--regex-typescript=/^[ \t]*(export)?[ \t]*interface[ \t]+([a-zA-Z0-9_]+)/\2/i,interfaces/
--regex-typescript=/^[ \t]*(export)?[ \t]*enum[ \t]+([a-zA-Z0-9_]+)/\2/e,enums/
--regex-typescript=/^[ \t]*import[ \t]+([a-zA-Z0-9_]+)/\1/I,imports/

Обертывание в псевдоним

Наконец, следуя примеру г-на Грассо, давайте избавимся от чрезмерно жадного сопоставления и превратим его в красивый псевдоним:

alias jtags=”ctags -R app config lib && sed -i ‘’ -E ‘/^(if|switch|function|module\.exports|it|describe).+language:js$/d’ tags”

Удачного вимминга!