Skip to content
6 changes: 6 additions & 0 deletions autoload/pymode.vim
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,15 @@ fun! pymode#PlaceSigns() "{{{
"
if has('signs')
sign unplace *

if !pymode#Default("g:pymode_lint_signs_always_visible", 0) || g:pymode_lint_signs_always_visible
call RopeShowSignsRulerIfNeeded()
endif

for item in filter(getqflist(), 'v:val.bufnr != ""')
execute printf('silent! sign place 1 line=%d name=%s buffer=%d', item.lnum, item.type, item.bufnr)
endfor

endif
endfunction "}}}

Expand Down
45 changes: 44 additions & 1 deletion plugin/pymode.vim
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,10 @@ if !pymode#Default("g:pymode_lint", 1) || g:pymode_lint
" OPTION: g:pymode_lint_mccabe_complexity -- int. Maximum allowed complexity
call pymode#Default("g:pymode_lint_mccabe_complexity", 8)

" OPTION: g:pymode_lint_signs_always_visible -- bool. Always show the
" errors ruller, even if there's no errors.
call pymode#Default("g:pymode_lint_signs_always_visible", 0)

" OPTION: g:pymode_lint_signs -- bool. Place error signs
if (!pymode#Default("g:pymode_lint_signs", 1) || g:pymode_lint_signs) && has('signs')

Expand All @@ -109,6 +113,12 @@ if !pymode#Default("g:pymode_lint", 1) || g:pymode_lint
sign define E text=EE texthl=Error
sign define I text=II texthl=Info

if !pymode#Default("g:pymode_lint_signs_always_visible", 0) || g:pymode_lint_signs_always_visible
" Show the sign's ruller if asked for, even it there's no error to show
sign define __dummy__
autocmd BufRead,BufNew * call RopeShowSignsRulerIfNeeded()
endif

endif

" DESC: Set default pylint configuration
Expand Down Expand Up @@ -175,9 +185,17 @@ endif

if !pymode#Default("g:pymode_rope", 1) || g:pymode_rope

" OPTION: g:pymode_rope_auto_project -- bool. Auto open ropeproject
" OPTION: g:pymode_rope_auto_project -- bool. Auto create ropeproject
call pymode#Default("g:pymode_rope_auto_project", 1)

" OPTION: g:pymode_rope_auto_project_open -- bool.
" Auto open existing projects, ie, if the current directory has a
" `.ropeproject` subdirectory.
call pymode#Default("g:pymode_rope_auto_project_open", 1)

" OPTION: g:pymode_rope_auto_session_manage -- bool
call pymode#Default("g:pymode_rope_auto_session_manage", 0)

" OPTION: g:pymode_rope_enable_autoimport -- bool. Enable autoimport
call pymode#Default("g:pymode_rope_enable_autoimport", 1)

Expand Down Expand Up @@ -234,6 +252,15 @@ if !pymode#Default("g:pymode_rope", 1) || g:pymode_rope
return ""
endfunction "}}}

fun! RopeOpenExistingProject() "{{{
if isdirectory(getcwd() . '/.ropeproject')
" In order to pass it the quiet kwarg I need to open the project
" using python and not vim, which should be no major issue
py ropevim._interface.open_project(quiet=True)
return ""
endif
endfunction "}}}

fun! RopeLuckyAssistInsertMode() "{{{
call RopeLuckyAssist()
return ""
Expand All @@ -249,6 +276,13 @@ if !pymode#Default("g:pymode_rope", 1) || g:pymode_rope
endif
endfunction "}}}

fun! RopeShowSignsRulerIfNeeded() "{{{
if &ft == 'python'
execute printf('silent! sign place 1 line=1 name=__dummy__ file=%s', expand("%:p"))
endif
endfunction "}}}


" Rope menu
menu <silent> Rope.Autoimport :RopeAutoImport<CR>
menu <silent> Rope.ChangeSignature :RopeChangeSignature<CR>
Expand All @@ -270,6 +304,15 @@ if !pymode#Default("g:pymode_rope", 1) || g:pymode_rope
menu <silent> Rope.Undo :RopeUndo<CR>
menu <silent> Rope.UseFunction :RopeUseFunction<CR>

if !pymode#Default("g:pymode_rope_auto_project_open", 1) || g:pymode_rope_auto_project_open
call RopeOpenExistingProject()
endif

if !pymode#Default("g:pymode_rope_auto_session_manage", 0) || g:pymode_rope_auto_session_manage
autocmd VimLeave * call RopeSaveSession()
autocmd VimEnter * call RopeRestoreSession()
endif

endif

" }}}
Expand Down
109 changes: 79 additions & 30 deletions pylibs/ropevim.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""ropevim, a vim mode for using rope refactoring library"""
import glob
import os
import tempfile
import re
Expand All @@ -9,6 +10,9 @@

import vim

# Gobal var to be able to shutup output
_rope_quiet = False


class VimUtils(environment.Environment):

Expand All @@ -21,8 +25,8 @@ def ask(self, prompt, default=None, starting=None):
if starting is None:
starting = ''
if default is not None:
prompt = prompt + ('[%s] ' % default)
result = call('input("%s", "%s")' % (prompt, starting))
prompt = prompt + '[{0}] '.format(default)
result = call('input("{0}", "{1}")'.format(prompt, starting))
if default is not None and result == '':
return default
return result
Expand All @@ -32,11 +36,14 @@ def ask_values(self, prompt, values, default=None,
if show_values or (show_values is None and len(values) < 14):
self._print_values(values)
if default is not None:
prompt = prompt + ('[%s] ' % default)
prompt = prompt + '[{0}] '.format(default)
starting = starting or ''
_completer.values = values
answer = call('input("%s", "%s", "customlist,RopeValueCompleter")' %
(prompt, starting))
answer = call(
'input("{0}", "{1}", "customlist,RopeValueCompleter")'.format(
prompt, starting
)
)
if answer is None:
if 'cancel' in values:
return 'cancel'
Expand All @@ -54,14 +61,14 @@ def _print_values(self, values):
echo('\n'.join(numbered) + '\n')

def ask_directory(self, prompt, default=None, starting=None):
return call('input("%s", ".", "dir")' % prompt)
return call('input("{0}", ".", "dir")'.format(prompt))

def _update_proposals(self, values):
self.completeopt = vim.eval('&completeopt')
self.preview = 'preview' in self.completeopt

if not self.get('extended_complete'):
return u','.join(u"'%s'" % self._completion_text(proposal)
return u','.join(u"'{0}'".format(self._completion_text(proposal))
for proposal in values)

return u','.join(self._extended_completion(proposal)
Expand All @@ -78,7 +85,7 @@ def ask_completion(self, prompt, values, starting=None):
col = int(call('col(".")'))
if starting:
col -= len(starting)
self._command(u'call complete(%s, [%s])' % (col, proposals),
self._command(u'call complete({0}, [{1}])'.format(col, proposals),
encode=True)
return None

Expand All @@ -95,8 +102,8 @@ def y_or_n(self, prompt):
return self.yes_or_no(prompt)

def get(self, name, default=None):
vimname = 'g:pymode_rope_%s' % name
if str(vim.eval('exists("%s")' % vimname)) == '0':
vimname = 'g:pymode_rope_{0}'.format(name)
if str(vim.eval('exists("{0}")'.format(vimname))) == '0':
return default
result = vim.eval(vimname)
if isinstance(result, str) and result.isdigit():
Expand Down Expand Up @@ -261,8 +268,9 @@ def _writedefs(self, locations, filename):

def show_doc(self, docs, altview=False):
if docs:
cmd = 'call pymode#ShowStr("%s")' % str(docs.replace('"', '\\"'))
vim.command(cmd)
vim.command(
'call pymode#ShowStr("{0}")'.format(docs.replace('"', '\\"'))
)

def preview_changes(self, diffs):
echo(diffs)
Expand All @@ -281,23 +289,33 @@ def add_hook(self, name, callback, hook):
'after_save': 'FileWritePost,BufWritePost',
'exit': 'VimLeave'}
self._add_function(name, callback)
vim.command('autocmd %s *.py call %s()' %
(mapping[hook], _vim_name(name)))
vim.command(
'autocmd {0} *.py call {1}()'.format(
mapping[hook], _vim_name(name)
)
)

def _add_command(self, name, callback, key, prefix, prekey):
self._add_function(name, callback, prefix)
vim.command('command! -range %s call %s()' %
(_vim_name(name), _vim_name(name)))
vim.command(
'command! -range {0} call {1}()'.format(
_vim_name(name), _vim_name(name)
)
)
if key is not None:
key = prekey + key.replace(' ', '')
vim.command('noremap %s :call %s()<cr>' % (key, _vim_name(name)))
vim.command(
'noremap {0} :call {1}()<cr>'.format(key, _vim_name(name))
)

def _add_function(self, name, callback, prefix=False):
globals()[name] = callback
arg = 'None' if prefix else ''
vim.command('function! %s()\n' % _vim_name(name) +
'python ropevim.%s(%s)\n' % (name, arg) +
'endfunction\n')
vim.command(
'function! {0}()\n'
'python ropevim.{1}({2})\n'
'endfunction\n'.format(_vim_name(name), name, arg)
)

def _completion_data(self, proposal):
return proposal
Expand All @@ -317,7 +335,7 @@ def _extended_completion(self, proposal):

if proposal.scope == 'parameter_keyword':
default = proposal.get_default()
ci["menu"] += '*' if default is None else '= %s' % default
ci["menu"] += '*' if default is None else '= {0}'.format(default)

if self.preview and not ci['menu']:
doc = proposal.get_doc()
Expand All @@ -328,9 +346,9 @@ def _extended_completion(self, proposal):
def _conv(self, obj):
if isinstance(obj, dict):
return u'{' + u','.join([
u"%s:%s" % (self._conv(key), self._conv(value))
u"{0}:{1}".format(self._conv(key), self._conv(value))
for key, value in obj.iteritems()]) + u'}'
return u'"%s"' % str(obj).replace(u'"', u'\\"')
return u'"{0}"'.format(str(obj).replace(u'"', u'\\"'))


def _vim_name(name):
Expand All @@ -344,31 +362,38 @@ class VimProgress(object):
def __init__(self, name):
self.name = name
self.last = 0
status('%s ... ' % self.name)
status('{0} ... '.format(self.name))

def update(self, percent):
try:
vim.eval('getchar(0)')
except vim.error:
raise KeyboardInterrupt('Task %s was interrupted!' % self.name)
raise KeyboardInterrupt(
'Task {0} was interrupted!'.format(self.name)
)
if percent > self.last + 4:
status('%s ... %s%%%%' % (self.name, percent))
status('{0} ... {1}%'.format(self.name, percent))
self.last = percent

def done(self):
status('%s ... done' % self.name)
status('{0} ... done'.format(self.name))


def echo(message):
if _rope_quiet:
return
if isinstance(message, unicode):
message = message.encode(vim.eval('&encoding'))
print message


def status(message):
if _rope_quiet:
return

if isinstance(message, unicode):
message = message.encode(vim.eval('&encoding'))
vim.command('redraw | echon "%s"' % message)
vim.command('redraw | echon "{0}"'.format(message))


def call(command):
Expand All @@ -395,13 +420,37 @@ def __call__(self, arg_lead, cmd_line, cursor_pos):
else:
result = [proposal for proposal in self.values
if proposal.startswith(arg_lead)]
vim.command('let s:completions = %s' % result)
vim.command('let s:completions = {0}'.format(result))


class RopeMode(interface.RopeMode):
@decorators.global_command('o')
def open_project(self, root=None, quiet=False):
global _rope_quiet
_rope_quiet = quiet

super(RopeMode, self).open_project(root=root)
rope_project_dir = os.path.join(self.project.address, '.ropeproject')
vimfiles = glob.glob(os.path.join(rope_project_dir, '*.vim'))

if not vimfiles:
return

txt = 'Sourcing vim files under \'.ropeproject/\''
progress = self.env.create_progress(txt)
for idx, vimfile in enumerate(sorted(vimfiles)):
progress.name = txt + ' ({0})'.format(os.path.basename(vimfile))
vim.command(':silent source {0}'.format(vimfile))
progress.update(idx * 100 / len(vimfiles))

progress.name = txt
progress.done()
echo('Project opened!')

decorators.logger.message = echo
decorators.logger.only_short = True

_completer = _ValueCompleter()

_env = VimUtils()
_interface = interface.RopeMode(env=_env)
_interface = RopeMode(env=_env)