mirror of
1
0
Fork 0

jedi for python

This commit is contained in:
liushouda 2015-07-24 19:34:08 +08:00
parent 2a8d620b8a
commit d931023720
27 changed files with 2517 additions and 0 deletions

View File

@ -1,5 +1,6 @@
nnoremap <F9> :exe 'NERDTreeToggle'<CR>
"set pastetoggle=<F2>
set mouse=
"for outside paste mistake
nnoremap <F2> :set invpaste paste?<CR>
@ -24,3 +25,5 @@ map <leader>6 :tabnext 6<CR>
map <leader>7 :tabnext 7<CR>
map <leader>8 :tabnext 8<CR>
"let g:clang_library_path = '/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/'
highlight OverLength ctermbg=red ctermfg=white guibg=#592929
match OverLength /\%81v.\+/

View File

@ -0,0 +1,6 @@
*~
*.sw?
*.py[cod]
.ropeproject
doc/tags
.cache

View File

@ -0,0 +1,3 @@
[submodule "jedi"]
path = jedi
url = https://github.com/davidhalter/jedi.git

View File

@ -0,0 +1,6 @@
language: python
install:
- pip install --quiet --use-mirrors pytest
script:
- vim --version
- py.test

View File

@ -0,0 +1,51 @@
Main Authors
============
David Halter (@davidhalter) <davidhalter88@gmail.com>
Contributors (in order of contributions)
========================================
Patrice Peterson (@runiq)
tek (@tek)
heavenshell (@heavenshell) <heavenshell.jp@gmail.com>
Danilo Bargen (@dbrgn) <gezuru@gmail.com>
mattn (@mattn) <mattn.jp@gmail.com>
Enrico Batista da Luz (@ricobl) <rico.bl@gmail.com>
coot (@coot) <mszamot@gmail.com>
Artur Dryomov (@ming13) <artur.dryomov@gmail.com>
andviro (@andviro)
Jean-Louis Fuchs (@ganwell) <ganwell@fangorn.ch>
Mathieu Comandon (@strycore) <strider@strycore.com>
Nick Hurley (@todesschaf) <hurley@todesschaf.org>
gpoulin (@gpoulin)
Akinori Hattori (@hattya)
Luper Rouch (@flupke)
Matthew Moses (@mlmoses) <moses.matthewl@gmail.com>
Tyler Wymer (@twymer)
Artem Nezvigin (@artnez)
rogererens (@rogererens)
Emily Strickland (@emilyst) <mail@emily.st>
Tin Tvrtković (@Tinche) <tinchester@gmail.com>
Zekeriya Koc (@zekzekus) <zekzekus@gmail.com>
ethinx (@ethinx) <eth2net@gmail.com>
Wouter Overmeire (@lodagro) <lodagro@gmail.com>
Stephen J. Fuhry (@fuhrysteve) <fuhrysteve@gmail.com>
Sheng Yun (@ShengYun) <uewing@gmail.com>
Yann Thomas-Gérard (@inside) <inside@gmail.com>
Colin Su (@littleq0903) <littleq0903@gmail.com>
Arthur Jaron (@eyetracker)
Justin M. Keyes (@justinmk)
nagev (@np1)
Chris Lasher (@gotgenes) <chris.lasher@gmail.com>
Doan Thanh Nam (@tndoan)
Markus Koller (@toupeira)
Justin Cheevers @justincheevers
Talha Ahmed (@talha81) <talha.ahmed@gmail.com>
Matthew Tylee Atkinson (@matatk)
Pedro Ferrari (@petobens)
Dave Honneffer (@pearofducks)
@something are github user names.

View File

@ -0,0 +1,9 @@
We <3 pull requests!
1. Fork the Repo on github.
2. Add yourself to AUTHORS.txt
3. Add a test if possible.
4. Push to your fork and submit a pull request.
Please use PEP8 as a Python code style. For VIM, just stick try to style your
code similar to the jedi-vim code that's there.

View File

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) <2013> <David Halter and others, see AUTHORS.txt>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@ -0,0 +1,226 @@
#################################################
jedi-vim - awesome Python autocompletion with VIM
#################################################
.. image:: https://travis-ci.org/davidhalter/jedi-vim.png?branch=master
:target: https://travis-ci.org/davidhalter/jedi-vim
:alt: Travis-CI build status
jedi-vim is a VIM binding to the autocompletion library
`Jedi <http://github.com/davidhalter/jedi>`_.
Here are some pictures:
.. image:: https://github.com/davidhalter/jedi/raw/master/docs/_screenshots/screenshot_complete.png
Completion for almost anything (Ctrl+Space).
.. image:: https://github.com/davidhalter/jedi/raw/master/docs/_screenshots/screenshot_function.png
Display of function/class bodies, docstrings.
.. image:: https://github.com/davidhalter/jedi/raw/master/docs/_screenshots/screenshot_pydoc.png
Documentation (Pydoc) support (with highlighting, Shift+k).
There is also support for goto and renaming.
Get the latest from `github <http://github.com/davidhalter/jedi-vim>`_.
Documentation
=============
Documentation is available in your vim: ``:help jedi-vim``. You can also look
it up `on github <http://github.com/davidhalter/jedi-vim/blob/master/doc/jedi-vim.txt>`_.
You can read the Jedi library documentation `here <http://jedi.jedidjah.ch>`_.
If you want to report issues, just use the github issue tracker. In case of
questions about the software, please use `stackoverflow
<https://stackoverflow.com>`_ and tag your question with ``jedi-vim``.
Contributing
============
We love Pull Requests! Read the instructions in ``CONTRIBUTING.md``.
Features
========
The Jedi library understands most of Python's core features. From decorators to
generators, there is broad support.
Apart from that, jedi-vim supports the following commands
- Completion ``<C-Space>``
- Goto assignments ``<leader>g`` (typical goto function)
- Goto definitions ``<leader>d`` (follow identifier as far as possible,
includes imports and statements)
- Show Documentation/Pydoc ``K`` (shows a popup with assignments)
- Renaming ``<leader>r``
- Usages ``<leader>n`` (shows all the usages of a name)
- Open module, e.g. ``:Pyimport os`` (opens the ``os`` module)
Installation
============
You might want to use `pathogen <https://github.com/tpope/vim-pathogen>`_ or
`vundle <https://github.com/gmarik/vundle>`_ to install jedi in VIM. Also you
need a VIM version that was compiled with ``+python``, which is typical for most
distributions on Linux. The Python version compiled into VIM must be 2.6 or later
(you can check this from within VIM using ``:python import sys; print sys.version`` )
The first thing you need after that is an up-to-date version of Jedi. You can
either get it via ``pip install jedi`` or with ``git submodule update --init``
in your jedi-vim repository.
Example Installation Command using Pathogen:
.. code-block:: sh
cd ~/.vim/bundle/ && git clone --recursive https://github.com/davidhalter/jedi-vim.git
On Arch Linux, you can also install jedi-vim from official repositories as `vim-jedi
<https://www.archlinux.org/packages/community/any/vim-jedi/>`__. It is also available
on `Debian (≥8) <https://packages.debian.org/vim-python-jedi>`__ and `Ubuntu (≥14.04)
<http://packages.ubuntu.com/vim-python-jedi>`__ as vim-python-jedi.
Note that the `python-mode <https://github.com/klen/python-mode>`_ VIM plugin seems
to conflict with jedi-vim, therefore you should disable it before enabling
jedi-vim.
To enjoy the full features of jedi-vim, you should have VIM >= 7.3, compiled with
``+conceal`` (which is not the case on some platforms, including OS X). If your VIM
does not meet these requirements, the parameter recommendation list may not appear
when you type an open bracket after a function name. Please read
`the documentation <http://github.com/davidhalter/jedi-vim/blob/master/doc/jedi-vim.txt>`_
for details.
Settings
========
Jedi is by default automatically initialized. If you don't want that I suggest
you disable the auto-initialization in your ``.vimrc``:
.. code-block:: vim
let g:jedi#auto_initialization = 0
There are also some VIM options (like ``completeopt`` and key defaults) which
are automatically initialized, but you can skip this:
.. code-block:: vim
let g:jedi#auto_vim_configuration = 0
You can make jedi-vim use tabs when going to a definition etc:
.. code-block:: vim
let g:jedi#use_tabs_not_buffers = 1
If you are a person who likes to use VIM-splits, you might want to put this in your ``.vimrc``:
.. code-block:: vim
let g:jedi#use_splits_not_buffers = "left"
This options could be "left", "right", "top", "bottom" or "winwidth". It will decide the direction where the split open.
Jedi automatically starts the completion, if you type a dot, e.g. ``str.``, if
you don't want this:
.. code-block:: vim
let g:jedi#popup_on_dot = 0
Jedi selects the first line of the completion menu: for a better typing-flow
and usually saves one keypress.
.. code-block:: vim
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.
.. code-block:: vim
NOTE: subject to change!
let g:jedi#goto_command = "<leader>d"
let g:jedi#goto_assignments_command = "<leader>g"
let g:jedi#goto_definitions_command = ""
let g:jedi#documentation_command = "K"
let g:jedi#usages_command = "<leader>n"
let g:jedi#completions_command = "<C-Space>"
let g:jedi#rename_command = "<leader>r"
Finally, if you don't want completion, but all the other features, use:
.. code-block:: vim
let g:jedi#completions_enabled = 0
FAQ
===
I don't want the docstring window to popup during completion
------------------------------------------------------------
This depends on the ``completeopt`` option. Jedi initializes it in its
``ftplugin``. Add the following line to your ``.vimrc`` to disable it:
.. code-block:: vim
autocmd FileType python setlocal completeopt-=preview
I want <Tab> to do autocompletion
---------------------------------
Don't even think about changing the Jedi command to ``<Tab>``,
use `supertab <https://github.com/ervandew/supertab>`_!
The completion is waaay too slow!
---------------------------------
Completion of complex libraries (like Numpy) should only be slow the first time
you complete it. After that, the results should be cached and very fast.
If it's still slow, in case you've installed the python-mode VIM plugin, disable
it. It seems to conflict with jedi-vim. See issue `#163
<https://github.com/davidhalter/jedi-vim/issues/163>`__.
Testing
=======
jedi-vim is being tested with a combination of `vspec
<https://github.com/kana/vim-vspec>`_ and `py.test <http://pytest.org/>`_.
The tests are in the ``test`` subdirectory, you can run them calling::
py.test
The tests are automatically run with `travis
<https://travis-ci.org/davidhalter/jedi-vim>`_.

