Skip to content

Commit bda0b92

Browse files
committed
Implement rope autoimport.
1 parent 886d08b commit bda0b92

File tree

6 files changed

+69
-22
lines changed

6 files changed

+69
-22
lines changed

autoload/pymode/rope.vim

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,3 +145,10 @@ fun! pymode#rope#module_to_package() "{{{
145145
endif
146146
PymodePython rope.ModuleToPackageRefactoring().run()
147147
endfunction "}}}
148+
149+
fun! pymode#rope#autoimport(word) "{{{
150+
if !pymode#save()
151+
return 0
152+
endif
153+
PymodePython rope.autoimport()
154+
endfunction "}}}

ftplugin/python/pymode.vim

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ if g:pymode_options
5050
setlocal nowrap
5151
setlocal textwidth=79
5252
setlocal commentstring=#%s
53+
setlocal define=^\s*\\(def\\\\|class\\)
5354
endif
5455

5556
if g:pymode_lint
@@ -155,4 +156,8 @@ if g:pymode_rope
155156
command! -buffer PymodeRopeRenameModule call pymode#rope#rename_module()
156157
command! -buffer PymodeRopeModuleToPackage call pymode#rope#module_to_package()
157158

159+
if g:pymode_rope_autoimport
160+
command! -buffer PymodeRopeAutoImport call pymode#rope#autoimport(expand('<cword>'))
161+
end
162+
158163
end

pymode/rope.py

Lines changed: 48 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
import json
1111
import multiprocessing
1212
from .utils import (
13-
message, PY2, error, pymode_input, pymode_inputlist, pymode_y_n)
13+
pymode_message, PY2, pymode_error, pymode_input, pymode_inputlist, pymode_y_n)
1414

1515
if PY2:
1616
sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'libs'))
@@ -19,7 +19,7 @@
1919

2020
from rope.base import project, libutils, exceptions, change # noqa
2121
from rope.base.fscommands import FileSystemCommands # noqa
22-
from rope.contrib import autoimport, codeassist, findit # noqa
22+
from rope.contrib import autoimport as rope_autoimport, codeassist, findit # noqa
2323
from rope.refactor import ModuleToPackage, ImportOrganizer, rename, extract, inline, usefunction, move # noqa
2424
from rope.base.taskhandle import TaskHandle # noqa
2525

@@ -193,7 +193,7 @@ def show_doc():
193193
raise exceptions.BadIdentifierError
194194
vim.command('let l:output = %s' % json.dumps(doc.split('\n')))
195195
except exceptions.BadIdentifierError:
196-
error("No documentation found.")
196+
pymode_error("No documentation found.")
197197

198198

199199
def find_it():
@@ -259,7 +259,7 @@ def new():
259259
root = vim.eval('input("Enter project root: ", getcwd())')
260260
prj = project.Project(projectroot=root)
261261
prj.close()
262-
message("Project is opened: %s" % root)
262+
pymode_message("Project is opened: %s" % root)
263263

264264

265265
def undo():
@@ -272,7 +272,7 @@ def undo():
272272
with RopeContext() as ctx:
273273
changes = ctx.project.history.tobe_undone
274274
if changes is None:
275-
error('Nothing to undo!')
275+
pymode_error('Nothing to undo!')
276276
return False
277277

278278
if pymode_y_n(yes=False, msg='Undo [%s]?' % str(changes)):
@@ -291,7 +291,7 @@ def redo():
291291
with RopeContext() as ctx:
292292
changes = ctx.project.history.tobe_redone
293293
if changes is None:
294-
error('Nothing to redo!')
294+
pymode_error('Nothing to redo!')
295295
return False
296296

297297
if pymode_y_n(yes=False, msg='Redo [%s]?' % str(changes)):
@@ -318,6 +318,41 @@ def get_ctx(*args, **kwargs):
318318
return get_ctx
319319

320320

321+
def autoimport():
322+
""" Autoimport modules.
323+
324+
:return bool:
325+
326+
"""
327+
word = vim.eval('a:word')
328+
if not word:
329+
pymode_error("Should be word under cursor.")
330+
return False
331+
332+
def insert_import(name, module, ctx, source):
333+
linenum = int(ctx.importer.find_insertion_line(source))
334+
line = 'from %s insert %s' % (module, name)
335+
vim.current.buffer[linenum - 1:linenum - 1] = [line]
336+
337+
with RopeContext() as ctx:
338+
if not ctx.importer.names:
339+
ctx.generate_autoimport_cache()
340+
modules = ctx.importer.get_modules(word)
341+
if not modules:
342+
pymode_message('Global name %s not found.' % word)
343+
return False
344+
345+
source, _ = get_assist_params()
346+
if len(modules) == 1:
347+
insert_import(word, modules[0], ctx, source)
348+
349+
else:
350+
module = pymode_inputlist('Wich module to import:', modules)
351+
insert_import(word, module, ctx, source)
352+
353+
return True
354+
355+
321356
@cache_project
322357
class RopeContext(object):
323358

