tmhedberg/SimpylFold

Include next empty line(s) after block to support PEP-8 newline recommendation

Closed this issue · 10 comments

https://www.python.org/dev/peps/pep-0008/#blank-lines recommends surrounding function definitions with one empty line, and class definitions with two empty lines.

SimpylFold's current behavior is to not include trailing empty lines in the fold. This means that a series of folded definitions leave unsightly unfolded whitespace that hinders browsing code (especially with most color schemes that use a different bgcolor for folds).

Code would be more browsable and readable if the empty lines were included in the fold.

Compare the following for an example:
capture

Some users (i.e. me) like to see the empty lines between functions and classes outside folds. This makes it easy to see PEP-8 violations (too many or not enough blank lines). I also makes it easier for me to refactor code (select several folded functions in visual mode, delete them, then move into a blank line between two other functions where you want and paste).

(Technically I'm not a user of SimpylFold yet; but I'm looking to move away from my custom foldexpr and start using a plugin that someone else maintains ;)

I personally prefer the existing behavior as well; not everyone is going to agree on this. I'd be open to adding a g:SimpylFold_trailing_whitespace option, though, if you're interested in implementing it.

I would be very interested in being able to use the optional flag g:SimpylFold_trailing_whitespace. Of course, I don't have the expertise needed to implement it unfortunately. Is there any movement on this in the last year?

I'm still interested, but I'm not doing enough Python work these days to justify the time to learn the skills I'd need to submit the PR.

I have a forked version of this plugin that appears to address this issue. See the added code here: amhankin@6bd3d11

However, I have not tested this exhaustively for pathological cases. Can others who are interested in this feature run my modifications through a few files and see if it produces sensible results?

You have to place 'let g:SimpylFold_next_blank = 1' in your .vimrc file for this to work.

I just set up Simpylfold (which I have a terrible time typing for some reason) and I found the two blank lines left between folded top-level functions to be a bit excessive. Had a look at amhankin's fork but it the upstream code has diverged so much in the intervening time that I can't even identify where the second hunk would go.

I'm guessing that the if cache[lnum]['is_def']block would need to look ahead to the next line(s) and set them to the same foldlevel, but I'm not sure what blanks_adj is for and whether it would have to be called again after doing that.

Here is a first attempt:
amhankin@0576eb8a799

The commit adds code defines the end of a fold one line behind a function definition. In its current form, it only works for functions separated by single blank lines.

I have a solution that appears to work at first glance. Here is the commit (just realized the tabs/whites space are strange. Please ignore that for now): amhankin@7f1f1a47dab3f

I got this working with simple guess and check, so I don't fully understand the consequences of these changes. @jasontibbitts Can you stress test the code to see if you can get the folding behavior to break? If you don't see any problems I can submit a pull request to @tmhedberg for the changes.

It's taken me this long to get back into a project written in Python.

I just manually applied the two commits in your branch and it appears to be working as I'd expect. However, I guess one thing might give some people pause: it eats all blank lines at the end of a def. So top-level definitions have no space between them, where previously they had two spaces. That might now appear to be too dense for some but it doesn't bother me at all. Though I guess you can go on endlessly about what looks better.

Sorry for the late reply. I found recently that the folding breaks when there are no spaces between function definitions, so it is going to need slightly more advanced checking to avoid this (i.e. revert to the default behavior when the first line above a function definition is not blank or something like this).