all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Gustaf Waldemarson <gustaf.waldemarson@gmail.com>
To: kobarity <kobarity@gmail.com>
Cc: 62696@debbugs.gnu.org
Subject: bug#62696: python.el: Extra indentation for conditionals
Date: Tue, 11 Apr 2023 13:11:54 +0200	[thread overview]
Message-ID: <CABehr5ffFuykHkieRRX+zTSZF0t_qv3fd86USZZfET+Qc+se1g@mail.gmail.com> (raw)
In-Reply-To: <eke7ile3kbjs.wl-kobarity@gmail.com>


[-- Attachment #1.1: Type: text/plain, Size: 1592 bytes --]

Hello Kobarity,

Being Swedish, I am hardly an authority on the English language. That said,
I went
ahead and double-checked the docstring and such, and the only thing that I
found a
bit confusing is the `python-indent-block-paren-deeper` description as
follows:

"Increase indentation inside parens of a block.
When this variable is set to non-nil and the contents of a block
inside parens are indented to the same level as outside the same
block, increase the indentation of the line."

This is really nitpicking though, and I may be using some terms incorrectly
since
since I don't know a lot of the internals here, so feel free to disregard
any of this. These
changes are also available in attached patch, feel free to use it if need
be!

Best regards,
Gustaf

Den mån 10 apr. 2023 kl 17:21 skrev kobarity <kobarity@gmail.com>:

>
> Gustaf Waldemarson wrote:
> > Thanks a lot for this! I had no idea that they had changed the relevant
> PEPs to account
> > for this, but as mentioned it is still a good idea to have the option to
> change this depending
> > on your preference. And as far as I have been able to tell from coding
> with this patch for a
> > few hours, it seems to work beautifully and I would love to see this as
> an official feature!
>
> Hi Gustaf,
>
> Thank you for testing my patch.  I am relieved that it seems to have
> fulfilled your request.
>
> As I am not a native English speaker, I welcome any feedback from
> anyone on the name and/or docstrings of the new user option as well as
> on the behavior and coding.
>

[-- Attachment #1.2: Type: text/html, Size: 2068 bytes --]

[-- Attachment #2: 0001-Add-a-new-user-option-in-Python-mode-to-improve-indent-2.patch --]
[-- Type: text/x-patch, Size: 10909 bytes --]

From ea2de07164cee80a85226e68b83692d6eeda4f46 Mon Sep 17 00:00:00 2001
From: kobarity <kobarity@gmail.com>
Date: Sun, 9 Apr 2023 20:48:00 +0900
Subject: [PATCH] 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)
---
 etc/NEWS                            |   8 ++
 lisp/progmodes/python.el            |  41 ++++++++--
 test/lisp/progmodes/python-tests.el | 116 +++++++++++++++++++++++++++-
 3 files changed, 156 insertions(+), 9 deletions(-)

diff --git a/etc/NEWS b/etc/NEWS
index 5e1fd76e99e..1fd97c35208 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -266,6 +266,14 @@ When non-nil, it will automatically register every package as a
 project, that you can quickly select using 'project-switch-project'
 ('C-x p p').
 
+** Python mode
+
+*** New user option 'python-indent-block-paren-deeper'.
+Increase indentation inside parens of a block.
+When this variable is set to non-nil and the contents of a block
+inside parens are indented to the same level as outside the same
+block, increase the indentation of the line.
+
 \f
 * New Modes and Packages in Emacs 30.1
 
diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el
index bbabce80b4d..0868b77f201 100644
--- a/lisp/progmodes/python.el
+++ b/lisp/progmodes/python.el
@@ -1270,6 +1270,15 @@ python-indent-def-block-scale
   :type 'integer
   :safe 'natnump)
 
+(defcustom python-indent-block-paren-deeper nil
+  "Increase indentation inside parens of a block.
+When this variable is set to non-nil and the contents of a block
+inside parens are indented to the same level as outside the same
+block, increase the indentation of the line."
+  :version "30.1"
+  :type 'boolean
+  :safe 'booleanp)
+
 (defvar python-indent-current-level 0
   "Deprecated var available for compatibility.")
 
@@ -1367,6 +1376,10 @@ python-indent-context
  - 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 +1463,16 @@ python-indent-context
              (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 +1620,17 @@ python-indent--calculate-indentation
         (`(,(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.
diff --git a/test/lisp/progmodes/python-tests.el b/test/lisp/progmodes/python-tests.el
index 50153e66da5..60b11d572cf 100644
--- a/test/lisp/progmodes/python-tests.el
+++ b/test/lisp/progmodes/python-tests.el
@@ -1139,7 +1139,7 @@ python-indent-inside-paren-5
    (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 @@ python-indent-inside-paren-7
    ;; 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 @@ python-indent-dedenters-8
    (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))
-- 
2.25.1


  reply	other threads:[~2023-04-11 11:11 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-04-06 12:47 bug#62696: python.el: Extra indentation for conditionals Gustaf Waldemarson
2023-04-09 12:11 ` kobarity
2023-04-10 11:11   ` Gustaf Waldemarson
2023-04-10 15:21     ` kobarity
2023-04-11 11:11       ` Gustaf Waldemarson [this message]
2023-04-12 15:26         ` kobarity
2023-04-16 13:24           ` kobarity
2023-04-16 15:49             ` Gustaf Waldemarson
2023-04-18 14:23               ` kobarity
2023-04-20  8:22                 ` Eli Zaretskii
2023-04-20 13:40                   ` Gustaf Waldemarson
2023-04-20 14:19                     ` kobarity
2023-04-20 17:44                       ` Gustaf Waldemarson
2023-04-22  9:33                       ` Eli Zaretskii

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CABehr5ffFuykHkieRRX+zTSZF0t_qv3fd86USZZfET+Qc+se1g@mail.gmail.com \
    --to=gustaf.waldemarson@gmail.com \
    --cc=62696@debbugs.gnu.org \
    --cc=kobarity@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.