如何在VIM中折叠Python源代码中的长文档字符串?

vatpfxk5  于 2022-11-11  发布在  Python
关注(0)|答案(7)|浏览(127)

有没有人知道一个方法,或者一个插件,可以在Python中自动折叠很长的docstring?我的代码中有跨越几页的docstring,所以一直翻阅它们是很麻烦的。另一个棘手的部分是,docstring中嵌入了python测试代码,因此可能会使解析它们变得困难。注意,我只需要自动折叠整个docstring,不管里面有什么。

hi3rlvi2

hi3rlvi21#

这是一个有点肮脏的黑客,但你可以通过python语法文件(:sp $VIMRUNTIME/syntax/python.vim),找到所有三引号字符串的语法区域(搜索'''"""),并将fold关键字添加到这些语句的末尾。然后只需为python文件设置foldmethod=syntax,注解就应该折叠起来。

xfb7svmp

xfb7svmp2#

我不确定是插件还是自动化,但是如果你输入zf/,你就可以搜索到某个东西,它会折叠到它的下一个示例。所以在下面的文档中(其中[]是光标):

def foo():
    """[]
    Some long docstring
    that takes up many
    lines
    """
    pass

请先查看edit 2以获取更新的搜索字符串!

如果您使用命令zf/"""[ENTER],它应该折叠从当前行(文档字符串的开头)到下一个"""(文档字符串的结尾)的所有内容。
我知道这不是自动化,但也许它会在过渡期间有所帮助,或者引导您走上正确的自动化道路。请参阅edit 2以获得更好的搜索功能,尽管我仍然不知道如何实现自动化。
希望这对你有帮助。

Edit:作为推论,您可以使用/"""\_.\{-}"""搜索任何文档字符串,尽管这也将返回文档字符串中的代码。要搜索后面跟着文档字符串的函数定义,您可以使用/def\_.\{-}"""\_.\{-}""",尽管这会在文档字符串中的def上中断。
Edit 2:实际上,对正则表达式的更多操作使我得出了以下结论:/def.\{-}):\_s*"""\_.\{-}""",它应该查找后跟文档字符串的任何函数。它搜索后跟任何字符的def,然后搜索后跟换行符和/或空格的):,再搜索后跟任意行数的"""(不包括下一个"""),但始终确保第二个三重引号紧跟在第一个三重引号之后。

pieyvz9o

pieyvz9o3#

在.vimrc中添加:

" folding
set foldmethod=indent

这将在每一个缩进处自动折叠,在python中,这将转换为docstring。它工作得非常非常好。给予看。上面的答案是正确的,但是需要一堆按键(废话!)

f0brbegy

f0brbegy4#

我想我已经找到了一个稍微改进@too_much_php的答案,尝试弄清楚如何在没有root访问权限的情况下做同样的事情。将语法区域定义从$VIMRUNTIME/syntax/python.vim复制到~/.vim/after/syntax/python.vim并编辑它们为我解决了这个问题。下面是我为~/.vim/after/syntax/python.vim编写的代码:

syn region  docString1
      \ start=+[uU]\=\z('''\|"""\)+ end="\z1" keepend transparent fold
syn region  docString2
      \ start=+[uU]\=[rR]\z('''\|"""\)+ end="\z1" keepend transparent fold

现在我可以运行:set foldmethod=syntax来折叠文档字符串。
PS:最初的想法归功于@too_much_php

iqjalb3h

iqjalb3h5#

我想你可以用:set foldmethod=marker foldmarker=""","""来做这个,我还没有测试过,但是应该可以了。foldmarker的参数是开始和结束标记。

1zmg4dgp

1zmg4dgp6#

很多年前我写了一个vimscript插件来完成这个任务,但是一直没有时间发布它。我把它作为一个gist来发布,但是也把源代码粘贴在下面。我也复制了它的功能用于Sublime Text here

"
" Fold multi-line Python comments into one line.
"
" Also maps the "-" key to toggle expansion and <C-f> to toggle all folding.
"
setlocal foldmethod=syntax
setlocal foldtext=FoldText()
setlocal fillchars=

map <buffer> - za
map <buffer> <C-f> :call ToggleFold()<CR>

let b:folded = 1

hi Folded     gui=bold cterm=bold guifg=cyan ctermfg=cyan guibg=NONE ctermbg=NONE

function! ToggleFold()
  if b:folded == 0
    exec "normal! zM"
    let b:folded = 1
  else
    exec "normal! zR"
    let b:folded = 0
  endif
endfunction

function! s:Strip(string)
  return substitute(a:string, '^[[:space:][:return:][:cntrl:]]\+\|[[:space:][:return:][:cntrl:]]\+$', '', '')
endfunction

" Extract the first line of a multi-line comment to use as the fold snippet
function! FoldText()
  let l:snippet = getline(v:foldstart)
  if len(s:Strip(l:snippet)) == 3
    let l:snippet = strpart(l:snippet, 1) . s:Strip(getline(v:foldstart + 1))
  endif
  return '+' . l:snippet . ' ...'
endfunction
fquxozlt

fquxozlt7#

我的解决方案涉及到使用SimpylFold。在使用Vundle安装它之后,我把它放在我的vimrc文件中:

autocmd FileType python setlocal foldlevel=2

这使得当你打开一个python文件时,所有的文档字符串都默认折叠,这是超级棒的。

相关问题