22" Language: Python
33" Author: Jorrit Wiersma (foldexpr), Max Ischenko (foldtext), Robert,
44" Ames (line counts), Jean-Pierre Chauvel (bugfixes and improvements)
5- " Last Change: 2008 Apr 18
6- " Version: 2.8.3.7 .a
5+ " Last Change: 2008 Apr 20
6+ " Version: 2.9 .a
77" Bugfixes: Jean-Pierre Chauvel
88
99
1010if exists (" b:did_ftplugin" )
1111 finish
1212endif
13-
1413let b: did_ftplugin = 1
1514
16- if ! exists (" g:ifold_support_markers" )
17- let g: ifold_support_markers = 0
18- endif
19-
20- if ! exists (" g:ifold_show_text" )
21- let g: ifold_show_text = 0
22- endif
23-
24- if ! exists (" g:ifold_accuracy" )
25- let g: ifold_accuracy = 0
15+ if ! exists (" g:ifold_mode" )
16+ let g: ifold_mode = 0
2617endif
2718
2819map <buffer> f :call ToggleFold()<CR>
2920
21+ let w: nestinglevel = 0
22+ let w: signature = 0
23+ let w: is_folded = 1
24+
3025function ! PythonFoldText ()
3126 let line = getline (v: foldstart )
3227 let nnum = nextnonblank (v: foldstart + 1 )
@@ -53,13 +48,7 @@ function! PythonFoldText()
5348 return size . " lines: " . line
5449endfunction
5550
56-
57- let b: nestinglevel = 0
58- let b: classdefinition = 0
59-
6051function ! GetPythonFold (lnum)
61- " Determine folding level in Python source
62- "
6352 let line = getline (a: lnum - 1 )
6453
6554 " Classes and functions get their own folds
@@ -73,31 +62,26 @@ function! GetPythonFold(lnum)
7362 let pind = indent (a: lnum - 1 )
7463 if pind >= nind
7564 let nline = getline (nnum)
76- let b : nestinglevel = nind
77- return " <" . ((b : nestinglevel + &sw ) / &sw )
65+ let w : nestinglevel = nind
66+ return " <" . ((w : nestinglevel + &sw ) / &sw )
7867 endif
7968 endif
80- let b: classdefinition = 1
81- let b: nestinglevel = indent (a: lnum - 1 )
82- endif
83-
84- if line = ~ ' ^.*:' && b: classdefinition
85- let b: classdefinition = 0
86- return " >" . ((b: nestinglevel + &sw ) / &sw )
69+ let w: nestinglevel = indent (a: lnum - 1 )
70+ return " >" . ((w: nestinglevel + &sw ) / &sw )
8771 endif
8872
8973 " If next line has less or equal indentation than the first one,
9074 " we end a fold.
9175 let nind = indent (nextnonblank (a: lnum + 1 ))
92- if nind <= b : nestinglevel
93- let b : nestinglevel = nind
94- return " <" . ((b : nestinglevel + &sw ) / &sw )
76+ if nind <= w : nestinglevel
77+ let w : nestinglevel = nind
78+ return " <" . ((w : nestinglevel + &sw ) / &sw )
9579 else
9680 let ind = indent (a: lnum )
97- if ind == (b : nestinglevel + &sw )
81+ if ind == (w : nestinglevel + &sw )
9882 if nind < ind
99- let b : nestinglevel = nind
100- return " <" . ((b : nestinglevel + &sw ) / &sw )
83+ let w : nestinglevel = nind
84+ return " <" . ((w : nestinglevel + &sw ) / &sw )
10185 endif
10286 endif
10387 endif
@@ -106,20 +90,71 @@ function! GetPythonFold(lnum)
10690 return " ="
10791endfunction
10892
109- function ! GetPythonFoldAccurately (lnum)
93+ function ! GetPythonFoldBest (lnum)
11094 " Determine folding level in Python source
11195 "
11296 let line = getline (a: lnum - 1 )
11397
114- " Support markers
115- if g: ifold_support_markers
116- if line = ~ ' {{{'
117- return " a1"
118- elseif line = ~ ' }}}'
119- return " s1"
98+ " Handle Support markers
99+ if line = ~ ' {{{'
100+ return " a1"
101+ elseif line = ~ ' }}}'
102+ return " s1"
103+ endif
104+
105+ " Classes and functions get their own folds
106+ if line = ~ ' ^\s*\(class\|def\)\s'
107+ " Verify if the next line is a class or function definition
108+ " as well
109+ let imm_nnum = a: lnum + 1
110+ let nnum = nextnonblank (imm_nnum)
111+ let nind = indent (nnum)
112+ let pind = indent (a: lnum - 1 )
113+ if pind >= nind
114+ let nline = getline (nnum)
115+ let w: nestinglevel = nind
116+ return " <" . ((w: nestinglevel + &sw ) / &sw )
117+ endif
118+ let w: nestinglevel = indent (a: lnum - 1 )
119+ return " >" . ((w: nestinglevel + &sw ) / &sw )
120+ endif
121+
122+ " If next line has less or equal indentation than the first one,
123+ " we end a fold.
124+ let nnonblank = nextnonblank (a: lnum + 1 )
125+ let nextline = getline (nnonblank)
126+ if (nextline !~ ' ^#\+.*' )
127+ let nind = indent (nnonblank)
128+ if nind <= w: nestinglevel
129+ let w: nestinglevel = nind
130+ return " <" . ((w: nestinglevel + &sw ) / &sw )
131+ else
132+ let ind = indent (a: lnum )
133+ if ind == (w: nestinglevel + &sw )
134+ if nind < ind
135+ let w: nestinglevel = nind
136+ return " <" . ((w: nestinglevel + &sw ) / &sw )
137+ endif
138+ endif
120139 endif
121140 endif
122141
142+ " If none of the above apply, keep the indentation
143+ return " ="
144+ endfunction
145+
146+ function ! GetPythonFoldExperimental (lnum)
147+ " Determine folding level in Python source
148+ "
149+ let line = getline (a: lnum - 1 )
150+
151+ " Handle suport markers
152+ if line = ~ ' {{{'
153+ return " a1"
154+ elseif line = ~ ' }}}'
155+ return " s1"
156+ endif
157+
123158 " Classes and functions get their own folds
124159 if line = ~ ' ^\s*\(class\|def\)\s'
125160 " Verify if the next line is a class or function definition
@@ -130,33 +165,33 @@ function! GetPythonFoldAccurately(lnum)
130165 let pind = indent (a: lnum - 1 )
131166 if pind >= nind
132167 let nline = getline (nnum)
133- let b : nestinglevel = nind
134- return " <" . ((b : nestinglevel + &sw ) / &sw )
168+ let w : nestinglevel = nind
169+ return " <" . ((w : nestinglevel + &sw ) / &sw )
135170 endif
136- let b: classdefinition = 1
137- let b : nestinglevel = indent (a: lnum - 1 )
171+ let w: signature = 1
172+ let w : nestinglevel = indent (a: lnum - 1 )
138173 endif
139174
140- if line = ~ ' ^.*:' && b: classdefinition
141- let b: classdefinition = 0
142- return " >" . ((b : nestinglevel + &sw ) / &sw )
175+ if line = ~ ' ^.*:' && w: signature
176+ let w: signature = 0
177+ return " >" . ((w : nestinglevel + &sw ) / &sw )
143178 endif
144179
145180 " If next line has less or equal indentation than the first one,
146181 " we end a fold.
147182 let nnonblank = nextnonblank (a: lnum + 1 )
148183 let nextline = getline (nnonblank)
149- if (nextline !~ ' ^\s* #\+.*' )
184+ if (nextline !~ ' ^#\+.*' )
150185 let nind = indent (nnonblank)
151- if nind <= b : nestinglevel
152- let b : nestinglevel = nind
153- return " <" . ((b : nestinglevel + &sw ) / &sw )
186+ if nind <= w : nestinglevel
187+ let w : nestinglevel = nind
188+ return " <" . ((w : nestinglevel + &sw ) / &sw )
154189 else
155190 let ind = indent (a: lnum )
156- if ind == (b : nestinglevel + &sw )
191+ if ind == (w : nestinglevel + &sw )
157192 if nind < ind
158- let b : nestinglevel = nind
159- return " <" . ((b : nestinglevel + &sw ) / &sw )
193+ let w : nestinglevel = nind
194+ return " <" . ((w : nestinglevel + &sw ) / &sw )
160195 endif
161196 endif
162197 endif
@@ -166,17 +201,17 @@ function! GetPythonFoldAccurately(lnum)
166201 return " ="
167202endfunction
168203
169- let b: is_folding = 1
170-
171204function ! ToggleFold ()
172- if b: is_folding
205+ let w: nestinglevel = 0
206+ let w: signature = 0
207+ if w: is_folded
173208 set foldexpr = 0
174- let b: is_folding = 0
209+ let w: is_folded = 0
175210 else
176211 call ReFold ()
177212 " Open the fold we are in
178213 exec ' norm! zO'
179- let b: is_folding = 1
214+ let w: is_folded = 1
180215 endif
181216endfunction
182217
@@ -185,12 +220,19 @@ function! ReFold()
185220 set foldmethod = expr
186221 set foldexpr = 0
187222 set foldmethod = expr
188- if g: ifold_accuracy
189- set foldexpr = GetPythonFoldAccurately (v: lnum )
190- else
223+ if g: ifold_mode == 0
191224 set foldexpr = GetPythonFold (v: lnum )
225+ else
226+ if g: ifold_mode == 1
227+ set foldexpr = GetPythonFoldBest (v: lnum )
228+ else
229+ if g: ifold_mode == 2
230+ set foldexpr = GetPythonFoldExperimental (v: lnum )
231+ endif
232+ endif
192233 endif
193- if g: ifold_show_text
234+
235+ if g: ifold_mode
194236 set foldtext = PythonFoldText ()
195237 else
196238 set foldtext = ' Folded\ code'
0 commit comments