mirror of
https://git.savannah.gnu.org/git/emacs.git
synced 2024-11-25 07:28:20 +00:00
Add a new user option in Python mode to improve the indentation
* lisp/progmodes/python.el (python-indent-block-paren-deeper): New user option. (python-indent-context): Add a new context :inside-paren-from-block. (python-indent--calculate-indentation): Modify according to `python-indent-block-paren-deeper' and :inside-paren-from-block. * test/lisp/progmodes/python-tests.el (python-indent-inside-paren-block-1) (python-indent-inside-paren-block-2) (python-indent-inside-paren-block-3) (python-indent-inside-paren-block-4): New tests. (python-indent-inside-paren-5, python-indent-dedenters-8): Modify according to the new context. * etc/NEWS: Document the new user option. (Bug#62696)
This commit is contained in:
parent
2f013c46f7
commit
711e8bc717
17
etc/NEWS
17
etc/NEWS
@ -280,6 +280,23 @@ distracting and easily confused with actual code, or a significant
|
||||
early aid that relieves you from moving the buffer or reaching for the
|
||||
mouse to consult an error message.
|
||||
|
||||
** Python mode
|
||||
|
||||
*** New user option 'python-indent-block-paren-deeper'.
|
||||
If non-nil, increase the indentation of the lines inside parens in a
|
||||
header of a block when they are indented to the same level as the body
|
||||
of the block:
|
||||
|
||||
if (some_expression
|
||||
and another_expression):
|
||||
do_something()
|
||||
|
||||
instead of:
|
||||
|
||||
if (some_expression
|
||||
and another_expression):
|
||||
do_something()
|
||||
|
||||
|
||||
* New Modes and Packages in Emacs 30.1
|
||||
|
||||
|
@ -1270,6 +1270,31 @@ For NODE, OVERRIDE, START, END, and ARGS, see
|
||||
:type 'integer
|
||||
:safe 'natnump)
|
||||
|
||||
(defcustom python-indent-block-paren-deeper nil
|
||||
"Increase indentation inside parens of a block.
|
||||
If non-nil, increase the indentation of the lines inside parens
|
||||
in a header of a block when they are indented to the same level
|
||||
as the body of the block:
|
||||
|
||||
if (some_expression
|
||||
and another_expression):
|
||||
do_something()
|
||||
|
||||
instead of:
|
||||
|
||||
if (some_expression
|
||||
and another_expression):
|
||||
do_something()
|
||||
|
||||
This variable only works if the opening paren is followed by
|
||||
non-whitespace characters on the same line. Modify
|
||||
`python-indent-def-block-scale' to customize the case where
|
||||
non-whitespace character does not follow the opening paren on the
|
||||
same line."
|
||||
:version "30.1"
|
||||
:type 'boolean
|
||||
:safe 'booleanp)
|
||||
|
||||
(defvar python-indent-current-level 0
|
||||
"Deprecated var available for compatibility.")
|
||||
|
||||
@ -1367,6 +1392,10 @@ keyword
|
||||
- Point is inside a paren with items starting in their own line
|
||||
from a block start.
|
||||
- START is the position of the open paren.
|
||||
:inside-paren-from-block
|
||||
- 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.
|
||||
|
||||
:after-backslash
|
||||
- Fallback case when point is after backslash.
|
||||
@ -1450,12 +1479,16 @@ keyword
|
||||
(starts-in-newline
|
||||
(cons :inside-paren-newline-start start))
|
||||
;; General case.
|
||||
(t (cons :inside-paren
|
||||
(save-excursion
|
||||
(goto-char (1+ start))
|
||||
(skip-syntax-forward "(" 1)
|
||||
(skip-syntax-forward " ")
|
||||
(point))))))))
|
||||
(t (let ((after-start (save-excursion
|
||||
(goto-char (1+ start))
|
||||
(skip-syntax-forward "(" 1)
|
||||
(skip-syntax-forward " ")
|
||||
(point))))
|
||||
(if (save-excursion
|
||||
(python-nav-beginning-of-statement)
|
||||
(python-info-looking-at-beginning-of-block))
|
||||
(cons :inside-paren-from-block after-start)
|
||||
(cons :inside-paren after-start))))))))
|
||||
;; After backslash.
|
||||
((let ((start (when (not (python-syntax-comment-or-string-p ppss))
|
||||
(python-info-line-ends-backslash-p
|
||||
@ -1603,7 +1636,17 @@ possibilities can be narrowed to specific indentation points."
|
||||
(`(,(or :inside-paren-newline-start-from-block) . ,start)
|
||||
(goto-char start)
|
||||
(+ (current-indentation)
|
||||
(* python-indent-offset python-indent-def-block-scale))))))
|
||||
(* python-indent-offset python-indent-def-block-scale)))
|
||||
(`(,:inside-paren-from-block . ,start)
|
||||
(goto-char start)
|
||||
(let ((column (current-column)))
|
||||
(if (and python-indent-block-paren-deeper
|
||||
(= column (+ (save-excursion
|
||||
(python-nav-beginning-of-statement)
|
||||
(current-indentation))
|
||||
python-indent-offset)))
|
||||
(+ column python-indent-offset)
|
||||
column))))))
|
||||
|
||||
(defun python-indent--calculate-levels (indentation)
|
||||
"Calculate levels list given INDENTATION.
|
||||
|
@ -1139,7 +1139,7 @@ while ((not some_condition) and
|
||||
(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))
|
||||
(should (eq (car (python-indent-context)) :inside-paren-from-block))
|
||||
(should (= (python-indent-calculate-indentation) 7))
|
||||
(forward-line 1)
|
||||
(should (eq (car (python-indent-context)) :after-block-start))
|
||||
@ -1174,6 +1174,118 @@ 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-block-1 ()
|
||||
"`python-indent-block-paren-deeper' set to nil (default).
|
||||
See Bug#62696."
|
||||
(python-tests-with-temp-buffer
|
||||
"
|
||||
if ('VALUE' in my_unnecessarily_long_dictionary and
|
||||
some_other_long_condition_case):
|
||||
do_something()
|
||||
elif (some_case or
|
||||
another_case):
|
||||
do_another()
|
||||
"
|
||||
(python-tests-look-at "if")
|
||||
(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-from-block))
|
||||
(should (= (python-indent-calculate-indentation) 4))
|
||||
(forward-line 1)
|
||||
(should (eq (car (python-indent-context)) :after-block-start))
|
||||
(should (= (python-indent-calculate-indentation) 4))
|
||||
(forward-line 1)
|
||||
(should (eq (car (python-indent-context)) :at-dedenter-block-start))
|
||||
(should (= (python-indent-calculate-indentation) 0))
|
||||
(forward-line 1)
|
||||
(should (eq (car (python-indent-context)) :inside-paren-from-block))
|
||||
(should (= (python-indent-calculate-indentation) 6))
|
||||
(forward-line 1)
|
||||
(should (eq (car (python-indent-context)) :after-block-start))
|
||||
(should (= (python-indent-calculate-indentation) 4))))
|
||||
|
||||
(ert-deftest python-indent-inside-paren-block-2 ()
|
||||
"`python-indent-block-paren-deeper' set to t.
|
||||
See Bug#62696."
|
||||
(python-tests-with-temp-buffer
|
||||
"
|
||||
if ('VALUE' in my_unnecessarily_long_dictionary and
|
||||
some_other_long_condition_case):
|
||||
do_something()
|
||||
elif (some_case or
|
||||
another_case):
|
||||
do_another()
|
||||
"
|
||||
(let ((python-indent-block-paren-deeper t))
|
||||
(python-tests-look-at "if")
|
||||
(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-from-block))
|
||||
(should (= (python-indent-calculate-indentation) 8))
|
||||
(forward-line 1)
|
||||
(should (eq (car (python-indent-context)) :after-block-start))
|
||||
(should (= (python-indent-calculate-indentation) 4))
|
||||
(forward-line 1)
|
||||
(should (eq (car (python-indent-context)) :at-dedenter-block-start))
|
||||
(should (= (python-indent-calculate-indentation) 0))
|
||||
(forward-line 1)
|
||||
(should (eq (car (python-indent-context)) :inside-paren-from-block))
|
||||
(should (= (python-indent-calculate-indentation) 6))
|
||||
(forward-line 1)
|
||||
(should (eq (car (python-indent-context)) :after-block-start))
|
||||
(should (= (python-indent-calculate-indentation) 4)))))
|
||||
|
||||
(ert-deftest python-indent-inside-paren-block-3 ()
|
||||
"With backslash. `python-indent-block-paren-deeper' set to nil (default).
|
||||
See Bug#62696."
|
||||
(python-tests-with-temp-buffer
|
||||
"
|
||||
if 'VALUE' in my_uncessarily_long_dictionary and\\
|
||||
(some_other_long_condition_case or
|
||||
another_case):
|
||||
do_something()
|
||||
"
|
||||
(python-tests-look-at "if")
|
||||
(should (eq (car (python-indent-context)) :no-indent))
|
||||
(should (= (python-indent-calculate-indentation) 0))
|
||||
(forward-line 1)
|
||||
(should (eq (car (python-indent-context))
|
||||
:after-backslash-block-continuation))
|
||||
(should (= (python-indent-calculate-indentation) 3))
|
||||
(forward-line 1)
|
||||
(should (eq (car (python-indent-context)) :inside-paren-from-block))
|
||||
(should (= (python-indent-calculate-indentation) 4))
|
||||
(forward-line 1)
|
||||
(should (eq (car (python-indent-context)) :after-block-start))
|
||||
(should (= (python-indent-calculate-indentation) 4))))
|
||||
|
||||
(ert-deftest python-indent-inside-paren-block-4 ()
|
||||
"With backslash. `python-indent-block-paren-deeper' set to t.
|
||||
See Bug#62696."
|
||||
(python-tests-with-temp-buffer
|
||||
"
|
||||
if 'VALUE' in my_uncessarily_long_dictionary and\\
|
||||
(some_other_long_condition_case or
|
||||
another_case):
|
||||
do_something()
|
||||
"
|
||||
(let ((python-indent-block-paren-deeper t))
|
||||
(python-tests-look-at "if")
|
||||
(should (eq (car (python-indent-context)) :no-indent))
|
||||
(should (= (python-indent-calculate-indentation) 0))
|
||||
(forward-line 1)
|
||||
(should (eq (car (python-indent-context))
|
||||
:after-backslash-block-continuation))
|
||||
(should (= (python-indent-calculate-indentation) 3))
|
||||
(forward-line 1)
|
||||
(should (eq (car (python-indent-context)) :inside-paren-from-block))
|
||||
(should (= (python-indent-calculate-indentation) 8))
|
||||
(forward-line 1)
|
||||
(should (eq (car (python-indent-context)) :after-block-start))
|
||||
(should (= (python-indent-calculate-indentation) 4)))))
|
||||
|
||||
(ert-deftest python-indent-after-block-1 ()
|
||||
"The most simple after-block case that shouldn't fail."
|
||||
(python-tests-with-temp-buffer
|
||||
@ -1670,7 +1782,7 @@ a == 4):
|
||||
(should (= (python-indent-calculate-indentation) 0))
|
||||
(should (= (python-indent-calculate-indentation t) 0))
|
||||
(python-tests-look-at "a == 4):\n")
|
||||
(should (eq (car (python-indent-context)) :inside-paren))
|
||||
(should (eq (car (python-indent-context)) :inside-paren-from-block))
|
||||
(should (= (python-indent-calculate-indentation) 6))
|
||||
(python-indent-line)
|
||||
(should (= (python-indent-calculate-indentation t) 4))
|
||||
|
Loading…
Reference in New Issue
Block a user