@@ -43,9 +43,25 @@ let s:paren_pairs = ['()', '{}', '[]']
4343let s: control_statement = ' ^\s*\(class\|def\|if\|while\|with\|for\|except\)\>'
4444let s: stop_statement = ' ^\s*\(break\|continue\|raise\|return\|pass\)\>'
4545
46- " Skip strings and comments
46+ " Skip strings and comments. Return 1 for chars to skip.
47+ " jedi* refers to syntax definitions from jedi-vim for call signatures, which
48+ " are inserted temporarily into the buffer.
4749let s: skip_special_chars = ' synIDattr(synID(line("."), col("."), 0), "name") ' .
48- \ ' =~? "string\\|comment"'
50+ \ ' =~? "\\vstring|comment|jedi\\S"'
51+
52+ let s: skip_after_opening_paren = ' synIDattr(synID(line("."), col("."), 0), "name") ' .
53+ \ ' =~? "\\vcomment|jedi\\S"'
54+
55+ " Also ignore anything concealed.
56+ " Wrapper around synconcealed for older Vim (7.3.429, used on Travis CI).
57+ function ! s: is_concealed (line , col )
58+ let concealed = synconcealed (a: line , a: col )
59+ return len (concealed) && concealed[0 ]
60+ endfunction
61+ if has (' conceal' )
62+ let s: skip_special_chars .= ' || s:is_concealed(line("."), col("."))'
63+ endif
64+
4965
5066let s: skip_search = ' synIDattr(synID(line("."), col("."), 0), "name") ' .
5167 \ ' =~? "comment"'
@@ -134,6 +150,27 @@ function! s:find_start_of_block(lnum, types)
134150 return 0
135151endfunction
136152
153+ " Is "expr" true for every position in "lnum", beginning at "start"?
154+ " (optionally up to a:1 / 4th argument)
155+ function ! s: match_expr_on_line (expr , lnum, start , ... )
156+ let text = getline (a: lnum )
157+ let end = a: 0 ? a: 1 : len (text)
158+ if a: start > end
159+ return 1
160+ endif
161+ let save_pos = getpos (' .' )
162+ let r = 1
163+ for i in range (a: start , end )
164+ call cursor (a: lnum , i )
165+ if ! (eval (a: expr ) || text[i - 1 ] = ~ ' \s' )
166+ let r = 0
167+ break
168+ endif
169+ endfor
170+ call setpos (' .' , save_pos)
171+ return r
172+ endfunction
173+
137174" Line up with open parenthesis/bracket/brace.
138175function ! s: indent_like_opening_paren (lnum)
139176 let [paren_lnum, paren_col] = s: find_opening_paren (a: lnum )
@@ -143,7 +180,8 @@ function! s:indent_like_opening_paren(lnum)
143180 let text = getline (paren_lnum)
144181 let base = indent (paren_lnum)
145182
146- let nothing_after_opening_paren = text = ~ ' \%' .(paren_col + 1 ).' c\s*$'
183+ let nothing_after_opening_paren = s: match_expr_on_line (
184+ \ s: skip_after_opening_paren , paren_lnum, paren_col+ 1 )
147185 let starts_with_closing_paren = getline (a: lnum ) = ~ ' ^\s*[])}]'
148186
149187 if nothing_after_opening_paren
@@ -204,13 +242,18 @@ function! s:indent_like_previous_line(lnum)
204242 call cursor (lnum, len (text))
205243 let ignore_last_char = eval (s: skip_special_chars )
206244
207- " Search for final colon that is not inside a string or comment.
208- while search (' :\s*\%(#.*\)\?$' , ' bcW' , lnum)
209- if eval (s: skip_special_chars )
245+ " Search for final colon that is not inside something to be ignored.
246+ while search (' :' , ' bcW' , lnum)
247+ let curpos = getpos (" ." )[2 ]
248+ if curpos == 1 | break | endif
249+ if eval (s: skip_special_chars )
250+ normal ! h
251+ continue
252+ endif
253+ if ! s: match_expr_on_line (s: skip_special_chars , lnum, curpos)
254+ return base + s: sw ()
255+ endif
210256 normal ! h
211- else
212- return base + s: sw ()
213- endif
214257 endwhile
215258
216259 if text = ~ ' \\$' && ! ignore_last_char
0 commit comments