你没有做错任何事。Python 全方位补全不使用标签文件。这是故意的。您不需要为全方位完成制作标签文件。您仍然可以为通常的标签堆栈跳转制作标签文件,但它会被全能补全忽略。
我花了很长时间才弄清楚这一点,因为C 全方位完成确实使用了标签文件。Python 全方位补全的工作方式不同。
python
您可以通过在具有文件类型和文件类型的 Python 文件中尝试全能补全来快速观察此行为c
。
首先:set filetype=python
(这是默认设置),然后是:echo &omnifunc
. Omni complete 会忽略标签文件,因为&omnifunc
ispython3complete#Complete
不使用标签文件。
现在:set filetype=c
和:echo &omnifunc
。Vim 将 Python 脚本视为 C 文件,因此&omnifunc
is ccomplete#Complete
,它使用标签文件。当然,将 Python 文件视为 C 文件并不是解决方案!
以下是:
- 如何做 Python 全方位补全的两个例子
- ( syntaxcomplete
&omnifunc
#Complete) Vimscript 的实现位置
preview
标签文件预览 ( :pta
) 和全方位完整预览之间的窗口行为有何不同。
还有标签完成:<C-x><C-]>
. 如果您已经使用了一个tags
文件并希望 Vim 使用这些标签来<C-x><C-]>
完成,那么您正在寻找的是完成,而不是<C-x><C-o>
.
但我鼓励你继续阅读。Omni 补全不仅仅是标签补全:
- Omni 补全识别模块名称并使用正确的 Python 语法自动补全。例如,如果您
import numpy as np
,则显示以字母“a”开头np.a<C-x><C-o>
的功能菜单。numpy
标记完成仅自动完成标记文件中的匹配项。
- Omni 完成使用文档填充预览窗口。标记完成不会打开预览窗口。
- 而且,对于 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 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似乎损坏,请检查导入的模块是否可执行
如果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
选项必须包含preview
和menu
或menuone
。
completeopt
默认为menu,preview
. 明确设置选项,例如,改为menuone
使用menu
:
set completeopt=menuone,preview
menuone
使菜单始终出现,即使只有一个匹配的模式。使用menu
,菜单不会出现单个匹配项,因此preview
窗口也不会出现。使用menuone
保证会preview
弹出窗口。
关闭preview
以防止在全能完成期间窗口拆分:
set completeopt-=preview
请注意,(当您突出显示菜单项时打开)的行为与标签的行为(您使用preview
or打开)不同omni complete
preview
<C-w>}
:pta
- tag-preview 在预览窗口中打开代码
- omni-complete-preview 打开文档
Omni complete 会preview
根据完成菜单中突出显示的项目显示不同的内容。如果是变量,则显示其数据类型的 pydoc;如果它是一个函数,则显示其文档字符串。