+ return base
+endfunction
+
+" If this line is dedented and the number of indent spaces is valid
+" (multiple of the indentation size), trust the user.
+function! s:is_dedented_already(current, base)
+ let dedent_size = a:current - a:base
+ return (dedent_size < 0 && a:current % s:sw() == 0) ? 1 : 0
+endfunction
+
+" Is the syntax at lnum (and optionally cnum) a python string?
+function! s:is_python_string(lnum, ...)
+ let line = getline(a:lnum)
+ let linelen = len(line)
+ if linelen < 1
+ let linelen = 1
+ endif
+ let cols = a:0 ? type(a:1) != type([]) ? [a:1] : a:1 : range(1, linelen)
+ for cnum in cols
+ if match(map(synstack(a:lnum, cnum),
+ \ 'synIDattr(v:val,"name")'), 'python\S*String') == -1
+ return 0
+ end
+ endfor
+ return 1
+endfunction
+
+function! GetPythonPEPIndent(lnum)
+ " First line has indent 0
+ if a:lnum == 1
+ return 0
+ endif
+
+ " Multilinestrings: continous, docstring or starting.
+ if s:is_python_string(a:lnum, 1)
+ \ && s:is_python_string(a:lnum-1, len(getline(a:lnum-1)))
+ " Keep existing indent.
+ if match(getline(a:lnum), '\v^\s*\S') != -1
+ return -1
+ endif
+
+ if s:is_python_string(a:lnum-1)
+ " Previous line is (completely) a string.
+ return indent(a:lnum-1)
+ endif
+
+ if match(getline(a:lnum-1), '^\s*\%("""\|''''''\)') != -1
+ " docstring.
+ return indent(a:lnum-1)
+ endif
+
+ let indent_multi = get(b:, 'python_pep8_indent_multiline_string',
+ \ get(g:, 'python_pep8_indent_multiline_string', 0))
+ if indent_multi != -2
+ return indent_multi
+ endif
+
+ if match(getline(a:lnum-1), '\v%("""|'''''')$') != -1
+ " Opening multiline string, started in previous line.
+ return indent(a:lnum-1) + s:sw()
+ endif
+ return s:indent_like_opening_paren(a:lnum)
+ endif
+
+ " Parens: If we can find an open parenthesis/bracket/brace, line up with it.
+ let indent = s:indent_like_opening_paren(a:lnum)
+ if indent >= -1
+ return indent
+ endif
+
+ " Blocks: Match indent of first block of this type.
+ let indent = s:indent_like_block(a:lnum)
+ if indent >= -1
+ return indent
+ endif
+
+ return s:indent_like_previous_line(a:lnum)