python.vim (8320B)
1 " Vim filetype plugin file 2 " Language: python 3 " Maintainer: Tom Picton <tom@tompicton.com> 4 " Previous Maintainer: James Sully <sullyj3@gmail.com> 5 " Previous Maintainer: Johannes Zellner <johannes@zellner.org> 6 " Repository: https://github.com/tpict/vim-ftplugin-python 7 " Last Change: 2024/05/13 8 " 2024 Nov 30 use pytest compiler (#16130) 9 10 if exists("b:did_ftplugin") | finish | endif 11 let b:did_ftplugin = 1 12 let s:keepcpo= &cpo 13 set cpo&vim 14 15 setlocal cinkeys-=0# 16 setlocal indentkeys-=0# 17 setlocal include=^\\s*\\(from\\\|import\\) 18 setlocal define=^\\s*\\(\\(async\\s\\+\\)\\?def\\\|class\\) 19 20 " For imports with leading .., append / and replace additional .s with ../ 21 let b:grandparent_match = '^\(.\.\)\(\.*\)' 22 let b:grandparent_sub = '\=submatch(1)."/".repeat("../",strlen(submatch(2)))' 23 24 " For imports with a single leading ., replace it with ./ 25 let b:parent_match = '^\.\(\.\)\@!' 26 let b:parent_sub = './' 27 28 " Replace any . sandwiched between word characters with / 29 let b:child_match = '\(\w\)\.\(\w\)' 30 let b:child_sub = '\1/\2' 31 32 setlocal includeexpr=substitute(substitute(substitute( 33 \v:fname, 34 \b:grandparent_match,b:grandparent_sub,''), 35 \b:parent_match,b:parent_sub,''), 36 \b:child_match,b:child_sub,'g') 37 38 setlocal suffixesadd=.py 39 setlocal comments=b:#,fb:- 40 setlocal commentstring=#\ %s 41 42 if has('python3') 43 setlocal omnifunc=python3complete#Complete 44 elseif has('python') 45 setlocal omnifunc=pythoncomplete#Complete 46 endif 47 48 set wildignore+=*.pyc 49 50 let b:next_toplevel='\v%$\|^(class\|def\|async def)>' 51 let b:prev_toplevel='\v^(class\|def\|async def)>' 52 let b:next_endtoplevel='\v%$\|\S.*\n+(def\|class)' 53 let b:prev_endtoplevel='\v\S.*\n+(def\|class)' 54 let b:next='\v%$\|^\s*(class\|def\|async def)>' 55 let b:prev='\v^\s*(class\|def\|async def)>' 56 let b:next_end='\v\S\n*(%$\|^(\s*\n*)*(class\|def\|async def)\|^\S)' 57 let b:prev_end='\v\S\n*(^(\s*\n*)*(class\|def\|async def)\|^\S)' 58 59 if !exists('g:no_plugin_maps') && !exists('g:no_python_maps') 60 execute "nnoremap <silent> <buffer> ]] :<C-U>call <SID>Python_jump('n', '". b:next_toplevel."', 'W', v:count1)<cr>" 61 execute "nnoremap <silent> <buffer> [[ :<C-U>call <SID>Python_jump('n', '". b:prev_toplevel."', 'Wb', v:count1)<cr>" 62 execute "nnoremap <silent> <buffer> ][ :<C-U>call <SID>Python_jump('n', '". b:next_endtoplevel."', 'W', v:count1, 0)<cr>" 63 execute "nnoremap <silent> <buffer> [] :<C-U>call <SID>Python_jump('n', '". b:prev_endtoplevel."', 'Wb', v:count1, 0)<cr>" 64 execute "nnoremap <silent> <buffer> ]m :<C-U>call <SID>Python_jump('n', '". b:next."', 'W', v:count1)<cr>" 65 execute "nnoremap <silent> <buffer> [m :<C-U>call <SID>Python_jump('n', '". b:prev."', 'Wb', v:count1)<cr>" 66 execute "nnoremap <silent> <buffer> ]M :<C-U>call <SID>Python_jump('n', '". b:next_end."', 'W', v:count1, 0)<cr>" 67 execute "nnoremap <silent> <buffer> [M :<C-U>call <SID>Python_jump('n', '". b:prev_end."', 'Wb', v:count1, 0)<cr>" 68 69 execute "onoremap <silent> <buffer> ]] :call <SID>Python_jump('o', '". b:next_toplevel."', 'W', v:count1)<cr>" 70 execute "onoremap <silent> <buffer> [[ :call <SID>Python_jump('o', '". b:prev_toplevel."', 'Wb', v:count1)<cr>" 71 execute "onoremap <silent> <buffer> ][ :call <SID>Python_jump('o', '". b:next_endtoplevel."', 'W', v:count1, 0)<cr>" 72 execute "onoremap <silent> <buffer> [] :call <SID>Python_jump('o', '". b:prev_endtoplevel."', 'Wb', v:count1, 0)<cr>" 73 execute "onoremap <silent> <buffer> ]m :call <SID>Python_jump('o', '". b:next."', 'W', v:count1)<cr>" 74 execute "onoremap <silent> <buffer> [m :call <SID>Python_jump('o', '". b:prev."', 'Wb', v:count1)<cr>" 75 execute "onoremap <silent> <buffer> ]M :call <SID>Python_jump('o', '". b:next_end."', 'W', v:count1, 0)<cr>" 76 execute "onoremap <silent> <buffer> [M :call <SID>Python_jump('o', '". b:prev_end."', 'Wb', v:count1, 0)<cr>" 77 78 execute "xnoremap <silent> <buffer> ]] :call <SID>Python_jump('x', '". b:next_toplevel."', 'W', v:count1)<cr>" 79 execute "xnoremap <silent> <buffer> [[ :call <SID>Python_jump('x', '". b:prev_toplevel."', 'Wb', v:count1)<cr>" 80 execute "xnoremap <silent> <buffer> ][ :call <SID>Python_jump('x', '". b:next_endtoplevel."', 'W', v:count1, 0)<cr>" 81 execute "xnoremap <silent> <buffer> [] :call <SID>Python_jump('x', '". b:prev_endtoplevel."', 'Wb', v:count1, 0)<cr>" 82 execute "xnoremap <silent> <buffer> ]m :call <SID>Python_jump('x', '". b:next."', 'W', v:count1)<cr>" 83 execute "xnoremap <silent> <buffer> [m :call <SID>Python_jump('x', '". b:prev."', 'Wb', v:count1)<cr>" 84 execute "xnoremap <silent> <buffer> ]M :call <SID>Python_jump('x', '". b:next_end."', 'W', v:count1, 0)<cr>" 85 execute "xnoremap <silent> <buffer> [M :call <SID>Python_jump('x', '". b:prev_end."', 'Wb', v:count1, 0)<cr>" 86 endif 87 88 if !exists('*<SID>Python_jump') 89 fun! <SID>Python_jump(mode, motion, flags, count, ...) range 90 let l:startofline = (a:0 >= 1) ? a:1 : 1 91 92 if a:mode == 'x' 93 normal! gv 94 endif 95 96 if l:startofline == 1 97 normal! 0 98 endif 99 100 let cnt = a:count 101 mark ' 102 while cnt > 0 103 call search(a:motion, a:flags) 104 let cnt = cnt - 1 105 endwhile 106 107 if l:startofline == 1 108 normal! ^ 109 endif 110 endfun 111 endif 112 113 if has("browsefilter") && !exists("b:browsefilter") 114 let b:browsefilter = "Python Files (*.py)\t*.py\n" 115 if has("win32") 116 let b:browsefilter .= "All Files (*.*)\t*\n" 117 else 118 let b:browsefilter .= "All Files (*)\t*\n" 119 endif 120 endif 121 122 if !exists("g:python_recommended_style") || g:python_recommended_style != 0 123 " As suggested by PEP8. 124 setlocal expandtab tabstop=4 softtabstop=4 shiftwidth=4 125 endif 126 127 " Use pydoc for keywordprg. 128 " Unix users preferentially get pydoc3, then pydoc2. 129 " Windows doesn't have a standalone pydoc executable in $PATH by default, nor 130 " does it have separate python2/3 executables, so Windows users just get 131 " whichever version corresponds to their installed Python version. 132 if executable('python3') 133 setlocal keywordprg=python3\ -m\ pydoc 134 elseif executable('python') 135 setlocal keywordprg=python\ -m\ pydoc 136 endif 137 138 if expand('%:t') =~# '\v^test_.*\.py$|_test\.py$' && executable('pytest') 139 compiler pytest 140 let &l:makeprg .= ' %:S' 141 endif 142 143 " Script for filetype switching to undo the local stuff we may have changed 144 let b:undo_ftplugin = 'setlocal cinkeys<' 145 \ . '|setlocal comments<' 146 \ . '|setlocal commentstring<' 147 \ . '|setlocal expandtab<' 148 \ . '|setlocal include<' 149 \ . '|setlocal includeexpr<' 150 \ . '|setlocal indentkeys<' 151 \ . '|setlocal keywordprg<' 152 \ . '|setlocal omnifunc<' 153 \ . '|setlocal shiftwidth<' 154 \ . '|setlocal softtabstop<' 155 \ . '|setlocal suffixesadd<' 156 \ . '|setlocal tabstop<' 157 \ . '|setlocal makeprg<' 158 \ . '|silent! nunmap <buffer> [M' 159 \ . '|silent! nunmap <buffer> [[' 160 \ . '|silent! nunmap <buffer> []' 161 \ . '|silent! nunmap <buffer> [m' 162 \ . '|silent! nunmap <buffer> ]M' 163 \ . '|silent! nunmap <buffer> ][' 164 \ . '|silent! nunmap <buffer> ]]' 165 \ . '|silent! nunmap <buffer> ]m' 166 \ . '|silent! ounmap <buffer> [M' 167 \ . '|silent! ounmap <buffer> [[' 168 \ . '|silent! ounmap <buffer> []' 169 \ . '|silent! ounmap <buffer> [m' 170 \ . '|silent! ounmap <buffer> ]M' 171 \ . '|silent! ounmap <buffer> ][' 172 \ . '|silent! ounmap <buffer> ]]' 173 \ . '|silent! ounmap <buffer> ]m' 174 \ . '|silent! xunmap <buffer> [M' 175 \ . '|silent! xunmap <buffer> [[' 176 \ . '|silent! xunmap <buffer> []' 177 \ . '|silent! xunmap <buffer> [m' 178 \ . '|silent! xunmap <buffer> ]M' 179 \ . '|silent! xunmap <buffer> ][' 180 \ . '|silent! xunmap <buffer> ]]' 181 \ . '|silent! xunmap <buffer> ]m' 182 \ . '|unlet! b:browsefilter' 183 \ . '|unlet! b:child_match' 184 \ . '|unlet! b:child_sub' 185 \ . '|unlet! b:grandparent_match' 186 \ . '|unlet! b:grandparent_sub' 187 \ . '|unlet! b:next' 188 \ . '|unlet! b:next_end' 189 \ . '|unlet! b:next_endtoplevel' 190 \ . '|unlet! b:next_toplevel' 191 \ . '|unlet! b:parent_match' 192 \ . '|unlet! b:parent_sub' 193 \ . '|unlet! b:prev' 194 \ . '|unlet! b:prev_end' 195 \ . '|unlet! b:prev_endtoplevel' 196 \ . '|unlet! b:prev_toplevel' 197 \ . '|unlet! b:undo_ftplugin' 198 199 let &cpo = s:keepcpo 200 unlet s:keepcpo