From 0137922173eb3655aa0d9787991ecb62602e47c9 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Fabi=C3=A1n=20Ezequiel=20Gallina?= Date: Wed, 25 Dec 2013 15:07:31 -0300 Subject: [PATCH] * lisp/progmodes/python.el: (python-nav--lisp-forward-sexp): New function. (python-nav--lisp-forward-sexp-safe): Use it. Rename from python-nav-lisp-forward-sexp-safe. (python-nav--forward-sexp): New argument SAFE allows switching forward sexp movement behavior for parens. (python-nav-forward-sexp): Throw errors on unterminated parens. (python-nav-backward-sexp, python-nav-forward-sexp-safe) (python-nav-backward-sexp-safe): New functions. (python-shell-buffer-substring): Use `python-nav-forward-sexp-safe'. * test/automated/python-tests.el (python-nav-lisp-forward-sexp-safe-1): Remove test. (python-nav-forward-sexp-safe-1): New test. Fixes: debbugs:16191 --- lisp/ChangeLog | 15 ++++++ lisp/progmodes/python.el | 88 ++++++++++++++++++++++++---------- test/ChangeLog | 6 +++ test/automated/python-tests.el | 45 ++++++++--------- 4 files changed, 108 insertions(+), 46 deletions(-) diff --git a/lisp/ChangeLog b/lisp/ChangeLog index b1a76998639..cc4000428fc 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,18 @@ +2013-12-25 Fabián Ezequiel Gallina + + * progmodes/python.el: + (python-nav--lisp-forward-sexp): New function. + (python-nav--lisp-forward-sexp-safe): Use it. Rename from + python-nav-lisp-forward-sexp-safe. + (python-nav--forward-sexp): New argument SAFE allows switching + forward sexp movement behavior for parens. + (python-nav-forward-sexp): Throw errors on unterminated parens + (Bug#16191). + (python-nav-backward-sexp, python-nav-forward-sexp-safe) + (python-nav-backward-sexp-safe): New functions. + (python-shell-buffer-substring): Use + `python-nav-forward-sexp-safe'. + 2013-12-25 Lars Ingebrigtsen * net/shr.el (shr-find-fill-point): Don't break lines before a diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el index 07a8bba6b18..0646eade780 100644 --- a/lisp/progmodes/python.el +++ b/lisp/progmodes/python.el @@ -1424,25 +1424,36 @@ backward to previous block." (and (goto-char starting-pos) nil) (and (not (= (point) starting-pos)) (point-marker))))) -(defun python-nav-lisp-forward-sexp-safe (&optional arg) - "Safe version of standard `forward-sexp'. -When ARG > 0 move forward, else if ARG is < 0." - (or arg (setq arg 1)) +(defun python-nav--lisp-forward-sexp (&optional arg) + "Standard version `forward-sexp'. +It ignores completely the value of `forward-sexp-function' by +setting it to nil before calling `forward-sexp'. With positive +ARG move forward only one sexp, else move backwards." (let ((forward-sexp-function) - (paren-regexp - (if (> arg 0) (python-rx close-paren) (python-rx open-paren))) - (search-fn - (if (> arg 0) #'re-search-forward #'re-search-backward))) + (arg (if (or (not arg) (> arg 0)) 1 -1))) + (forward-sexp arg))) + +(defun python-nav--lisp-forward-sexp-safe (&optional arg) + "Safe version of standard `forward-sexp'. +When at end of sexp (i.e. looking at a opening/closing paren) +skips it instead of throwing an error. With positive ARG move +forward only one sexp, else move backwards." + (let* ((arg (if (or (not arg) (> arg 0)) 1 -1)) + (paren-regexp + (if (> arg 0) (python-rx close-paren) (python-rx open-paren))) + (search-fn + (if (> arg 0) #'re-search-forward #'re-search-backward))) (condition-case nil - (forward-sexp arg) + (python-nav--lisp-forward-sexp arg) (error (while (and (funcall search-fn paren-regexp nil t) (python-syntax-context 'paren))))))) -(defun python-nav--forward-sexp (&optional dir) +(defun python-nav--forward-sexp (&optional dir safe) "Move to forward sexp. -With positive Optional argument DIR direction move forward, else -backwards." +With positive optional argument DIR direction move forward, else +backwards. When optional argument SAFE is non-nil do not throw +errors when at end of sexp, skip it instead." (setq dir (or dir 1)) (unless (= dir 0) (let* ((forward-p (if (> dir 0) @@ -1460,7 +1471,9 @@ backwards." (eq (syntax-class (syntax-after (1- (point)))) (car (string-to-syntax ")"))))) ;; Inside a paren or looking at it, lisp knows what to do. - (python-nav-lisp-forward-sexp-safe dir)) + (if safe + (python-nav--lisp-forward-sexp-safe dir) + (python-nav--lisp-forward-sexp dir))) (t ;; This part handles the lispy feel of ;; `python-nav-forward-sexp'. Knowing everything about the @@ -1474,7 +1487,9 @@ backwards." ((python-info-end-of-statement-p) 'statement-end))) (next-sexp-pos (save-excursion - (python-nav-lisp-forward-sexp-safe dir) + (if safe + (python-nav--lisp-forward-sexp-safe dir) + (python-nav--lisp-forward-sexp dir)) (point))) (next-sexp-context (save-excursion @@ -1528,23 +1543,48 @@ backwards." (python-nav-beginning-of-statement)) (t (goto-char next-sexp-pos)))))))))) -(defun python-nav--backward-sexp () - "Move to backward sexp." - (python-nav--forward-sexp -1)) - (defun python-nav-forward-sexp (&optional arg) - "Move forward across one block of code. -With ARG, do it that many times. Negative arg -N means -move backward N times." + "Move forward across expressions. +With ARG, do it that many times. Negative arg -N means move +backward N times." + (interactive "^p") + (or arg (setq arg 1)) + (while (> arg 0) + (python-nav--forward-sexp 1) + (setq arg (1- arg))) + (while (< arg 0) + (python-nav--forward-sexp -1) + (setq arg (1+ arg)))) + +(defun python-nav-backward-sexp (&optional arg) + "Move backward across expressions. +With ARG, do it that many times. Negative arg -N means move +backward N times." + (interactive "^p") + (or arg (setq arg 1)) + (python-nav-forward-sexp (- arg))) + +(defun python-nav-forward-sexp-safe (&optional arg) + "Move forward safely across expressions. +With ARG, do it that many times. Negative arg -N means move +backward N times." (interactive "^p") (or arg (setq arg 1)) (while (> arg 0) - (python-nav--forward-sexp) + (python-nav--forward-sexp 1 t) (setq arg (1- arg))) (while (< arg 0) - (python-nav--backward-sexp) + (python-nav--forward-sexp -1 t) (setq arg (1+ arg)))) +(defun python-nav-backward-sexp-safe (&optional arg) + "Move backward safely across expressions. +With ARG, do it that many times. Negative arg -N means move +backward N times." + (interactive "^p") + (or arg (setq arg 1)) + (python-nav-forward-sexp-safe (- arg))) + (defun python-nav--up-list (&optional dir) "Internal implementation of `python-nav-up-list'. DIR is always 1 or -1 and comes sanitized from @@ -2212,7 +2252,7 @@ the python shell: (save-excursion (when (python-nav-if-name-main) (cons (point) - (progn (python-nav-forward-sexp) + (progn (python-nav-forward-sexp-safe) (point))))))) ;; Oh destructuring bind, how I miss you. (if-name-main-start (car if-name-main-start-end)) diff --git a/test/ChangeLog b/test/ChangeLog index cefdd2de9fd..1f4d5164e37 100644 --- a/test/ChangeLog +++ b/test/ChangeLog @@ -1,3 +1,9 @@ +2013-12-25 Fabián Ezequiel Gallina + + * automated/python-tests.el + (python-nav-lisp-forward-sexp-safe-1): Remove test. + (python-nav-forward-sexp-safe-1): New test. + 2013-12-20 Dmitry Gutov * automated/ruby-mode-tests.el: Add tests for diff --git a/test/automated/python-tests.el b/test/automated/python-tests.el index 5756507fc92..03667a74666 100644 --- a/test/automated/python-tests.el +++ b/test/automated/python-tests.el @@ -1339,28 +1339,6 @@ if request.user.is_authenticated(): (python-tests-look-at "if request.user.is_authenticated():" -1))))) -(ert-deftest python-nav-lisp-forward-sexp-safe-1 () - (python-tests-with-temp-buffer - " -profile = Profile.objects.create(user=request.user) -profile.notify() -" - (python-tests-look-at "profile =") - (python-nav-lisp-forward-sexp-safe 4) - (should (looking-at "(user=request.user)")) - (python-tests-look-at "user=request.user") - (python-nav-lisp-forward-sexp-safe -1) - (should (looking-at "(user=request.user)")) - (python-nav-lisp-forward-sexp-safe -4) - (should (looking-at "profile =")) - (python-tests-look-at "user=request.user") - (python-nav-lisp-forward-sexp-safe 3) - (should (looking-at ")")) - (python-nav-lisp-forward-sexp-safe 1) - (should (looking-at "$")) - (python-nav-lisp-forward-sexp-safe 1) - (should (looking-at ".notify()")))) - (ert-deftest python-nav-forward-sexp-1 () (python-tests-with-temp-buffer " @@ -1477,6 +1455,29 @@ def another_statement(): (python-nav-forward-sexp -1) (should (looking-at "from some_module import some_sub_module")))) +(ert-deftest python-nav-forward-sexp-safe-1 () + (python-tests-with-temp-buffer + " +profile = Profile.objects.create(user=request.user) +profile.notify() +" + (python-tests-look-at "profile =") + (python-nav-forward-sexp-safe 1) + (should (looking-at "$")) + (beginning-of-line 1) + (python-tests-look-at "user=request.user") + (python-nav-forward-sexp-safe -1) + (should (looking-at "(user=request.user)")) + (python-nav-forward-sexp-safe -4) + (should (looking-at "profile =")) + (python-tests-look-at "user=request.user") + (python-nav-forward-sexp-safe 3) + (should (looking-at ")")) + (python-nav-forward-sexp-safe 1) + (should (looking-at "$")) + (python-nav-forward-sexp-safe 1) + (should (looking-at "$")))) + (ert-deftest python-nav-up-list-1 () (python-tests-with-temp-buffer " -- 2.39.2