diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 8f00403c39b..fe06ac671b7 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,8 @@ +2014-11-15 Fabián Ezequiel Gallina + + * progmodes/python.el (python-indent-region): Use + python-indent-line and skip special cases. (Bug#18843) + 2014-11-15 Michael Albinus * vc/vc-hg.el (vc-hg-state): Disable pager. (Bug#18940) diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el index 95fc52d4d54..5f8d7a29fa6 100644 --- a/lisp/progmodes/python.el +++ b/lisp/progmodes/python.el @@ -1061,24 +1061,34 @@ Called from a program, START and END specify the region to indent." (or (bolp) (forward-line 1)) (while (< (point) end) (or (and (bolp) (eolp)) - (let (word) - (forward-line -1) - (back-to-indentation) - (setq word (current-word)) - (forward-line 1) - (when (and word - ;; Don't mess with strings, unless it's the - ;; enclosing set of quotes. - (or (not (python-syntax-context 'string)) - (eq - (syntax-after - (+ (1- (point)) - (current-indentation) - (python-syntax-count-quotes (char-after) (point)))) - (string-to-syntax "|")))) - (beginning-of-line) - (delete-horizontal-space) - (indent-to (python-indent-calculate-indentation))))) + (when (and + ;; Skip if previous line is empty or a comment. + (save-excursion + (let ((line-is-comment-p + (python-info-current-line-comment-p))) + (forward-line -1) + (not + (or (and (python-info-current-line-comment-p) + ;; Unless this line is a comment too. + (not line-is-comment-p)) + (python-info-current-line-empty-p))))) + ;; Don't mess with strings, unless it's the + ;; enclosing set of quotes. + (or (not (python-syntax-context 'string)) + (eq + (syntax-after + (+ (1- (point)) + (current-indentation) + (python-syntax-count-quotes (char-after) (point)))) + (string-to-syntax "|"))) + ;; Skip if current line is a block start, a + ;; dedenter or block ender. + (save-excursion + (back-to-indentation) + (not (looking-at + (python-rx + (or block-start dedenter block-ender)))))) + (python-indent-line))) (forward-line 1)) (move-marker end nil)))) diff --git a/test/ChangeLog b/test/ChangeLog index a5ee4b60589..971a4f8f400 100644 --- a/test/ChangeLog +++ b/test/ChangeLog @@ -1,3 +1,9 @@ +2014-11-15 Fabián Ezequiel Gallina + + * automated/python-tests.el (python-indent-region-1) + (python-indent-region-2, python-indent-region-3) + (python-indent-region-4, python-indent-region-5): New tests. + 2014-11-08 Michael Albinus Backport Tramp changes from trunk. diff --git a/test/automated/python-tests.el b/test/automated/python-tests.el index 39195fd7086..8c657c38b64 100644 --- a/test/automated/python-tests.el +++ b/test/automated/python-tests.el @@ -725,6 +725,110 @@ def b() (python-tests-self-insert ":") (should (= (current-indentation) 0)))) +(ert-deftest python-indent-region-1 () + "Test indentation case from Bug#18843." + (let ((contents " +def foo (): + try: + pass + except: + pass +")) + (python-tests-with-temp-buffer + contents + (python-indent-region (point-min) (point-max)) + (should (string= (buffer-substring-no-properties (point-min) (point-max)) + contents))))) + +(ert-deftest python-indent-region-2 () + "Test region indentation on comments." + (let ((contents " +def f(): + if True: + pass + +# This is +# some multiline +# comment +")) + (python-tests-with-temp-buffer + contents + (python-indent-region (point-min) (point-max)) + (should (string= (buffer-substring-no-properties (point-min) (point-max)) + contents))))) + +(ert-deftest python-indent-region-3 () + "Test region indentation on comments." + (let ((contents " +def f(): + if True: + pass +# This is +# some multiline +# comment +") + (expected " +def f(): + if True: + pass + # This is + # some multiline + # comment +")) + (python-tests-with-temp-buffer + contents + (python-indent-region (point-min) (point-max)) + (should (string= (buffer-substring-no-properties (point-min) (point-max)) + expected))))) + +(ert-deftest python-indent-region-4 () + "Test region indentation block starts, dedenders and enders." + (let ((contents " +def f(): + if True: +a = 5 + else: + a = 10 + return a +") + (expected " +def f(): + if True: + a = 5 + else: + a = 10 + return a +")) + (python-tests-with-temp-buffer + contents + (python-indent-region (point-min) (point-max)) + (should (string= (buffer-substring-no-properties (point-min) (point-max)) + expected))))) + +(ert-deftest python-indent-region-5 () + "Test region indentation leaves strings untouched (start delimiter)." + (let ((contents " +def f(): +''' +this is +a multiline +string +''' +") + (expected " +def f(): + ''' +this is +a multiline +string +''' +")) + (python-tests-with-temp-buffer + contents + (python-indent-region (point-min) (point-max)) + (should (string= (buffer-substring-no-properties (point-min) (point-max)) + expected))))) + ;;; Navigation