【问题标题】:More accurate alternative/workaround to ctags/Cscope for PHP?PHP 的 ctags/Cscope 更准确的替代方案/解决方法?
【发布时间】:2012-01-11 02:06:17
【问题描述】:

我知道可以使用 Ctrl+] 来跳转到 Vim 中的定义,这可以与 ctags 或 Cscope 结合使用。在使用 PHP 时,我正在寻找一个更准确的替代 ctags 和 Cscope 的方法。有时有多种可能的结果可供选择或误报。我只想跳转到 光标下任何内容的实际定义。理想情况下,这应该适用于变量、函数、常量和类。

我不明白为什么这不能通过分析文件来完成。通过学习和定制,我终于克服了我对 Vim 的所有其他烦恼/误解,所以如果我能解决这个问题,那就太棒了。

另外,其他人是否同意 Cscope 和 ctags 对于 PHP 不够准确,或者我做错了什么?

更新

4 年后,我仍在使用 Vim 和 PHP,但仍然遇到这个问题。我尝试过 eclim、ctags、exubarant-ctags、universal-ctags 和 cscope。我尝试将各种参数传递给这些程序,以使它们生成更好的标签。所有这些选项的体验都很差。

但我现在更好地理解了这个问题。这些程序生成的标签可能没有任何问题。问题似乎是,当您在 Vim 或 Neovim 中按 Ctrl + ] 时,它只会查找该名称的标签。它不会查看您正在编辑的文件的上下文以查看它应该使用哪个名称的标签。它甚至不了解您正在编辑的语言,并从该语言的代码中查找标签。

有没有办法让vim根据上下文更智能地搜索标签文件,然后跳转到最可能的位置?你知道,就像在一个好的 IDE 中会发生什么?

【问题讨论】:

标签: php vim ctags cscope


【解决方案1】:

更多的解决方法,但如果你按g CTRL+[ 而不是CTRL+',你会得到一个包含该名称的所有标签的列表,你可以选择跳转到哪个标签。

【讨论】:

  • 其实这是我想要避免的。重点是跳转到定义,而不是手动搜索它。自己去定义比使用它更容易。
【解决方案2】:

要改进 PHP 的 ctags,您可以创建如下标签文件:

#!/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

取自我的blog post

【讨论】:

  • 我试过这个,但在这之后 ctags 仍然很重。例如,当尝试导航到当前文件中存在的函数时,它会将我带到该文件中的随机行。
  • 好的,由于某种原因,按 g 可以更准确地工作,因为如上所述不会跳转到随机行,即使这不会显示选项列表。现在我已经将 映射到 g 并且将看到它是如何进行的......
【解决方案3】:

您可能还想看看eclim

这可以利用 eclipse 的补全功能,它应该适用于 PHP(我没有尝试过)。

【讨论】:

  • 我之前尝试过eclim,发现它与真正的Vim相比非常缺乏。我怀疑是否有任何我会满意的 Vim 插件或仿真模式。
  • 你觉得eclim比Vim少了哪一部分?
  • 你知道吗,我已经很久没有尝试这个了,我已经不记得了。我刚刚再次查看了 eclim 页面,它似乎是一个很好的解决方案,尤其是因为它的设计目的是让您可以使用 Vim 作为您的主要编辑器。我也看到它一直在积极开发中,所以这给了我希望。我现在已经删除了反对票。有时间我会试试这个。
  • 我发现 eclim 比 ctags 工作得更好,但依赖于 eclipse 会增加成本。它使移植你的 vim 配置更加痛苦,但如果你不关心这一点,我会给 eclim 一个机会。
  • 我终于尝试了eclim。它甚至比使用标签更糟糕。我不明白这一点,因为当我以前在 PHP 项目中使用 eclipse 时,代码定义查找功能工作得很好。但是当我对eclim使用cursor命令下的上下文php查找时,它一点也不智能。
【解决方案4】:

作为一名 C++ 开发人员,我长期以来一直遇到类似的问题。直到几年前,我重新组织了在 Vim 下使用标记文件的方法。让它对我有用的技巧是为不同的代码片段生成单独的标签文件:我的项目、各种外部代码库等......然后我必须设置“标签”选项以优先查找文件顺序,我的本地代码项目文件首先出现,然后从那里向外工作,系统头文件是最后的。

在我的例子中,我为每一个都有单独的标签文件,并在“标签”选项中按此顺序列出:

  1. 我的本地项目
  2. 此项目使用的任何其他项目
  3. 系统捆绑库(增强)
  4. 系统捆绑库 (WxWidgets)
  5. 系统库(C++ 标准库)
  6. 系统库(所有其他)

我不是 PHP 开发人员,但长期以来我犯的主要错误就是为所有内容生成单个标签文件。我将有超过 30 个标签进行多次搜索(使用 :tag 命令)。如果您生成多个标签文件,您可以更好地控制标签的搜索顺序,从而控制在哪些标签中找到文件。

看看这是否适合你。它对我有用。

【讨论】:

  • 虽然您的方法作为对问题的实用 答案绝对是好的,但说生成单个索引“不好”是一种谬论。 真正的 问题是索引不是使用特定语言语义构建的。从哲学上讲,我经常讨厌修改我的工作流程,因为它没有真正的好处(而不是人为的好处),尤其是当我使用的工具有明显的局限性时。话虽如此,总体而言,这只是另一种妥协,我们每天都会做出很多妥协。
  • 删除了“不好”作为对所有内容使用单个标签文件的方法,并将重点更多地转移到如何使用多个标签文件有助于通过标签进行搜索。
  • 这是有用的建议。它并没有完全解决我的问题,但它向前迈进了一步。
【解决方案5】:

PHP 不是一种设计良好的语言,它也不是静态类型的。因此,没有任何基础可以制造出在现实世界项目中实用的此类好的工具。 IDE、语言服务器以及 Vim 和 Neovim 插件只能在语言允许的范围内了解代码。可以用尽可能多的类型在 PHP 中编写非常一致的代码,并且只使用语言的有限子集,以便工具可以理解它。但是,如果您的团队能够编写出如此优秀的 PHP 代码,那么他们就足以用一种设计更完善的语言来重写代码,这种语言可以支持更好的工具,比如 Kotlin,它也有很好的 IDE 支持。

【讨论】:

    【解决方案6】:

    为同样的问题苦苦挣扎了很久,直到找到LanguageServer for 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>

    迄今为止我发现的最佳解决方案。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-04-13
      • 2016-10-24
      • 2020-08-29
      • 2011-02-27
      • 2018-11-16
      • 1970-01-01
      • 2014-09-27
      相关资源
      最近更新 更多