View File

@ -0,0 +1,23 @@
if !jedi#init_python()
finish
endif
if g:jedi#auto_initialization
if g:jedi#completions_enabled
" We need our own omnifunc, so this overrides the omnifunc set by
" $VIMRUNTIME/ftplugin/python.vim.
setlocal omnifunc=jedi#completions
" map ctrl+space for autocompletion
if g:jedi#completions_command == "<C-Space>"
" In terminals, <C-Space> sometimes equals <Nul>.
imap <buffer> <Nul> <C-Space>
smap <buffer> <Nul> <C-Space>
endif
if g:jedi#completions_command != ""
execute "inoremap <expr> <buffer> ".g:jedi#completions_command." jedi#complete_string(0)"
" A separate mapping for select mode: deletes and completes.
execute "snoremap <expr> <buffer> ".g:jedi#completions_command." '\<C-g>c'.jedi#complete_string(0)"
endif
endif
endif

View File

@ -0,0 +1,32 @@
if !jedi#init_python()
finish
endif
if g:jedi#show_call_signatures > 0 && has('conceal')
" +conceal is the default for vim >= 7.3
let s:e = g:jedi#call_signature_escape
let s:full = s:e.'jedi=.\{-}'.s:e.'.\{-}'.s:e.'jedi'.s:e
let s:ignore = s:e.'jedi.\{-}'.s:e
exe 'syn match jediIgnore "'.s:ignore.'" contained conceal'
setlocal conceallevel=2
syn match jediFatSymbol "\*_\*" contained conceal
syn match jediFat "\*_\*.\{-}\*_\*" contained contains=jediFatSymbol
syn match jediSpace "\v[ ]+( )@=" contained
exe 'syn match jediFunction "'.s:full.'" keepend extend '
\ .' contains=jediIgnore,jediFat,jediSpace'
\ .' containedin=pythonComment,pythonString,pythonRawString'
unlet! s:e s:full s:ignore
hi def link jediIgnore Ignore
hi def link jediFatSymbol Ignore
hi def link jediSpace Normal
if exists('g:colors_name')
hi def link jediFunction CursorLine
hi def link jediFat TabLine
else
hi jediFunction term=NONE cterm=NONE ctermfg=6 guifg=Black gui=NONE ctermbg=0 guibg=Grey
hi jediFat term=bold,underline cterm=bold,underline gui=bold,underline ctermbg=0 guibg=#555555
endif
endif

View File

