]> git.eshelyaron.com Git - emacs.git/commitdiff
Fix nested defuns handling in `python-nav-beginning-of-defun'
authorkobarity <kobarity@gmail.com>
Tue, 21 Jun 2022 11:37:08 +0000 (13:37 +0200)
committerLars Ingebrigtsen <larsi@gnus.org>
Tue, 21 Jun 2022 11:37:08 +0000 (13:37 +0200)
* lisp/progmodes/python.el (python-nav--beginning-of-defun): Fix
handling of nested defuns (bug#56105).

lisp/progmodes/python.el
test/lisp/progmodes/python-tests.el

index c2483436fe90ca87d7fb6aab74b2a327369c5d03..e0c937d7ce51f204c6f0a85312d55394a50376b9 100644 (file)
@@ -1455,11 +1455,17 @@ With positive ARG search backwards, else search forwards."
          (line-beg-pos (line-beginning-position))
          (line-content-start (+ line-beg-pos (current-indentation)))
          (pos (point-marker))
+         (min-indentation (+ (current-indentation)
+                             (if (python-info-looking-at-beginning-of-defun)
+                                 python-indent-offset 0)))
          (body-indentation
           (and (> arg 0)
                (save-excursion
                  (while (and
-                         (not (python-info-looking-at-beginning-of-defun))
+                         (or (not (python-info-looking-at-beginning-of-defun))
+                             (>= (current-indentation) min-indentation))
+                         (setq min-indentation
+                               (min min-indentation (current-indentation)))
                          (python-nav-backward-block)))
                  (or (and (python-info-looking-at-beginning-of-defun)
                           (+ (current-indentation) python-indent-offset))
index 8db0a07170de319ab6d0d5a2f0e559719c033d99..e17bc0df92534b6c9950d0c6227db8f2e878304b 100644 (file)
@@ -1736,6 +1736,27 @@ class C:
      (should (= (marker-position (mark-marker))
                 expected-mark-end-position)))))
 
+(ert-deftest python-mark-defun-4 ()
+  "Test `python-mark-defun' with nested functions."
+  (python-tests-with-temp-buffer
+   "
+def foo(x):
+    def bar():
+        return x
+    if True:
+        return bar
+"
+   (let ((expected-mark-beginning-position
+          (progn
+            (python-tests-look-at "def foo(x):")
+            (1- (line-beginning-position))))
+         (expected-mark-end-position (point-max)))
+     (python-tests-look-at "return bar")
+     (python-mark-defun 1)
+     (should (= (point) expected-mark-beginning-position))
+     (should (= (marker-position (mark-marker))
+                expected-mark-end-position)))))
+
 \f
 ;;; Navigation
 
@@ -1762,12 +1783,20 @@ def decoratorFunctionWithArguments(arg1, arg2, arg3):
         return wrapped_f
     return wwrap
 "
-   (python-tests-look-at "return wrap")
+   (python-tests-look-at "return wwrap")
    (should (= (save-excursion
                 (python-nav-beginning-of-defun)
                 (point))
               (save-excursion
-                (python-tests-look-at "def wrapped_f(*args):" -1)
+                (python-tests-look-at "def decoratorFunctionWithArguments" -1)
+                (beginning-of-line)
+                (point))))
+   (python-tests-look-at "return wrap" -1)
+   (should (= (save-excursion
+                (python-nav-beginning-of-defun)
+                (point))
+              (save-excursion
+                (python-tests-look-at "def wwrap(f):" -1)
                 (beginning-of-line)
                 (point))))
    (python-tests-look-at "def wrapped_f(*args):" -1)
@@ -1801,11 +1830,23 @@ class C(object):
         def a():
             pass
 
+        if True:
+            return a
+
     def c(self):
         pass
 "
    ;; Nested defuns, are handled with care.
    (python-tests-look-at "def c(self):")
+   (should (= (save-excursion
+                (python-nav-beginning-of-defun)
+                (point))
+              (save-excursion
+                (python-tests-look-at "def m(self):" -1)
+                (beginning-of-line)
+                (point))))
+   ;; Nested defuns shuld be skipped.
+   (python-tests-look-at "return a" -1)
    (should (= (save-excursion
                 (python-nav-beginning-of-defun)
                 (point))