1
0
mirror of https://github.com/amix/vimrc synced 2025-06-30 20:05:01 +08:00

Added jedi-vim

This commit is contained in:
Amir
2022-09-21 10:47:47 +02:00
parent 3978f7b467
commit 950b470eb9
37 changed files with 4193 additions and 0 deletions

View File

@ -0,0 +1,11 @@
function! CurrentBufferIsModule(module_name)
return EndsWith(bufname('%'), a:module_name.'.py')
endfunction
function EndsWith(string, end)
let l:should = len(a:string) - strlen(a:end)
return l:should == stridx(a:string, a:end, should)
endfunction
" vim: et:ts=4:sw=4

View File

@ -0,0 +1,65 @@
"""Runs tests from ./vspec in vim-vspec."""
import os
import subprocess
try:
from urllib.request import urlretrieve
except ImportError:
from urllib import urlretrieve
import zipfile
import pytest
vspec_version = '1.9.0'
VSPEC_URL = 'https://github.com/kana/vim-vspec/archive/%s.zip' % vspec_version
root = os.path.dirname(os.path.dirname(__file__))
CACHE_FOLDER = os.path.join(root, 'build')
VSPEC_FOLDER = os.path.join(CACHE_FOLDER, 'vim-vspec-%s' % vspec_version)
VSPEC_RUNNER = os.path.join(VSPEC_FOLDER, 'bin/vspec')
TEST_DIR = os.path.join(root, 'test', 'vspec')
@pytest.fixture(scope='session')
def install_vspec():
if not os.path.isdir(CACHE_FOLDER):
os.mkdir(CACHE_FOLDER)
if not os.path.exists(VSPEC_FOLDER):
name, hdrs = urlretrieve(VSPEC_URL)
z = zipfile.ZipFile(name)
for n in z.namelist():
dest = os.path.join(CACHE_FOLDER, n)
destdir = os.path.dirname(dest)
if not os.path.isdir(destdir):
os.makedirs(destdir)
data = z.read(n)
if not os.path.isdir(dest):
with open(dest, 'wb') as f:
f.write(data)
z.close()
os.chmod(VSPEC_RUNNER, 0o777)
def get_vspec_tests():
for f in os.listdir(TEST_DIR):
yield os.path.relpath(os.path.join(TEST_DIR, f))
@pytest.mark.parametrize('path', get_vspec_tests())
def test_integration(install_vspec, path):
output = subprocess.check_output(
[VSPEC_RUNNER, '.', VSPEC_FOLDER, os.path.relpath(path, root)],
cwd=root,
)
had_ok = False
for line in output.splitlines():
if (line.startswith(b'not ok') or
line.startswith(b'Error') or
line.startswith(b'Bail out!')):
pytest.fail(u"{0} failed:\n{1}".format(
path, output.decode('utf-8')), pytrace=False)
if not had_ok and line.startswith(b'ok'):
had_ok = True
if not had_ok:
pytest.fail(u"{0} failed: no 'ok' found:\n{1}".format(
path, output.decode('utf-8')), pytrace=False)

View File

@ -0,0 +1,8 @@
" Minimal vimrc to use jedi-vim.
"
" Not used anywhere yet, but allows for easy testing.
let script_dir = fnamemodify(expand('<sfile>'), ':h:h')
let &runtimepath = script_dir.','.&runtimepath.','.script_dir.'/after'
syntax on
filetype plugin indent on

View File

@ -0,0 +1,29 @@
source plugin/jedi.vim
source test/_utils.vim
describe 'simple:'
before
new
normal! ifoo
end
after
bd!
end
it 'choose'
Expect g:jedi#environment_path == 'auto'
Expect bufname('%') == ''
JediChooseEnvironment
" A Python executable needs to be a few letters
Expect len(getline('.')) > 5
Expect bufname('%') == 'Hit Enter to Choose an Environment'
execute "normal \<CR>"
Expect g:jedi#environment_path != 'auto'
bd " TODO why is this necessary? There seems to be a random buffer.
Expect bufname('%') == ''
Expect getline('.') == 'foo'
end
end

View File

