Merge pull request #315 from wilywampa/master

Add option to show call signatures in command line
This commit is contained in:
Dave Halter
2014-12-19 14:14:59 +01:00
7 changed files with 157 additions and 5 deletions

View File

@@ -147,6 +147,16 @@ and usually saves one keypress.
let g:jedi#popup_select_first = 0
Jedi displays function call signatures in insert mode in real-time, highlighting
the current argument. The call signatures can be displayed as a pop-up in the
buffer (set to 1, the default), which has the advantage of being easier to refer
to, or in Vim's command line aligned with the function call (set to 2), which
can improve the integrity of Vim's undo history.
.. code-block:: vim
let g:jedi#show_call_signatures = "1"
Here are a few more defaults for actions, read the docs (``:help jedi-vim``) to
get more information. If you set them to ``""``, they are not assigned.
@@ -158,7 +168,6 @@ get more information. If you set them to ``""``, they are not assigned.
let g:jedi#usages_command = "<leader>n"
let g:jedi#completions_command = "<C-Space>"
let g:jedi#rename_command = "<leader>r"
let g:jedi#show_call_signatures = "1"
Finally, if you don't want completion, but all the other features, use:

View File

@@ -1,4 +1,4 @@
if g:jedi#show_call_signatures == 1 && has('conceal')
if g:jedi#show_call_signatures > 0 && has('conceal')
" conceal is normal for vim >= 7.3
let s:e = g:jedi#call_signature_escape

View File

@@ -155,10 +155,66 @@ endfunction
function! jedi#configure_call_signatures()
if g:jedi#show_call_signatures == 2 " Command line call signatures
" Need to track changes to avoid multiple undo points for a single edit
if v:version >= 704 || has("patch-7.3.867")
let b:normaltick = b:changedtick
autocmd TextChanged,InsertLeave,BufWinEnter <buffer> let b:normaltick = b:changedtick
endif
autocmd InsertEnter <buffer> let g:jedi#first_col = s:save_first_col()
endif
autocmd InsertLeave <buffer> Python jedi_vim.clear_call_signatures()
autocmd CursorMovedI <buffer> Python jedi_vim.show_call_signatures()
endfunction
" Determine where the current window is on the screen for displaying call
" signatures in the correct column.
function! s:save_first_col()
if bufname('%') ==# '[Command Line]' || winnr('$') == 1
return 0
endif
let l:eventignore = &eventignore
set eventignore=all
let startwin = winnr()
let startaltwin = winnr('#')
let winwidth = winwidth(0)
try
wincmd h
let win_on_left = winnr() == startwin
if win_on_left
return 0
else
" Walk left and count up window widths until hitting the edge
execute startwin."wincmd w"
let width = 0
let winnr = winnr()
wincmd h
while winnr != winnr()
let width += winwidth(0) + 1 " Extra column for window divider
let winnr = winnr()
wincmd h
endwhile
return width
endif
finally
let &eventignore = l:eventignore
execute startaltwin."wincmd w"
execute startwin."wincmd w"
" If the event that triggered InsertEnter made a change (e.g. open a
" new line, substitude a word), join that change with the rest of this
" edit.
if exists('b:normaltick') && b:normaltick != b:changedtick
try
undojoin
catch /^Vim\%((\a\+)\)\=:E790/
" This can happen if an undo happens during a :normal command.
endtry
endif
endtry
endfunction
" Helper function instead of `python vim.eval()`, and `.command()` because
" these also return error definitions.
function! jedi#_vim_exceptions(str, is_eval)

View File

@@ -379,9 +379,10 @@ Default: 1 (Automatically close preview window upon leaving insert mode)
Jedi-vim can display a small window detailing the arguments of the currently
completed function and highlighting the currently selected argument. This can
be disabled by setting this option to 0.
be disabled by setting this option to 0. Setting this option to 2 shows call
signatures in the command line instead of a popup window.
Options: 0 or 1
Options: 0, 1, or 2
Default: 1 (Show call signatures window)
Note: This setting is ignored if |g:jedi#auto_initialization| is set to 0. In

