Vim: How to indent to an open paren or bracket when hitting enter?

北城余情 提交于 2019-11-29 12:26:04

问题


I've been programming Python with Vim for a while but one thing I haven't been able to figure out how to do it set it to auto indent to the level of the last open paren.

According to pep8 if you have an open paren and you need to break the line to fit in 80 columns then you're supposed to continue the next line at that open paren. Example:

calling_some_really_long_function(that, has, way, too, many, arguments, to, fit,
                                  on, one, line)

Obviously this is a crazy example, but that's how you're supposed to break your lines in python.

What I'd really like to be able to do is set up Vim so that when I type fit,<cr> and it will place my cursor on the next line just to the right of the open paren, so I can just type on, etc. instead of some combination of <tab> and <space> keys beforehand.

I don't think I'll ever trust the auto-formatter for python code in Vim but bonus points if that works too.


回答1:


This can be refined a bit, but should work 99% of the time. Add this in your .vimrc:

function! PythonEnterFunc()
  let l:li = getline('.')
  execute "normal! a\<Cr>"
  if l:li =~ '([^)]*$'
    let l:pos = stridx(l:li, '(') + 1
    for i in range(l:pos)
      execute "normal! a\<Space>"
    endfor
  endif
endfunction

au FileType python inoremap <Cr> <Esc>:call PythonEnterFunc()<CR>a



回答2:


Use gq, either over the whole selection with a VISUAL block, or with a movement, like gqq or gqj




回答3:


It has been included in Vim since V7.0 at least:

See the following snippet from usr/share/vim/vim80/indent/python.vim (line 74) https://github.com/vim/vim/blob/master/runtime/indent/python.vim

function GetPythonIndent(lnum)
  ...
  " When inside parenthesis: If at the first line below the parenthesis add
  " two 'shiftwidth', otherwise same as previous line.
  " i = (a
  "       + b
  "       + c)
  call cursor(a:lnum, 1)
  let p = searchpair('(\|{\|\[', '', ')\|}\|\]', 'bW',
      \ "line('.') < " . (a:lnum - s:maxoff) . " ? dummy :"
      \ . " synIDattr(synID(line('.'), col('.'), 1), 'name')"
      \ . " =~ '\\(Comment\\|Todo\\|String\\)$'")
  if p > 0
    if p == plnum
      " When the start is inside parenthesis, only indent one 'shiftwidth'.
      let pp = searchpair('(\|{\|\[', '', ')\|}\|\]', 'bW',
      \ "line('.') < " . (a:lnum - s:maxoff) . " ? dummy :"
      \ . " synIDattr(synID(line('.'), col('.'), 1), 'name')"
      \ . " =~ '\\(Comment\\|Todo\\|String\\)$'")
      if pp > 0
    return indent(plnum) + (exists("g:pyindent_nested_paren") ? eval(g:pyindent_nested_paren) : shiftwidth())
      endif
      return indent(plnum) + (exists("g:pyindent_open_paren") ? eval(g:pyindent_open_paren) : (shiftwidth() * 2))
    endif
    if plnumstart == p
      return indent(plnum)
    endif
    return plindent
  endif
  ...


来源:https://stackoverflow.com/questions/9492345/vim-how-to-indent-to-an-open-paren-or-bracket-when-hitting-enter

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!