tags:

views:

75

answers:

4

Hi,

Does anybody know of a method, or perhaps a plug-in, that will automatically fold long docstrings in python? I have docstrings in my code that span several pages, so it is troublesome to keep paging through them. The other tricky part is that there is embedded python testing code in the docstrings, so that might make parsing them difficult. Note that I only need to automatically fold the entire docstring, regardless of what is in it.

Thanks in advance.

+1  A: 

I'm not sure about a plugin or automation, but if you type zf/ you can then search for something and it will fold up to the next instance of it. So in a document like the following (where [] is the cursor):

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

Look at edit2 first for the updated search string!

If you use the command zf/"""[ENTER], it should fold everything from the current line (the beginning of the docstring) to the next occurrence of """ which should be the end of the docstring.

I know this isn't automation, but perhaps it will help in the interim, or lead you down the right path to automating it. See edit2 for a better search function, although I still don't know how to automate.

Hope this helps.

Edit: in a corollary, you can search for any docstring with /"""\_.\{-}""", although this will also return the code within the docstring. To search for a function definition followed by a docstring, you can use /def\_.\{-}"""\_.\{-}""", although this breaks on a def inside the docstring.

Edit2: Actually, some more playing with regexs led me to this: /def.\{-}):\_s*"""\_.\{-}""" which should find any function followed by a docstring. It searches for def followed by any characters, then ): followed by a newline and/or whitespace followed by """ followed by any number of lines than the next """, but always ensures the 2nd triple quote is the one immediately following the first.

nearlymonolith
This doesn't seem to like embedded mathematical functions or blank lines in the docstring. I'll keep playing with it. Good idea!
reckoner
Did you try the one I proposed in Edit2? It _should_ (there's a dangerous word) function properly for at least the blank line case, so long as the docstring is between """ and """ and there are no other instances of """ in the docstring, which would seemingly result in invalid python code anyway. If you have some example code I'd be happy to play some more - I've only recently started diving into regexes.
nearlymonolith
A: 

In your .vimrc add:

" folding
set foldmethod=indent

This will auto-fold at every indentation, which, in python, translates to docstrings. It works VERY VERY nice. Give it a try. The above answer is correct, but requires a bunch of keystrokes (blah!)

b14ck
Will this also fold `if`, `for`, `while`, etc. statements (since they are delimited by indentation as well?
nearlymonolith
It will, but I think you can tweak the "depth" of the indentation.
Daenyth
You can tweak the depth, but the defaults are usually fine. I mostly do OOP stuff, so It'll show my class definition, followed by a fold, then it will also fold on all other docstrings (since I use those immediately inside all method definitions). This way I can open the class, then open each method separately. Very smooth.
b14ck
This is clever, however, when I open the fold, I'm in the same situation I started out with -- I have to page down through the long docstring to get to the start of the source. Maybe something in the VIM fold options can deal with this. I read the documentation on controlling how folds are applied, but it's pretty hard to understand.
reckoner
+1  A: 

This is a bit of a dirty hack, but you can go through the python syntax file (:sp $VIMRUNTIME/syntax/python.vim) and find all the syntax regions for triple-quoted strings (search for ''' and """) and add the fold keyword to the end of those statements. Then just set foldmethod=syntax for python files and the comments should be folded.

too much php
this works perfectly! for future reference, the file ( at least in my case) that had to be changed was c:\vim\vim72\syntax\python.vim and the lines that contain triple single-quotes such as: syn region pythonString ...,@Spell had to be changed to the following: syn region pythonString ...,@Spell foldThanks again
reckoner
A: 

You can do this with :set foldmethod=marker foldmarker=""",""", I think. I haven't tested it, but that should do the trick. The arguments to foldmarker are start and end markers.

Daenyth
This doesn't work because of the way the indents follow the statements which results in the following code to be folded. It seems like this method only works if you separately mark up the code ahead of time with the appropriate markers to control the folding.
reckoner
Does it work if you split it onto multiple lines like: `"""\nDoc\n"""`?
Daenyth