@@ -35,10 +35,12 @@ setlocal shiftwidth=4
3535let s: maxoff = 50
3636let s: block_rules = {
3737 \ ' ^\s*elif\>' : [' if' , ' elif' ],
38- \ ' ^\s*else\>' : [' if' , ' elif' , ' for' , ' try' , ' except' ],
3938 \ ' ^\s*except\>' : [' try' , ' except' ],
4039 \ ' ^\s*finally\>' : [' try' , ' except' , ' else' ]
4140 \ }
41+ let s: block_rules_multiple = {
42+ \ ' ^\s*else\>' : [' if' , ' elif' , ' for' , ' try' , ' except' ],
43+ \ }
4244let s: paren_pairs = [' ()' , ' {}' , ' []' ]
4345if &ft == ' pyrex' || &ft == ' cython'
4446 let b: control_statement = ' \v^\s*(class|def|if|while|with|for|except|cdef|cpdef)>'
@@ -136,22 +138,28 @@ function! s:find_start_of_multiline_statement(lnum)
136138 endwhile
137139endfunction
138140
139- " Find the block starter that matches the current line
140- function ! s: find_start_of_block (lnum, types)
141+ " Find possible indent(s) of the block starter that matches the current line.
142+ function ! s: find_start_of_block (lnum, types, multiple)
143+ let r = []
141144 let re = ' \V\^\s\*\(' .join (a: types , ' \|' ).' \)\>'
142-
143145 let lnum = a: lnum
144146 let last_indent = indent (lnum) + 1
145147 while lnum > 0 && last_indent > 0
146- if indent (lnum) < last_indent
148+ let indent = indent (lnum)
149+ if indent < last_indent
147150 if getline (lnum) = ~# re
148- return lnum
151+ if ! a: multiple
152+ return [indent ]
153+ endif
154+ if ! len (r ) || index (r , indent ) == -1
155+ let r += [indent ]
156+ endif
149157 endif
150158 let last_indent = indent (lnum)
151159 endif
152160 let lnum = prevnonblank (lnum - 1 )
153161 endwhile
154- return 0
162+ return r
155163endfunction
156164
157165" Is "expr" true for every position in "lnum", beginning at "start"?
@@ -212,20 +220,31 @@ endfunction
212220" Match indent of first block of this type.
213221function ! s: indent_like_block (lnum)
214222 let text = getline (a: lnum )
223+ for [multiple, block_rules] in [
224+ \ [0 , s: block_rules ],
225+ \ [1 , s: block_rules_multiple ]]
226+ for [line_re, blocks] in items (block_rules)
227+ if text !~# line_re
228+ continue
229+ endif
215230
216- for [line_re, blocks] in items (s: block_rules )
217- if text !~# line_re
218- continue
219- endif
220-
221- let lnum = s: find_start_of_block (a: lnum - 1 , blocks)
222- if lnum > 0
223- return indent (lnum)
224- else
225- return -1
226- endif
231+ let indents = s: find_start_of_block (a: lnum - 1 , blocks, multiple)
232+ if ! len (indents)
233+ return -1
234+ endif
235+ if len (indents) == 1
236+ return indents[0 ]
237+ endif
238+ " Multiple valid indents, e.g. for 'else' with both try and if.
239+ let indent = indent (a: lnum )
240+ for possible_indent in indents
241+ if indent == possible_indent
242+ return indent
243+ endif
244+ endfor
245+ return -2
246+ endfor
227247 endfor
228-
229248 return -2
230249endfunction
231250
0 commit comments