@ -0,0 +1,131 @@
let g:jedi#completions_command = 'X'
source plugin/jedi.vim
describe 'completions'
before
new
set filetype=python
end
after
" default
let g:jedi#popup_select_first = 1
bd!
end
it 'longest in completeopt'
" This gets set up with Vim only on VimEnter.
if has('nvim')
Expect stridx(&completeopt, 'longest') > -1
else
Expect stridx(&completeopt, 'longest') == -1
doautocmd VimEnter
Expect stridx(&completeopt, 'longest') > -1
endif
" Do not use it for following tests.
set completeopt-=longest
end
it 'no smart import by default'
exec "normal ifrom os "
Expect getline('.') == 'from os '
end
it 'import'
" X is the completion command
normal oimporX
Expect getline('.') == 'import'
normal a subproX
Expect getline('.') == 'import subprocess'
end
it 'exception'
normal oIndentationErrX
Expect getline('.') == 'IndentationError'
" Do not remap keys (".") here, otherwise this triggers completion in
" Neovim already.
normal! a().filena
normal aX
Expect getline('.') == 'IndentationError().filename'
end
it 'multi complete'
" NOTE: nvim results in "importErr()" here with completeopt+=longest,
" but Vim is fine.
" This is due to `pumvisible()` in jedi#complete_opened being true
" with nvim still, but it is 0 with Vim, i.e. Vim appears to close
" the pum already (with the tests).
"
" This might be a misunderstanding though, since the test might not
" expect the "import" keyword to be offered for completion?!
normal oImpXErrX()
Expect getline('.') == 'ImportError()'
end
it 'cycling through entries popup_select_first=0'
set completeopt+=longest
let g:jedi#popup_select_first = 0
execute "normal oraise impX\<C-n>"
Expect getline('.') == 'raise ImportError'
set completeopt-=longest
end
it 'cycling through entries popup_select_first=1'
execute "normal oraise impX\<C-n>"
Expect getline('.') == 'raise ImportWarning'
end
it 'cycling through entries popup_select_first=1 and longest'
set completeopt+=longest
execute "normal oraise impX"
Expect getline('.') == 'raise Import'
" With Neovim pumvisible() is 1 in jedi#complete_opened, which then
" triggers the <Down>. This is not the case with Vim.
if has('nvim')
execute "normal oraise impX\<C-n>"
Expect getline('.') == 'raise ImportWarning'
execute "normal oraise impX\<C-n>\<C-n>"
Expect getline('.') == 'raise imp'
else
execute "normal oraise impX\<C-n>"
Expect getline('.') == 'raise ImportError'
execute "normal oraise impX\<C-n>\<C-n>"
Expect getline('.') == 'raise ImportWarning'
endif
set completeopt-=longest
end
end
describe 'smart completions'
before
new
let g:jedi#smart_auto_mappings = 1
set filetype=python
end
after
" default
let g:jedi#smart_auto_mappings = 0
bd!
end
it 'smart import'
exec "normal ifrom os "
Expect getline('.') == 'from os import '
end
it 'no smart import after space'
exec "normal! ifrom os "
exec "normal a "
Expect getline('.') == 'from os '
end
end
" vim: et:ts=4:sw=4

View File

@ -0,0 +1,20 @@
let g:jedi#completions_command = 'X'
let g:jedi#completions_enabled = 0
source plugin/jedi.vim
describe 'completions_disabled'
before
set filetype=python
end
after
try | %bwipeout! | catch | endtry
end
it 'typing'
normal oraise ImportErrX
Expect getline('.') == 'raise ImportErrX'
end
end
" vim: et:ts=4:sw=4

View File

@ -0,0 +1,34 @@
source plugin/jedi.vim
describe 'documentation docstrings'
before
set filetype=python
end
after
try | %bwipeout! | catch | endtry
end
it 'simple'
Expect maparg('K') == ':call jedi#show_documentation()<CR>'
put = 'ImportError'
normal GK
Expect bufname('%') == "__doc__"
Expect &filetype == 'rst'
let header = getline(1, 2)
Expect header[0] == "Docstring for class builtins.ImportError"
Expect header[1] == "========================================"
let content = join(getline(3, '$'), "\n")
Expect stridx(content, "Import can't find module") > 0
normal K
Expect bufname('%') == ''
end
it 'no documentation'
put = 'x = 2'
normal o<ESC>GK
Expect bufname('%') == ''
end
end
" vim: et:ts=4:sw=4

View File

