Subject: bug#40563: 28.0.50; Narrow to defun in python buffer

From: Tomas Nordin <[email-masked]>
Date: Sun, 13 Dec 2020 14:32:38 +0100

Hello

Lars Ingebrigtsen <[email-masked]> writes:

> Tomas Nordin <[email-masked]> writes:
>
>> I then noticed that placing point just below the class definition and
>> then narrow works as expected. But I think the recipe way should work as
>> well. And even if not, this behavior is confusing.
>
> This bug is still present on the trunk.
>
> The problem is most easily reproduced by calling the
>
>   (python-nav--beginning-of-defun)
>
> function directly.  If point is on the first line, then this function
> won't do the right thing:
>
> def a1(self):
>     pass

Attached is a patch that fix the problems described in this report. The
change of variable name 'beg-indentation' to 'body-indentation' is not
part of the fix, but something I did during study making it easier for
me to understand the meaning of it. Feel free to disagree on that
change. The naming beg-indentation does not re-occur in python.el

The patch mean to say it might be necessary to move forward on the line
before search if point start off at the beginning of the defun, to allow
re-search-backward to succeed on the intended place.

The patch fixes this report, but it doesn't allow narrowing nested
python defuns (like a def in a class). For that I think it is necassary
to look at narrow-to-defun. I intend to suggest something about that in
another report.

What do you think?

Best regards
--
Tomas

diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el
index e9c3b3986a..32ffc5a9d6 100644
--- a/lisp/progmodes/python.el
+++ b/lisp/progmodes/python.el
@@ -1404,7 +1404,7 @@ python-nav--beginning-of-defun
          (line-beg-pos (line-beginning-position))
          (line-content-start (+ line-beg-pos (current-indentation)))
          (pos (point-marker))
-         (beg-indentation
+         (body-indentation
           (and (> arg 0)
                (save-excursion
                  (while (and
@@ -1415,9 +1415,16 @@ python-nav--beginning-of-defun
                      0))))
          (found
           (progn
-            (when (and (< arg 0)
-                       (python-info-looking-at-beginning-of-defun))
+            (when (and (python-info-looking-at-beginning-of-defun)
+                       (or (< arg 0)
+                           ;; If looking at beginning of defun, and if
+                           ;; pos is > line-content-start, ensure a
+                           ;; backward re search match this defun by
+                           ;; going to end of line before calling
+                           ;; re-search-fn bug#40563
+                           (and (> arg 0) (> pos line-content-start))))
               (end-of-line 1))
+
             (while (and (funcall re-search-fn
                                  python-nav-beginning-of-defun-regexp nil t)
                         (or (python-syntax-context-type)
@@ -1425,7 +1432,7 @@ python-nav--beginning-of-defun
                             ;; backwards by checking indentation.
                             (and (> arg 0)
                                  (not (= (current-indentation) 0))
-                                 (>= (current-indentation) beg-indentation)))))
+                                 (>= (current-indentation) body-indentation)))))
             (and (python-info-looking-at-beginning-of-defun)
                  (or (not (= (line-number-at-pos pos)
                              (line-number-at-pos)))