jedi.vim 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427
  1. scriptencoding utf-8
  2. " ------------------------------------------------------------------------
  3. " Settings initialization
  4. " ------------------------------------------------------------------------
  5. let s:deprecations = {
  6. \ 'get_definition_command': 'goto_definitions_command',
  7. \ 'goto_command': 'goto_assignments_command',
  8. \ 'pydoc': 'documentation_command',
  9. \ 'related_names_command': 'usages_command',
  10. \ 'autocompletion_command': 'completions_command',
  11. \ 'show_function_definition': 'show_call_signatures',
  12. \ }
  13. let s:default_settings = {
  14. \ 'use_tabs_not_buffers': 1,
  15. \ 'use_splits_not_buffers': 1,
  16. \ 'auto_initialization': 1,
  17. \ 'auto_vim_configuration': 1,
  18. \ 'goto_assignments_command': "'<leader>g'",
  19. \ 'completions_command': "'<C-Space>'",
  20. \ 'goto_definitions_command': "'<leader>d'",
  21. \ 'call_signatures_command': "'<leader>n'",
  22. \ 'usages_command': "'<leader>n'",
  23. \ 'rename_command': "'<leader>r'",
  24. \ 'popup_on_dot': 1,
  25. \ 'documentation_command': "'K'",
  26. \ 'show_call_signatures': 1,
  27. \ 'call_signature_escape': "'=`='",
  28. \ 'auto_close_doc': 1,
  29. \ 'popup_select_first': 1,
  30. \ 'quickfix_window_height': 10,
  31. \ 'completions_enabled': 1,
  32. \ 'force_py_version': "'auto'"
  33. \ }
  34. for [key, val] in items(s:deprecations)
  35. if exists('g:jedi#'.key)
  36. echom "'g:jedi#".key."' is deprecated. Please use 'g:jedi#".val."' instead. Sorry for the inconvenience."
  37. exe 'let g:jedi#'.val.' = g:jedi#'.key
  38. endif
  39. endfor
  40. for [key, val] in items(s:default_settings)
  41. if !exists('g:jedi#'.key)
  42. exe 'let g:jedi#'.key.' = '.val
  43. endif
  44. endfor
  45. " ------------------------------------------------------------------------
  46. " Python initialization
  47. " ------------------------------------------------------------------------
  48. let s:script_path = fnameescape(expand('<sfile>:p:h:h'))
  49. function! s:init_python()
  50. if g:jedi#force_py_version != 'auto'
  51. " Always use the user supplied version.
  52. try
  53. return jedi#force_py_version(g:jedi#force_py_version)
  54. catch
  55. throw "Could not setup g:jedi#force_py_version: ".v:exception
  56. endtry
  57. endif
  58. " Handle "auto" version.
  59. if has('nvim') || (has('python') && has('python3'))
  60. " Neovim usually has both python providers. Skipping the `has` check
  61. " avoids starting both of them.
  62. " Get default python version from interpreter in $PATH.
  63. let s:def_py = system("python -c 'import sys; sys.stdout.write(str(sys.version_info[0]))'")
  64. if v:shell_error != 0 || !len(s:def_py)
  65. if !exists("g:jedi#squelch_py_warning")
  66. echohl WarningMsg
  67. echom "Warning: jedi-vim failed to get Python version from sys.version_info: " . s:def_py
  68. echom "Falling back to version 2."
  69. echohl None
  70. endif
  71. let s:def_py = 2
  72. elseif &verbose
  73. echom "jedi-vim: auto-detected Python: ".s:def_py
  74. endif
  75. " Make sure that the auto-detected version is available in Vim.
  76. if !has('nvim') || has('python'.(s:def_py == 2 ? '' : s:def_py))
  77. return jedi#force_py_version(s:def_py)
  78. endif
  79. endif
  80. if has('python3')
  81. call jedi#setup_py_version(3)
  82. elseif has('python')
  83. call jedi#setup_py_version(2)
  84. else
  85. throw "jedi-vim requires Vim with support for Python 2 or 3."
  86. endif
  87. return 1
  88. endfunction
  89. function! jedi#init_python()
  90. if !exists('s:_init_python')
  91. try
  92. let s:_init_python = s:init_python()
  93. catch
  94. if !exists("g:jedi#squelch_py_warning")
  95. echohl WarningMsg
  96. echom "Error: jedi-vim failed to initialize Python: ".v:exception." (in ".v:throwpoint.")"
  97. echohl None
  98. endif
  99. let s:_init_python = 0
  100. endtry
  101. endif
  102. return s:_init_python
  103. endfunction
  104. function! jedi#setup_py_version(py_version)
  105. if a:py_version == 2
  106. let cmd_init = 'pyfile'
  107. let cmd_exec = 'python'
  108. elseif a:py_version == 3
  109. let cmd_init = 'py3file'
  110. let cmd_exec = 'python3'
  111. else
  112. throw "jedi#setup_py_version: invalid py_version: ".a:py_version
  113. endif
  114. try
  115. execute cmd_init.' '.s:script_path.'/initialize.py'
  116. execute 'command! -nargs=1 PythonJedi '.cmd_exec.' <args>'
  117. return 1
  118. catch
  119. throw "jedi#setup_py_version: ".v:exception
  120. endtry
  121. endfunction
  122. function! jedi#force_py_version(py_version)
  123. let g:jedi#force_py_version = a:py_version
  124. return jedi#setup_py_version(a:py_version)
  125. endfunction
  126. function! jedi#force_py_version_switch()
  127. if g:jedi#force_py_version == 2
  128. call jedi#force_py_version(3)
  129. elseif g:jedi#force_py_version == 3
  130. call jedi#force_py_version(2)
  131. else
  132. throw "Don't know how to switch from ".g:jedi#force_py_version."!"
  133. endif
  134. endfunction
  135. if !jedi#init_python()
  136. " Do not define any functions when Python initialization failed.
  137. finish
  138. endif
  139. " ------------------------------------------------------------------------
  140. " functions that call python code
  141. " ------------------------------------------------------------------------
  142. function! jedi#goto_assignments()
  143. PythonJedi jedi_vim.goto()
  144. endfunction
  145. function! jedi#goto_definitions()
  146. PythonJedi jedi_vim.goto(is_definition=True)
  147. endfunction
  148. function! jedi#usages()
  149. PythonJedi jedi_vim.goto(is_related_name=True)
  150. endfunction
  151. function! jedi#rename(...)
  152. PythonJedi jedi_vim.rename()
  153. endfunction
  154. function! jedi#completions(findstart, base)
  155. PythonJedi jedi_vim.completions()
  156. endfunction
  157. function! jedi#enable_speed_debugging()
  158. PythonJedi jedi_vim.jedi.set_debug_function(jedi_vim.print_to_stdout, speed=True, warnings=False, notices=False)
  159. endfunction
  160. function! jedi#enable_debugging()
  161. PythonJedi jedi_vim.jedi.set_debug_function(jedi_vim.print_to_stdout)
  162. endfunction
  163. function! jedi#disable_debugging()
  164. PythonJedi jedi_vim.jedi.set_debug_function(None)
  165. endfunction
  166. function! jedi#py_import(args)
  167. PythonJedi jedi_vim.py_import()
  168. endfun
  169. function! jedi#py_import_completions(argl, cmdl, pos)
  170. PythonJedi jedi_vim.py_import_completions()
  171. endfun
  172. " ------------------------------------------------------------------------
  173. " show_documentation
  174. " ------------------------------------------------------------------------
  175. function! jedi#show_documentation()
  176. PythonJedi if jedi_vim.show_documentation() is None: vim.command('return')
  177. let bn = bufnr("__doc__")
  178. if bn > 0
  179. let wi=index(tabpagebuflist(tabpagenr()), bn)
  180. if wi >= 0
  181. " If the __doc__ buffer is open in the current tab, jump to it
  182. silent execute (wi+1).'wincmd w'
  183. else
  184. silent execute "sbuffer ".bn
  185. endif
  186. else
  187. split '__doc__'
  188. endif
  189. setlocal modifiable
  190. setlocal noswapfile
  191. setlocal buftype=nofile
  192. silent normal! ggdG
  193. silent $put=l:doc
  194. silent normal! 1Gdd
  195. setlocal nomodifiable
  196. setlocal nomodified
  197. setlocal filetype=rst
  198. if l:doc_lines > 30 " max lines for plugin
  199. let l:doc_lines = 30
  200. endif
  201. execute "resize ".l:doc_lines
  202. " quit comands
  203. nnoremap <buffer> q ZQ
  204. execute "nnoremap <buffer> ".g:jedi#documentation_command." ZQ"
  205. " highlight python code within rst
  206. unlet! b:current_syntax
  207. syn include @rstPythonScript syntax/python.vim
  208. " 4 spaces
  209. syn region rstPythonRegion start=/^\v {4}/ end=/\v^( {4}|\n)@!/ contains=@rstPythonScript
  210. " >>> python code -> (doctests)
  211. syn region rstPythonRegion matchgroup=pythonDoctest start=/^>>>\s*/ end=/\n/ contains=@rstPythonScript
  212. let b:current_syntax = "rst"
  213. endfunction
  214. " ------------------------------------------------------------------------
  215. " helper functions
  216. " ------------------------------------------------------------------------
  217. function! jedi#add_goto_window(len)
  218. set lazyredraw
  219. cclose
  220. let height = min([a:len, g:jedi#quickfix_window_height])
  221. execute 'belowright copen '.height
  222. set nolazyredraw
  223. if g:jedi#use_tabs_not_buffers == 1
  224. noremap <buffer> <CR> :call jedi#goto_window_on_enter()<CR>
  225. endif
  226. au WinLeave <buffer> q " automatically leave, if an option is chosen
  227. redraw!
  228. endfunction
  229. function! jedi#goto_window_on_enter()
  230. let l:list = getqflist()
  231. let l:data = l:list[line('.') - 1]
  232. if l:data.bufnr
  233. " close goto_window buffer
  234. normal ZQ
  235. PythonJedi jedi_vim.new_buffer(vim.eval('bufname(l:data.bufnr)'))
  236. call cursor(l:data.lnum, l:data.col)
  237. else
  238. echohl WarningMsg | echo "Builtin module cannot be opened." | echohl None
  239. endif
  240. endfunction
  241. function! s:syn_stack()
  242. if !exists("*synstack")
  243. return []
  244. endif
  245. return map(synstack(line('.'), col('.') - 1), 'synIDattr(v:val, "name")')
  246. endfunc
  247. function! jedi#do_popup_on_dot_in_highlight()
  248. let highlight_groups = s:syn_stack()
  249. for a in highlight_groups
  250. if a == 'pythonDoctest'
  251. return 1
  252. endif
  253. endfor
  254. for a in highlight_groups
  255. for b in ['pythonString', 'pythonComment', 'pythonNumber']
  256. if a == b
  257. return 0
  258. endif
  259. endfor
  260. endfor
  261. return 1
  262. endfunc
  263. function! jedi#configure_call_signatures()
  264. if g:jedi#show_call_signatures == 2 " Command line call signatures
  265. " Need to track changes to avoid multiple undo points for a single edit
  266. if v:version >= 704 || has("patch-7.3.867")
  267. let b:normaltick = b:changedtick
  268. autocmd TextChanged,InsertLeave,BufWinEnter <buffer> let b:normaltick = b:changedtick
  269. endif
  270. autocmd InsertEnter <buffer> let g:jedi#first_col = s:save_first_col()
  271. endif
  272. autocmd InsertLeave <buffer> PythonJedi jedi_vim.clear_call_signatures()
  273. autocmd CursorMovedI <buffer> PythonJedi jedi_vim.show_call_signatures()
  274. endfunction
  275. " Determine where the current window is on the screen for displaying call
  276. " signatures in the correct column.
  277. function! s:save_first_col()
  278. if bufname('%') ==# '[Command Line]' || winnr('$') == 1
  279. return 0
  280. endif
  281. let l:eventignore = &eventignore
  282. set eventignore=all
  283. let startwin = winnr()
  284. let startaltwin = winnr('#')
  285. let winwidth = winwidth(0)
  286. try
  287. wincmd h
  288. let win_on_left = winnr() == startwin
  289. if win_on_left
  290. return 0
  291. else
  292. " Walk left and count up window widths until hitting the edge
  293. execute startwin."wincmd w"
  294. let width = 0
  295. let winnr = winnr()
  296. wincmd h
  297. while winnr != winnr()
  298. let width += winwidth(0) + 1 " Extra column for window divider
  299. let winnr = winnr()
  300. wincmd h
  301. endwhile
  302. return width
  303. endif
  304. finally
  305. let &eventignore = l:eventignore
  306. execute startaltwin."wincmd w"
  307. execute startwin."wincmd w"
  308. " If the event that triggered InsertEnter made a change (e.g. open a
  309. " new line, substitude a word), join that change with the rest of this
  310. " edit.
  311. if exists('b:normaltick') && b:normaltick != b:changedtick
  312. try
  313. undojoin
  314. catch /^Vim\%((\a\+)\)\=:E790/
  315. " This can happen if an undo happens during a :normal command.
  316. endtry
  317. endif
  318. endtry
  319. endfunction
  320. " Helper function instead of `python vim.eval()`, and `.command()` because
  321. " these also return error definitions.
  322. function! jedi#_vim_exceptions(str, is_eval)
  323. let l:result = {}
  324. try
  325. if a:is_eval
  326. let l:result.result = eval(a:str)
  327. else
  328. execute a:str
  329. let l:result.result = ''
  330. endif
  331. catch
  332. let l:result.exception = v:exception
  333. let l:result.throwpoint = v:throwpoint
  334. endtry
  335. return l:result
  336. endfunction
  337. function! jedi#complete_string(is_popup_on_dot)
  338. if a:is_popup_on_dot && !(g:jedi#popup_on_dot && jedi#do_popup_on_dot_in_highlight())
  339. return ''
  340. endif
  341. if pumvisible() && !a:is_popup_on_dot
  342. return "\<C-n>"
  343. else
  344. return "\<C-x>\<C-o>\<C-r>=jedi#complete_opened(".a:is_popup_on_dot.")\<CR>"
  345. endif
  346. endfunction
  347. function! jedi#complete_opened(is_popup_on_dot)
  348. if pumvisible()
  349. if a:is_popup_on_dot
  350. " Prevent completion of the first entry with dot completion.
  351. return "\<C-p>"
  352. endif
  353. " Only go down if it is visible, user-enabled and the longest
  354. " option is set.
  355. if g:jedi#popup_select_first && stridx(&completeopt, 'longest') > -1
  356. return "\<Down>"
  357. endif
  358. endif
  359. return ""
  360. endfunction
  361. "PythonJedi jedi_vim.jedi.set_debug_function(jedi_vim.print_to_stdout, speed=True, warnings=False, notices=False)
  362. "PythonJedi jedi_vim.jedi.set_debug_function(jedi_vim.print_to_stdout)
  363. " vim: set et ts=4: