Vim's Omnicompletion with Python just doesn't work

21,946

Solution 1

What module contains the symbol you are trying to complete? Is it in the python stdlib? Or is it a third-party module?

Make sure that the module/package is in the PYTHONPATH.

In Vim, do:

:python import sys
:python print sys.path

To add the module's directory:

:python sys.path.append("/path/to/directory/")

Solution 2

Sounds like the questioner has long since gone to the dark side*, but for what it's worth I've just had this symptom, and in my case the cause was that a module I was using relied on Python 2.7 but my version of Vim was compiled with Python 2.5.

To diagnose I tried :python import mymodule, which failed with an error about importing a dependent module. Then :python import dependentmodule which failed with the next step in the chain. And so on & so on, until it failed trying to import a system module that was new since Python 2.7. Problem found.

To solve, I just did sudo port install vim +python27. But that's for OSX. YMMV.

(* I'm kidding. Emacs users are our friends. It's the people programming in Notepad we all have to save...)

Solution 3

Since you were prudent and made certain your code is reachable by the PYTHONPATH, per codeape's suggestion, is there a possibility that you are running into the import bug for Vim Python omni-complete? This bug still exists as of Vim 7.2.245.

Essentially, if any import statement fails in the file you are working in, regardless of whether it's wrapped in a Try-Except clause, it will completely break omni-completion. It should be fairly easy to check for this, since most imports occur at the very beginning of the file.

If you do decide that this bug is the cause of your troubles, your options include:

  • making sure that the modules you import are on the system path, not just the project files
  • commenting out any import statements that fail
  • fixing the bug
  • using ropevim as your completion method
  • using a different editor; Netbeans IDE has Python support, and the jVi plugin is rather good if you're a Vim addict like myself (don't let the 1990s look of the home page fool you)

Solution 4

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.

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:

  1. 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.
  2. Omni completion populates the preview window with documentation. Tag completion does not open a preview window.
  3. 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!

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.

Solution 5

I had a similar problem with omni completion not working. In my case it turned out that the minibufexpl.vim plugin was interfering with omni completion. Here is how I found out:

Normal keyword completion works. Omni complete does not work for any language, not just Python. omnifunc is set correctly. After I C-X C-O, nothing happens. I do ":py print globals()" and it is clear that the pythoncomplete was not loaded. I can ":call pythoncomplete#Complete(1, '')" and see it get loaded. To me this rules out it being a Vim issue. It seems something is interfering with keymapping or otherwise intercept the omni completion request. So I start to disable my plugins one by one. It turns out the culprit in my case is "minibufexpl". I have the Holgado version from github.

It looks like there are many open issues with MBE according to the issue tracker on github and there hasn't been any progress since early 2012. I am just going to disable it for now so I can use auto completion. Meanwhile I will just add the following to my vimrc to keep multiple modified buffers open at the same time and use a simple key sequence to cycle through them (MBE more intelligently select the buffers to cycle through but seems too heavy-handed for a simple problem):

set hidden
noremap <C-TAB> :bnext<CR>
noremap <C-S-TAB> :bprev<CR>
Share:
21,946
a paid nerd
Author by

a paid nerd

I'm a professional programmer. I also like riding bicycles. I haven't seen the ResEdit clown in a long time -- or in as anachronistic an environment ever. -- @ruffin 8bde9408bf59382c3194ec7c1bf6afbd837875d7

Updated on March 13, 2020

Comments

  • a paid nerd
    a paid nerd about 4 years

    I've searched around for an hour, both on Stack Overflow and elsewhere. Alas! Please help. Vim's omnicompletion just doesn't work.

    1. I have Vim 7.2 compiled with Python support.

    2. filetype plugin on is in my .vimrc.

    3. When a .py file is open, :echo &omnifunc prints pythoncomplete#Complete.

    4. I'm working with a large project and I have a tags file generated with exhuberant-ctags. It's in Vim's ctags path. I can test it by typing ^] on a symbol and I'm then taken to the symbols' definition.

    5. Update 1: All of my project's code is in the python-in-Vim's path. I can :python import myproject successfully.

    Now, anywhere I try C-x C-o, all I get is:

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

    What am I doing wrong?

    Update 2: When I type C-x C-o C-n at the module-level, Vim displays a completion popup with a few module-level constants from other modules in my project. But it's only constants (symbols capital letters) and the completion still doesn't work anywhere else.

    Update 3: I've found that C-x C-o at the top of the file starts some kind of omnicompletion, and completion for pprint. brings up the menu and quick-reference of everything in the pprint module. However, none of my own module's imports are being completed.

    Update 4, one year later: I gave up and learned Emacs. I have been to the dark side, the mystical land of intrigue and spice, and I say to thee that I have found The Way.

    Update 5, two years later: I went back to Vim. Emacs is beautiful, but even after 1.5 years of Emacs, I'm still faster at getting work done in Vim. I've stopped writing Python for now, however, and can't test how well these suggestions work.

  • a paid nerd
    a paid nerd over 14 years
    Good suggestions, thanks. These are symbols from my project's code. Yes, the path is in Vim's Python's path. I've updated the question description.
  • a paid nerd
    a paid nerd over 12 years
    This is one of the most promising solutions. Thanks!
  • Bodhi
    Bodhi about 12 years
    Interesting..I have a strong feeling I'm running into this too! I'm using MacVim (Macports build) with python support, and it's linked to (also Macports) Python 2.5 I'm working on a project that is Python 2.7 and I'm sure we import some 2.7-only modules. When mine fails on tab completing (Supertab plugin), it actually SEGV faults my vim session! I'm hoping reinstalling MacVim with python2.7 will solve it. Cheers!
  • Bodhi
    Bodhi about 12 years
    Felt a report back was worthwhile - my Supertab plugin and omnicompletion work much better now, but still do crash my macvim session sometimes :( It appears to be whenever there is something bad in the import sequence the completion is looking through (like a potential circular import for example). Things are looking up, anyway, thanks!
  • Bodhi
    Bodhi about 12 years
    I too have run into this issue of any import problem just trashing my omni-complete entirely. I think even "warnings" about a module having already been imported from a different location in the project will crash your vim session when you try to omni-complete it.
  • gotgenes
    gotgenes about 12 years
    Bodhi, have a look at ropevim. (See the link in my edited answer above.)
  • gitaarik
    gitaarik about 10 years
    So, is it not possible to have autocompletion in your own libraries?
  • codeape
    codeape about 10 years
    Yes it is possible, just make sure that the modules and packages are somewhere in Python's module search path.
  • alexche8
    alexche8 almost 10 years
    If you use virtualenv for your project, make sure that you switched to your environment in terminal before you will run vim(in the same terminal!). Check your sys.path in vim command line when you switched to env - modules that you need to autocomplete must be there.
  • nexayq
    nexayq about 7 years
    I fixed an issue by adding: let g:SuperTabDefaultCompletionType = "<c-n>" to my .vimrc (SuperTab plugin configuration)
  • mondaugen
    mondaugen about 4 years
    I tried this but got "Sorry, the command is not available in this version". But running vim --version showed +python3 and -python (python3 support but no python2) with my vim and the above commands work simply by changing python to python3.
  • Ignatius J. Reilly
    Ignatius J. Reilly almost 2 years
    I had to use :py3 instead of :python. However it did not solve my problem :-)