'Python text-folding in TextMate 2 not folding lists/tuples/dictionaries

I'm a little behind the times and just noticed Textmate 2 exists—I've been using 1.5.10 for years.

I'm trying it out, and in some ways the code folding for Python is improved. (It no longer eats a line of whitespace after collapsed method/class definitions). However, it no longer folds lists, tuples, and dictionaries that are split onto multiple lines. The following code, for example, has folding arrows in 1.5.10 but not in 2.0.6:

foo = [
    1,
    2,
    3,
]

The default Folding setting in the Python bundle is:

{   foldingStartMarker = '^\s*"""(?=.)(?!.*""")';
    foldingStopMarker = '^\s*"""\s*$';
}

And the default Folding Patterns reads:

{ foldingIndentedBlockStart = '^\s*(class|def|for|while|if|elif|else|with|try|finally|except)\b.*:\s*(#.*)?$'; }

I'm not entirely sure how these two work together, especially since the only documentation I can find for folding definitions is for TextMate 1.5 and appears outdated. I've tried fiddling with them, so far to no avail. Does anyone have any ideas?



Solution 1:[1]

I figured out how the regexes work. foldingIndentBlockStart is responsible for most Python folding, that is, everything based on indentation. foldingStartMarker and foldingStopMarker handle all other folding, though the bundle's default patterns only fold triple-quoted docstrings.

I wrote a pair of patterns to check for opening and closing {}, (), and [], with support for comments on the same line (and a comma afterward, in case it's part of a longer sequence). I added my new patterns to the existing ones with a |, like so:

{   foldingStartMarker = '^\s*"""(?=.)(?!.*""")|(\{|\(|\[)\s*(#.*)?$';
    foldingStopMarker = '^\s*"""\s*$|^\s*(\}|\)|\]),?\s*(#.*)?$';
}

I may be missing some corner cases, but so far it seems to work.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1