@ -0,0 +1,428 @@
scriptencoding utf-8
" ------------------------------------------------------------------------
" Settings initialization
" ------------------------------------------------------------------------
let s:deprecations = {
\ 'get_definition_command': 'goto_definitions_command',
\ 'pydoc': 'documentation_command',
\ 'related_names_command': 'usages_command',
\ 'autocompletion_command': 'completions_command',
\ 'show_function_definition': 'show_call_signatures',
\ }
let s:default_settings = {
\ 'use_tabs_not_buffers': 0,
\ 'use_splits_not_buffers': 1,
\ 'auto_initialization': 1,
\ 'auto_vim_configuration': 1,
\ 'goto_command': "'<leader>d'",
\ 'goto_assignments_command': "'<leader>g'",
\ 'goto_definitions_command': "''",
\ 'completions_command': "'<C-Space>'",
\ 'call_signatures_command': "'<leader>n'",
\ 'usages_command': "'<leader>n'",
\ 'rename_command': "'<leader>r'",
\ 'popup_on_dot': 1,
\ 'documentation_command': "'K'",
\ 'show_call_signatures': 1,
\ 'call_signature_escape': "'=`='",
\ 'auto_close_doc': 1,
\ 'max_doc_height': 30,
\ 'popup_select_first': 1,
\ 'quickfix_window_height': 10,
\ 'completions_enabled': 1,
\ 'force_py_version': "'auto'"
\ }
for [key, val] in items(s:deprecations)
if exists('g:jedi#'.key)
echom "'g:jedi#".key."' is deprecated. Please use 'g:jedi#".val."' instead. Sorry for the inconvenience."
exe 'let g:jedi#'.val.' = g:jedi#'.key
endif
endfor
for [key, val] in items(s:default_settings)
if !exists('g:jedi#'.key)
exe 'let g:jedi#'.key.' = '.val
endif
endfor
" ------------------------------------------------------------------------
" Python initialization
" ------------------------------------------------------------------------
let s:script_path = fnameescape(expand('<sfile>:p:h:h'))
function! s:init_python()
if g:jedi#force_py_version != 'auto'
" Always use the user supplied version.
try
return jedi#force_py_version(g:jedi#force_py_version)
catch
throw "Could not setup g:jedi#force_py_version: ".v:exception
endtry
endif
" Handle "auto" version.
if has('nvim') || (has('python') && has('python3'))
" Neovim usually has both python providers. Skipping the `has` check
" avoids starting both of them.
" Get default python version from interpreter in $PATH.
let s:def_py = system("python -c 'import sys; sys.stdout.write(str(sys.version_info[0]))'")
if v:shell_error != 0 || !len(s:def_py)
if !exists("g:jedi#squelch_py_warning")
echohl WarningMsg
echom "Warning: jedi-vim failed to get Python version from sys.version_info: " . s:def_py
echom "Falling back to version 2."
echohl None
endif
let s:def_py = 2
elseif &verbose
echom "jedi-vim: auto-detected Python: ".s:def_py
endif
" Make sure that the auto-detected version is available in Vim.
if !has('nvim') || has('python'.(s:def_py == 2 ? '' : s:def_py))
return jedi#force_py_version(s:def_py)
endif
endif
if has('python')
call jedi#setup_py_version(2)
elseif has('python3')
call jedi#setup_py_version(3)
else
throw "jedi-vim requires Vim with support for Python 2 or 3."
endif
return 1
endfunction
function! jedi#init_python()
if !exists('s:_init_python')
try
let s:_init_python = s:init_python()
catch
if !exists("g:jedi#squelch_py_warning")
echohl WarningMsg
echom "Error: jedi-vim failed to initialize Python: ".v:exception." (in ".v:throwpoint.")"
echohl None
endif
let s:_init_python = 0
endtry
endif
return s:_init_python
endfunction
function! jedi#setup_py_version(py_version)
if a:py_version == 2
let cmd_init = 'pyfile'
let cmd_exec = 'python'
elseif a:py_version == 3
let cmd_init = 'py3file'
let cmd_exec = 'python3'
else
throw "jedi#setup_py_version: invalid py_version: ".a:py_version
endif
try
execute cmd_init.' '.s:script_path.'/initialize.py'
execute 'command! -nargs=1 PythonJedi '.cmd_exec.' <args>'
return 1
catch
throw "jedi#setup_py_version: ".v:exception
endtry
endfunction
function! jedi#force_py_version(py_version)
let g:jedi#force_py_version = a:py_version
return jedi#setup_py_version(a:py_version)
endfunction
function! jedi#force_py_version_switch()
if g:jedi#force_py_version == 2
call jedi#force_py_version(3)
elseif g:jedi#force_py_version == 3
call jedi#force_py_version(2)
else
throw "Don't know how to switch from ".g:jedi#force_py_version."!"
endif
endfunction
" Helper function instead of `python vim.eval()`, and `.command()` because
" these also return error definitions.
function! jedi#_vim_exceptions(str, is_eval)
let l:result = {}
try
if a:is_eval
let l:result.result = eval(a:str)
else
execute a:str
let l:result.result = ''
endif
catch
let l:result.exception = v:exception
let l:result.throwpoint = v:throwpoint
endtry
return l:result
endfunction
if !jedi#init_python()
" Do not define any functions when Python initialization failed.
finish
endif
" ------------------------------------------------------------------------
" functions that call python code
" ------------------------------------------------------------------------
function! jedi#goto()
PythonJedi jedi_vim.goto(mode="goto")
endfunction
function! jedi#goto_assignments()
PythonJedi jedi_vim.goto(mode="assignment")
endfunction
function! jedi#goto_definitions()
PythonJedi jedi_vim.goto(mode="definition")
endfunction
function! jedi#usages()
PythonJedi jedi_vim.goto(mode="related_name")
endfunction
function! jedi#rename(...)
PythonJedi jedi_vim.rename()
endfunction
function! jedi#rename_visual(...)
PythonJedi jedi_vim.rename_visual()
endfunction
function! jedi#completions(findstart, base)
PythonJedi jedi_vim.completions()
endfunction
function! jedi#enable_speed_debugging()
PythonJedi jedi_vim.jedi.set_debug_function(jedi_vim.print_to_stdout, speed=True, warnings=False, notices=False)
endfunction
function! jedi#enable_debugging()
PythonJedi jedi_vim.jedi.set_debug_function(jedi_vim.print_to_stdout)
endfunction
function! jedi#disable_debugging()
PythonJedi jedi_vim.jedi.set_debug_function(None)
endfunction
function! jedi#py_import(args)
PythonJedi jedi_vim.py_import()
endfun
function! jedi#py_import_completions(argl, cmdl, pos)
PythonJedi jedi_vim.py_import_completions()
endfun
" ------------------------------------------------------------------------
" show_documentation
" ------------------------------------------------------------------------
function! jedi#show_documentation()
PythonJedi if jedi_vim.show_documentation() is None: vim.command('return')
let bn = bufnr("__doc__")
if bn > 0
let wi=index(tabpagebuflist(tabpagenr()), bn)
if wi >= 0
" If the __doc__ buffer is open in the current tab, jump to it
silent execute (wi+1).'wincmd w'
else
silent execute "sbuffer ".bn
endif
else
split '__doc__'
endif
setlocal modifiable
setlocal noswapfile
setlocal buftype=nofile
silent normal! ggdG
silent $put=l:doc
silent normal! 1Gdd
setlocal nomodifiable
setlocal nomodified
setlocal filetype=rst
if l:doc_lines > g:jedi#max_doc_height " max lines for plugin
let l:doc_lines = g:jedi#max_doc_height
endif
execute "resize ".l:doc_lines
" quit comands
nnoremap <buffer> q ZQ
execute "nnoremap <buffer> ".g:jedi#documentation_command." ZQ"
" highlight python code within rst
unlet! b:current_syntax
syn include @rstPythonScript syntax/python.vim
" 4 spaces
syn region rstPythonRegion start=/^\v {4}/ end=/\v^( {4}|\n)@!/ contains=@rstPythonScript
" >>> python code -> (doctests)
syn region rstPythonRegion matchgroup=pythonDoctest start=/^>>>\s*/ end=/\n/ contains=@rstPythonScript
let b:current_syntax = "rst"
endfunction
" ------------------------------------------------------------------------
" helper functions
" ------------------------------------------------------------------------
function! jedi#add_goto_window(len)
set lazyredraw
cclose
let height = min([a:len, g:jedi#quickfix_window_height])
execute 'belowright copen '.height
set nolazyredraw
if g:jedi#use_tabs_not_buffers == 1
noremap <buffer> <CR> :call jedi#goto_window_on_enter()<CR>
endif
au WinLeave <buffer> q " automatically leave, if an option is chosen
redraw!
endfunction
function! jedi#goto_window_on_enter()
let l:list = getqflist()
let l:data = l:list[line('.') - 1]
if l:data.bufnr
" close goto_window buffer
normal ZQ
PythonJedi jedi_vim.new_buffer(vim.eval('bufname(l:data.bufnr)'))
call cursor(l:data.lnum, l:data.col)
else
echohl WarningMsg | echo "Builtin module cannot be opened." | echohl None
endif
endfunction
function! s:syn_stack()
if !exists("*synstack")
return []
endif
return map(synstack(line('.'), col('.') - 1), 'synIDattr(v:val, "name")')
endfunc
function! jedi#do_popup_on_dot_in_highlight()
let highlight_groups = s:syn_stack()
for a in highlight_groups
if a == 'pythonDoctest'
return 1
endif
endfor
for a in highlight_groups
for b in ['pythonString', 'pythonComment', 'pythonNumber']
if a == b
return 0
endif
endfor
endfor
return 1
endfunc
function! jedi#configure_call_signatures()
if g:jedi#show_call_signatures == 2 " Command line call signatures
autocmd InsertEnter <buffer> let g:jedi#first_col = s:save_first_col()
endif
autocmd InsertLeave <buffer> PythonJedi jedi_vim.clear_call_signatures()
autocmd CursorMovedI <buffer> PythonJedi 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 startwin = winnr()
let winwidth = winwidth(0)
if winwidth == &columns
return 0
elseif winnr('$') == 2
return startwin == 1 ? 0 : (winwidth(1) + 1)
elseif winnr('$') == 3
if startwin == 1
return 0
endif
let ww1 = winwidth(1)
let ww2 = winwidth(2)
let ww3 = winwidth(3)
if ww1 + ww2 + ww3 + 2 == &columns
if startwin == 2
return ww1 + 1
else
return ww1 + ww2 + 2
endif
elseif startwin == 2
if ww2 + ww3 + 1 == &columns
return 0
else
return ww1 + 1
endif
else " startwin == 3
if ww2 + ww3 + 1 == &columns
return ww2 + 1
else
return ww1 + 1
endif
endif
endif
return 0
endfunction
function! jedi#complete_string(is_popup_on_dot)
if a:is_popup_on_dot && !(g:jedi#popup_on_dot && jedi#do_popup_on_dot_in_highlight())
return ''
endif
if pumvisible() && !a:is_popup_on_dot
return "\<C-n>"
else
return "\<C-x>\<C-o>\<C-r>=jedi#complete_opened(".a:is_popup_on_dot.")\<CR>"
endif
endfunction
function! jedi#complete_opened(is_popup_on_dot)
if pumvisible()
" Only go down if it is visible, user-enabled and the longest
" option is set.
if g:jedi#popup_select_first && stridx(&completeopt, 'longest') > -1
return "\<Down>"
endif
if a:is_popup_on_dot
" Prevent completion of the first entry with dot completion.
return "\<C-p>"
endif
endif
return ""
endfunction
"PythonJedi jedi_vim.jedi.set_debug_function(jedi_vim.print_to_stdout, speed=True, warnings=False, notices=False)
"PythonJedi jedi_vim.jedi.set_debug_function(jedi_vim.print_to_stdout)
" vim: set et ts=4:

View File

@ -0,0 +1,60 @@
import os
import subprocess
import urllib
import zipfile
import pytest
VSPEC_URL = 'https://github.com/kana/vim-vspec/archive/1.4.1.zip'
CACHE_FOLDER = '.cache'
VSPEC_FOLDER = os.path.join(CACHE_FOLDER, 'vim-vspec-1.4.1')
VSPEC_RUNNER = os.path.join(VSPEC_FOLDER, 'bin/vspec')
TEST_DIR = 'test'
class IntegrationTestFile(object):
def __init__(self, path):
self.path = path
def run(self):
output = subprocess.check_output(
[VSPEC_RUNNER, '.', VSPEC_FOLDER, self.path])
for line in output.splitlines():
if line.startswith(b'not ok') or line.startswith(b'Error'):
pytest.fail("{} failed:\n{}".format(
self.path, output.decode('utf-8')), pytrace=False)
def __repr__(self):
return "<%s: %s>" % (type(self), self.path)
def pytest_configure(config):
if not os.path.isdir(CACHE_FOLDER):
os.mkdir(CACHE_FOLDER)
if not os.path.exists(VSPEC_FOLDER):
name, hdrs = urllib.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, 'w') as f:
f.write(data)
z.close()
os.chmod(VSPEC_RUNNER, 0o777)
def pytest_generate_tests(metafunc):
"""
:type metafunc: _pytest.python.Metafunc
"""
def collect_tests():
for f in os.listdir(TEST_DIR):
if f.endswith('.vim'):
yield IntegrationTestFile(os.path.join(TEST_DIR, f))
metafunc.parametrize('case', list(collect_tests()))

View File

@ -0,0 +1,508 @@
*jedi-vim.txt* - For Vim version 7.3 - Last change: 2014/07/29
__ _______ _______ __ ____ ____ __ .___ ___.~
| | | ____|| \ | | \ \ / / | | | \/ |~
| | | |__ | .--. || | _____\ \/ / | | | \ / |~
.--. | | | __| | | | || | |______\ / | | | |\/| |~
| `--' | | |____ | '--' || | \ / | | | | | |~
\______/ |_______||_______/ |__| \__/ |__| |__| |__|~
jedi-vim - awesome Python autocompletion with Vim
==============================================================================
Contents *jedi-vim-contents*
1. Introduction |jedi-vim-introduction|
2. Installation |jedi-vim-installation|
2.0. Requirements |jedi-vim-installation-requirements|
2.1. Manually |jedi-vim-installation-manually|
2.2. Using Pathogen |jedi-vim-installation-pathogen|
2.3. Using Vundle |jedi-vim-installation-vundle|
2.4. Installing from Repositories |jedi-vim-installation-repos|
3. Supported Python features |jedi-vim-support|
4. Usage |jedi-vim-usage|
5. Mappings |jedi-vim-keybindings|
5.1. Start completion |g:jedi#completions_command|
5.2. Go to definition |g:jedi#goto_command|
5.3. Go to assignment |g:jedi#goto_assignments_command|
5.4 Go to definition (deprecated) |g:jedi#goto_definitions_command|
5.5. Show documentation |g:jedi#documentation_command|
5.6. Rename variables |g:jedi#rename_command|
5.7. Show name usages |g:jedi#usages_command|
5.8. Open module by name |:Pyimport|
6. Configuration |jedi-vim-configuration|
6.1. auto_initialization |g:jedi#auto_initialization|
6.2. auto_vim_configuration |g:jedi#auto_vim_configuration|
6.3. popup_on_dot |g:jedi#popup_on_dot|
6.4. popup_select_first |g:jedi#popup_select_first|
6.5. auto_close_doc |g:jedi#auto_close_doc|
6.6. show_call_signatures |g:jedi#show_call_signatures|
6.7. use_tabs_not_buffers |g:jedi#use_tabs_not_buffers|
6.8. squelch_py_warning |g:jedi#squelch_py_warning|
6.9. completions_enabled |g:jedi#completions_enabled|
6.10. use_splits_not_buffers |g:jedi#use_splits_not_buffers|
6.11. force_py_version |g:jedi#force_py_version|
7. Testing |jedi-vim-testing|
8. Contributing |jedi-vim-contributing|
9. License |jedi-vim-license|
==============================================================================
1. Introduction *jedi-vim-introduction*
Jedi-vim is a Vim binding to the awesome Python autocompletion library
`jedi`. Among jedi's (and, therefore, jedi-vim's) features are:
- Completion for a wide array of Python features (see |jedi-vim-support|)
- Robust in dealing with syntax errors and wrong indentation
- Parses complex module/function/class structures
- Infers function arguments from Sphinx/Epydoc strings
- Doesn't execute Python code
- Supports Virtualenv
- Supports Python 2.5+ and 3.2+
By leveraging this library, jedi-vim adds the following capabilities to Vim:
- Displaying function/class bodies
- "Go to definition" command
- Displaying docstrings
- Renaming and refactoring
- Looking up related names
==============================================================================
2. Installation *jedi-vim-installation*
------------------------------------------------------------------------------
2.0. Requirements *jedi-vim-installation-requirements*
First of all, jedi-vim requires Vim to be compiled with the `+python` option.
The jedi library has to be installed for jedi-vim to work properly. You can
install it first, by using e.g. your distribution's package manager, or by
using pip: >
pip install jedi
However, you can also install it as a git submodule if you don't want to use
jedi for anything but this plugin. How to do this is detailed below.
It is best if you have VIM >= 7.3, compiled with the `+conceal` option. With
older versions, you will probably not see the parameter recommendation list
for functions after typing the open bracket. Some platforms (including OS X
releases) do not ship a VIM with `+conceal`. You can check if your VIM has the
feature with >
:ver
and look for "`+conceal`" (as opposed to "`-conceal`") or >
:echo has('conceal')
which will report 0 (not included) or 1 (included). If your VIM lacks this
feature and you would like function parameter completion, you will need to
build your own VIM, or use a package for your operating system that has this
feature (such as MacVim on OS X, which also contains a console binary).
------------------------------------------------------------------------------
2.1. Installing manually *jedi-vim-installation-manually*
1a. Get the latest repository from Github: >
git clone http://github.com/davidhalter/jedi-vim path/to/bundles/jedi-vim
1b. If you want to install jedi as a submodule instead, issue this command: >
git clone --recursive http://github.com/davidhalter/jedi-vim
2. Put the plugin files into their respective folders in your vim runtime
directory (usually ~/.vim). Be sure to pay attention to the directory
structure!
3. Update the Vim help tags with >
:helptags <path/to/vimruntime>/doc
------------------------------------------------------------------------------
2.1. Installing using Pathogen *jedi-vim-installation-pathogen*
Pathogen simplifies installation considerably.
1.a Clone the git repository into your bundles directory: >
git clone http://github.com/davidhalter/jedi-vim path/to/bundles/jedi-vim
1b. Again, if you want to install jedi as a submodule, use this command
instead: >
git clone --recursive http://github.com/davidhalter/jedi-vim
------------------------------------------------------------------------------
2.3. Installing using Vundle *jedi-vim-installation-vundle*
1. Vundle automatically downloads subrepositories as git submodules, so you
will automatically get the jedi library with the jedi-vim plugin. Add the
following to the Bundles section in your .vimrc file: >
Plugin 'davidhalter/jedi-vim'
2. Issue the following command in Vim: >
:PluginInstall
Help tags are generated automatically, so you should be good to go.
------------------------------------------------------------------------------
2.4. Installing from Repositories *jedi-vim-installation-repos*
Some Linux distributions have jedi-vim packages in their official
repositories. On Arch Linux, install vim-jedi. On Debian (8+) or Ubuntu
(14.04+) install vim-python-jedi.
==============================================================================
3. Supported Python features *jedi-vim-support*
The Jedi library does all the hard work behind the scenes. It supports
completion of a large number of Python features, among them:
- Builtins
- Multiple `return`s or `yield`s
- Tuple assignments/array indexing/dictionary indexing
- `with`-statement/exception handling
- `*args` and `**kwargs`
- Decorators, lambdas, closures
- Generators, iterators
- Some descriptors: `property`/`staticmethod`/`classmethod`
- Some magic methods: `__call__`, `__iter__`, `__next__`, `__get__`,
`__getitem__`, `__init__`
- `list.append()`, `set.add()`, `list.extend()`, etc.
- (Nested) list comprehensions and ternary expressions
- Relative `import`s
- `getattr()`/`__getattr__`/`__getattribute__`
- Function annotations (py3k feature, are being ignored at the moment, but are
parsed)
- Class decorators (py3k feature, are being ignored at the moment, but are
parsed)
- Simple/usual `sys.path` modifications
- `isinstance` checks for `if`/`while`/`assert` case, that doesnt work with
Jedi
- And more...
Note: This list is not necessarily up to date. For a complete list of
features, please refer to the Jedi documentation at http://jedi.jedidjah.ch.
==============================================================================
4. Usage *jedi-vim-usage*
With the default settings, autocompletion can be triggered by typing
<Ctrl-Space>. The first entry will automatically be selected, so you can press
<Return> to insert it into your code or keep typing and narrow down your
completion options. The usual <C-X><C-O> and <C-P>/<C-N> keybindings work as
well. Autocompletion is also triggered by typing a period in insert mode.
Since periods rarely occur in Python code outside of method/import lookups,
this is handy to have (but can be disabled).
When it encounters a new module, jedi might take a few seconds to parse that
module's contents. Afterwards, the contents are cached and completion will be
almost instantaneous.
==============================================================================
5. Key Bindings *jedi-vim-keybindings*
All keybindings can be mapped by setting the appropriate global option. For
example, to set the keybinding for starting omnicompletion to <C-N> instead of
<Ctrl-Space>, add the following setting to your .vimrc file: >
let g:jedi#completions_command = "<C-N>"
Note: If you have |g:jedi#auto_initialization| set to 0, you have to create
a mapping yourself by calling a function: >
" Using <C-N> for omnicompletion
inoremap <silent> <buffer> <C-N> <c-x><c-o>
" Use <localleader>r (by default <\-r>) for renaming
nnoremap <silent> <buffer> <localleader>r :call jedi#rename()<cr>
" etc.
Note: You can set commands to '', which means that they are empty and not
assigned. It's an easy way to "disable" functionality of jedi-vim.
------------------------------------------------------------------------------
5.1. `g:jedi#completions_command` *g:jedi#completions_command*
Function: n/a; see above
Default: <Ctrl-Space> Start completion
Performs autocompletion (or omnicompletion, to be precise).
Note: If you want to use <Tab> for completion, please install Supertab:
https://github.com/ervandew/supertab.
------------------------------------------------------------------------------
5.2. `g:jedi#goto_command` *g:jedi#goto_command*
Function: `jedi#goto()`
Default: <leader>d Go to definition (or assignment)
This function first tries |jedi#goto_definitions|, and falls back to
|jedi#goto_assignments| for builtin modules. It produces an error if nothing
could be found.
NOTE: this implementation is subject to change.
Ref: https://github.com/davidhalter/jedi/issues/570
This command tries to find the original definition of the function/class under
the cursor. Just like the `jedi#goto_assignments()` function, it does not work
if the definition isn't in a Python source file.
The difference between `jedi#goto_assignments()` and `jedi#goto_definitions()`
is that the latter performs recursive lookups. Take, for example, the
following module structure: >
# file1.py:
from file2 import foo
# file2.py:
from file3 import bar as foo
# file3.py
def bar():
pass
The `jedi#goto_assignments()` function will take you to the >
from file2 import foo
statement in file1.py, while the `jedi#goto_definitions()` function will take
you all the way to the >
def bar():
line in file3.py.
------------------------------------------------------------------------------
5.3. `g:jedi#goto_assignments_command` *g:jedi#goto_assignments_command*
Function: `jedi#goto_assignments()`
Default: <leader>g Go to assignment
This function finds the first definition of the function/class under the
cursor. It produces an error if the definition is not in a Python file.
------------------------------------------------------------------------------
5.4. `g:jedi#goto_definitions_command` *g:jedi#goto_definitions_command*
Function: `jedi#goto_definitions()`
Default: - Go to original definition
NOTE: Deprecated. Use |g:jedi#goto_command| / |jedi#goto()| instead, which
currently uses this internally.
------------------------------------------------------------------------------
5.5. `g:jedi#documentation_command` *g:jedi#documentation_command*
Function: `jedi#show_documentation()`
Default: <K> Show pydoc documentation
This shows the pydoc documentation for the item currently under the cursor.
The documentation is opened in a horizontally split buffer. The height of this
buffer is controlled by `g:jedi#max_doc_height` (set by default to 30).
------------------------------------------------------------------------------
5.6. `g:jedi#rename_command` *g:jedi#rename_command*
Function: `jedi#rename()`
Default: <leader>r Rename variables
Jedi-vim deletes the word currently under the cursor and puts Vim in insert
mode, where the user is expected to enter the new variable name. Upon leaving
insert mode, jedi-vim then renames all occurences of the old variable name
with the new one. The number of performed renames is displayed in the command
line.
------------------------------------------------------------------------------
5.7. `g:jedi#usages_command` *g:jedi#usages_command*
Function: `jedi#usages()`
Default: <leader>n Show usages of a name.
The quickfix window is populated with a list of all names which point to the
definition of the name under the cursor.
------------------------------------------------------------------------------
5.8. Open module by name *:Pyimport*
Function: `jedi#py_import(args)`
Default: :Pyimport e.g. `:Pyimport os` shows os.py in VIM.
Simulate an import and open that module in VIM.
==============================================================================
6. Configuration *jedi-vim-configuration*
Note: You currently have to set these options in your .vimrc. Setting them in
an ftplugin (e.g. ~/.vim/ftplugin/python/jedi-vim-settings.vim) will not work
because jedi-vim is not set up as an filetype plugin, but as a "regular"
plugin.
------------------------------------------------------------------------------
6.1. `g:jedi#auto_initialization` *g:jedi#auto_initialization*
Upon initialization, jedi-vim performs the following steps:
1. Set the current buffers 'omnifunc' to its own completion function
`jedi#completions`
2. Create mappings to commands specified in |jedi-vim-keybindings|
3. Call `jedi#configure_call_signatures()` if
`g:jedi#show_call_signatures` is set
You can disable the default initialization routine by setting this option to
0. Beware that you have to perform the above steps yourself, though.
Options: 0 or 1
Default: 1 (Perform automatic initialization)
------------------------------------------------------------------------------
6.2. `g:jedi#auto_vim_configuration` *g:jedi#auto_vim_configuration*
Jedi-vim sets 'completeopt' to `menuone,longest,preview` by default, if
'completeopt' is not changed from Vim's default.
It also remaps <Ctrl-C> to <Esc> in insert mode.
If you want to keep your own configuration, disable this setting.
Options: 0 or 1
Default: 1 (Set 'completeopt' and mapping as described above)
------------------------------------------------------------------------------
6.3. `g:jedi#popup_on_dot` *g:jedi#popup_on_dot*
Jedi-vim automatically starts completion upon typing a period in insert mode.
However, when working with large modules, this can slow down your typing flow
since you have to wait for jedi to parse the module and show the completion
menu. By disabling this setting, completion is only started when you manually
press the completion key.
Options: 0 or 1
Default: 1 (Start completion on typing a period)
------------------------------------------------------------------------------
6.4. `g:jedi#popup_select_first` *g:jedi#popup_select_first*
Upon starting completion, jedi-vim can automatically select the first entry
that pops up (without actually inserting it).
This leads to a better typing flow: As you type more characters, the entries
in the completion menu are narrowed down. If they are narrowed down enough,
you can just press <Return> to insert the first match.
Options: 0 or 1
Default: 1 (Automatically select first completion entry)
------------------------------------------------------------------------------
6.5. `g:jedi#auto_close_doc` *g:jedi#auto_close_doc*
When doing completion, jedi-vim shows the docstring of the currently selected
item in a preview window. By default, this window is being closed after
insertion of a completion item.
Set this to 0 to leave the preview window open even after leaving insert mode.
This could be useful if you want to browse longer docstrings.
Options: 0 or 1
Default: 1 (Automatically close preview window upon leaving insert mode)
------------------------------------------------------------------------------
6.6. `g:jedi#show_call_signatures` *g:jedi#show_call_signatures*
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. Setting this option to 2 shows call
signatures in the command line instead of a popup window.
Options: 0, 1, or 2
Default: 1 (Show call signatures window)
Note: 'showmode' must be disabled for command line call signatures to be
visible.
Note: This setting is ignored if |g:jedi#auto_initialization| is set to 0. In
that case, if you want to see call signatures, you have to set it up
manually by calling a function in your configuration file: >
call jedi#configure_call_signatures()
------------------------------------------------------------------------------
6.7. `g:jedi#use_tabs_not_buffers` *g:jedi#use_tabs_not_buffers*
You can make jedi-vim open a new tab if you use the "go to", "show
definition", or "related names" commands. When you leave this at the default
(0), they open in the current buffer instead.
Options: 0 or 1
Default: 0 (Command output is put in a new tab)
------------------------------------------------------------------------------
6.8. `g:jedi#squelch_py_warning` *g:jedi#squelch_py_warning*
When Vim has not been compiled with +python, jedi-vim shows a warning to that
effect and aborts loading itself. Set this to 1 to suppress that warning.
Options: 0 or 1
Default: 0 (Warning is shown)
------------------------------------------------------------------------------
6.9. `g:jedi#completions_enabled` *g:jedi#completions_enabled*
If you don't want Jedi completion, but all the other features, you can disable
it in favor of another completion engine (that probably also uses Jedi, like
YCM).
Options: 0 or 1
Default: 1
------------------------------------------------------------------------------
6.10. `g:jedi#use_splits_not_buffers` *g:jedi#use_splits_not_buffers*
If you want to open new split for "go to", you could set this option to the
direction which you want to open a split with.
Options: top, left, right, bottom or winwidth
Default: "" (not enabled by default)
Note: with the 'winwidth' option the window is split vertically or horizontally
depending on the width of the window relative to 'textwidth'. This essentially
means that if the window is big enough it will be split vertically but if it is
small a horizontal split happens.
------------------------------------------------------------------------------
6.11. `g:jedi#force_py_version` *g:jedi#force_py_version*
If you have installed both python 2 and python 3, you can force which one jedi
should use by setting this variable. It forces the internal Vim command, which
will be used for every jedi call to the respective python interpreter.
The variable can be set in the .vimrc like this to force python 3:
let g:jedi#force_py_version = 3
This variable can be switched during runtime using the following function:
Function: `jedi#force_py_version_switch()`
or set directly using this function, which has the same name as the variable:
Function: `jedi#force_py_version(py_version)`
Options: 2 or 3
Default: "auto" (will use sys.version_info from "python" in your $PATH)
==============================================================================
7. Testing *jedi-vim-testing*
jedi-vim is being tested with a combination of vspec
https://github.com/kana/vim-vspec and py.test http://pytest.org/.
The tests are in the test subdirectory, you can run them calling::
py.test
The tests are automatically run with `travis
<https://travis-ci.org/davidhalter/jedi-vim>`_.
==============================================================================
8. Contributing *jedi-vim-contributing*
We love Pull Requests! Read the instructions in `CONTRIBUTING.md`.
==============================================================================
9. License *jedi-vim-license*
Jedi-vim is licensed with the MIT license.
vim: textwidth=78 tabstop=8 filetype=help:norightleft:

View File

@ -0,0 +1,44 @@
if !jedi#init_python()
finish
endif
" ------------------------------------------------------------------------
" Initialization of jedi-vim
" ------------------------------------------------------------------------
if g:jedi#auto_initialization
" goto / get_definition / usages
if g:jedi#goto_command != ''
execute "nnoremap <buffer> ".g:jedi#goto_command." :call jedi#goto()<CR>"
endif
if g:jedi#goto_assignments_command != ''
execute "nnoremap <buffer> ".g:jedi#goto_assignments_command." :call jedi#goto_assignments()<CR>"
endif
if g:jedi#goto_definitions_command != ''
execute "nnoremap <buffer> ".g:jedi#goto_definitions_command." :call jedi#goto_definitions()<CR>"
endif
if g:jedi#usages_command != ''
execute "nnoremap <buffer> ".g:jedi#usages_command." :call jedi#usages()<CR>"
endif
" rename
if g:jedi#rename_command != ''
execute "nnoremap <buffer> ".g:jedi#rename_command." :call jedi#rename()<CR>"
execute "vnoremap <buffer> ".g:jedi#rename_command." :call jedi#rename_visual()<CR>"
endif
" documentation/pydoc
if g:jedi#documentation_command != ''
execute "nnoremap <silent> <buffer>".g:jedi#documentation_command." :call jedi#show_documentation()<CR>"
endif
if g:jedi#show_call_signatures > 0 && has('conceal')
call jedi#configure_call_signatures()
endif
if g:jedi#completions_enabled == 1
inoremap <silent> <buffer> . .<C-R>=jedi#complete_string(1)<CR>
endif
if g:jedi#auto_close_doc
" close preview if its still open after insert
autocmd InsertLeave <buffer> if pumvisible() == 0|pclose|endif
endif
endif

View File

@ -0,0 +1,22 @@
''' ------------------------------------------------------------------------
Python initialization
---------------------------------------------------------------------------
here we initialize the jedi stuff '''
import vim
# update the system path, to include the jedi path
import sys
import os
# vim.command('echom expand("<sfile>:p:h:h")') # broken, <sfile> inside function
# sys.path.insert(0, os.path.join(vim.eval('expand("<sfile>:p:h:h")'), 'jedi'))
sys.path.insert(0, os.path.join(vim.eval('expand(s:script_path)'), 'jedi'))
# to display errors correctly
import traceback
# update the sys path to include the jedi_vim script
sys.path.insert(0, vim.eval('expand(s:script_path)'))
import jedi_vim
sys.path.pop(1)

@ -0,0 +1 @@
Subproject commit 66557903ae4c1174eb437a8feeeb718e69d5fa3a

View File

@ -0,0 +1,643 @@
"""
The Python parts of the Jedi library for VIM. It is mostly about communicating
with VIM.
"""
import traceback # for exception output
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
is_py3 = sys.version_info[0] >= 3
if is_py3:
unicode = str
class PythonToVimStr(unicode):
""" Vim has a different string implementation of single quotes """
__slots__ = []
def __new__(cls, obj, encoding='UTF-8'):
if is_py3 or isinstance(obj, unicode):
return unicode.__new__(cls, obj)
else:
return unicode.__new__(cls, obj, encoding)
def __repr__(self):
# this is totally stupid and makes no sense but vim/python unicode
# support is pretty bad. don't ask how I came up with this... It just
# works...
# It seems to be related to that bug: http://bugs.python.org/issue5876
if unicode is str:
s = self
else:
s = self.encode('UTF-8')
return '"%s"' % s.replace('\\', '\\\\').replace('"', r'\"')
class VimError(Exception):
def __init__(self, message, throwpoint, executing):
super(type(self), self).__init__(message)
self.message = message
self.throwpoint = throwpoint
self.executing = executing
def __str__(self):
return self.message + '; created by: ' + repr(self.executing)
def _catch_exception(string, is_eval):
"""
Interface between vim and python calls back to it.
Necessary, because the exact error message is not given by `vim.error`.
"""
e = 'jedi#_vim_exceptions(%s, %s)'
result = vim.eval(e % (repr(PythonToVimStr(string, 'UTF-8')), is_eval))
if 'exception' in result:
raise VimError(result['exception'], result['throwpoint'], string)
return result['result']
def vim_command(string):
_catch_exception(string, 0)
def vim_eval(string):
return _catch_exception(string, 1)
def no_jedi_warning():
vim.command('echohl WarningMsg'
'| echom "Please install Jedi if you want to use jedi-vim."'
'| echohl None')
def echo_highlight(msg):
vim_command('echohl WarningMsg | echom "{}" | echohl None'.format(
msg.replace('"', '\\"')))
import vim
try:
import jedi
except ImportError:
no_jedi_warning()
jedi = None
else:
try:
version = jedi.__version__
except Exception as e: # e.g. AttributeError
echo_highlight("Could not load jedi python module: {}".format(e))
jedi = None
else:
if isinstance(version, str):
# the normal use case, now.
from jedi import utils
version = utils.version_info()
if version < (0, 7):
echo_highlight('Please update your Jedi version, it is too old.')
def catch_and_print_exceptions(func):
def wrapper(*args, **kwargs):
try:
return func(*args, **kwargs)
except (Exception, vim.error):
print(traceback.format_exc())
return None
return wrapper
def _check_jedi_availability(show_error=False):
def func_receiver(func):
def wrapper(*args, **kwargs):
if jedi is None:
if show_error:
no_jedi_warning()
return
else:
return func(*args, **kwargs)
return wrapper
return func_receiver
@catch_and_print_exceptions
def get_script(source=None, column=None):
jedi.settings.additional_dynamic_modules = \
[b.name for b in vim.buffers if b.name is not None and b.name.endswith('.py')]
if source is None:
source = '\n'.join(vim.current.buffer)
row = vim.current.window.cursor[0]
if column is None:
column = vim.current.window.cursor[1]
buf_path = vim.current.buffer.name
encoding = vim_eval('&encoding') or 'latin1'
return jedi.Script(source, row, column, buf_path, encoding)
@_check_jedi_availability(show_error=False)
@catch_and_print_exceptions
def completions():
row, column = vim.current.window.cursor
# Clear call signatures in the buffer so they aren't seen by the completer.
# Call signatures in the command line can stay.
if vim_eval("g:jedi#show_call_signatures") == '1':
clear_call_signatures()
if vim.eval('a:findstart') == '1':
count = 0
for char in reversed(vim.current.line[:column]):
if not re.match('[\w\d]', char):
break
count += 1
vim.command('return %i' % (column - count))
else:
base = vim.eval('a:base')
source = ''
for i, line in enumerate(vim.current.buffer):
# enter this path again, otherwise source would be incomplete
if i == row - 1:
source += line[:column] + base + line[column:]
else:
source += line
source += '\n'
# here again hacks, because jedi has a different interface than vim
column += len(base)
try:
script = get_script(source=source, column=column)
completions = script.completions()
signatures = script.call_signatures()
out = []
for c in completions:
d = dict(word=PythonToVimStr(c.name[:len(base)] + c.complete),
abbr=PythonToVimStr(c.name),
# stuff directly behind the completion
menu=PythonToVimStr(c.description),
info=PythonToVimStr(c.docstring()), # docstr
icase=1, # case insensitive
dup=1 # allow duplicates (maybe later remove this)
)
out.append(d)
strout = str(out)
except Exception:
# print to stdout, will be in :messages
print(traceback.format_exc())
strout = ''
completions = []
signatures = []
show_call_signatures(signatures)
vim.command('return ' + strout)
@_check_jedi_availability(show_error=True)
@catch_and_print_exceptions
def goto(mode="goto", no_output=False):
"""
:param str mode: "related_name", "definition", "assignment", "auto"
:return: list of definitions/assignments
:rtype: list
"""
script = get_script()
try:
if mode == "goto":
definitions = [x for x in script.goto_definitions()
if not x.in_builtin_module()]
if not definitions:
definitions = script.goto_assignments()
elif mode == "related_name":
definitions = script.usages()
elif mode == "definition":
definitions = script.goto_definitions()
elif mode == "assignment":
definitions = script.goto_assignments()
except jedi.NotFoundError:
echo_highlight("Cannot follow nothing. Put your cursor on a valid name.")
definitions = []
else:
if no_output:
return definitions
if not definitions:
echo_highlight("Couldn't find any definitions for this.")
elif len(definitions) == 1 and mode != "related_name":
# just add some mark to add the current position to the jumplist.
# this is ugly, because it overrides the mark for '`', so if anyone
# has a better idea, let me know.
vim_command('normal! m`')
d = list(definitions)[0]
if d.in_builtin_module():
if d.is_keyword:
echo_highlight("Cannot get the definition of Python keywords.")
else:
echo_highlight("Builtin modules cannot be displayed (%s)."
% d.desc_with_module)
else:
if d.module_path != vim.current.buffer.name:
result = new_buffer(d.module_path)
if not result:
return []
vim.current.window.cursor = d.line, d.column
else:
# multiple solutions
lst = []
for d in definitions:
if d.in_builtin_module():
lst.append(dict(text=PythonToVimStr('Builtin ' + d.description)))
else:
lst.append(dict(filename=PythonToVimStr(d.module_path),
lnum=d.line, col=d.column + 1,
text=PythonToVimStr(d.description)))
vim_eval('setqflist(%s)' % repr(lst))
vim_eval('jedi#add_goto_window(' + str(len(lst)) + ')')
return definitions
@_check_jedi_availability(show_error=True)
@catch_and_print_exceptions
def show_documentation():
script = get_script()
try:
definitions = script.goto_definitions()
except jedi.NotFoundError:
definitions = []
except Exception:
# print to stdout, will be in :messages
definitions = []
print("Exception, this shouldn't happen.")
print(traceback.format_exc())
if not definitions:
echo_highlight('No documentation found for that.')
vim.command('return')
else:
docs = ['Docstring for %s\n%s\n%s' % (d.desc_with_module, '=' * 40, d.docstring())
if d.docstring() else '|No Docstring for %s|' % d for d in definitions]
text = ('\n' + '-' * 79 + '\n').join(docs)
vim.command('let l:doc = %s' % repr(PythonToVimStr(text)))
vim.command('let l:doc_lines = %s' % len(text.split('\n')))
return True
@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')
# We need two turns here to search and replace certain lines:
# 1. Search for a line with a call signature and save the appended
# characters
# 2. Actually replace the line and redo the status quo.
py_regex = r'%sjedi=([0-9]+), (.*?)%s.*?%sjedi%s'.replace('%s', e)
for i, line in enumerate(vim.current.buffer):
match = re.search(py_regex, line)
if match is not None:
# Some signs were added to minimize syntax changes due to call
# signatures. We have to remove them again. The number of them is
# specified in `match.group(1)`.
after = line[match.end() + int(match.group(1)):]
line = line[:match.start()] + match.group(2) + after
vim.current.buffer[i] = line
vim.current.window.cursor = cursor
@_check_jedi_availability(show_error=False)
@catch_and_print_exceptions
def show_call_signatures(signatures=()):
if vim_eval("has('conceal') && g:jedi#show_call_signatures") == '0':
return
if signatures == ():
signatures = get_script().call_signatures()
clear_call_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
line_to_replace = line - i - 1
# because there's a space before the bracket
insert_column = column - 1
if insert_column < 0 or line_to_replace <= 0:
# Edge cases, when the call signature has no space on the screen.
break
# TODO check if completion menu is above or below
line = vim_eval("getline(%s)" % line_to_replace)
params = [p.description.replace('\n', '') for p in signature.params]
try:
# *_*PLACEHOLDER*_* makes something fat. See after/syntax file.
params[signature.index] = '*_*%s*_*' % params[signature.index]
except (IndexError, TypeError):
pass
# This stuff is reaaaaally a hack! I cannot stress enough, that
# this is a stupid solution. But there is really no other yet.
# There is no possibility in VIM to draw on the screen, but there
# will be one (see :help todo Patch to access screen under Python.
# (Marko Mahni, 2010 Jul 18))
text = " (%s) " % ', '.join(params)
text = ' ' * (insert_column - len(line)) + text
end_column = insert_column + len(text) - 2 # -2 due to bold symbols
# Need to decode it with utf8, because vim returns always a python 2
# string even if it is unicode.
e = vim_eval('g:jedi#call_signature_escape')
if hasattr(e, 'decode'):
e = e.decode('UTF-8')
# replace line before with cursor
regex = "xjedi=%sx%sxjedix".replace('x', e)
prefix, replace = line[:insert_column], line[insert_column:end_column]
# Check the replace stuff for strings, to append them
# (don't want to break the syntax)
regex_quotes = r'''\\*["']+'''
# `add` are all the quotation marks.
# join them with a space to avoid producing '''
add = ' '.join(re.findall(regex_quotes, replace))
# search backwards
if add and replace[0] in ['"', "'"]:
a = re.search(regex_quotes + '$', prefix)
add = ('' if a is None else a.group(0)) + add
tup = '%s, %s' % (len(add), replace)
repl = prefix + (regex % (tup, text)) + add + line[end_column:]
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).replace('"', '\\"').replace(r'\n', r'\\n')
# 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]
escaped_param = params[index].replace(r'\n', r'\\n')
left = text.index(escaped_param)
right = left + len(escaped_param)
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))
@_check_jedi_availability(show_error=True)
@catch_and_print_exceptions
def rename():
if not int(vim.eval('a:0')):
vim_command('augroup jedi_rename')
vim_command('autocmd InsertLeave <buffer> call jedi#rename(1)')
vim_command('augroup END')
vim_command("let s:jedi_replace_orig = expand('<cword>')")
vim_command('normal! diw')
vim_command("let s:jedi_changedtick = b:changedtick")
vim_command('startinsert')
else:
# Remove autocommand.
vim_command('autocmd! jedi_rename InsertLeave')
# Get replacement, if there is something on the cursor.
# This won't be the case when the user ends insert mode right away,
# and `<cword>` would pick up the nearest word instead.
if vim_eval('getline(".")[getpos(".")[2]-1]') != ' ':
replace = vim_eval("expand('<cword>')")
else:
replace = None
cursor = vim.current.window.cursor
# Undo new word, but only if something was changed, which is not the
# case when ending insert mode right away.
if vim_eval('b:changedtick != s:jedi_changedtick') == '1':
vim_command('normal! u') # Undo new word.
vim_command('normal! u') # Undo diw.
vim.current.window.cursor = cursor
if replace:
return do_rename(replace)
def rename_visual():
replace = vim.eval('input("Rename to: ")')
orig = vim.eval('getline(".")[(getpos("\'<")[2]-1):getpos("\'>")[2]]')
do_rename(replace, orig)
def do_rename(replace, orig=None):
if not len(replace):
echo_highlight('No rename possible without name.')
return
if orig is None:
orig = vim_eval('s:jedi_replace_orig')
# Save original window / tab.
saved_tab = int(vim_eval('tabpagenr()'))
saved_win = int(vim_eval('winnr()'))
temp_rename = goto(mode="related_name", no_output=True)
# Sort the whole thing reverse (positions at the end of the line
# must be first, because they move the stuff before the position).
temp_rename = sorted(temp_rename, reverse=True,
key=lambda x: (x.module_path, x.start_pos))
buffers = set()
for r in temp_rename:
if r.in_builtin_module():
continue
if os.path.abspath(vim.current.buffer.name) != r.module_path:
result = new_buffer(r.module_path)
if not result:
echo_highlight("Jedi-vim: failed to create buffer window for {}!".format(r.module_path))
continue
buffers.add(vim.current.buffer.name)
# Save view.
saved_view = vim_eval('string(winsaveview())')
# Replace original word.
vim.current.window.cursor = r.start_pos
vim_command('normal! c{:d}l{}'.format(len(orig), replace))
# Restore view.
vim_command('call winrestview(%s)' % saved_view)
# Restore previous tab and window.
vim_command('tabnext {:d}'.format(saved_tab))
vim_command('{:d}wincmd w'.format(saved_win))
if len(buffers) > 1:
echo_highlight('Jedi did {:d} renames in {:d} buffers!'.format(
len(temp_rename), len(buffers)))
else:
echo_highlight('Jedi did {:d} renames!'.format(len(temp_rename)))
@_check_jedi_availability(show_error=True)
@catch_and_print_exceptions
def py_import():
# args are the same as for the :edit command
args = shsplit(vim.eval('a:args'))
import_path = args.pop()
text = 'import %s' % import_path
scr = jedi.Script(text, 1, len(text), '')
try:
completion = scr.goto_assignments()[0]
except IndexError:
echo_highlight('Cannot find %s in sys.path!' % import_path)
else:
if completion.in_builtin_module():
echo_highlight('%s is a builtin module.' % import_path)
else:
cmd_args = ' '.join([a.replace(' ', '\\ ') for a in args])
new_buffer(completion.module_path, cmd_args)
@catch_and_print_exceptions
def py_import_completions():
argl = vim.eval('a:argl')
try:
import jedi
except ImportError:
print('Pyimport completion requires jedi module: https://github.com/davidhalter/jedi')
comps = []
else:
text = 'import %s' % argl
script = jedi.Script(text, 1, len(text), '')
comps = ['%s%s' % (argl, c.complete) for c in script.completions()]
vim.command("return '%s'" % '\n'.join(comps))
@catch_and_print_exceptions
def new_buffer(path, options=''):
# options are what you can to edit the edit options
if vim_eval('g:jedi#use_tabs_not_buffers') == '1':
_tabnew(path, options)
elif not vim_eval('g:jedi#use_splits_not_buffers') == '1':
user_split_option = vim_eval('g:jedi#use_splits_not_buffers')
split_options = {
'top': 'topleft split',
'left': 'topleft vsplit',
'right': 'botright vsplit',
'bottom': 'botright split',
'winwidth': 'vs'
}
if user_split_option == 'winwidth' and vim.current.window.width <= 2 * int(vim_eval("&textwidth ? &textwidth : 80")):
split_options['winwidth'] = 'sp'
if user_split_option not in split_options:
print('g:jedi#use_splits_not_buffers value is not correct, valid options are: %s' % ','.join(split_options.keys()))
else:
vim_command(split_options[user_split_option] + " %s" % path)
else:
if vim_eval("!&hidden && &modified") == '1':
if vim_eval("bufname('%')") is None:
echo_highlight('Cannot open a new buffer, use `:set hidden` or save your buffer')
return False
else:
vim_command('w')
vim_command('edit %s %s' % (options, escape_file_path(path)))
# sometimes syntax is being disabled and the filetype not set.
if vim_eval('!exists("g:syntax_on")') == '1':
vim_command('syntax enable')
if vim_eval("&filetype != 'python'") == '1':
vim_command('set filetype=python')
return True
@catch_and_print_exceptions
def _tabnew(path, options=''):
"""
Open a file in a new tab or switch to an existing one.
:param options: `:tabnew` options, read vim help.
"""
path = os.path.abspath(path)
if vim_eval('has("gui")') == '1':
vim_command('tab drop %s %s' % (options, escape_file_path(path)))
return
for tab_nr in range(int(vim_eval("tabpagenr('$')"))):
for buf_nr in vim_eval("tabpagebuflist(%i + 1)" % tab_nr):
buf_nr = int(buf_nr) - 1
try:
buf_path = vim.buffers[buf_nr].name
except (LookupError, ValueError):
# Just do good old asking for forgiveness.
# don't know why this happens :-)
pass
else:
if buf_path == path:
# tab exists, just switch to that tab
vim_command('tabfirst | tabnext %i' % (tab_nr + 1))
# Goto the buffer's window.
vim_command('exec bufwinnr(%i) . " wincmd w"' % (buf_nr + 1))
break
else:
continue
break
else:
# tab doesn't exist, add a new one.
vim_command('tabnew %s' % escape_file_path(path))
def escape_file_path(path):
return path.replace(' ', r'\ ')
def print_to_stdout(level, str_out):
print(str_out)

