Skip to content

Commit 5304abe

Browse files
committed
Fix more corner cases
- Fix folding of code between two defs nested under the same def - Don't search for lines other than def or class in BlockStart because only def and class can contain nested folds - Fix pattern used to find next_def - Fix case where last_block_end is not followed by a blank line
1 parent 391ece0 commit 5304abe

File tree

1 file changed

+20
-19
lines changed

1 file changed

+20
-19
lines changed

autoload/pymode/folding.vim

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -65,32 +65,33 @@ fun! pymode#folding#expr(lnum) "{{{
6565
let last_block_indent = indent(last_block)
6666

6767
" Check if last class/def is not indented and therefore can't be
68-
" nested and make sure it is a class/def block instead of a zero
69-
" indented regular statement
70-
if last_block_indent && getline(last_block) =~ s:def_regex
68+
" nested.
69+
if last_block_indent
7170
" Note: This relies on the cursor position being set by s:BlockStart
72-
let next_def = searchpos('^\s*def \w', 'nW')[0]
71+
let next_def = searchpos(s:def_regex, 'nW')[0]
7372
let next_def_indent = next_def ? indent(next_def) : -1
7473
let last_block_end = s:BlockEnd(last_block)
7574

76-
" If the next def has the same or greater indent than the
77-
" previous def, it is either nested at the same level or
78-
" nested one level deeper, and in either case will have its
79-
" own fold. If the class/def containing the current line is on
80-
" the first line it can't be nested, and if the this block
81-
" ends on the last line, it contains no trailing code that
82-
" should not be folded. Finally, if the next non-blank line
83-
" after the end of the previous def is less indented than the
84-
" previous def, it is not part of the same fold as that def.
85-
" Otherwise, we know the current line is at the end of a
86-
" nested def.
87-
if next_def_indent < last_block_indent && last_block > 1 && last_block_end < line('$')
75+
" If the next def has greater indent than the previous def, it
76+
" is nested one level deeper and will have its own fold. If
77+
" the class/def containing the current line is on the first
78+
" line it can't be nested, and if this block ends on the last
79+
" line, it contains no trailing code that should not be
80+
" folded. Finally, if the next non-blank line after the end of
81+
" the previous def is less indented than the previous def, it
82+
" is not part of the same fold as that def. Otherwise, we know
83+
" the current line is at the end of a nested def.
84+
if next_def_indent <= last_block_indent && last_block > 1 && last_block_end < line('$')
8885
\ && indent(nextnonblank(last_block_end)) >= last_block_indent
8986

9087
" Include up to one blank line in the fold
91-
let fold_end = min([prevnonblank(last_block_end - 1) + 1, last_block_end])
88+
if getline(last_block_end) =~ s:blank_regex
89+
let fold_end = min([prevnonblank(last_block_end - 1), last_block_end]) + 1
90+
else
91+
let fold_end = last_block_end
92+
endif
9293
if a:lnum == fold_end
93-
return next_def ? 's1' : 0
94+
return 's1'
9495
else
9596
return '='
9697
endif
@@ -124,7 +125,7 @@ fun! s:BlockStart(lnum) "{{{
124125
" Note: Make sure to reset cursor position after using this function.
125126
call cursor(a:lnum, 0)
126127
let max_indent = max([indent(prevnonblank(a:lnum)) - &shiftwidth, 0])
127-
return searchpos('\v^(\s{,'.max_indent.'}(def |class |\@)\w|[^ \t#])', 'bcnW')[0]
128+
return searchpos('\v^\s{,'.max_indent.'}(def |class )\w', 'bcnW')[0]
128129
endfunction "}}}
129130

130131
fun! s:BlockEnd(lnum) "{{{

0 commit comments

Comments
 (0)