Более точная альтернатива / обходной путь для ctags / Cscope для PHP?

Я знаю, что можно использовать Ctrl + ] для перехода к определению в Vim, и это может работать вместе с ctags или Cscope. Я ищу более точную альтернативу как ctags, так и Cscope при работе с PHP. Иногда есть несколько возможных результатов на выбор или ложные срабатывания. Я хочу только перейти к фактическому определению того, что находится под курсором. В идеале это должно работать для переменных, функций, констант и классов.

Я не понимаю, почему этого нельзя сделать, анализируя файлы. Я, наконец, преодолел почти все остальные раздражения / недоразумения, возникающие у меня с Vim, изучив и настроив, так что, если бы я мог решить это, было бы здорово.

Кроме того, согласны ли другие, что Cscope и ctags недостаточно точны для PHP, или я что-то делаю не так?

ОБНОВЛЕНИЕ

Спустя 4 года я все еще использую Vim с PHP, и эта проблема все еще не устранена. Я пробовал eclim, ctags, exubarant-ctags, universal-ctags и cscope. Я пробовал передавать этим программам различные аргументы, чтобы заставить их создавать более качественные теги. Опыт работы со всеми этими вариантами оставляет желать лучшего.

Но теперь я гораздо лучше понимаю проблему. В тегах, генерируемых этими программами, может быть нет ничего плохого. Проблема, похоже, в том, что когда вы нажимаете Ctrl + ] в Vim или Neovim, он просто ищет тег с таким именем. Он не смотрит на контекст файла, который вы редактируете, чтобы увидеть, какой тег с таким именем он должен использовать. Он даже не понимает, на каком языке вы редактируете, и ищет теги в коде на этом языке.

Есть ли способ сделать так, чтобы vim выполнял более интеллектуальный поиск в файле тегов в зависимости от контекста, а затем переходил к наиболее вероятному месту? Знаете, что могло бы случиться внутри хорошей IDE?


person still_dreaming_1    schedule 01.12.2011    source источник
comment
Похоже, что github.com/vim-php/phpctags может улучшить работу ctags для PHP. . Я когда-нибудь попробую.   -  person still_dreaming_1    schedule 10.03.2015


Ответы (6)


Как разработчик на C ++, у меня долгое время были похожие проблемы. До тех пор, пока я не реорганизовал свой подход к использованию файлов тегов в Vim несколько лет назад. Уловка, которая заставила меня работать, заключалась в том, чтобы сгенерировать отдельные файлы тегов для разных фрагментов кода: мой проект, различные библиотеки внешнего кода и т. Д. Затем мне пришлось установить параметр 'теги', чтобы искать файлы в приоритетном порядке. При этом мои файлы проекта с локальным кодом идут первыми, а затем работают дальше оттуда, причем файлы заголовков системы остаются ПОСЛЕДНИМИ.

В моем случае у меня были отдельные файлы тегов для каждого из них, и они были перечислены в следующем порядке в параметре 'теги':

  1. Мой местный проект
  2. Любой другой проект, который используется в этом проекте.
  3. Системные библиотеки (boost)
  4. Системные библиотеки (WxWidgets)
  5. Системные библиотеки (стандартные библиотеки C ++)
  6. Системные библиотеки (все остальное)

Я не разработчик PHP, но опять же основная ошибка, которую я совершал в течение долгого времени, заключалась в том, что я просто создавал один файл тегов ДЛЯ ВСЕГО. У меня было бы более 30 тегов для многократного поиска (с помощью команды: tag). Если вы создаете несколько файлов тегов, у вас гораздо больше контроля над порядком поиска тегов и, следовательно, над тем, какие теги и какие файлы находятся.

Посмотрите, работает ли это для вас. Это сработало для меня.

person David Harrison    schedule 10.03.2015
comment
Хотя ваш подход определенно хорош в качестве прагматичного ответа на вопрос, утверждение, что создание единого индекса нехорошо, является ошибкой. Настоящая проблема в том, что индекс не строится с использованием определенной языковой семантики. С философской точки зрения я часто ненавижу изменять свой рабочий процесс, когда он не дает реальных преимуществ (в отличие от искусственных преимуществ), и особенно когда все дело в том, что у инструментов, которые я использую, есть четкие ограничения. Тем не менее, по большому счету, это просто еще один компромисс, и мы делаем его каждый день. - person tne; 22.06.2015
comment
Удалено НЕ ХОРОШО как подход к использованию одного файла тегов для всего, и акцент сместился больше на то, как использование нескольких файлов тегов может помочь при поиске по тегам. - person David Harrison; 03.08.2015
comment
Это полезный совет. Это не решает полностью мою проблему, но это шаг вперед. - person still_dreaming_1; 29.02.2016

Чтобы улучшить ctags для PHP, вы можете создать файл тегов следующим образом:

