@@ -38,6 +38,15 @@ if !exists('g:python_pep8_indent_hang_closing')
38
38
let g: python_pep8_indent_hang_closing = 0
39
39
endif
40
40
41
+ " TODO: check required patch for timeout argument, likely lower than 7.3.429 though.
42
+ if ! exists (' g:python_pep8_indent_searchpair_timeout' )
43
+ if has (' patch-8.0.1483' )
44
+ let g: python_pep8_indent_searchpair_timeout = 150
45
+ else
46
+ let g: python_pep8_indent_searchpair_timeout = 0
47
+ endif
48
+ endif
49
+
41
50
let s: block_rules = {
42
51
\ ' ^\s*elif\>' : [' if' , ' elif' ],
43
52
\ ' ^\s*except\>' : [' try' , ' except' ],
57
66
endif
58
67
let s: stop_statement = ' ^\s*\(break\|continue\|raise\|return\|pass\)\>'
59
68
60
- " Skip strings and comments. Return 1 for chars to skip.
61
- " jedi* refers to syntax definitions from jedi-vim for call signatures, which
62
- " are inserted temporarily into the buffer.
63
- let s: skip_special_chars = ' synIDattr(synID(line("."), col("."), 0), "name") ' .
64
- \ ' =~? "\\vstring|comment|^pythonbytes%(contents)=$|jedi\\S"'
65
-
66
69
let s: skip_after_opening_paren = ' synIDattr(synID(line("."), col("."), 0), "name") ' .
67
70
\ ' =~? "\\vcomment|jedi\\S"'
68
71
69
- " Also ignore anything concealed.
70
- " Wrapper around synconcealed for older Vim (7.3.429, used on Travis CI).
71
- function ! s: is_concealed (line , col )
72
- let concealed = synconcealed (a: line , a: col )
73
- return len (concealed) && concealed[0 ]
74
- endfunction
75
- if has (' conceal' )
76
- let s: skip_special_chars .= ' || s:is_concealed(line("."), col("."))'
77
- endif
72
+ if ! get (g: , ' python_pep8_indent_skip_concealed' , 0 ) || ! has (' conceal' )
73
+ " Skip strings and comments. Return 1 for chars to skip.
74
+ " jedi* refers to syntax definitions from jedi-vim for call signatures, which
75
+ " are inserted temporarily into the buffer.
76
+ function ! s: _skip_special_chars (line , col )
77
+ return synIDattr (synID (a: line , a: col , 0 ), ' name' )
78
+ \ = ~? " \\ vstring|comment|^pythonbytes%(contents)=$|jedi\\ S"
79
+ endfunction
80
+ else
81
+ " Also ignore anything concealed.
82
+ " TODO: doc; likely only necessary with jedi-vim, where a better version is
83
+ " planned (https://github.com/Vimjas/vim-python-pep8-indent/pull/98).
84
+
85
+ " Wrapper around synconcealed for older Vim (7.3.429, used on Travis CI).
86
+ function ! s: is_concealed (line , col )
87
+ let concealed = synconcealed (a: line , a: col )
88
+ return len (concealed) && concealed[0 ]
89
+ endfunction
78
90
91
+ function ! s: _skip_special_chars (line , col )
92
+ return synIDattr (synID (a: line , a: col , 0 ), ' name' )
93
+ \ = ~? " \\ vstring|comment|^pythonbytes%(contents)=$|jedi\\ S"
94
+ \ || s: is_concealed (a: line , a: col )
95
+ endfunction
96
+ endif
79
97
80
98
" Use 'shiftwidth()' instead of '&sw'.
81
99
" (Since Vim patch 7.3.629, 'shiftwidth' can be set to 0 to follow 'tabstop').
@@ -99,10 +117,12 @@ function! s:find_opening_paren(lnum, col)
99
117
call cursor (a: lnum , a: col )
100
118
101
119
let nearest = [0 , 0 ]
120
+ let timeout = g: python_pep8_indent_searchpair_timeout
121
+ let skip_special_chars = ' s:_skip_special_chars(line("."), col("."))'
102
122
for [p , maxoff] in items (s: paren_pairs )
103
123
let stopline = max ([0 , line (' .' ) - maxoff, nearest[0 ]])
104
124
let next = searchpairpos (
105
- \ ' \V' .p [0 ], ' ' , ' \V' .p [1 ], ' bnW' , s: skip_special_chars , stopline)
125
+ \ ' \V' .p [0 ], ' ' , ' \V' .p [1 ], ' bnW' , skip_special_chars, stopline, timeout )
106
126
if next [0 ] && (next [0 ] > nearest[0 ] || (next [0 ] == nearest[0 ] && next [1 ] > nearest[1 ]))
107
127
let nearest = next
108
128
endif
@@ -257,24 +277,23 @@ function! s:indent_like_previous_line(lnum)
257
277
let base = indent (start )
258
278
let current = indent (a: lnum )
259
279
260
- " Jump to last character in previous line.
261
- call cursor (lnum, len (text) )
262
- let ignore_last_char = eval ( s: skip_special_chars )
280
+ " Ignore last character in previous line?
281
+ let lastcol = len (text)
282
+ let col = lastcol
263
283
264
284
" Search for final colon that is not inside something to be ignored.
265
285
while 1
266
- let curpos = getpos (' .' )[2 ]
267
- if curpos == 1 | break | endif
268
- if eval (s: skip_special_chars ) || text[curpos- 1 ] = ~# ' \s'
269
- normal ! h
286
+ if col == 1 | break | endif
287
+ if text[col - 1 ] = ~# ' \s' || s: _skip_special_chars (lnum, col )
288
+ let col = col - 1
270
289
continue
271
- elseif text[curpos - 1 ] == # ' :'
290
+ elseif text[col - 1 ] == # ' :'
272
291
return base + s: sw ()
273
292
endif
274
293
break
275
294
endwhile
276
295
277
- if text = ~# ' \\$' && ! ignore_last_char
296
+ if text = ~# ' \\$' && ! s: _skip_special_chars (lnum, lastcol)
278
297
" If this line is the continuation of a control statement
279
298
" indent further to distinguish the continuation line
280
299
" from the next logical line.
@@ -356,11 +375,12 @@ function! GetPythonPEPIndent(lnum)
356
375
if match_quotes != -1
357
376
" closing multiline string
358
377
let quotes = line [match_quotes: (match_quotes+ 2 )]
359
- let pairpos = searchpairpos (quotes, ' ' , quotes, ' b' )
378
+ call cursor (a: lnum , 1 )
379
+ let pairpos = searchpairpos (quotes, ' ' , quotes, ' bW' , ' ' , 0 , g: python_pep8_indent_searchpair_timeout )
360
380
if pairpos[0 ] != 0
361
381
return indent (pairpos[0 ])
362
382
else
363
- " TODO: test to cover this!
383
+ return -1
364
384
endif
365
385
endif
366
386
0 commit comments