From: kobarity Date: Tue, 21 Jun 2022 11:37:08 +0000 (+0200) Subject: Fix nested defuns handling in `python-nav-beginning-of-defun' X-Git-Tag: emacs-29.0.90~1447^2~1566 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=3491c7a322dd3d7b67f52a90605181c51fbe5881;p=emacs.git Fix nested defuns handling in `python-nav-beginning-of-defun' * lisp/progmodes/python.el (python-nav--beginning-of-defun): Fix handling of nested defuns (bug#56105). --- diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el index c2483436fe9..e0c937d7ce5 100644 --- a/lisp/progmodes/python.el +++ b/lisp/progmodes/python.el @@ -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)) diff --git a/test/lisp/progmodes/python-tests.el b/test/lisp/progmodes/python-tests.el index 8db0a07170d..e17bc0df925 100644 --- a/test/lisp/progmodes/python-tests.el +++ b/test/lisp/progmodes/python-tests.el @@ -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))))) + ;;; 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))