View File

@@ -25,7 +25,7 @@ if g:jedi#auto_initialization
execute "nnoremap <silent> <buffer>".g:jedi#documentation_command." :call jedi#show_documentation()<CR>"
endif
if g:jedi#show_call_signatures == 1 && has('conceal')
if g:jedi#show_call_signatures > 0 && has('conceal')
call jedi#configure_call_signatures()
endif

View File

@@ -8,6 +8,10 @@ import re
import os
import sys
from shlex import split as shsplit
try:
from itertools import zip_longest
except ImportError:
from itertools import izip_longest as zip_longest # Python 2
import vim
import jedi
@@ -228,6 +232,10 @@ def show_documentation():
@catch_and_print_exceptions
def clear_call_signatures():
# Check if using command line call signatures
if vim_eval("g:jedi#show_call_signatures") == '2':
vim_command('echo ""')
return
cursor = vim.current.window.cursor
e = vim_eval('g:jedi#call_signature_escape')
regex = r'%sjedi=([0-9]+), ([^%s]*)%s.*%sjedi%s'.replace('%s', e)
@@ -255,6 +263,9 @@ def show_call_signatures(signatures=()):
if not signatures:
return
if vim_eval("g:jedi#show_call_signatures") == '2':
return cmdline_call_signatures(signatures)
for i, signature in enumerate(signatures):
line, column = signature.bracket_start
# signatures are listed above each other
@@ -310,6 +321,54 @@ def show_call_signatures(signatures=()):
vim_eval('setline(%s, %s)' % (line_to_replace, repr(PythonToVimStr(repl))))
@catch_and_print_exceptions
def cmdline_call_signatures(signatures):
def get_params(s):
return [p.description.replace('\n', '') for p in s.params]
if len(signatures) > 1:
params = zip_longest(*map(get_params, signatures), fillvalue='_')
params = ['(' + ', '.join(p) + ')' for p in params]
else:
params = get_params(signatures[0])
text = ', '.join(params)
# Allow 12 characters for ruler/showcmd - setting noruler/noshowcmd
# here causes incorrect undo history
max_msg_len = int(vim_eval('&columns')) - 12
max_num_spaces = (max_msg_len - len(signatures[0].call_name)
- len(text) - 2) # 2 accounts for parentheses
if max_num_spaces < 0:
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:
index = [s.index for s in signatures if isinstance(s.index, int)][0]
left = text.index(params[index])
right = left + len(params[index])
vim_command(' echon "%s" | '
'echohl Function | echon "%s" | '
'echohl None | echon "(" | '
'echohl jediFunction | echon "%s" | '
'echohl jediFat | echon "%s" | '
'echohl jediFunction | echon "%s" | '
'echohl None | echon ")"'
% (spaces, signatures[0].call_name, text[:left],
text[left:right], text[right:]))
except (TypeError, IndexError):
vim_command(' echon "%s" | '
'echohl Function | echon "%s" | '
'echohl None | echon "(" | '
'echohl jediFunction | echon "%s" | '
'echohl None | echon ")"'
% (spaces, signatures[0].call_name, text))
@catch_and_print_exceptions
def rename():
if not int(vim.eval('a:0')):

View File

@@ -36,4 +36,31 @@ describe 'signatures'
let g:jedi#show_call_signatures = 1
end
it 'command line simple'
let g:jedi#show_call_signatures = 2
call jedi#configure_call_signatures()
normal oabs(
redir => msg
Python jedi_vim.show_call_signatures()
redir END
Expect msg == "\nabs(number)"
redir => msg
doautocmd InsertLeave
redir END
Expect msg == "\n\n"
end
it 'command line no signature'
let g:jedi#show_call_signatures = 2
call jedi#configure_call_signatures()
normal ostr
redir => msg
Python jedi_vim.show_call_signatures()
redir END
Expect msg == "\n"
end
end