]> git.eshelyaron.com Git - emacs.git/commitdiff
python.el: Indent docstring lines to base-indent
authorFabián Ezequiel Gallina <fgallina@gnu.org>
Thu, 9 Apr 2015 04:41:55 +0000 (01:41 -0300)
committerFabián Ezequiel Gallina <fgallina@gnu.org>
Thu, 9 Apr 2015 04:41:55 +0000 (01:41 -0300)
Fixes: debbugs:19595
Thanks to immerrr <immerrr@gmail.com> for reporting and providing
an initial patch.

* lisp/progmodes/python.el
(python-indent-context): Add :inside-docstring context.
(python-indent--calculate-indentation): Handle :inside-docstring.
(python-indent-region): Re-indent docstrings.

* test/automated/python-tests.el (python-indent-region-5)
(python-indent-inside-string-2): Fix tests.

lisp/progmodes/python.el
test/automated/python-tests.el

index da38152558f2a7083871d8e0ce1feb4e7097fcff..856ed322ec62ac66b1a1002380ecc920c2555589 100644 (file)
@@ -844,7 +844,9 @@ keyword
        ;; 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
@@ -989,6 +991,12 @@ possibilities can be narrowed to specific indentation points."
          ;; 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)
@@ -1138,14 +1146,15 @@ Called from a program, START and END specify the region to indent."
                                  (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
index 22c111fc04a1b99a78daf59e9945d4e0700fb157..47264c3ad319c63e25e3cdd3319e02a816a69c60 100644 (file)
@@ -1014,7 +1014,7 @@ lines
 def fn(a, b, c=True):
     '''docstring
     bunch
-    of
+        of
     lines
     '''
 "
@@ -1022,16 +1022,17 @@ def fn(a, b, c=True):
    (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 ()
@@ -1189,21 +1190,33 @@ def f():
                       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