Vim 的 Python Omnicompletion 不起作用

Posted

技术标签:

【中文标题】Vim 的 Python Omnicompletion 不起作用【英文标题】:Vim's Omnicompletion with Python just doesn't work 【发布时间】:2011-01-06 07:01:10 【问题描述】:

我已经在 Stack Overflow 和其他地方搜索了一个小时。唉!请帮忙。 Vim 的omnicompletion 只是不起作用

    我已经编译了支持 Python 的 Vim 7.2。

    filetype plugin on 在我的.vimrc 中。

    .py 文件打开时,:echo &omnifunc 打印pythoncomplete#Complete

    我正在处理一个大型项目,我有一个使用exhuberant-ctags 生成的tags 文件。它在 Vim 的 ctags 路径中。我可以通过在符号上键入 ^] 来测试它,然后我会转到符号的定义。

    更新 1: 我所有项目的代码都在 python-in-Vim 的路径中。我可以:python import myproject成功了。

现在,无论我尝试 C-x C-o,我得到的都是:

-- Omni completion (^O^N^P) Pattern not found

我做错了什么?

更新 2: 当我在模块级键入 Cx Co Cn 时,Vim 会显示一个完成弹出窗口,其中包含来自我项目中其他模块的一些模块级常量.但它只是常量(符号大写字母),并且在其他任何地方都无法完成。

更新 3: 我发现文件顶部的 Cx Co 开始了某种全补全功能,pprint. 的补全会调出菜单并pprint 模块中所有内容的快速参考。但是,我自己的模块的导入都没有完成。

一年后更新 4: 我放弃并学习了 Emacs。我去过黑暗的一面,那是充满阴谋和香料的神秘之地,我告诉你我找到了道路。

两年后更新 5: 我又回到了 Vim。 Emacs 很漂亮,但即使在使用 Emacs 1.5 年后,我在 Vim 中完成工作的速度仍然更快。不过,我现在已经停止编写 Python,并且无法测试这些建议的效果如何。

【问题讨论】:

如果您还没有,您可能想尝试一下:blog.dispatched.ch/2009/05/24/vim-as-python-ide @jellybean -- 很好的链接,谢谢!我已经使用了minibufexpl.vimTaglist.vim,但是TODO 列表将是一个很好的补充。 从来没有找到答案:( Vim 7.3.45 全能补全 python 开箱即用,当然是 +pythonfiletype plugin on 【参考方案1】:

你没有做错任何事。 Python 全方位补全不使用标签 文件。这是故意的。您不需要为omni 创建标签文件 完成。您仍然可以为通常的标签堆栈跳转制作标签文件,但是 它被全能补全忽略。

我花了很长时间才弄清楚这一点,因为 C 全方位补全确实使用 一个标签文件。 Python 全方位补全的工作方式不同。

您可以通过在 Python 文件中尝试使用 python 文件类型和 c 文件类型的全向补全来快速观察到这种行为。

首先是:set filetype=python(这是默认设置),然后是:echo &omnifunc。 Omni Complete 会忽略标签文件,因为&omnifuncpython3complete#Complete,它不使用标签文件。

现在:set filetype=c:echo &omnifunc。 Vim 将 Python 脚本视为 C 文件,因此 &omnifuncccomplete#Complete,它使用标签文件。当然把 Python 文件当成 C 文件处理不是解决办法!

以下是:

如何进行 Python 全方位补全的两个示例 &omnifunc (syntaxcomplete#Complete) Vimscript 的实现位置 preview 窗口行为在标签文件预览 (:pta) 和 全方位完整预览。

还有标签补全:<C-x><C-]>。如果你已经使用了tags 文件并希望 Vim 使用这些标签来完成,<C-x><C-]> 是你正在寻找的完成,而不是 <C-x><C-o>

但我鼓励您继续阅读。 Omni 补全不仅仅是标签补全:

    Omni 补全识别模块名称并使用正确的 Python 语法自动补全。例如,如果您import numpy as np,则np.a<C-x><C-o> 会显示一个以字母“a”开头的numpy 功能菜单。标记完成只会自动完成标记文件中的匹配项。 Omni 补全会在预览窗口中填充文档。标记完成不会打开预览窗口。 而且,对于 Python,omni 补全不需要更新标签文件!

