使用Python的Vim的Omnicompletion不起作用

时间:2010-01-18 09:08:04

标签: python vim autocomplete omnicomplete

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

  1. 我使用Python支持编译了Vim 7.2。

  2. filetype plugin on位于我的.vimrc

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

  4. 我正在处理一个大型项目,并且我使用tags生成了exhuberant-ctags个文件。它在Vim的ctags路径中。我可以通过在符号上键入 ^] 来测试它,然后我将其用于符号的定义。

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

  6. 现在,无论我在哪里尝试 C-x C-o ,我得到的只是:

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

    我做错了什么?

    更新2:当我在模块级别输入 Cx Co Cn 时,Vim会显示一个完成弹出窗口,其中包含项目中其他模块的几个模块级常量。但它只是常量(符号大写字母),并且完成在其他任何地方仍然不起作用。

    更新3:我发现文件顶部的 Cx Co 启动某种omnicompletion,pprint.完成后会显示菜单和pprint模块中所有内容的快速参考。但是,我自己的模块的导入都没有完成。

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

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

10 个答案:

答案 0 :(得分:12)

哪个模块包含您要完成的符号?它在python stdlib中吗?或者它是第三方模块?

确保模块/包在PYTHONPATH中。

在Vim中,请执行:

:python import sys
:python print sys.path

添加模块的目录:

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

答案 1 :(得分:9)

由于您谨慎并确保您的代码可以通过PYTHONPATH访问,根据代码提示,您是否有可能遇到import bug for Vim Python omni-complete?从Vim 7.2.245开始,这个bug仍然存在。

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

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

  • 确保导入的模块位于系统路径上,而不仅仅是项目文件
  • 评论任何失败的import语句
  • 修复错误
  • 使用ropevim作为完成方法
  • 使用不同的编辑器; Netbeans IDE支持Python,如果你是像我这样的Vim上瘾者,那么jVi plugin就相当不错了(不要让20世纪90年代的主页愚弄你)

答案 2 :(得分:9)

听起来提问者早已走向黑暗面*,但是对于它的价值我只是有这种症状,而在我的情况下,原因是我使用的模块依赖于Python 2.7但是我的版本Vim是用Python 2.5编译的。

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

要解决,我刚做sudo port install vim +python27。但这适用于OSX。 YMMV。

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

答案 3 :(得分:2)

更新到Fedora 16(但仍然从源代码编译vim),omni完成停止使用与上面相同的消息。我通过重新锁定键来“修复”它。

inoremap <C-space> <C-x><C-o>
<{1>}中的

现在再次有效。

答案 4 :(得分:2)

我有一个类似的问题,omni完成无法正常工作。在我的情况下,事实证明minibufexpl.vim插件干扰了omni完成。以下是我的发现:

正常关键字完成有效。 Omni complete不适用于任何语言,而不仅仅是Python。 omn​​ifunc设置正确。在我C-X C-O之后,没有任何事情发生。我做“:py print globals()”,很明显没有加载pythoncomplete。我可以“:调用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 :(得分:1)

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

我花了很长时间才弄清楚这个问题,因为 C omni完成确实使用了 标记文件。 Python全能完成的工作方式有所不同。

通过在文件类型为python然后在文件类型为c的Python文件中尝试全部完成,您可以快速观察到此行为。

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

现在:set filetype=c:echo &omnifunc。 Vim将Python脚本视为C文件,因此&omnifuncccomplete#Complete,它使用了标签文件。当然不能将Python文件像C文件一样对待!

以下是:

  • 两个如何完成Python全能的示例
  • 实施&omnifunc(语法完成#完整)Vimscript的地方
  • preview窗口行为在标记文件预览(:pta)和 全方位预览。

还有标签补全:<C-x><C-]>。如果您已经使用tags文件并希望Vim使用这些标签完成操作,则<C-x><C-]>是您要查找的完成内容,而不是<C-x><C-o>

但我鼓励您继续阅读。全方位补全不只是标记补全:

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

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

Python omni完成要求您正在编辑的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:全向匹配输入模块中的模式

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

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

import mymodule

一旦我输入了import mymodulei_<C-x><C-o>就会在 模块名称:

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

Omni complete将其转换为:

import mymodule
mymodule.

,然后弹出一个模式菜单(有关配置菜单,请参见:h completeopt 行为),此时我可以按照通常的<C-n><C-y>选择第一个 列表中的项目并退出omni,然后完全返回到插入模式。

import mymodule
mymodule.foo_name_I_expect_omni_completion

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

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

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

例如,我安装了3.6和3.7,但是我只安装了 包装于3.6。那个包是由我导入的模块导入的 在我尝试使用omni complete进行编辑的脚本中。

不知何故,python3.6是bash中我的默认python3,但是python3.7是我的 Vim默认。因此,当我从bash运行模块时,似乎模块有效,因为 我的python3.6安装具有必要的软件包。

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

python3 print(sys.version)

文档

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

从Vim帮助中:

:h compl-omni-filetypes
  

用于{filetype}的文件应该是autoload / {filetype} complete.vim   在“ runtimepath”中。因此,对于“ java”,它是autoload / javacomplete.vim。

这些autoload/{filetype}complete.vim文件在您的Vim安装中。例如,这是我的C和Python文件:

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

或者,调用:echo &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选项必须包含preview以及menumenuone

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

set completeopt=menuone,preview

menuone使菜单始终出现,即使只有一个匹配的模式也是如此。使用menu时,菜单不会出现单个匹配项,因此preview窗口也不会出现。使用menuone可确保弹出preview窗口。

关闭preview,以防止在全过程中窗口分裂:

set completeopt-=preview

请注意,preview的{​​{1}}行为(突出显示菜单项时将打开)与标签的omni complete行为(您使用preview打开)不同或<C-w>}

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

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

答案 6 :(得分:0)

您是否尝试过使用<C_x><C-]>

答案 7 :(得分:0)

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

答案 8 :(得分:0)

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

因为C-x C-o使用

有点令人沮丧 <。> .vimrc:

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

然后只使用Tabb进行omnicompletion

答案 9 :(得分:0)

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

sudo apt-get install vim.nox-py2 

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