neovim

Neovim text editor
git clone https://git.dasho.dev/neovim.git
Log | Files | Refs | README

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