1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2026-01-30 20:32:00 -08:00

Fix Python indentation of continuation lines within parens

* lisp/progmodes/python.el (python-indent-context): Add a new indent
context `:inside-paren-continuation-line'.
(python-indent--calculate-indentation): Use the new indent context.
* test/lisp/progmodes/python-tests.el (python-indent-pep8-2)
(python-indent-pep8-3)
(python-indent-inside-paren-1)
(python-indent-inside-paren-2)
(python-indent-inside-paren-3)
(python-indent-inside-paren-6)
(python-indent-after-backslash-2): Change to use the new indent
context.
(python-indent-inside-paren-8)
(python-indent-inside-paren-9): New tests. (Bug#63959)
This commit is contained in:
kobarity 2023-06-18 23:47:25 +09:00 committed by Eli Zaretskii
parent 5b7e999e24
commit 9c2cbfa49d
2 changed files with 101 additions and 14 deletions

View file

@ -1406,6 +1406,10 @@ keyword
- Point is inside a paren from a block start followed by some
items on the same line.
- START is the first non space char position *after* the open paren.
:inside-paren-continuation-line
- Point is on a continuation line inside a paren.
- START is the position where the previous line (excluding lines
for inner parens) starts.
:after-backslash
- Fallback case when point is after backslash.
@ -1460,7 +1464,21 @@ keyword
(= (line-number-at-pos)
(progn
(python-util-forward-comment)
(line-number-at-pos))))))))
(line-number-at-pos)))))))
(continuation-start
(when start
(save-excursion
(forward-line -1)
(back-to-indentation)
;; Skip inner parens.
(cl-loop with prev-start = (python-syntax-context 'paren)
while (and prev-start (>= prev-start start))
if (= prev-start start)
return (point)
else do (goto-char prev-start)
(back-to-indentation)
(setq prev-start
(python-syntax-context 'paren)))))))
(when start
(cond
;; Current line only holds the closing paren.
@ -1476,6 +1494,9 @@ keyword
(back-to-indentation)
(python-syntax-closing-paren-p))
(cons :inside-paren-at-closing-nested-paren start))
;; This line is a continuation of the previous line.
(continuation-start
(cons :inside-paren-continuation-line continuation-start))
;; This line starts from an opening block in its own line.
((save-excursion
(goto-char start)
@ -1591,7 +1612,8 @@ possibilities can be narrowed to specific indentation points."
(`(,(or :after-line
:after-comment
:inside-string
:after-backslash) . ,start)
:after-backslash
:inside-paren-continuation-line) . ,start)
;; Copy previous indentation.
(goto-char start)
(current-indentation))

View file

