Fix `python-nav-beginning-of-defun' line continuation using backslash

* lisp/progmodes/python.el (python-nav--beginning-of-defun): Allow
line continuation using backslash in defuns (bug#55702).
(python-info-looking-at-beginning-of-defun): Add CHECK-STATEMENT
argument.
This commit is contained in:
kobarity 2022-07-03 14:22:13 +02:00 committed by Lars Ingebrigtsen
parent c61c647f72
commit 6e2f9dd3dd
2 changed files with 97 additions and 9 deletions

View file

@ -1472,15 +1472,17 @@ With positive ARG search backwards, else search forwards."
0))))
(found
(progn
(when (and (python-info-looking-at-beginning-of-defun)
(when (and (python-info-looking-at-beginning-of-defun nil t)
(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))
(and (> arg 0)
(or (python-info-continuation-line-p)
(> pos line-content-start)))))
(python-nav-end-of-statement))
(while (and (funcall re-search-fn
python-nav-beginning-of-defun-regexp nil t)
@ -1490,14 +1492,18 @@ With positive ARG search backwards, else search forwards."
(and (> arg 0)
(not (= (current-indentation) 0))
(>= (current-indentation) body-indentation)))))
(and (python-info-looking-at-beginning-of-defun)
(and (python-info-looking-at-beginning-of-defun nil t)
(or (not (= (line-number-at-pos pos)
(line-number-at-pos)))
(and (>= (point) line-beg-pos)
(<= (point) line-content-start)
(> pos line-content-start)))))))
(if found
(or (beginning-of-line 1) t)
(progn
(when (< arg 0)
(python-nav-beginning-of-statement))
(beginning-of-line 1)
t)
(and (goto-char pos) nil))))
(defun python-nav-beginning-of-defun (&optional arg)
@ -5299,10 +5305,15 @@ operator."
(forward-line -1)
(python-info-assignment-statement-p t))))
(defun python-info-looking-at-beginning-of-defun (&optional syntax-ppss)
"Check if point is at `beginning-of-defun' using SYNTAX-PPSS."
(defun python-info-looking-at-beginning-of-defun (&optional syntax-ppss
check-statement)
"Check if point is at `beginning-of-defun' using SYNTAX-PPSS.
When CHECK-STATEMENT is non-nil, the current statement is checked
instead of the current physical line."
(and (not (python-syntax-context-type (or syntax-ppss (syntax-ppss))))
(save-excursion
(when check-statement
(python-nav-beginning-of-statement))
(beginning-of-line 1)
(looking-at python-nav-beginning-of-defun-regexp))))

View file

@ -1757,6 +1757,36 @@ def foo(x):
(should (= (marker-position (mark-marker))
expected-mark-end-position)))))
(ert-deftest python-mark-defun-5 ()
"Test `python-mark-defun' with point inside backslash escaped defun."
(python-tests-with-temp-buffer
"
def \\
foo(x):
return x
"
(let ((transient-mark-mode t)
(expected-mark-beginning-position
(progn
(python-tests-look-at "def ")
(1- (line-beginning-position))))
(expected-mark-end-position
(save-excursion
(python-tests-look-at "return x")
(forward-line)
(point))))
(python-tests-look-at "def ")
(python-mark-defun 1)
(should (= (point) expected-mark-beginning-position))
(should (= (marker-position (mark-marker))
expected-mark-end-position))
(deactivate-mark)
(python-tests-look-at "foo(x)")
(python-mark-defun 1)
(should (= (point) expected-mark-beginning-position))
(should (= (marker-position (mark-marker))
expected-mark-end-position)))))
;;; Navigation
@ -1905,17 +1935,47 @@ class C(object):
(ert-deftest python-nav-beginning-of-defun-4 ()
(python-tests-with-temp-buffer
"
def a():
pass
def \\
a():
b():
return 0
def c():
pass
"
(python-tests-look-at "return 0")
(python-tests-look-at "def c():")
(should (= (save-excursion
(python-nav-beginning-of-defun)
(point))
(save-excursion
(python-tests-look-at "def \\" -1)
(beginning-of-line)
(point))))
(python-tests-look-at "return 0" -1)
(should (= (save-excursion
(python-nav-beginning-of-defun)
(point))
(save-excursion
(python-tests-look-at "def \\" -1)
(beginning-of-line)
(point))))
(python-tests-look-at "b():" -1)
(should (= (save-excursion
(python-nav-beginning-of-defun)
(point))
(save-excursion
(python-tests-look-at "def \\" -1)
(beginning-of-line)
(point))))
(python-tests-look-at "def a():" -1)
(should (= (save-excursion
(python-nav-beginning-of-defun -1)
(point))
(save-excursion
(python-tests-look-at "def \\")
(beginning-of-line)
(point))))))
(ert-deftest python-nav-end-of-defun-1 ()
@ -5242,6 +5302,23 @@ def decorat0r(deff):
(python-tests-look-at "deff()")
(should (not (python-info-looking-at-beginning-of-defun)))))
(ert-deftest python-info-looking-at-beginning-of-defun-2 ()
(python-tests-with-temp-buffer
"
def \\
foo(arg):
pass
"
(python-tests-look-at "def \\")
(should (python-info-looking-at-beginning-of-defun))
(should (python-info-looking-at-beginning-of-defun nil t))
(python-tests-look-at "foo(arg):")
(should (not (python-info-looking-at-beginning-of-defun)))
(should (python-info-looking-at-beginning-of-defun nil t))
(python-tests-look-at "pass")
(should (not (python-info-looking-at-beginning-of-defun)))
(should (not (python-info-looking-at-beginning-of-defun nil t)))))
(ert-deftest python-info-current-line-comment-p-1 ()
(python-tests-with-temp-buffer
"