Fix region indentation

Fixes: debbugs:18843

* lisp/progmodes/python.el (python-indent-region): Use
python-indent-line and skip special cases.

* test/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.
This commit is contained in:
Fabián Ezequiel Gallina 2014-11-15 18:10:58 -03:00
parent a6b42789b5
commit 89ebffc1f6
4 changed files with 143 additions and 18 deletions

View file

@ -1,3 +1,8 @@
2014-11-15 Fabián Ezequiel Gallina <fgallina@gnu.org>
* progmodes/python.el (python-indent-region): Use
python-indent-line and skip special cases. (Bug#18843)
2014-11-15 Michael Albinus <michael.albinus@gmx.de>
* vc/vc-hg.el (vc-hg-state): Disable pager. (Bug#18940)

View file

@ -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))))

View file

@ -1,3 +1,9 @@
2014-11-15 Fabián Ezequiel Gallina <fgallina@gnu.org>
* 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 <michael.albinus@gmx.de>
Backport Tramp changes from trunk.

View file

@ -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