Add option to show call signatures in command line

This commit is contained in:
Jacob Niehus
2014-10-19 14:35:11 -07:00
parent 0ce1af78b2
commit cfd71a6b54
5 changed files with 113 additions and 4 deletions

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,60 @@ 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
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()
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()
let gutterwidth = &fdc + &number * max([&numberwidth, len(line('$')) + 1])
if bufname('%') ==# '[Command Line]' | return gutterwidth + 1 | endif
if winnr('$') == 1 | return gutterwidth | 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 gutterwidth
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 + gutterwidth
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 b:normaltick != b:changedtick
undojoin
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,53 @@ 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')) +
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')):