You are not doing anything wrong. Python omni completion does not use a tags
file. This is on purpose. You do not need to make a tags file for omni
completion. You can still make a tags file for the usual tag-stack jumping, but
it is ignored by omni completion.
It took me a long time to figure this out because C omni completion does use
a tags file. Python omni completion works differently.
You can quickly observe this behavior by attempting omni completion in a Python file with python
filetype and then with c
filetype.
First :set filetype=python
(this is the default), then :echo &omnifunc
. Omni complete ignores the tags file because &omnifunc
is python3complete#Complete
, which does not use the tags file.
Note there is no omnifunc
set if your Vim is not built to support Python. Check for Python support.
Here is an example showing no Python support:
vim --version | grep python
+cmdline_hist +langmap -python +viminfo
+cmdline_info +libcall -python3 +virtualedit
Now :set filetype=c
and :echo &omnifunc
. Vim treats the Python script as a C file, so &omnifunc
is ccomplete#Complete
, which uses the tags file. Of course treating Python files like C files is not the solution!
Below are:
- two examples of how to do Python omni completion
- where the
&omnifunc
(syntaxcomplete#Complete) Vimscripts are implemented
- how
preview
window behavior differs between a tags file preview (:pta
) and
the omni complete preview.
There is also tag completion: <C-x><C-]>
. If you already use a tags
file and want Vim to complete using those tags, <C-x><C-]>
is the completion you are looking for, not <C-x><C-o>
.
But I encourage you to read on. Omni completion does more than tag completion:
- Omni completion recognizes module names and auto completes using the correct Python syntax. For example, if you
import numpy as np
, then np.a<C-x><C-o>
presents a menu of numpy
functions starting with letter 'a'. Tag completion only auto-completes a match in the tags file.
- Omni completion populates the preview window with documentation. Tag completion does not open a preview window.
- And, for Python, omni completion does not require updating a tags file!
Example 1: omni complete to match a pattern in this file
Python omni completion requires that the Python script you are editing is
working Python code. Here is a simple example with a local variable:
foo_name_I_expect_omni_completion
This one-line script does not run (my variable name is not defined), so if I
edit this script and attempt to omni complete:
foo_name_I_expect_omni_completion
foo_name_<C-x><C-o>
I get the "Pattern not found" message.
This is infuriating because the pattern it should match is literally on the
line above!
But all we need to make omni completion work is change this to valid
Python code:
foo_name_I_expect_omni_completion = 2
foo_name_<C-x><C-o>
Now omni completion works!
Note: an empty script docstring (the doctsring at the top of the script) also causes the "Pattern not found" message. Either erase the empty script docstring or put any text at all in the script docstring and omni completion works again.
Example 2: omni complete to match a pattern in an imported module
As a second example, omni completion also works if the pattern to match is in
another file, as long as that file is visible (with an import
statement) to
the script being edited.
Again, I'll use foo_name_I_expect_omni_completion=2
. I save the file with this
one-liner as mymodule.py
. Now in a new file, example.py
, I import
mymodule
:
import mymodule
Once I've typed import mymodule
, i_<C-x><C-o>
works on
the module name:
import mymodule
mym<C-x><C-o>
Omni complete turns this into:
import mymodule
mymodule.
and a menu of patterns pops up (see :h completeopt
for configuring the menu
behavior), at which point I can do the usual <C-n><C-y>
to select the first
item on the list and exit omni complete back to insert mode.
import mymodule
mymodule.foo_name_I_expect_omni_completion
If omni complete seems broken, check that the imported module is executable
If omni completion seems unable to see an imported module, it is because the
module you are importing is not executable.
Unlike the toy example above, this is hard to track down if the imported module
also imports packages and you have multiple versions of Python with different
packages installed in each version.
For example, I have 3.6 and 3.7 installed, but I'd only installed a certain
package on 3.6. And that same package was imported by the module I was importing
in the script I was trying to edit with omni complete.
Somehow, python3.6 was my default python3 from bash, but python3.7 was my
default from Vim. So the module seemed valid when I ran it from bash, because
my python3.6 installation had the necessary package.
Check which version of Python Vim is using:
:py3 print(sys.version)
Also check sys.path
, as explained in the answer by codeape:
:py3 print(sys.path)
I have many installations of Python, and every Python installation has its own USER_SITE
path.
:py3 import site; print(site.USER_SITE)
I use one USER_SITE
folder and find a way to point each Python installation at it. For the Python installation Vim omni-complete uses, I do this by editing the PYTHONPATH environment variable.
In my case, my one active USER_SITE
is for Python 3.7, and Vim is using Python 3.6, so I put this in my .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
Documentation
I figured this out by tracking down the Vim scripts that do the completion.
From Vim help:
:h compl-omni-filetypes
The file used for {filetype} should be autoload/{filetype}complete.vim
in 'runtimepath'. Thus for "java" it is autoload/javacomplete.vim.
These autoload/{filetype}complete.vim
files are in your Vim installation. For example, here are my C and Python files:
/usr/share/vim/vim81/autoload/ccomplete.vim
/usr/share/vim/vim81/autoload/python3complete.vim
Alternatively, call :echo &omnifunc
and find the Vimscript on GitHub:
https://github.com/vim/vim/blob/master/runtime/autoload/
I started to suspect my fundamental misunderstanding of the problem when I found the word tag
does not appear in the python3complete.vim
file :)
Omni complete has a special preview
behavior
I've always been confused by the behavior of the preview window. Omni complete has a different preview
behavior from tags.
First, to get a preview window with omni complete
, Vim completeopt
option must contain preview
and either menu
or menuone
.
completeopt
defaults to menu,preview
. To set options explicitly, e.g.,
to use menuone
instead on menu
:
set completeopt=menuone,preview
menuone
makes a menu always appear, even if there is only one pattern that matches. With menu
, the menu does not appear for a single match, so neither does the preview
window. Using menuone
guarantees the preview
window pops up.
Turn off preview
to prevent the window split during omni complete:
set completeopt-=preview
Notice that the preview
behavior for omni complete
(which opens when you highlight a menu item) is different from the preview
behavior for tags (which you open with <C-w>}
or :pta
)
- tag-preview opens the code in the preview window
- omni-complete-preview opens documentation
Omni complete's preview
shows different things depending on the item
highlighted in the completion menu. If it is a variable, the pydoc for its
datatype is shown; if it is a function, its docstring is shown.
minibufexpl.vim
andTaglist.vim
, but theTODO
listing thing would be a great addition. – Blowy+python
andfiletype plugin on
of course. – Kimbell