View File

@ -0,0 +1,33 @@
"jedi-vim - Omni Completion for python in vim
" Maintainer: David Halter <davidhalter88@gmail.com>
"
" This part of the software is just the vim interface. The really big deal is
" the Jedi Python library.
if !exists("g:jedi#auto_vim_configuration") || g:jedi#auto_vim_configuration
" jedi-vim doesn't work in compatible mode (vim script syntax problems)
if &compatible
set nocompatible
endif
" jedi-vim really needs, otherwise jedi-vim cannot start.
filetype plugin on
" Change completeopt, but only if it has Vim's default value.
let s:save_completeopt=&completeopt
set completeopt&
let s:default_completeopt=&completeopt
let &completeopt=s:save_completeopt
if s:default_completeopt == &completeopt
set completeopt=menuone,longest,preview
endif
if len(mapcheck('<C-c>', 'i')) == 0
inoremap <C-c> <ESC>
endif
endif
" Pyimport command
command! -nargs=1 -complete=custom,jedi#py_import_completions Pyimport :call jedi#py_import(<q-args>)
" vim: set et ts=4:

View File

@ -0,0 +1,3 @@
[pytest]
# Ignore all files
norecursedirs = *

View File

@ -0,0 +1,52 @@
let g:jedi#completions_command = 'X'
source plugin/jedi.vim
describe 'completions'
before
new
set filetype=python
end
after
bd!
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'
normal a().filenaX
Expect getline('.') == 'IndentationError().filename'
end
it 'dot_open'
normal oraisX ImpXErrX()
Expect getline('.') == 'raise ImportError()'
end
it 'cycling through entries'
" testing select_first doesn't seem to work in ex mode
execute "normal oraise impX\<C-n>\<C-n>\<C-n>"
Expect getline('.') == 'raise ImportWarning'
let g:jedi#popup_select_first = 0
execute "normal oraise impX\<C-n>\<C-n>\<C-n>"
Expect getline('.') == 'raise ImportWarning'
let g:jedi#popup_select_first = 1
" -longest completes the first one
set completeopt -=longest
execute "normal oraise baseX"
Expect getline('.') == 'raise BaseException'
set completeopt +=longest
end
end
" vim: et:ts=4:sw=4

