Как настроить ctags для работы с CSS, SCSS, HTML?

Я уже прочитал много сообщений в блогах и ответов на stackoverflow, но, похоже, я делаю что-то не так, потому что у меня все еще есть ошибка E388: Couldn't find definition. Что я сделал:

  • Загрузите ctags отсюда http://ctags.sourceforge.net/
  • Установите его: ./configure && make install
  • Установите tags+=tags;$HOME в моем файле .vimrc
  • Добавьте несколько строк в ~/.ctags (см. ниже)
  • Сделайте ctags -R . в корне проекта и получите несколько предупреждений (см. ниже)
  • Проверьте классы :tag .<C-D>, что дает мне большой список классов (это радует)

Предупреждения:

ctags: Warning: regcomp ([A-Za-z0-9._$]+)[ t]*[:=][ t]*{: Unmatched \{
ctags: Warning: regcomp ([A-Za-z0-9._$()]+)[ t]*[:=][ t]*function[ t]*(: Unmatched ( or \(
ctags: Warning: regcomp ([A-Za-z0-9._$]+)[ t]*[:=][ t]*[: Invalid regular expression
ctags: Warning: cannot open source file "static/img/touch/packages" : No such file or directory

Мой файл ~/.ctags выглядит следующим образом:

--exclude=*.min.js
--exclude=*.min.css
--exclude=*.map
--exclude=.backup
--exclude=.sass-cache
--exclude=vendors
--exclude=.git

--langdef=css
--langmap=css:.css
--langmap=css:+.sass
--langmap=css:+.styl
--langmap=css:+.less
--regex-css=/^[ \t]*\.([A-Za-z0-9_-]+)/.\1/c,class,classes/
--regex-css=/^[ \t]*#([A-Za-z0-9_-]+)/#\1/i,id,ids/
--regex-css=/^[ \t]*(([A-Za-z0-9_-]+[ \t\n,]+)+)\{/\1/t,tag,tags/
--regex-css=/^[ \t]*@media\s+([A-Za-z0-9_-]+)/\1/m,media,medias/

--langdef=scss
--langmap=scss:.scss
--regex-scss=/^[ \t]*@mixin ([A-Za-z0-9_-]+)/\1/m,mixin,mixins/
--regex-scss=/^[ \t]*\$([A-Za-z0-9_-]+)/\1/v,variable,variables/
--regex-scss=/^([A-Za-z0-9_-]*)*(\.[A-Za-z0-9_-]+) *[,{]/\2/c,class,classes/
--regex-scss=/^[ \t]+(\.[A-Za-z0-9_-]+) *[,{]/\1/c,class,classes/
--regex-scss=/^(.*)*\#([A-Za-z0-9_-]+) *[,{]/\2/i,id,ids/
--regex-scss=/^[ \t]*#([A-Za-z0-9_-]+)/\1/i,id,ids/
--regex-scss=/(^([A-Za-z0-9_-])*([A-Za-z0-9_-]+)) *[,|\{]/\1/t,tag,tags/
--regex-scss=/(^([^\/\/])*)[ \t]+([A-Za-z0-9_-]+)) *[,|\{]/\3/t,tag,tags/
--regex-scss=/(^(.*, *)([A-Za-z0-9_-]+)) *[,|\{]/\3/t,tag,tags/
--regex-scss=/(^[ \t]+([A-Za-z0-9_-]+)) *[,|\{]/\1/t,tag,tags/
--regex-scss=/^[ \t]*@media\s+([A-Za-z0-9_-]+)/\1/d,media,media/

--regex-html=/id="([A-Za-z0-9_-]+)"/\1/i,id,ids/
--regex-html=/class="([A-Za-z0-9_-]+)"/\1/c,class,classes/

--langdef=js
--langmap=js:.js
--regex-js=/([A-Za-z0-9._$]+)[ t]*[:=][ t]*{/1/,object/
--regex-js=/([A-Za-z0-9._$()]+)[ t]*[:=][ t]*function[ t]*(/1/,function/
--regex-js=/function[ t]+([A-Za-z0-9._$]+)[ t]*(([^)]))/1/,function/
--regex-js=/([A-Za-z0-9._$]+)[ t]*[:=][ t]*[/1/,array/
--regex-js=/([^= ]+)[ t]*=[ t]*[^"]'[^']*/1/,string/
--regex-js=/([^= ]+)[ t]*=[ t]*[^']"[^"]*/1/,string/

Структура проекта:

введите здесь описание изображения

Где бы (static/index.html, static/css/main.scss или static/css/components/set.scss) я ни пытался перейти к определению, используя ]^D, я всегда получаю E388: Couldn't find definition. Что случается?

ОБНОВЛЕНИЕ

<C-]> нажимается в начале _col-2 имени:

  • в случае <div class="_col-2">.. дает E426: Tag not found: _col. Похоже, vim неправильно определяет имя класса.
  • в случае .class { @extend ._col-2; } дает то же самое.

Как предлагает @romainl, после добавления set iskeyword+=- в .vimrc, чтобы тире было частью ключевого слова, нажатие на <div class="_col-2">.. бросает меня в начало строки.


person Timur Fayzrakhmanov    schedule 11.11.2015    source источник
comment
На заметку: вместо этого вам следует рассмотреть возможность использования менее ярких, но поддерживаемых универсальных ctags.   -  person Sato Katsura    schedule 11.11.2015
comment
Я это уже видел, но хорошего ридми нет (типа эй, это переимплементация! и все :)), поэтому я его пропускаю. В чем преимущества использования универсальных тегов по сравнению с классическими?   -  person Timur Fayzrakhmanov    schedule 11.11.2015
comment
Классический ctags 1970-х давно умер. Exuberant ctags не такой уж классический и не так давно умер, но все же мертв. Универсальный ctags — это форк Exuberant ctags, который активно поддерживается. Помимо прочего, он устранил некоторые давние проблемы в Exuberant ctags и добавил поддержку большего количества языков. Насколько я могу судить, единственная регрессия — это случайное использование engrish в различных документах. :)   -  person Sato Katsura    schedule 11.11.2015
comment
Хорошее объяснение)) Кстати, а есть какая-нибудь информация с перечислением поддерживаемых языков? Я не мог найти его.   -  person Timur Fayzrakhmanov    schedule 11.11.2015


Ответы (3)


О E426: Tag not found: txal-center

Эти строки в вашем .ctags будут индексировать .foo-barс точкой в ​​начале — в *.scss файлах:

--regex-scss=/^([A-Za-z0-9_-]*)*(\.[A-Za-z0-9_-]+) *[,{]/\2/c,class,classes/
--regex-scss=/^[ \t]+(\.[A-Za-z0-9_-]+) *[,{]/\1/c,class,classes/

Когда вы нажимаете <C-]> над именем класса в HTML-документе, Vim будет искать именно это имя класса, скажем, foo-bar, но не найдет его, потому что в вашем файле tags есть только .foo-bar. Это потому, что Vim по умолчанию выполняет поиск «по всему слову».

Решение этой конкретной проблемы состоит в том, чтобы оставить точку вне тега:

--regex-scss=/^([A-Za-z0-9_-]*)*\.([A-Za-z0-9_-]+) *[,{]/\2/c,class,classes/
--regex-scss=/^[ \t]+\.([A-Za-z0-9_-]+) *[,{]/\1/c,class,classes/
person romainl    schedule 11.11.2015
comment
Хм.. Я изменил его, как вы предлагаете, удалите старый ctags файл, сгенерируйте его снова ctags -R . и проверьте его :tag ^D. Однако точки остались. Здесь много классов, начинающихся с точки. Что случилось? - person Timur Fayzrakhmanov; 11.11.2015

Движение ]<C-D> предназначено для определений макросов, основанных на внутреннем поиске файлов Vim и опции 'define'. Он не использует базу данных тегов и в основном предназначен для макросов C/C++. То, что вы хотите, эквивалентно команде :tag (которая, по-видимому, работает для вас). Это <C-]> (или <C-LeftMouse>); вы найдете его прямо под :help :tag.

person Ingo Karkat    schedule 11.11.2015
comment
К сожалению, но когда я нажимаю ‹C-]› ничего не происходит, я просто получаю сообщение внизу экрана: tag 1 of 3 or more. - person Timur Fayzrakhmanov; 11.11.2015
comment
Он неправильно определяет имя класса, например, когда я нажимаю ^] на <div class="_col-3" ... (курсор на _) - я получаю сообщение об ошибке E426: Tag not found: _col - person Timur Fayzrakhmanov; 11.11.2015
comment
@TimurFayzrakhmanov, это потому, что - не является частью параметра «ключевое слово». Вы можете добавить его с помощью :set iskeyword+=-. Это будет полезно как в файлах HTML, так и в файлах CSS/LESS/SASS/SCSS. - person romainl; 11.11.2015
comment
Теперь, когда я нажимаю _col-3, меня просто бросает в начало строки. Нажатие на _row по-прежнему дает тот же tag 1 of 3 or more. - person Timur Fayzrakhmanov; 11.11.2015
comment
@romainl, я уже добавил это (в моем предыдущем комментарии тоже). Странно, но несмотря на явное выполнение :tag .txal-center перемещает меня в нужное место, нажатие ^] в том же классе, но в HTML выдает ошибку: E426: Tag not found: txal-center. Похоже, что в vim отсутствует автоматическое добавление точки перед именем класса. - person Timur Fayzrakhmanov; 11.11.2015

Кажется, я нашел решение, спасибо @romainl и @IngoKarkat за подсказку с исключением точек из регулярного выражения. Итак, вот шаги, если вы еще не пробовали Ctags с HTML, CSS, SCSS.

  • Загрузите последнюю версию и извлеките
  • Перейдите в извлеченную папку и запустите: ./configure && make && sudo make install. Теперь проверьте, правильно ли установлены ctags, запустив ctags --help
  • Создайте файл ~/.ctags и поместите туда код (см. ниже)
  • Добавьте строку set tags+=tags;$HOME в ~/.vimrc, затем запустите :so ~/.vimrc, чтобы обновить параметры. tags+=tags;$HOME означает рекурсивный поиск tags файлов от текущей папки до вашего домашнего каталога. Если вы предпочитаете другой
  • Перейдите в папку вашего проекта и запустите ctags -R .. Он создает файл ctags, который является индексом (базой данных) найденных определений.
  • Теперь перейдите в vim vim . и проверьте, доступны ли теги с помощью :tag ^D (нажмите CTRL-D)
  • Теперь вы можете перечислить теги, перейти к определению, вернуться на предыдущее место по b], CTRL-], CTRL-T соответственно.

  • (опционально) Вы можете запустить ctags -R -f .tags для создания скрытого файла вместо имени по умолчанию tags. Не забудьте изменить set tags+=tags;$HOME на set tags+=.tags;$HOME

  • (необязательно) Добавьте nmap <leader><leader> :!ctags -R -f .tags<CR> в .vimrc, если хотите быстрее обновлять индекс. Отслеживайте родительский каталог, когда вы делаете это до :pwd, чтобы не засорять каждую папку проекта tags файлами.

~/.ctags содержание:

--exclude=*.min.js
--exclude=*.min.css
--exclude=*.map
--exclude=.backup
--exclude=.sass-cache
--exclude=vendors
--exclude=.git

--langdef=css
--langmap=css:.css
--langmap=css:+.styl
--langmap=css:+.less
--regex-css=/^[ \t]*\.([A-Za-z0-9_-]+)/\1/c,class,classes/
--regex-css=/^[ \t]*#([A-Za-z0-9_-]+)/\1/i,id,ids/
--regex-css=/^[ \t]*(([A-Za-z0-9_-]+[ \t\n,]+)+)\{/\1/t,tag,tags/
--regex-css=/^[ \t]*@media\s+([A-Za-z0-9_-]+)/\1/m,media,medias/

--langdef=scss
--langmap=scss:.sass
--langmap=scss:+.scss
--regex-scss=/^[ \t]*@mixin ([A-Za-z0-9_-]+)/\1/m,mixin,mixins/
--regex-scss=/^[ \t]*@function ([A-Za-z0-9_-]+)/\1/f,function,functions/
--regex-scss=/^[ \t]*\$([A-Za-z0-9_-]+)/\1/v,variable,variables/
--regex-scss=/^([A-Za-z0-9_-]*)*\.([A-Za-z0-9_-]+) *[,{]/\2/c,class,classes/
--regex-scss=/^[ \t]+\.([A-Za-z0-9_-]+) *[,{]/\1/c,class,classes/
--regex-scss=/^(.*)*\#([A-Za-z0-9_-]+) *[,{]/\2/i,id,ids/
--regex-scss=/^[ \t]*#([A-Za-z0-9_-]+)/\1/i,id,ids/
--regex-scss=/(^([A-Za-z0-9_-])*([A-Za-z0-9_-]+)) *[,|\{]/\1/t,tag,tags/
--regex-scss=/(^([^\/\/])*)[ \t]+([A-Za-z0-9_-]+)) *[,|\{]/\3/t,tag,tags/
--regex-scss=/(^(.*, *)([A-Za-z0-9_-]+)) *[,|\{]/\3/t,tag,tags/
--regex-scss=/(^[ \t]+([A-Za-z0-9_-]+)) *[,|\{]/\1/t,tag,tags/
--regex-scss=/^[ \t]*@media\s+([A-Za-z0-9_-]+)/\1/d,media,media/
person Timur Fayzrakhmanov    schedule 11.11.2015