8

I've seen similar questions asked before here and here, however they are 4 years old and did not yield answers that matched my requirements.

If I type Python code into Vim, for example:

os.path.join('my', 'path')
resp = requests.get('http://example.com')
HttpResponse('success')

Assuming that I had the third-party modules 'requests' and 'django' in my site-packages folder, is there any Vim plugin -- which does not use the Rope library -- that could automatically add the relevant import statements to the Python file (both for built-in & third-party modules, using either import or from as needed), like this:

import os
import requests
from django.http import HttpResponse

While I would traditionally use the venerable Rope package, I have been replacing Rope functions with modern alternatives to avoid the overhead of the .ropeproject folder. However, I haven't found a Vim alternative yet for auto-import.

Community
  • 1
  • 1
Christian Abbott
  • 6,497
  • 2
  • 21
  • 26
  • 1
    What’s wrong with rope? It is under maintenance again, and one ``echo .ropeproject/ >>.git/info/exclude`` can cure all your problems, cannot it? – mcepl Oct 19 '17 at 10:23
  • Okay there's https://lyz-code.github.io/autoimport/#alternatives , writing a vim plugin to do that should not be too hard – user202729 Dec 07 '21 at 15:30
  • @user202729 There are thankfully now (6 years after I posted the question) some great solutions. For example, Neovim 0.5 (having built-in LSP support) paired with nvim-cmp and pyright can automatically add import statements when auto-completing a class or function name. Which is fantastic. Now if only auto-importing understood when it should import from parent modules rather than always from the bottom-most level, I'd be living the dream. – Christian Abbott Dec 09 '21 at 07:39

3 Answers3

4

I am using python-imports.vim (https://github.com/mgedmin/python-imports.vim). Combine that with gutentags plugin and it is almost perfect. Perfect solution would create all imports and magically guess correct modules in case of name collision but I doubt that this is possible.

Update 2022-05-14: Another way is to use Ale (https://github.com/dense-analysis/ale) with pyright (https://github.com/microsoft/pyright) and :ALEImport command.

daliusd
  • 1,025
  • 11
  • 15
  • Some other caveats I noticed with this one is it will add the import from a submodule even when it's available from a parent module, and also it doesn't combine multiple imports from the same module on a single line, but overall this plugin accomplishes this task very well. Great find. – Christian Abbott Nov 04 '18 at 08:06
  • Use isort fixer with ale (recommended) or isort plugin to combine multiple imports. Report bug for first problem (or maybe even fix it). – daliusd Nov 05 '18 at 08:54
  • I think this solution (as well as the **vimpy** solution below), requires the user to *put the cursor at the identifier* instead of go through the file automatically, unlike (supposedly) the solutions using [ropevim](https://stackoverflow.com/a/4081465/5267751) or [mr.igor](https://stackoverflow.com/a/3860373/5267751). – user202729 Aug 13 '21 at 03:21
1

Have a look at vimpy. From its description it does what you are looking for.

Note that it requires pyflakes.

Roland Smith
  • 42,427
  • 3
  • 64
  • 94
0

Very late to the party but since this question exists, I might as well post a new answer.

I use coc-python for everything of this nature.

It just works like magic:

enter image description here

The only caveat is that you have to press Ctrl-y to accept the Auto-import suggestion.

Make sure you haven't got Ctrl-y mapped to anything else in insert mode (a common plugin called Emmet remaps this combination, for example.)

LondonRob
  • 73,083
  • 37
  • 144
  • 201