@@ -331,8 +366,8 @@ def __init__(self, path, project_path):
331366
self.project = project.Project(
332367
project_path, fscommands=FileSystemCommands())
333368

334-
self.importer = autoimport.AutoImport(project=self.project,
335-
observe=False)
369+
self.importer = rope_autoimport.AutoImport(
370+
project=self.project, observe=False)
336371

337372
update_python_path(self.project.prefs.get('python_path', []))
338373

@@ -388,7 +423,7 @@ def __init__(self, msg):
388423
def __call__(self):
389424
""" Show current progress. """
390425
percent_done = self.handle.current_jobset().get_percent_done()
391-
message('%s - done %s%%' % (self.message, percent_done))
426+
pymode_message('%s - done %s%%' % (self.message, percent_done))
392427

393428

394429
_scope_weight = {
@@ -413,7 +448,7 @@ def run(self):
413448

414449
with RopeContext() as ctx:
415450
try:
416-
message(self.__doc__)
451+
pymode_message(self.__doc__)
417452
refactor = self.get_refactor(ctx)
418453
input_str = self.get_input_str(refactor, ctx)
419454
if not input_str:
@@ -439,10 +474,10 @@ def run(self):
439474
ctx.project.do(changes, task_handle=progress.handle)
440475
reload_changes(changes)
441476
except exceptions.RefactoringError as e:
442-
error(str(e))
477+
pymode_error(str(e))
443478

444479
except Exception as e:
445-
error('Unhandled exception in Pymode: %s' % e)
480+
pymode_error('Unhandled exception in Pymode: %s' % e)
446481

447482
@staticmethod
448483
def get_refactor(ctx):
@@ -501,7 +536,7 @@ def get_input_str(self, refactor, ctx):
501536
newname = pymode_input(msg, oldname)
502537

503538
if newname == oldname:
504-
message("Nothing to do.")
539+
pymode_message("Nothing to do.")
505540
return False
506541

507542
return newname

pymode/run.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
import sys
1010
import vim # noqa
1111

12-
from .utils import error
12+
from .utils import pymode_error
1313

1414

1515
VIM_INPUT = lambda s: vim.eval('input("%s")' % s)
@@ -37,7 +37,7 @@ def run_code():
3737
# A non-false code indicates abnormal termination.
3838
# A false code will be treated as a
3939
# successful run, and the error will be hidden from Vim
40-
error("Script exited with code %s" % e.code)
40+
pymode_error("Script exited with code %s" % e.code)
4141
vim.command('return')
4242

4343
except Exception:

pymode/utils.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ def __wrapper():
2020
return __wrapper
2121

2222

23-
def message(content):
23+
def pymode_message(content):
2424
""" Show message. """
2525

2626
vim.command('call pymode#wide_message("%s")' % str(content))
@@ -51,13 +51,13 @@ def pymode_inputlist(msg, opts):
5151
input_str = 0
5252

5353
if not input_str:
54-
message('Cancelled!')
54+
pymode_message('Cancelled!')
5555
return False
5656

5757
try:
5858
return opts[input_str - 1]
5959
except (IndexError, ValueError):
60-
error('Invalid option: %s' % input_str)
60+
pymode_error('Invalid option: %s' % input_str)
6161
return pymode_inputlist(msg, opts)
6262

6363

@@ -81,7 +81,7 @@ def pymode_input(umsg, udefault='', opts=None):
8181
return input_str or default
8282

8383

84-
def error(content):
84+
def pymode_error(content):
8585
""" Show error. """
8686

8787
vim.command('call pymode#error("%s")' % str(content))
@@ -117,6 +117,6 @@ def wrapper(*args, **kwargs):
117117
try:
118118
return func(*args, **kwargs)
119119
except (Exception, vim.error): # noqa
120-
error(traceback.format_exc())
120+
pymode_error(traceback.format_exc())
121121
return None
122122
return wrapper

pymode/virtualenv.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import os.path
44
import vim # noqa
55

6-
from .utils import message
6+
from .utils import pymode_message
77

88

99
def enable_virtualenv():
@@ -30,7 +30,7 @@ def enable_virtualenv():
3030
source = f.read()
3131
exec(compile( # noqa
3232
source, activate_this, 'exec'), dict(__file__=activate_this))
33-
message('Activate virtualenv: ' + path)
33+
pymode_message('Activate virtualenv: ' + path)
3434
vim.command('let g:pymode_virtualenv_enabled = "%s"' % path)
3535
return True
3636
finally:

0 commit comments

Comments
 (0)