[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Emacs-diffs] master 659609d: python.el: Keep symmetry on sexp navigatio
From: |
Fabián Ezequiel Gallina |
Subject: |
[Emacs-diffs] master 659609d: python.el: Keep symmetry on sexp navigation with parens |
Date: |
Mon, 13 Apr 2015 01:44:05 +0000 |
branch: master
commit 659609d1820129217e8c4526b629feddf3416767
Author: Fabián Ezequiel Gallina <address@hidden>
Commit: Fabián Ezequiel Gallina <address@hidden>
python.el: Keep symmetry on sexp navigation with parens
Fixes: debbugs:19954
* lisp/progmodes/python.el
(python-nav--forward-sexp): Add argument skip-parens-p.
(python-nav-forward-sexp, python-nav-backward-sexp)
(python-nav-forward-sexp-safe)
(python-nav-backward-sexp-safe): Use it.
* test/automated/python-tests.el
(python-nav-forward-sexp-1): Fix test.
---
lisp/progmodes/python.el | 84 ++++++++++++++++++++++++++--------------
test/automated/python-tests.el | 25 ++++++++++--
2 files changed, 76 insertions(+), 33 deletions(-)
diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el
index 856ed32..c9774a1 100644
--- a/lisp/progmodes/python.el
+++ b/lisp/progmodes/python.el
@@ -1580,11 +1580,13 @@ forward only one sexp, else move backwards."
(while (and (funcall search-fn paren-regexp nil t)
(python-syntax-context 'paren)))))))
-(defun python-nav--forward-sexp (&optional dir safe)
+(defun python-nav--forward-sexp (&optional dir safe skip-parens-p)
"Move to forward sexp.
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."
+errors when at end of sexp, skip it instead. With optional
+argument SKIP-PARENS-P force sexp motion to ignore parenthised
+expressions when looking at them in either direction."
(setq dir (or dir 1))
(unless (= dir 0)
(let* ((forward-p (if (> dir 0)
@@ -1596,11 +1598,13 @@ errors when at end of sexp, skip it instead."
;; Inside of a string, get out of it.
(let ((forward-sexp-function))
(forward-sexp dir)))
- ((or (eq context-type 'paren)
- (and forward-p (looking-at (python-rx open-paren)))
- (and (not forward-p)
- (eq (syntax-class (syntax-after (1- (point))))
- (car (string-to-syntax ")")))))
+ ((and (not skip-parens-p)
+ (or (eq context-type 'paren)
+ (if forward-p
+ (eq (syntax-class (syntax-after (point)))
+ (car (string-to-syntax "(")))
+ (eq (syntax-class (syntax-after (1- (point))))
+ (car (string-to-syntax ")"))))))
;; Inside a paren or looking at it, lisp knows what to do.
(if safe
(python-nav--lisp-forward-sexp-safe dir)
@@ -1636,7 +1640,7 @@ errors when at end of sexp, skip it instead."
(cond ((and (not (eobp))
(python-info-current-line-empty-p))
(python-util-forward-comment dir)
- (python-nav--forward-sexp dir))
+ (python-nav--forward-sexp dir safe skip-parens-p))
((eq context 'block-start)
(python-nav-end-of-block))
((eq context 'statement-start)
@@ -1656,7 +1660,7 @@ errors when at end of sexp, skip it instead."
(cond ((and (not (bobp))
(python-info-current-line-empty-p))
(python-util-forward-comment dir)
- (python-nav--forward-sexp dir))
+ (python-nav--forward-sexp dir safe skip-parens-p))
((eq context 'block-end)
(python-nav-beginning-of-block))
((eq context 'statement-end)
@@ -1674,47 +1678,69 @@ errors when at end of sexp, skip it instead."
(python-nav-beginning-of-statement))
(t (goto-char next-sexp-pos))))))))))
-(defun python-nav-forward-sexp (&optional arg)
+(defun python-nav-forward-sexp (&optional arg safe skip-parens-p)
"Move forward across expressions.
With ARG, do it that many times. Negative arg -N means move
-backward N times."
+backward N times. When optional argument SAFE is non-nil do not
+throw errors when at end of sexp, skip it instead. With optional
+argument SKIP-PARENS-P force sexp motion to ignore parenthised
+expressions when looking at them in either direction (forced to t
+in interactive calls)."
(interactive "^p")
(or arg (setq arg 1))
+ ;; Do not follow parens on interactive calls. This hack to detect
+ ;; if the function was called interactively copes with the way
+ ;; `forward-sexp' works by calling `forward-sexp-function', losing
+ ;; interactive detection by checking `current-prefix-arg'. The
+ ;; reason to make this distinction is that lisp functions like
+ ;; `blink-matching-open' get confused causing issues like the one in
+ ;; Bug#16191. With this approach the user gets a simmetric behavior
+ ;; when working interactively while called functions expecting
+ ;; paren-based sexp motion work just fine.
+ (or
+ skip-parens-p
+ (setq skip-parens-p
+ (memq real-this-command
+ (list
+ #'forward-sexp #'backward-sexp
+ #'python-nav-forward-sexp #'python-nav-backward-sexp
+ #'python-nav-forward-sexp-safe #'python-nav-backward-sexp))))
(while (> arg 0)
- (python-nav--forward-sexp 1)
+ (python-nav--forward-sexp 1 safe skip-parens-p)
(setq arg (1- arg)))
(while (< arg 0)
- (python-nav--forward-sexp -1)
+ (python-nav--forward-sexp -1 safe skip-parens-p)
(setq arg (1+ arg))))
-(defun python-nav-backward-sexp (&optional arg)
+(defun python-nav-backward-sexp (&optional arg safe skip-parens-p)
"Move backward across expressions.
With ARG, do it that many times. Negative arg -N means move
-forward N times."
+forward N times. When optional argument SAFE is non-nil do not
+throw errors when at end of sexp, skip it instead. With optional
+argument SKIP-PARENS-P force sexp motion to ignore parenthised
+expressions when looking at them in either direction (forced to t
+in interactive calls)."
(interactive "^p")
(or arg (setq arg 1))
- (python-nav-forward-sexp (- arg)))
+ (python-nav-forward-sexp (- arg) safe skip-parens-p))
-(defun python-nav-forward-sexp-safe (&optional arg)
+(defun python-nav-forward-sexp-safe (&optional arg skip-parens-p)
"Move forward safely across expressions.
With ARG, do it that many times. Negative arg -N means move
-backward N times."
+backward N times. With optional argument SKIP-PARENS-P force
+sexp motion to ignore parenthised expressions when looking at
+them in either direction (forced to t in interactive calls)."
(interactive "^p")
- (or arg (setq arg 1))
- (while (> arg 0)
- (python-nav--forward-sexp 1 t)
- (setq arg (1- arg)))
- (while (< arg 0)
- (python-nav--forward-sexp -1 t)
- (setq arg (1+ arg))))
+ (python-nav-forward-sexp arg t skip-parens-p))
-(defun python-nav-backward-sexp-safe (&optional arg)
+(defun python-nav-backward-sexp-safe (&optional arg skip-parens-p)
"Move backward safely across expressions.
With ARG, do it that many times. Negative arg -N means move
-forward N times."
+forward N times. With optional argument SKIP-PARENS-P force sexp
+motion to ignore parenthised expressions when looking at them in
+either direction (forced to t in interactive calls)."
(interactive "^p")
- (or arg (setq arg 1))
- (python-nav-forward-sexp-safe (- arg)))
+ (python-nav-backward-sexp arg t skip-parens-p))
(defun python-nav--up-list (&optional dir)
"Internal implementation of `python-nav-up-list'.
diff --git a/test/automated/python-tests.el b/test/automated/python-tests.el
index 47264c3..ae4323b 100644
--- a/test/automated/python-tests.el
+++ b/test/automated/python-tests.el
@@ -1998,19 +1998,36 @@ c()
(should (save-excursion
(beginning-of-line)
(looking-at "c()")))
- ;; Movement next to a paren should do what lisp does and
- ;; unfortunately It can't change, because otherwise
- ;; `blink-matching-open' breaks.
+ ;; The default behavior when next to a paren should do what lisp
+ ;; does and, otherwise `blink-matching-open' breaks.
(python-nav-forward-sexp -1)
(should (looking-at "()"))
(should (save-excursion
(beginning-of-line)
(looking-at "c()")))
- (python-nav-forward-sexp -1)
+ (end-of-line)
+ ;; Skipping parens should jump to `bolp'
+ (python-nav-forward-sexp -1 nil t)
(should (looking-at "c()"))
+ (forward-line -1)
+ (end-of-line)
+ ;; b()
+ (python-nav-forward-sexp -1)
+ (should (looking-at "()"))
(python-nav-forward-sexp -1)
(should (looking-at "b()"))
+ (end-of-line)
+ (python-nav-forward-sexp -1 nil t)
+ (should (looking-at "b()"))
+ (forward-line -1)
+ (end-of-line)
+ ;; a()
(python-nav-forward-sexp -1)
+ (should (looking-at "()"))
+ (python-nav-forward-sexp -1)
+ (should (looking-at "a()"))
+ (end-of-line)
+ (python-nav-forward-sexp -1 nil t)
(should (looking-at "a()"))))
(ert-deftest python-nav-forward-sexp-2 ()
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Emacs-diffs] master 659609d: python.el: Keep symmetry on sexp navigation with parens,
Fabián Ezequiel Gallina <=