@ -0,0 +1,177 @@
let mapleader = '\'
source plugin/jedi.vim
source test/_utils.vim
describe 'goto simple:'
before
new
set filetype=python
put =[
\ 'def a(): pass',
\ 'b = a',
\ 'c = b',
\ ]
normal! ggdd
normal! G$
Expect line('.') == 3
end
after
bd!
end
it 'goto definitions'
normal \d
Expect line('.') == 2
Expect col('.') == 1
end
it 'goto assignments'
normal \g
Expect line('.') == 2
Expect col('.') == 1
" cursor before `=` means that it stays there.
normal \g
Expect line('.') == 2
Expect col('.') == 1
" going to the last line changes it.
normal! $
normal \g
Expect line('.') == 1
Expect col('.') == 5
end
end
describe 'goto with tabs:'
before
set filetype=python
let g:jedi#use_tabs_not_buffers = 1
end
after
try | %bwipeout! | catch | endtry
end
it 'follow import'
put = ['import subprocess', 'subprocess']
normal G\g
Expect getline('.') == 'import subprocess'
Expect line('.') == 2
Expect col('.') == 8
normal G\d
Expect CurrentBufferIsModule('subprocess') == 1
Expect line('.') == 1
Expect col('.') == 1
Expect tabpagenr('$') == 2
Expect winnr('$') == 1
bwipe
Expect tabpagenr('$') == 1
Expect bufname('%') == ''
end
end
describe 'goto with buffers'
before
set filetype=python
let g:jedi#use_tabs_not_buffers = 0
end
after
try | %bwipeout! | catch | endtry
set nohidden
end
it 'no new tabs'
put = ['import os']
normal G$
call jedi#goto_assignments()
python3 jedi_vim.goto()
Expect CurrentBufferIsModule('os') == 0
" Without hidden, it's not possible to open a new buffer, when the old
" one is not saved.
set hidden
call jedi#goto_assignments()
Expect CurrentBufferIsModule('os') == 1
Expect winnr('$') == 1
Expect tabpagenr('$') == 1
Expect line('.') == 1
Expect col('.') == 1
end
end
describe 'goto with splits'
before
enew!
set filetype=python
let g:jedi#use_splits_not_buffers = 'left'
end
after
try | %bwipeout! | catch | endtry
end
it 'follow import'
put = ['import subprocess', 'subprocess']
normal G\g
Expect getline('.') == 'import subprocess'
Expect line('.') == 2
Expect col('.') == 8
normal G\d
Expect CurrentBufferIsModule('subprocess') == 1
Expect line('.') == 1
Expect col('.') == 1
Expect winnr('$') == 2
wincmd l
Expect bufname('%') == ''
end
end
describe 'goto wildignore'
before
enew!
set filetype=python
set wildignore=*,with\ spaces,*.pyc
set hidden
let g:jedi#use_tag_stack = 1
let g:jedi#use_tabs_not_buffers = 0
" Need to use splits for code coverage in new_buffer()
let g:jedi#use_splits_not_buffers = 1
put = ['from subprocess import Popen', 'Popen']
Expect CurrentBufferIsModule('subprocess') == 0
normal G
end
after
try | %bwipeout! | catch | endtry
set wildignore&vim
end
it 'restores wildignore'
let before = &wildignore
call jedi#goto()
Expect getline('.') =~ 'Popen'
Expect &wildignore == before
end
it 'not using tagstack'
let g:jedi#use_tag_stack = 0
call jedi#goto()
Expect CurrentBufferIsModule('subprocess') == 1
Expect getline('.') =~ 'Popen'
end
end
" vim: et:ts=4:sw=4

View File

@ -0,0 +1,13 @@
source plugin/jedi.vim
describe 'JediDebugInfo'
it 'works'
redir @a | JediDebugInfo | redir END
let output = split(@a, '\n')
Expect output[0] == 'You should run this in a buffer with filetype "python".'
Expect output[1] == '#### Jedi-vim debug information'
Expect output[-1] == '</details>'
end
end
" vim: et:ts=4:sw=4

View File

@ -0,0 +1,34 @@
source plugin/jedi.vim
source test/_utils.vim
describe 'pyimport'
before
let g:jedi#use_tabs_not_buffers = 1
let g:jedi#project_path = 'autoload'
end
after
try | %bwipeout! | catch | endtry
unlet g:jedi#project_path
end
it 'open_tab'
Pyimport os
Expect CurrentBufferIsModule('os') == 1
Pyimport subprocess
Expect CurrentBufferIsModule('subprocess') == 1
" the empty tab is sometimes also a tab
Expect tabpagenr('$') >= 2
end
it 'completion'
" don't know how to test this directly
"execute "Pyimport subproc\<Tab>"
"Expect CurrentBufferIsModule('subprocess') == 1
Expect jedi#py_import_completions('subproc', 0, 0) == 'subprocess'
Expect jedi#py_import_completions('subprocess', 0, 0) == 'subprocess'
let g:comp = jedi#py_import_completions('sre_', 0, 0)
Expect g:comp == "sre_compile\nsre_constants\nsre_parse"
end
end