示例 1:完全匹配此文件中的模式

Python 全方位补全要求您正在编辑的 Python 脚本是 工作 Python 代码。这是一个带有局部变量的简单示例:

foo_name_I_expect_omni_completion

这个单行脚本不运行(我的变量名没有定义),所以如果我 编辑此脚本并尝试完全完成:

foo_name_I_expect_omni_completion
foo_name_<C-x><C-o>

我收到“找不到模式”消息。

这很令人生气,因为它应该匹配的模式实际上是在 上一行!

但我们只需要将其更改为 有效 Python代码:

foo_name_I_expect_omni_completion = 2
foo_name_<C-x><C-o>

现在全能补全工作了!

示例 2:omnicomplete 以匹配导入模块中的模式

作为第二个示例,如果要匹配的模式在 另一个文件,只要该文件可见(带有import 语句) 正在编辑的脚本。

再次,我将使用foo_name_I_expect_omni_completion=2。我用这个保存文件 单线为mymodule.py。现在在一个新文件中,example.py,我导入 mymodule:

import mymodule

一旦我输入了import mymodulei_&lt;C-x&gt;&lt;C-o&gt; 就可以工作了 模块名称:

import mymodule
mym<C-x><C-o>

Omni complete 将其变成:

import mymodule
mymodule.

然后会弹出一个模式菜单(请参阅:h completeopt 配置菜单 行为),此时我可以执行通常的&lt;C-n&gt;&lt;C-y&gt; 来选择第一个 列表中的项目并退出全能完全回到插入模式。

import mymodule
mymodule.foo_name_I_expect_omni_completion

如果omni complete似乎损坏,请检查导入的模块是否可执行

如果全能补全似乎无法看到导入的模块,那是因为 您正在导入的模块不可执行。

与上面的玩具示例不同,如果导入的模块很难追踪 还导入包,你有多个不同版本的 Python 每个版本中安装的软件包。

例如,我安装了 3.6 和 3.7,但我只安装了某个 3.6 包。我正在导入的模块也导入了同一个包 在脚本中,我尝试使用全功能进行编辑。

不知何故,python3.6 是我在 bash 中的默认 python3,但 python3.7 是我的 Vim 的默认设置。所以当我从 bash 运行它时,模块 似乎 有效,因为 我的 python3.6 安装有必要的包。

检查正在使用的 Python Vim 版本:

:py3 print(sys.version)

还要检查sys.path,正如codeape的回答中所解释的那样:

:py3 print(sys.path)

我安装了很多 Python,每个 Python 安装都有自己的USER_SITE 路径。

:py3 import site; print(site.USER_SITE)

我使用一个USER_SITE 文件夹并找到一种方法将每个Python 安装指向它。对于 Python 安装 Vim omni-complete 使用,我通过编辑 PYTHONPATH 环境变量来做到这一点。

在我的情况下,我的一个活动 USER_SITE 用于 Python 3.7,而 Vim 使用的是 Python 3.6,所以我把它放在我的 .bashrc 中:

# Python USERSITE folder
pkg=$HOME/.local/lib/python3.7/site-packages/

# Add to PYTHONPATH for Vim omni-complete to see packages I wrote
PYTHONPATH=$PYTHONPATH:$pkg

文档

我通过跟踪完成完成的 Vim 脚本来解决这个问题。

来自 Vim 帮助:

:h compl-omni-filetypes

用于 filetype 的文件应该是 autoload/filetypecomplete.vim 在“运行时路径”中。因此对于“java”,它是 autoload/javacomplete.vim。

这些autoload/filetypecomplete.vim 文件在你的 Vim 安装中。例如,这是我的 C 和 Python 文件:

/usr/share/vim/vim81/autoload/ccomplete.vim
/usr/share/vim/vim81/autoload/python3complete.vim