@ -683,7 +683,7 @@ def long_function_name(
(should (= (python-indent-calculate-indentation) 8))
(python-tests-look-at "var_four):")
(should (eq (car (python-indent-context))
:inside-paren-newline-start-from-block))
:inside-paren-continuation-line))
(should (= (python-indent-calculate-indentation) 8))
(python-tests-look-at "print (var_one)")
(should (eq (car (python-indent-context))
@ -707,8 +707,8 @@ foo = long_function_name(
(should (eq (car (python-indent-context)) :inside-paren-newline-start))
(should (= (python-indent-calculate-indentation) 4))
(python-tests-look-at "var_three, var_four)")
(should (eq (car (python-indent-context)) :inside-paren-newline-start))
(should (= (python-indent-calculate-indentation) 4))))
(should (eq (car (python-indent-context)) :inside-paren-continuation-line))
(should (= (python-indent-calculate-indentation) 2))))
(ert-deftest python-indent-hanging-close-paren ()
"Like first pep8 case, but with hanging close paren." ;; See Bug#20742.
@ -864,7 +864,7 @@ data = {
(should (eq (car (python-indent-context)) :inside-paren-newline-start))
(should (= (python-indent-calculate-indentation) 4))
(python-tests-look-at "{")
(should (eq (car (python-indent-context)) :inside-paren-newline-start))
(should (eq (car (python-indent-context)) :inside-paren-continuation-line))
(should (= (python-indent-calculate-indentation) 4))
(python-tests-look-at "'objlist': [")
(should (eq (car (python-indent-context)) :inside-paren-newline-start))
@ -876,20 +876,20 @@ data = {
(should (eq (car (python-indent-context)) :inside-paren-newline-start))
(should (= (python-indent-calculate-indentation) 16))
(python-tests-look-at "'name': 'first',")
(should (eq (car (python-indent-context)) :inside-paren-newline-start))
(should (eq (car (python-indent-context)) :inside-paren-continuation-line))
(should (= (python-indent-calculate-indentation) 16))
(python-tests-look-at "},")
(should (eq (car (python-indent-context))
:inside-paren-at-closing-nested-paren))
(should (= (python-indent-calculate-indentation) 12))
(python-tests-look-at "{")
(should (eq (car (python-indent-context)) :inside-paren-newline-start))
(should (eq (car (python-indent-context)) :inside-paren-continuation-line))
(should (= (python-indent-calculate-indentation) 12))
(python-tests-look-at "'pk': 2,")
(should (eq (car (python-indent-context)) :inside-paren-newline-start))
(should (= (python-indent-calculate-indentation) 16))
(python-tests-look-at "'name': 'second',")
(should (eq (car (python-indent-context)) :inside-paren-newline-start))
(should (eq (car (python-indent-context)) :inside-paren-continuation-line))
(should (= (python-indent-calculate-indentation) 16))
(python-tests-look-at "}")
(should (eq (car (python-indent-context))
@ -933,7 +933,7 @@ data = {'key': {
(should (eq (car (python-indent-context)) :inside-paren))
(should (= (python-indent-calculate-indentation) 9))
(python-tests-look-at "{'pk': 2,")
(should (eq (car (python-indent-context)) :inside-paren-newline-start))
(should (eq (car (python-indent-context)) :inside-paren-continuation-line))
(should (= (python-indent-calculate-indentation) 8))
(python-tests-look-at "'name': 'second'}")
(should (eq (car (python-indent-context)) :inside-paren))
@ -966,10 +966,10 @@ data = ('these',
(should (eq (car (python-indent-context)) :inside-paren))
(should (= (python-indent-calculate-indentation) 8))
(forward-line 1)
(should (eq (car (python-indent-context)) :inside-paren))
(should (eq (car (python-indent-context)) :inside-paren-continuation-line))
(should (= (python-indent-calculate-indentation) 8))
(forward-line 1)
(should (eq (car (python-indent-context)) :inside-paren))
(should (eq (car (python-indent-context)) :inside-paren-continuation-line))
(should (= (python-indent-calculate-indentation) 8))))
(ert-deftest python-indent-inside-paren-4 ()
@ -1023,7 +1023,7 @@ CHOICES = (('some', 'choice'),
(should (eq (car (python-indent-context)) :inside-paren))
(should (= (python-indent-calculate-indentation) 11))
(forward-line 1)
(should (eq (car (python-indent-context)) :inside-paren))
(should (eq (car (python-indent-context)) :inside-paren-continuation-line))
(should (= (python-indent-calculate-indentation) 11))))
(ert-deftest python-indent-inside-paren-7 ()
@ -1034,6 +1034,71 @@ CHOICES = (('some', 'choice'),
;; This signals an error if the test fails
(should (eq (car (python-indent-context)) :inside-paren-newline-start))))
(ert-deftest python-indent-inside-paren-8 ()
"Test for Bug#63959."
(python-tests-with-temp-buffer
"
for a in [ # comment
'some', # Manually indented.
'thing']: # Respect indentation of the previous line.
"
(python-tests-look-at "for a in [ # comment")
(should (eq (car (python-indent-context)) :no-indent))
(should (= (python-indent-calculate-indentation) 0))
(forward-line 1)
(should (eq (car (python-indent-context))
:inside-paren-newline-start-from-block))
(should (= (python-indent-calculate-indentation) 8))
(forward-line 1)
(should (eq (car (python-indent-context)) :inside-paren-continuation-line))
(should (= (python-indent-calculate-indentation) 10))))
(ert-deftest python-indent-inside-paren-9 ()
"Test `:inside-paren-continuation-line'."
(python-tests-with-temp-buffer
"
a = (((
1, 2),
3), # Do not respect the indentation of the previous line
4) # Do not respect the indentation of the previous line
b = ((
1, 2), # Manually indented
3, # Do not respect the indentation of the previous line
4, # Respect the indentation of the previous line
5, # Manually indented
6) # Respect the indentation of the previous line
"
(python-tests-look-at "a = (((")
(should (eq (car (python-indent-context)) :no-indent))
(should (= (python-indent-calculate-indentation) 0))
(forward-line 1)
(should (eq (car (python-indent-context)) :inside-paren-newline-start))
(should (= (python-indent-calculate-indentation) 4))
(forward-line 1)
(should (eq (car (python-indent-context)) :inside-paren))
(should (= (python-indent-calculate-indentation) 6))
(forward-line 1)
(should (eq (car (python-indent-context)) :inside-paren))
(should (= (python-indent-calculate-indentation) 5))
(forward-line 1)
(should (eq (car (python-indent-context)) :after-line))
(should (= (python-indent-calculate-indentation) 0))
(forward-line 1)
(should (eq (car (python-indent-context)) :inside-paren-newline-start))
(should (= (python-indent-calculate-indentation) 4))
(forward-line 1)
(should (eq (car (python-indent-context)) :inside-paren))
(should (= (python-indent-calculate-indentation) 5))
(forward-line 1)
(should (eq (car (python-indent-context)) :inside-paren-continuation-line))
(should (= (python-indent-calculate-indentation) 5))
(forward-line 1)
(should (eq (car (python-indent-context)) :inside-paren-continuation-line))
(should (= (python-indent-calculate-indentation) 5))
(forward-line 1)
(should (eq (car (python-indent-context)) :inside-paren-continuation-line))
(should (= (python-indent-calculate-indentation) 8))))
(ert-deftest python-indent-inside-paren-block-1 ()
"`python-indent-block-paren-deeper' set to nil (default).
See Bug#62696."
@ -1271,7 +1336,7 @@ objects = Thing.objects.all() \\
(should (eq (car (python-indent-context)) :inside-paren-newline-start))
(should (= (python-indent-calculate-indentation) 27))
(python-tests-look-at "status='bought'")
(should (eq (car (python-indent-context)) :inside-paren-newline-start))
(should (eq (car (python-indent-context)) :inside-paren-continuation-line))
(should (= (python-indent-calculate-indentation) 27))
(python-tests-look-at ") \\")
(should (eq (car (python-indent-context)) :inside-paren-at-closing-paren))