View File

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

View File

@ -0,0 +1,31 @@
source plugin/jedi.vim
describe 'documentation docstrings'
before
set filetype=python
end
after
bd!
bd!
end
it 'simple'
put = 'ImportError'
normal GK
Expect bufname('%') == "'__doc__'"
Expect &filetype == 'rst'
let content = join(getline(1,'$'), "\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,180 @@
let mapleader = '\'
source plugin/jedi.vim
source test/utils.vim
describe 'goto_simple'
before
new " open a new split
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'
silent normal \d
Expect line('.') == 1
"Expect col('.') == 5 " not working yet.
end
it 'goto_assignments'
silent normal \g
Expect line('.') == 2
Expect col('.') == 1
" cursor before `=` means that it stays there.
silent normal \g
Expect line('.') == 2
Expect col('.') == 1
" going to the last line changes it.
normal! $
silent 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
bd!
bd!
end
it 'follow_import'
put = ['import subprocess', 'subprocess']
silent normal G\g
Expect getline('.') == 'import subprocess'
Expect line('.') == 2
Expect col('.') == 8
silent normal G\d
Expect CurrentBufferIsModule('subprocess') == 1
Expect line('.') == 1
Expect col('.') == 1
Expect tabpagenr('$') == 2
Expect winnr('$') == 1
tabprevious
Expect bufname('%') == ''
end
it 'multi_definitions'
" This used to behave differently. Now we don't have any real multi
" definitions.
" put = ['import tokenize']
" silent normal G$\d
" Expect CurrentBufferIsModule('tokenize') == 1
" Expect CurrentBufferIsModule('token') == 0
" execute "normal \<CR>"
" Expect tabpagenr('$') == 2
" Expect winnr('$') == 1
" Expect CurrentBufferIsModule('token') == 1
" bd
" silent normal G$\d
" execute "normal j\<CR>"
" Expect tabpagenr('$') == 2
" Expect winnr('$') == 1
" Expect CurrentBufferIsModule('tokenize') == 1
end
end
describe 'goto_with_buffers'
before
set filetype=python
let g:jedi#use_tabs_not_buffers = 0
end
after
bd!
bd!
set nohidden
end
it 'no_new_tabs'
put = ['import os']
normal G$
call jedi#goto_assignments()
python 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
it 'multi_definitions'
" set hidden
" put = ['import tokenize']
" silent normal G$\d
" Expect CurrentBufferIsModule('tokenize') == 0
" Expect CurrentBufferIsModule('token') == 0
" execute "normal \<CR>"
" Expect tabpagenr('$') == 1
" Expect winnr('$') == 1
" Expect CurrentBufferIsModule('token') == 1
" bd
" silent normal G$\d
" execute "normal j\<CR>"
" Expect tabpagenr('$') == 1
" Expect winnr('$') == 1
" Expect CurrentBufferIsModule('tokenize') == 1
end
end
describe 'goto_with_splits'
before
set filetype=python
let g:jedi#use_splits_not_buffers = 'left'
end
after
bd!
bd!
end
it 'follow_import'
put = ['import subprocess', 'subprocess']
silent normal G\g
Expect getline('.') == 'import subprocess'
Expect line('.') == 2
Expect col('.') == 8
silent normal G\d
Expect CurrentBufferIsModule('subprocess') == 1
Expect line('.') == 1
Expect col('.') == 1
Expect winnr('$') == 2
wincmd l
Expect bufname('%') == ''
end
end
" vim: et:ts=4:sw=4

View File

@ -0,0 +1,32 @@
source plugin/jedi.vim
source test/utils.vim
describe 'pyimport'
before
let g:jedi#use_tabs_not_buffers = 1
end
after
bd!
bd!
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'
Expect jedi#py_import_completions('zip', 0, 0) == "zipfile\nzipimport"
end
end

View File

@ -0,0 +1,66 @@
source plugin/jedi.vim
describe 'signatures'
before
set filetype=python
end
after
bd!
bd!
end
it 'simple'
normal oabs(
" equals doautocmd CursorMovedI
Python jedi_vim.show_call_signatures()
Expect getline(1) == '=`=jedi=0, =`= (*_*number*_*) =`=jedi=`='
doautocmd InsertLeave
Expect getline(1) == ''
end
it 'no signature'
normal ostr
Python jedi_vim.show_call_signatures()
Expect getline(1, '$') == ['', 'str ']
end
it 'signatures disabled'
let g:jedi#show_call_signatures = 0
normal ostr(
Python 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()
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

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,2 @@
def test_integration(case, monkeypatch, pytestconfig):
case.run()