你没有做错任何事。 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/{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 的预览窗口,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 打开)
- tag-preview 在预览窗口中打开代码
- omni-complete-preview 打开文档
Omni complete 的 preview 会根据项目显示不同的内容
在完成菜单中突出显示。如果它是一个变量,它的 pydoc
显示数据类型;如果是函数,则显示其文档字符串。