51

我已经在 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成功。

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

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

我究竟做错了什么?

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

更新 3:我发现C-x C-o在文件的顶部开始了某种omnicompletion,并且completion for调出了模块pprint.中所有内容的菜单和快速参考。pprint但是,我自己的模块的导入都没有完成。

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

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

4

10 回答 10

12

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

确保模块/包在 PYTHONPATH 中。

在 Vim 中,执行:

:python import sys
:python print sys.path

添加模块目录:

:python sys.path.append("/path/to/directory/")
于 2010-01-18T13:35:29.237 回答
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 用户是我们的朋友。这是我们都必须保存在记事本中编程的人......)

于 2011-08-01T08:15:04.597 回答
9

由于您很谨慎,并确保 PYTHONPATH 可以访问您的代码,因此根据 codeape 的建议,您是否有可能遇到importVim Python 全方位的错误?这个错误在 Vim 7.2.245 中仍然存在。

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

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

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

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

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

python您可以通过在具有文件类型和文件类型的 Python 文件中尝试全能补全来快速观察此行为c

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

现在:set filetype=c:echo &omnifunc。Vim 将 Python 脚本视为 C 文件,因此&omnifuncis ccomplete#Complete,它使用标签文件。当然,将 Python 文件视为 C 文件并不是解决方案!

以下是:

  • 如何做 Python 全方位补全的两个例子
  • ( syntaxcomplete &omnifunc#Complete) Vimscript 的实现位置
  • preview标签文件预览 ( :pta) 和全方位完整预览之间的窗口行为有何不同。

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

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

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

示例 1:omni complete 以匹配此文件中的模式

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

foo_name_I_expect_omni_completion

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

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

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

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

但是我们需要让omni完成工作将其更改为有效的 Python代码:

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

现在全方位完成工作!

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

作为第二个示例,如果要匹配的模式在另一个文件中,只要该文件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>选择列表中的第一项并退出全能完整返回插入模式。

import mymodule
mymodule.foo_name_I_expect_omni_completion

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

如果omni completion 似乎不到导入的模块,那是因为您要导入的模块不可执行。

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

例如,我安装了 3.6 和 3.7,但我只在 3.6 上安装了某个包。我在尝试使用omni complete编辑的脚本中导入的模块也导入了同一个包。

不知何故,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} 的文件应该是 'runtimepath' 中的 autoload/{filetype}complete.vim。因此对于“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,Vimcompleteopt选项必须包含previewmenumenuone

completeopt默认为menu,preview. 明确设置选项,例如,改为menuone使用menu

set completeopt=menuone,preview

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

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

set completeopt-=preview

请注意,(当您突出显示菜单项时打开)的行为与标签的行为(您使用previewor打开)不同omni completepreview<C-w>}:pta

  • tag-preview 在预览窗口中打开代码
  • omn​​i-complete-preview 打开文档

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

于 2019-09-09T21:17:13.257 回答
2

我有一个类似的问题,全能完成不起作用。就我而言,结果证明 minibufexpl.vim 插件干扰了全能补全。这是我发现的方法:

正常的关键字完成工作。Omni complete 不适用于任何语言,而不仅仅是 Python。omn​​ifunc 设置正确。在我 CX CO 之后,什么也没有发生。我做了“: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>
于 2012-09-01T17:54:36.897 回答
2

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

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

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

于 2012-03-15T12:58:30.323 回答
1

你试过使用<C_x><C-]>吗?

于 2010-02-11T19:40:53.383 回答
0

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

由于 Cx Co 使用起来有点令人沮丧

在 .vimrc 中:

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

然后只需使用 Tabb 完成全功能

于 2011-03-04T10:11:45.790 回答
0

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

于 2010-06-24T00:01:43.930 回答
0

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

sudo apt-get install vim.nox-py2 

并使用 vim.nox-py2 而不是 vim。

于 2017-03-30T09:28:53.030 回答