#!/bin/bash
cd /path/to/framework/library
exec ctags-exuberant -f ~/.vim/mytags/framework \
-h ".php" -R \
--exclude="\.svn" \
--totals=yes \
--tag-relative=yes \
--PHP-kinds=+cf \
--regex-PHP='/abstract class ([^ ]*)/\1/c/' \
--regex-PHP='/interface ([^ ]*)/\1/c/' \
--regex-PHP='/(public |static |abstract |protected |private )+function ([^ (]*)/\2/f/'

затем загрузите теги

:set tags=~/.vim/mytags/framework

взято из моего сообщения в блоге

person helmi03    schedule 21.12.2011
comment
Я пробовал это, но после этого ctags все еще изрядно замедлился. Например, при попытке перейти к функции, которая существует в текущем файле, я попадаю в случайную строку в этом файле. - person still_dreaming_1; 04.02.2014
comment
Хорошо, по какой-то причине нажатие g ‹C -]› работает более точно, как не переход к случайной строке, как описано выше, даже если при этом не отображается список вариантов. На данный момент я сопоставил ‹C -]› с g ‹C -]› и посмотрю, как это пойдет ... - person still_dreaming_1; 04.02.2014

Вы также можете взглянуть на eclim.

Это может использовать функцию завершения eclipse, и она должна нормально работать для PHP (я не пробовал).

person xuhdev    schedule 15.02.2012
comment
Я пробовал eclim раньше и обнаружил, что его совсем не хватает по сравнению с настоящим Vim. Я сомневаюсь, что есть какой-либо плагин Vim или режим эмуляции для чего-либо, что меня удовлетворило бы. - person still_dreaming_1; 04.02.2014
comment
Как вы думаете, какой части не хватает eclim по сравнению с Vim? - person xuhdev; 04.02.2014
comment
Знаете что, я так давно не пробовал это, что уже не помню. Я только что снова посмотрел на страницу eclim, и мне показалось, что это хорошее решение, тем более что оно спроектировано так, чтобы вы могли использовать Vim в качестве основного редактора. Также я вижу, что он все еще находится в стадии активной разработки, так что это вселяет в меня надежду. Я снял голос против. Я попробую это, когда у меня будет время. - person still_dreaming_1; 06.02.2014
comment
Я обнаружил, что eclim работает лучше, чем ctags, но при добавлении дороговизны в зависимости от eclipse. Это делает перенос вашей конфигурации vim более сложной задачей, но если вас это не волнует, я бы дал эклиму шанс. - person Caleb Taylor; 04.04.2014
comment
Наконец-то я попробовал эклим. Это даже хуже, чем использовать теги. Я не понимаю этого, потому что, когда я использовал eclipse для проектов PHP, функция поиска определения кода работала очень хорошо. Но когда я использую контекстный поиск php под командой курсора для eclim, это совсем неразумно. - person still_dreaming_1; 29.02.2016

Долго боролся с той же проблемой, пока не нашел LanguageServer для PHP.

Он предоставляет такие функции, как GoToDefinition, ShowReferences, Теги в текущем документе и т. Д. Он отлично интегрируется с fzf прямо из коробки.

Что мне в нем не нравится:

  1. автозаполнение выполняется медленно по сравнению с другими фреймворками, такими как padawan
  2. он (пока) не кэширует индекс вашего проекта, что означает, что он должен переиндексировать, когда вы открываете neovim. Тем не менее, вы можете использовать функцию GoToDefinition, пока она индексируется.

Быстрая установка vim-plug:

Plug 'autozimu/LanguageClient-neovim', { 'do': ':UpdateRemotePlugins' }

Plug 'roxma/LanguageServer-php-neovim', {'do': 'composer install && composer run-script parse-stubs'}

autocmd FileType php LanguageClientStart

nnoremap <silent> gd :call LanguageClient_textDocument_definition()<CR>

nnoremap <silent> gr :call LanguageClient_textDocument_references()<CR>

Лучшее решение, которое я нашел до сих пор.

person phux    schedule 23.06.2017

Это скорее обходной путь, но если вы нажмете g CTRL+[ вместо просто CTRL+', вы получите список всех тегов с этим именем, и вы можете выбрать, к какому из них перейти.

person Idan Arye    schedule 02.12.2011
comment
На самом деле это то, чего я пытаюсь избежать. Весь смысл в том, чтобы перейти к определению, а не искать его вручную. Было бы легче самому подойти к определению, чем использовать его. - person still_dreaming_1; 04.02.2014

PHP не является хорошо разработанным языком, и он не имеет статической типизации. Таким образом, просто нет основы для создания каких-либо хороших инструментов такого рода, которые можно было бы использовать в реальных проектах. IDE, языковые серверы и плагины Vim и Neovim могут знать о коде ровно столько, сколько позволяет язык. Можно написать очень согласованный код на PHP с максимально возможным количеством типов и использовать только ограниченное подмножество языка, чтобы инструменты могли его понять. Однако, если ваша команда способна написать такой хороший PHP-код, они достаточно хороши, чтобы переписать код на более хорошо спроектированном языке, который может поддерживать еще лучшие инструменты, например, Kotlin, который также имеет отличную поддержку IDE.

person still_dreaming_1    schedule 01.08.2016