View File

@ -0,0 +1,143 @@
source plugin/jedi.vim
describe 'signatures'
before
enew
set filetype=python
end
after
try | %bwipeout! | catch | endtry
end
it 'simple'
normal odef xyz(number): return
normal o
normal oxyz()
doautocmd CursorHoldI
Expect getline(3) == '?!?jedi=0, ?!? (*_*number*_*) ?!?jedi?!?'
doautocmd InsertLeave
Expect getline(3) == ''
end
it 'multiple buffers'
set hidden
new
setfiletype python
redir => autocmds
autocmd jedi_call_signatures * <buffer>
redir END
Expect autocmds =~# 'jedi_call_signatures'
buffer #
redir => autocmds
autocmd jedi_call_signatures * <buffer>
redir END
Expect autocmds =~# 'jedi_call_signatures'
end
it 'simple after CursorHoldI with only parenthesis'
noautocmd normal o
doautocmd CursorHoldI
noautocmd normal istaticmethod()
doautocmd CursorHoldI
Expect getline(1) == '?!?jedi=0, ?!? (*_*f: Callable[..., Any]*_*) ?!?jedi?!?'
end
it 'highlights correct argument'
noautocmd normal o
doautocmd CursorHoldI
noautocmd normal iformat(42, "x")
" Move to x - highlights "x".
noautocmd normal 2h
doautocmd CursorHoldI
Expect getline(1) == '?!?jedi=0, ?!? (value: object, *_*format_spec: str=...*_*) ?!?jedi?!?'
" Move left to 42 - hightlights first argument ("value").
noautocmd normal 4h
doautocmd CursorHoldI
Expect getline(1) == '?!?jedi=0, ?!? (*_*value: object*_*, format_spec: str=...) ?!?jedi?!?'
end
it 'no signature'
exe 'normal ostr '
python3 jedi_vim.show_call_signatures()
Expect getline(1, '$') == ['', 'str ']
end
it 'signatures disabled'
let g:jedi#show_call_signatures = 0
exe 'normal ostr( '
python3 jedi_vim.show_call_signatures()
Expect getline(1, '$') == ['', 'str( ']
let g:jedi#show_call_signatures = 1
end
it 'command line simple'
let g:jedi#show_call_signatures = 2
call jedi#configure_call_signatures()
exe 'normal ostaticmethod( '
redir => msg
python3 jedi_vim.show_call_signatures()
redir END
Expect msg == "\nstaticmethod(f: Callable[..., Any])"
redir => msg
doautocmd InsertLeave
redir END
Expect msg == "\n"
normal Sdef foo(a, b): pass
exe 'normal ofoo(a, b, c, '
redir => msg
python3 jedi_vim.show_call_signatures()
redir END
Expect msg == "\nfoo(a, b)"
end
it 'command line truncation'
let g:jedi#show_call_signatures = 2
call jedi#configure_call_signatures()
function! Signature()
redir => msg
python3 jedi_vim.show_call_signatures()
redir END
return msg
endfunction
let funcname = repeat('a', &columns - (30 + (&ruler ? 18 : 0)))
put = 'def '.funcname.'(arg1, arg2, arg3, a, b, c):'
put = ' pass'
execute "normal o\<BS>".funcname."( "
Expect Signature() == "\n".funcname."(arg1, …)"
exe 'normal sarg1, '
Expect Signature() == "\n".funcname."(…, arg2, …)"
exe 'normal sarg2, arg3, '
Expect Signature() == "\n".funcname."(…, a, b, c)"
exe 'normal sa, b, '
Expect Signature() == "\n".funcname."(…, c)"
g/^/d
put = 'def '.funcname.'('.repeat('b', 20).', arg2):'
put = ' pass'
execute "normal o\<BS>".funcname."( "
Expect Signature() == "\n".funcname."(…)"
end
it 'command line no signature'
let g:jedi#show_call_signatures = 2
call jedi#configure_call_signatures()
exe 'normal ostr '
redir => msg
python3 jedi_vim.show_call_signatures()
redir END
Expect msg == "\n"
end
end