Merge branch 'wilywampa-callsig_columns'

Truncate command line call signature as described in #474 when the full
signature is too long to display.

Closes https://github.com/davidhalter/jedi-vim/issues/474.
Closes https://github.com/davidhalter/jedi-vim/pull/475.
This commit is contained in:
Daniel Hahler
2015-10-18 21:16:48 +02:00
2 changed files with 94 additions and 25 deletions

View File

@@ -1,3 +1,4 @@
# -*- coding: utf-8 -*-
""" """
The Python parts of the Jedi library for VIM. It is mostly about communicating The Python parts of the Jedi library for VIM. It is mostly about communicating
with VIM. with VIM.
@@ -18,7 +19,10 @@ except ImportError:
is_py3 = sys.version_info[0] >= 3 is_py3 = sys.version_info[0] >= 3
if is_py3: if is_py3:
ELLIPSIS = ""
unicode = str unicode = str
else:
ELLIPSIS = u""
class PythonToVimStr(unicode): class PythonToVimStr(unicode):
@@ -406,32 +410,65 @@ def cmdline_call_signatures(signatures):
def get_params(s): def get_params(s):
return [p.description.replace('\n', '') for p in s.params] return [p.description.replace('\n', '') for p in s.params]
def escape(string):
return string.replace('"', '\\"').replace(r'\n', r'\\n')
def join():
return ', '.join(filter(None, (left, center, right)))
def too_long():
return len(join()) > max_msg_len
if len(signatures) > 1: if len(signatures) > 1:
params = zip_longest(*map(get_params, signatures), fillvalue='_') params = zip_longest(*map(get_params, signatures), fillvalue='_')
params = ['(' + ', '.join(p) + ')' for p in params] params = ['(' + ', '.join(p) + ')' for p in params]
else: else:
params = get_params(signatures[0]) params = get_params(signatures[0])
text = ', '.join(params).replace('"', '\\"').replace(r'\n', r'\\n')
# Allow 12 characters for ruler/showcmd - setting noruler/noshowcmd index = next(iter(s.index for s in signatures if s.index is not None), None)
# here causes incorrect undo history
# Allow 12 characters for showcmd plus 18 for ruler - setting
# noruler/noshowcmd here causes incorrect undo history
max_msg_len = int(vim_eval('&columns')) - 12 max_msg_len = int(vim_eval('&columns')) - 12
max_num_spaces = (max_msg_len - len(signatures[0].call_name) if int(vim_eval('&ruler')):
- len(text) - 2) # 2 accounts for parentheses max_msg_len -= 18
if max_num_spaces < 0: max_msg_len -= len(signatures[0].call_name) + 2 # call name + parentheses
return # No room for the message
_, column = signatures[0].bracket_start
num_spaces = min(int(vim_eval('g:jedi#first_col +'
'wincol() - col(".")')) +
column - len(signatures[0].call_name),
max_num_spaces)
spaces = ' ' * num_spaces
try: if max_msg_len < 0:
index = [s.index for s in signatures if isinstance(s.index, int)][0] return
escaped_param = params[index].replace(r'\n', r'\\n') elif index is None:
left = text.index(escaped_param) pass
right = left + len(escaped_param) elif max_msg_len < len(ELLIPSIS):
return
else:
left = escape(', '.join(params[:index]))
center = escape(params[index])
right = escape(', '.join(params[index + 1:]))
while too_long():
if left and left != ELLIPSIS:
left = ELLIPSIS
continue
if right and right != ELLIPSIS:
right = ELLIPSIS
continue
if (left or right) and center != ELLIPSIS:
left = right = None
center = ELLIPSIS
continue
if too_long():
# Should never reach here
return
max_num_spaces = max_msg_len
if index is not None:
max_num_spaces -= len(join())
_, column = signatures[0].bracket_start
spaces = min(int(vim_eval('g:jedi#first_col +'
'wincol() - col(".")')) +
column - len(signatures[0].call_name),
max_num_spaces) * ' '
if index is not None:
vim_command(' echon "%s" | ' vim_command(' echon "%s" | '
'echohl Function | echon "%s" | ' 'echohl Function | echon "%s" | '
'echohl None | echon "(" | ' 'echohl None | echon "(" | '
@@ -439,15 +476,14 @@ def cmdline_call_signatures(signatures):
'echohl jediFat | echon "%s" | ' 'echohl jediFat | echon "%s" | '
'echohl jediFunction | echon "%s" | ' 'echohl jediFunction | echon "%s" | '
'echohl None | echon ")"' 'echohl None | echon ")"'
% (spaces, signatures[0].call_name, text[:left], % (spaces, signatures[0].call_name,
text[left:right], text[right:])) left + ', ' if left else '',
except (TypeError, IndexError): center, ', ' + right if right else ''))
else:
vim_command(' echon "%s" | ' vim_command(' echon "%s" | '
'echohl Function | echon "%s" | ' 'echohl Function | echon "%s" | '
'echohl None | echon "(" | ' 'echohl None | echon "()"'
'echohl jediFunction | echon "%s" | ' % (spaces, signatures[0].call_name))
'echohl None | echon ")"'
% (spaces, signatures[0].call_name, text))
@_check_jedi_availability(show_error=True) @_check_jedi_availability(show_error=True)

View File

@@ -53,6 +53,39 @@ describe 'signatures'
Expect msg == "\n" Expect msg == "\n"
end end
it 'command line truncation'
let g:jedi#show_call_signatures = 2
call jedi#configure_call_signatures()
function! Signature()
redir => msg
Python jedi_vim.show_call_signatures()
redir END
return msg
endfunction
let funcname = repeat('a', &columns - 30)
put = 'def '.funcname.'(arg1, arg2, arg3, a, b, c):'
put = ' pass'
execute "normal o".funcname."( "
Expect Signature() == "\n".funcname."(arg1, …)"
normal sarg1,
Expect Signature() == "\n".funcname."(…, arg2, …)"
normal sarg2, arg3,
Expect Signature() == "\n".funcname."(…, a, b, c)"
normal sa, b,
Expect Signature() == "\n".funcname."(…, c)"
g/^/d
put = 'def '.funcname.'('.repeat('b', 20).', arg2):'
put = ' pass'
execute "normal o".funcname."( "
Expect Signature() == "\n".funcname."(…)"
end
it 'command line no signature' it 'command line no signature'
let g:jedi#show_call_signatures = 2 let g:jedi#show_call_signatures = 2
call jedi#configure_call_signatures() call jedi#configure_call_signatures()