@@ -58,18 +58,41 @@ fun! pymode#folding#expr(lnum) "{{{
58
58
endif
59
59
60
60
" Handle nested defs
61
- let last_def = pymode#motion#BlockStart (a: lnum , s: def_regex )
62
- if getline (last_def) = ~ s: def_regex
63
- let last_def_end = pymode#motion#BlockEnd (last_def)
64
- if last_def_end < line (' $' )
65
- let nested = getline (pymode#motion#BlockStart (last_def - 1 )) = ~ s: def_regex
66
- if nested && getline (nextnonblank (a: lnum )) !~ s: def_regex
67
- let fold_end = min ([prevnonblank (last_def_end - 1 ) + 2 , last_def_end])
68
- if a: lnum == fold_end
69
- return ' s1'
61
+ if indent (prevnonblank (a: lnum ))
62
+ let curpos = getcurpos ()
63
+ try
64
+ let last_block = s: BlockStart (a: lnum )
65
+ let last_block_indent = indent (last_block)
66
+
67
+ " 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
71
+ " Note: This relies on the cursor position being set by s:BlockStart
72
+ let next_def = searchpos (' ^\s*def \w' , ' nW' )[0 ]
73
+ let next_def_indent = next_def ? indent (next_def) : -1
74
+ let last_block_end = s: BlockEnd (last_block)
75
+
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. Otherwise, we know the current line
83
+ " is at the end of a nested def.
84
+ if next_def_indent < last_block_indent && last_block > 1 && last_block_end < line (' $' )
85
+
86
+ " Include up to one blank line in the fold
87
+ let fold_end = min ([prevnonblank (last_block_end - 1 ) + 2 , last_block_end])
88
+ if a: lnum == fold_end
89
+ return ' s1'
90
+ endif
70
91
endif
71
92
endif
72
- endif
93
+ finally
94
+ call setpos (' .' , curpos)
95
+ endtry
73
96
endif
74
97
75
98
if line = ~ s: blank_regex
@@ -91,5 +114,17 @@ fun! pymode#folding#expr(lnum) "{{{
91
114
92
115
endfunction " }}}
93
116
117
+ fun ! s: BlockStart (lnum) " {{{
118
+ " Note: Make sure to reset cursor position after using this function.
119
+ call cursor (a: lnum , 0 )
120
+ let max_indent = max ([indent (prevnonblank (a: lnum )) - &shiftwidth , 0 ])
121
+ return searchpos (' \v^(\s{,' .max_indent.' }(def |class |\@)\w|[^ \t#])' , ' bcnW' )[0 ]
122
+ endfunction " }}}
123
+
124
+ fun ! s: BlockEnd (lnum) " {{{
125
+ " Note: Make sure to reset cursor position after using this function.
126
+ call cursor (a: lnum , 0 )
127
+ return searchpos (' \v^\s{,' .indent (' .' ).' }\S' , ' nW' )[0 ] - 1
128
+ endfunction " }}}
94
129
95
130
" vim: fdm = marker:fdl = 0
0 commit comments