7

According to the WIKI, scripts can be folded based on syntax. Does anyone have a solution to fold Python docstrings?

Basically, all I need is to fold """ text between triple quotation marks """, like this:

enter image description here

Thanks.

  • 1
    Do you want to fold only docstrings, or docstrings in addition to folding Python code? – Martin Tournoij Mar 17 '16 at 16:14
  • @Carpetsmoker, just docstrings. So far, I was unable to achive reliable python folding similar to full-fledged IDEs. – asv Mar 18 '16 at 12:49
2

There are a few funky factors at play that we should consider when playing with folds (they are complicated and not easy to understand without digging into the docs..)

  • setting foldmethod to syntax was my issue when I was fighting fold but lets take a look at the docs for more info..

SYNTAX fold-syntax

A fold is defined by syntax items that have the "fold" argument. |:syn-fold|

The fold level is defined by nesting folds. The nesting of folds is limited with 'foldnestmax'.

Be careful to specify proper syntax syncing. If this is not done right, folds may differ from the displayed highlighting. This is especially relevant when using patterns that match more than one line. In case of doubt, try using brute-force syncing:

    :syn sync fromstart

The main thing to note is the sync fromstart this is a useful helper if you have regex that would match throughout the file and only want to catch the header. In your case you should be able to ignore this but just something to be aware of.

  • top down regex scanning

Since the """ is fairly predictable we can simplify the start and end to look something like this:

syn region foldImports start='"""' end='"""' fold keepend

For both the start and end we are just trying to match on '"""'(or regexp) for the script tags. I did not test the above code out as I'm not much of a python guy but I bet you can get it figured out from here.

  • Thanks! It works after adding the line to ~/.vim/after/syntax/python.vim and manually setting foldingmethod to syntax in buffer. – asv Mar 23 '16 at 13:22
  • ...but breaks docstrings highlights. Life is tough. – asv Mar 23 '16 at 13:46
  • damn.. I personally have folding turned off in my config with a profane comment regarding my feelings towards the feature :| hopefully a bit more regex hacking can get things working (id check plugins [grep fold keywords] if its almost there) – Dan Bradbury Mar 23 '16 at 15:06
  • I used the syntax region definitions given at stackoverflow.com/a/16051080/455009 to target docstrings to be highlighted as comments, without affecting normal triple-quoted strings. Try those with fold added to the options, and it works pretty well for me. – ches Jul 2 '16 at 14:39
1

Here is a better method which will preserve all highlighting inside triple-quoted strings:

syn region  pythonString matchgroup=pythonTripleQuotes 
      \ start=+[uU]\=\z('''\|"""\)+ end="\z1" keepend fold
      \ contains=pythonEscape,pythonSpaceError,pythonDoctest,@Spell

Add this to ~/.vim/after/syntax/python.vim.

This command is taken exactly from /usr/share/vim/vim74/syntax/python.vim and only has the fold keyword added. Why does this preserve highlighting when Dan's answer doesn't? The key is that this has:

contains=pythonEscape,pythonSpaceError,pythonDoctest

Normally, Vim applies only one syntax region, but with contains= you can tell it that a syntax region can contain other syntax regions.

It's also highlighted as a String because it does:

HiLink pythonString           String

Just defining a syntax region is not enough, you need to link this to a highlight group.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.