【问题标题】:Vim autocomplete from ctags for system headers only works when popup is triggered manually仅当手动触发弹出窗口时,系统标头的 ctags 的 Vim 自动完成功能才有效
【发布时间】:2013-01-02 09:17:24
【问题描述】:

在 OS X 上,我为系统生成了一组 ctag,包括使用以下命令:

ctags -f c -h ".h" -R --c-kinds=+p --fields=+iaS --extra=+q /usr/include

这是在 ~/.vim/ctags/ 目录中运行的,我将我为系统范围的头文件生成的所有 ctags 放置在其中(我也有条件加载的 ROS 和 CPP 的东西,但这既不是这里也不是那里) .

无论如何。 ctags 文件在我的 .vimrc 中设置正确,vim 肯定可以看到 ctags,但由于某种原因,如果我写出整个符号然后开始退格,自动完成弹出窗口将仅显示来自 #included 头文件的结果。举个例子,如果我在一个项目中#include <string.h>,然后我想调用strlen(),然后我开始在活动的vim缓冲区中输入str,我只会得到当前在vim 缓冲区。但是,如果我输入strlen,然后开始退格一两个字符并点击<C-n>,弹出菜单将填充来自任何其他包含的头文件的匹配项。

编辑:事实证明,如果我只是点击“s”然后<C-n>,它也可以。所以问题似乎是它只有在手动启动弹出菜单时才有效。这让我觉得这是一个插件问题(见下文)

附加信息:

  • completeopt 设置为completeopt=menuone,menu,preview,longest

  • 我有OmniCppComplete,我想这可能会干扰行为。目前仅针对 C++ 文件有条件地加载。如果您希望我从我的 .vimrc 编辑和发布我的 OmniCppComplete 设置,请询问。

  • 我也安装了AutoComplPop,但我没有对其进行任何配置,因此它以默认设置运行。还没有真正研究过这个插件,所以不知道它的某些行为是否会干扰结果。

  • 我已经安装了AutoTagTagBar,但它们应该只是摆弄当前目录的本地标记文件。

老实说,我对 Vim 很陌生,我只是不知道从哪里开始调试这个问题,无论是使用随机插件还是使用我的 .vimrc 设置。

【问题讨论】:

    标签: c macos vim autocomplete ctags


    【解决方案1】:

    Vim 有许多特定的完成机制。

    • <C-n><C-p> 使用complete 选项定义的许多源。默认情况下,它们将使用当前和所有加载和卸载的缓冲区、标签和包含的文件来提供补全。虽然您通常可以通过这些获得非常有用的建议,但它有点“包罗万象”的解决方案:如果您从事相当大的项目,它根本不可靠。

    • <C-x><C-]> 仅使用 标签,因此它可能对你更有用。

    • 还有更多,请参阅:h ins-completion

    • Omni 补全更智能:它通常运行自定义文件类型特定的脚本,努力提供有意义的补全。它由<C-x><C-o> 触发,您可以在:h ft-c-omni 中了解它。使用代码时,Omni 补全通常是更好的选择。

    因为你有两个重叠的“自动”完成插件,所以很难说什么完成机制在起作用。您应该禁用这些插件并尝试使用您可用的不同完成机制。

    【讨论】:

    • 问题似乎是 AutoComplPop 没有为 C 和 C++ 文件定义的内置行为,它回退到使用 <C-x><C-u>,不管它做什么。当我在 C 文件中使用 <C-x><C-o> 时,它会返回一个未找到模式的错误,所以现在我只是禁用 AutoComplPop 并使用 <C-n> 以获得最低限度的特定结果。我将不得不做更多的研究和实验。感谢您为我指明正确的方向!
    • <C-x><C-u> 调用您没有的自定义函数,因此出现错误。我也用 ACP。它也不支持 JavaScript,所以我对其进行了修改。实际上,即使对于我当时的菜鸟来说,这也很容易。请参阅here 和同一个地方的其他地方。
    • 感谢您的链接。不过,我收到了<C-x><C-o> 的错误,我仍然假设这意味着我的 vim 运行时中不存在响应 C 文件中给定模式的函数。不过,我会看看我是否不能根据配置来摆弄 AutoComplPop。看起来很琐碎。我唯一的问题是,您是如何创建acp#meetsForJavaScriptOmni 的?其他一切我都明白。
    • 我只是复制了另一个看起来或多或少像 JS 的定义。我认为是 Python 或 Ruby。并根据我的需要进行调整。我认为对 C 做同样的事情应该不会太难。
    • 非常感谢大家的帮助。我能够实现一个简单的正则表达式,在“。”上短路。和“->”,否则在 3 个字符后调用omnifunc。事实证明,真正的问题是 #included 文件被注册为关键字,所以 ACP 在前进的路上调用了关键字完成,因此结果范围更小,但是当我因为正则表达式而退格时,omnifunc范围界定。通过在加载 C 文件时设置全局变量,我将关键字触发器更改为也使用 omnifunc 而不是 ACP 的函数。
    【解决方案2】:

    我还没有掌握这一点,但我认为以下观察可能会有所帮助。

    Vim 的默认自动完成功能可能非常嘈杂,经常妨碍您使用 <C-x><C-o> 调用的内容。具体来说,我发现自己使用<C-x><C-o> 调用基于标签的补全,只是为了让它们替换,并使用我的打开缓冲区继续输入Vim 的默认建议。

    关闭其中一个插件的建议是有道理的。就我而言,关键是如何关闭 Vim 的默认行为。我见过几个人(现在包括我自己),在触发 Vim 的默认值之前将表达式的长度设置为很大的数字。对我来说是:

        let g:deoplete#auto_complete_start_length = 99
    

    ...这样你就可以消除默认的完成层,无论你打算通知你的工作的命令是什么。

    这仍然感觉像是一个 hack,但它有助于让我的工作专注于基于标签的完成。

    仅供参考:我在 Mac 上使用 NVIM。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-19
      • 2011-12-03
      • 1970-01-01
      • 2014-09-30
      • 1970-01-01
      • 2013-07-14
      • 2010-09-14
      • 1970-01-01
      相关资源
      最近更新 更多