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.vim
和Taglist.vim
,但是TODO
列表将是一个很好的补充。
从来没有找到答案:(
Vim 7.3.45 全能补全 python 开箱即用,当然是 +python
和 filetype plugin on
。
【参考方案1】:
你没有做错任何事。 Python 全方位补全不使用标签 文件。这是故意的。您不需要为omni 创建标签文件 完成。您仍然可以为通常的标签堆栈跳转制作标签文件,但是 它被全能补全忽略。
我花了很长时间才弄清楚这一点,因为 C 全方位补全确实使用 一个标签文件。 Python 全方位补全的工作方式不同。
您可以通过在 Python 文件中尝试使用 python
文件类型和 c
文件类型的全向补全来快速观察到这种行为。
首先是:set filetype=python
(这是默认设置),然后是:echo &omnifunc
。 Omni Complete 会忽略标签文件,因为&omnifunc
是python3complete#Complete
,它不使用标签文件。
现在:set filetype=c
和:echo &omnifunc
。 Vim 将 Python 脚本视为 C 文件,因此 &omnifunc
是 ccomplete#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 mymodule
,i_<C-x><C-o>
就可以工作了
模块名称:
import mymodule
mym<C-x><C-o>
Omni complete 将其变成:
import mymodule
mymodule.
然后会弹出一个模式菜单(请参阅:h completeopt
配置菜单
行为),此时我可以执行通常的<C-n><C-y>
来选择第一个
列表中的项目并退出全能完全回到插入模式。
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 &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
和menu
或menuone
。
completeopt
默认为menu,preview
。明确设置选项,例如,
在menu
上使用menuone
:
set completeopt=menuone,preview
menuone
使菜单始终出现,即使只有一个匹配的模式。使用menu
,不会出现单个匹配的菜单,所以preview
窗口也不会出现。使用menuone
保证preview
窗口弹出。
关闭preview
以防止在全能完成期间窗口分裂:
set completeopt-=preview
请注意,omni complete
的 preview
行为(当您突出显示菜单项时打开)不同于标签的 preview
行为(您使用 <C-w>
或 :pta
打开)
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。 omnifunc 设置正确。在 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 = "<c-n>"
解决了一个问题【参考方案8】:
c-x c-n
用于获取对象的成员列表。
【讨论】:
【参考方案9】:您尝试过使用<C_x><C-]>
吗?
【讨论】:
【参考方案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 不起作用的主要内容,如果未能解决你的问题,请参考以下文章