或者,调用 :echo &amp;omnifunc 并在 GitHub 上找到 Vimscript: https://github.com/vim/vim/blob/master/runtime/autoload/

当我发现tag这个词没有出现在python3complete.vim文件中时,我开始怀疑我对这个问题的根本误解:)

Omni complete 具有特殊的preview 行为

我一直对预览窗口的行为感到困惑。 Omni complete 具有与标签不同的 preview 行为。

首先,要获得带有omni complete 的预览窗口,Vim 的completeopt 选项必须包含previewmenumenuone

completeopt 默认为menu,preview。明确设置选项,例如, 在menu 上使用menuone

set completeopt=menuone,preview

menuone 使菜单始终出现,即使只有一个匹配的模式。使用menu,不会出现单个匹配的菜单,所以preview 窗口也不会出现。使用menuone 保证preview 窗口弹出。

关闭preview 以防止在全能完成期间窗口分裂:

set completeopt-=preview

请注意,omni completepreview 行为(当您突出显示菜单项时打开)不同于标签的 preview 行为(您使用 &lt;C-w&gt;:pta 打开)

tag-preview 在预览窗口中打开代码 omni-complete-preview 打开文档

Omni complete 的 preview 会根据项目显示不同的内容 在完成菜单中突出显示。如果它是一个变量,它的 pydoc 显示数据类型;如果是函数,则显示其文档字符串。

【讨论】:

【参考方案2】:

如果你使用的是python2,请确保你

sudo apt-get install vim.nox-py2 

并使用 vim.nox-py2 代替 vim。

【讨论】:

【参考方案3】:

由于您谨慎并确定您的代码可以通过 PYTHONPATH 访问,根据 codeape 的建议,您是否有可能遇到import bug for Vim Python omni-complete?这个错误在 Vim 7.2.245 中仍然存在。

基本上,如果 any 导入语句在您正在处理的文件中失败,无论它是否包含在 Try-Except 子句中,它都会完全破坏全能补全。检查这一点应该相当容易,因为大多数导入都发生在文件的开头。

如果您确定此错误是造成您麻烦的原因,您的选择包括:

确保您导入的模块位于系统路径中,而不仅仅是项目文件 注释掉任何失败的 import 语句 修复错误 使用ropevim 作为完成方法 使用不同的编辑器; Netbeans IDE 支持 Python,如果您像我一样是 Vim 上瘾者,jVi plugin 相当不错(不要让 1990 年代的主页欺骗了您)

【讨论】:

我也遇到过任何导入问题的问题,只是完全破坏了我的全功能。我认为即使是关于已经从项目中不同位置导入的模块的“警告”也会在您尝试全能完成时使您的 vim 会话崩溃。 菩提,看看ropevim。 (请参阅上面我编辑的答案中的链接。)【参考方案4】:

我遇到了类似的问题,即全能补全不起作用。就我而言,结果证明 minibufexpl.vim 插件干扰了全功能补全。我是这样发现的:

正常的关键字完成工作。 Omni complete 不适用于任何语言,而不仅仅是 Python。 omn​​ifunc 设置正确。在 I C-X C-O 之后,什么也没有发生。我做了“:py print globals()”,很明显没有加载pythoncomplete。我可以 ":call pythoncomplete#Complete(1, '')" 并看到它被加载。对我来说,这排除了它是一个 Vim 问题。似乎有些东西干扰了键映射或以其他方式拦截了全方位完成请求。所以我开始一一禁用我的插件。事实证明,我的罪魁祸首是“minibufexpl”。我有来自 github 的 Holgado 版本。

根据 github 上的问题跟踪器,MBE 似乎存在许多未解决的问题,自 2012 年初以来没有任何进展。我现在将禁用它,以便使用自动完成功能。同时,我将在我的 vimrc 中添加以下内容,以同时打开多个修改过的缓冲区,并使用一个简单的键序列来循环它们(MBE 更智能地选择要循环的缓冲区,但对于一个简单的问题来说似乎过于笨拙):

set hidden
noremap <C-TAB> :bnext<CR>
noremap <C-S-TAB> :bprev<CR>

