;; Inside a string.
((let ((start (python-syntax-context 'string ppss)))
(when start
- (cons :inside-string start))))
+ (cons (if (python-info-docstring-p)
+ :inside-docstring
+ :inside-string) start))))
;; Inside a paren.
((let* ((start (python-syntax-context 'paren ppss))
(starts-in-newline
;; Copy previous indentation.
(goto-char start)
(current-indentation))
+ (`(:inside-docstring . ,start)
+ (let* ((line-indentation (current-indentation))
+ (base-indent (progn
+ (goto-char start)
+ (current-indentation))))
+ (max line-indentation base-indent)))
(`(,(or :after-block-start
:after-backslash-first-line
:inside-paren-newline-start) . ,start)
(not line-is-comment-p))
(python-info-current-line-empty-p)))))
;; Don't mess with strings, unless it's the
- ;; enclosing set of quotes.
+ ;; enclosing set of quotes or a docstring.
(or (not (python-syntax-context 'string))
(eq
(syntax-after
(+ (1- (point))
(current-indentation)
(python-syntax-count-quotes (char-after) (point))))
- (string-to-syntax "|")))
+ (string-to-syntax "|"))
+ (python-info-docstring-p))
;; Skip if current line is a block start, a
;; dedenter or block ender.
(save-excursion
def fn(a, b, c=True):
'''docstring
bunch
- of
+ of
lines
'''
"
(should (eq (car (python-indent-context)) :after-block-start))
(should (= (python-indent-calculate-indentation) 4))
(python-tests-look-at "bunch")
- (should (eq (car (python-indent-context)) :inside-string))
+ (should (eq (car (python-indent-context)) :inside-docstring))
(should (= (python-indent-calculate-indentation) 4))
(python-tests-look-at "of")
- (should (eq (car (python-indent-context)) :inside-string))
- (should (= (python-indent-calculate-indentation) 4))
+ (should (eq (car (python-indent-context)) :inside-docstring))
+ ;; Any indentation deeper than the base-indent must remain unmodified.
+ (should (= (python-indent-calculate-indentation) 8))
(python-tests-look-at "lines")
- (should (eq (car (python-indent-context)) :inside-string))
+ (should (eq (car (python-indent-context)) :inside-docstring))
(should (= (python-indent-calculate-indentation) 4))
(python-tests-look-at "'''")
- (should (eq (car (python-indent-context)) :inside-string))
+ (should (eq (car (python-indent-context)) :inside-docstring))
(should (= (python-indent-calculate-indentation) 4))))
(ert-deftest python-indent-inside-string-3 ()
expected)))))
(ert-deftest python-indent-region-5 ()
- "Test region indentation leaves strings untouched (start delimiter)."
+ "Test region indentation for docstrings."
(let ((contents "
def f():
'''
this is
-a multiline
+ a multiline
string
+'''
+ x = \\
+ '''
+this is an arbitrarily
+ indented multiline
+ string
'''
")
(expected "
def f():
'''
-this is
-a multiline
-string
+ this is
+ a multiline
+ string
+ '''
+ x = \\
+ '''
+this is an arbitrarily
+ indented multiline
+ string
'''
"))
(python-tests-with-temp-buffer