【讨论】:

【参考方案5】:

已更新到 Fedora 16(但仍从源代码编译 vim),omni completion 停止工作,并出现与上述相同的消息。我通过重新映射键来“修复”它。

inoremap <C-space> <C-x><C-o>

~/.vimrc 中,现在它又可以工作了。

【讨论】:

【参考方案6】:

听起来提问者早已陷入黑暗面*,但值得一提的是,我刚刚出现了这种症状,在我的情况下,原因是我使用的模块依赖于 Python 2.7,但我的版本Vim 是用 Python 2.5 编译的。

为了诊断,我尝试了:python import mymodule,但由于导入依赖模块的错误而失败。然后:python import dependentmodule 在链中的下一步失败。依此类推,直到尝试导入自 Python 2.7 以来新的系统模块失败。发现问题。

为了解决,我刚刚做了sudo port install vim +python27。但这是针对 OSX 的。 YMMV。

(* 我在开玩笑。Emacs 用户是我们的朋友。我们都必须保存使用记事本编程的人...)

【讨论】:

这是最有前途的解决方案之一。谢谢! 有趣..我有一种强烈的感觉,我也遇到了这个!我正在使用带有 python 支持的 MacVim(Macports 构建),它链接到(也是 Macports)Python 2.5 我正在开发一个 Python 2.7 项目,我确信我们导入了一些仅限 2.7 的模块。当我的选项卡完成失败(Supertab 插件)时,它实际上是 SEGV 使我的 vim 会话出错!我希望用 python2.7 重新安装 MacVim 可以解决它。干杯! 觉得回报是值得的 - 我的 Supertab 插件和omnicompletion 现在工作好多,但仍然有时会导致我的macvim会话崩溃:(似乎每当导入序列中出现问题时,完成正在查看(例如潜在的循环导入)。无论如何,事情正在寻找,谢谢!【参考方案7】:

我使用了 supertab (http://www.vim.org/scripts/script.php?script_id=1643)

由于 C-x C-o 使用起来有点令人沮丧

在 .vimrc 中:

let g:SuperTabDefaultCompletionType = "<c-x><c-o>"

然后只需使用 Tabb 进行全补

【讨论】:

我通过在我的 .vimrc(SuperTab 插件配置)中添加:let g:SuperTabDefaultCompletionType = "&lt;c-n&gt;" 解决了一个问题【参考方案8】:

c-x c-n 用于获取对象的成员列表。

【讨论】:

【参考方案9】:

您尝试过使用&lt;C_x&gt;&lt;C-]&gt; 吗?

【讨论】:

【参考方案10】:

哪个模块包含您要完成的符号?它在 python 标准库中吗?还是第三方模块?

确保模块/包在 PYTHONPATH 中。

在 Vim 中,执行:

:python import sys
:python print sys.path

添加模块目录:

:python sys.path.append("/path/to/directory/")

【讨论】:

好的建议,谢谢。这些是我项目代码中的符号。是的,路径在 Vim 的 Python 路径中。我已经更新了问题描述。 那么,是不是不能在自己的库中实现自动补全? 是的,这是可能的,只要确保模块和包在 Python 的模块搜索路径中的某个位置。 如果您在项目中使用 virtualenv,请确保在运行 vim 之前切换到终端中的环境(在同一个终端中!)。当您切换到 env 时,在 vim 命令行中检查您的 sys.path - 您需要自动完成的模块必须存在。 我试过了,但得到“对不起,这个版本的命令不可用”。但是在我的 vim 中运行 vim --version 显示 +python3 和 -python(python3 支持但不支持 python2),上述命令只需将 python 更改为 python3 即可。

以上是关于Vim 的 Python Omnicompletion 不起作用的主要内容,如果未能解决你的问题,请参考以下文章

支持vim为python IDE

vim配置python编程环境及YouCompleteMe的安装教程

使用vim搭建python开发环境-

[转] vim配置python自动补全

用 Vim 写 Python 的最佳实践

Vim配置(python版)