aboutsummaryrefslogtreecommitdiffstats
path: root/lisp/progmodes/python.el
diff options
context:
space:
mode:
authorFabián Ezequiel Gallina2015-04-12 22:43:44 -0300
committerFabián Ezequiel Gallina2015-04-12 22:43:44 -0300
commit659609d1820129217e8c4526b629feddf3416767 (patch)
tree0c3e47ff0f8852d6b60fc29d781cb9930e5732a9 /lisp/progmodes/python.el
parented28ca4c2429059608178d3d477dd169aae1f476 (diff)
downloademacs-659609d1820129217e8c4526b629feddf3416767.tar.gz
emacs-659609d1820129217e8c4526b629feddf3416767.zip
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.
Diffstat (limited to 'lisp/progmodes/python.el')
-rw-r--r--lisp/progmodes/python.el84
1 files changed, 55 insertions, 29 deletions
diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el
index 856ed322ec6..c9774a15bbb 100644
--- a/lisp/progmodes/python.el
+++ b/lisp/progmodes/python.el
@@ -1580,11 +1580,13 @@ forward only one sexp, else move backwards."
1580 (while (and (funcall search-fn paren-regexp nil t) 1580 (while (and (funcall search-fn paren-regexp nil t)
1581 (python-syntax-context 'paren))))))) 1581 (python-syntax-context 'paren)))))))
1582 1582
1583(defun python-nav--forward-sexp (&optional dir safe) 1583(defun python-nav--forward-sexp (&optional dir safe skip-parens-p)
1584 "Move to forward sexp. 1584 "Move to forward sexp.
1585With positive optional argument DIR direction move forward, else 1585With positive optional argument DIR direction move forward, else
1586backwards. When optional argument SAFE is non-nil do not throw 1586backwards. When optional argument SAFE is non-nil do not throw
1587errors when at end of sexp, skip it instead." 1587errors when at end of sexp, skip it instead. With optional
1588argument SKIP-PARENS-P force sexp motion to ignore parenthised
1589expressions when looking at them in either direction."
1588 (setq dir (or dir 1)) 1590 (setq dir (or dir 1))
1589 (unless (= dir 0) 1591 (unless (= dir 0)
1590 (let* ((forward-p (if (> dir 0) 1592 (let* ((forward-p (if (> dir 0)
@@ -1596,11 +1598,13 @@ errors when at end of sexp, skip it instead."
1596 ;; Inside of a string, get out of it. 1598 ;; Inside of a string, get out of it.
1597 (let ((forward-sexp-function)) 1599 (let ((forward-sexp-function))
1598 (forward-sexp dir))) 1600 (forward-sexp dir)))
1599 ((or (eq context-type 'paren) 1601 ((and (not skip-parens-p)
1600 (and forward-p (looking-at (python-rx open-paren))) 1602 (or (eq context-type 'paren)
1601 (and (not forward-p) 1603 (if forward-p
1602 (eq (syntax-class (syntax-after (1- (point)))) 1604 (eq (syntax-class (syntax-after (point)))
1603 (car (string-to-syntax ")"))))) 1605 (car (string-to-syntax "(")))
1606 (eq (syntax-class (syntax-after (1- (point))))
1607 (car (string-to-syntax ")"))))))
1604 ;; Inside a paren or looking at it, lisp knows what to do. 1608 ;; Inside a paren or looking at it, lisp knows what to do.
1605 (if safe 1609 (if safe
1606 (python-nav--lisp-forward-sexp-safe dir) 1610 (python-nav--lisp-forward-sexp-safe dir)
@@ -1636,7 +1640,7 @@ errors when at end of sexp, skip it instead."
1636 (cond ((and (not (eobp)) 1640 (cond ((and (not (eobp))
1637 (python-info-current-line-empty-p)) 1641 (python-info-current-line-empty-p))
1638 (python-util-forward-comment dir) 1642 (python-util-forward-comment dir)
1639 (python-nav--forward-sexp dir)) 1643 (python-nav--forward-sexp dir safe skip-parens-p))
1640 ((eq context 'block-start) 1644 ((eq context 'block-start)
1641 (python-nav-end-of-block)) 1645 (python-nav-end-of-block))
1642 ((eq context 'statement-start) 1646 ((eq context 'statement-start)
@@ -1656,7 +1660,7 @@ errors when at end of sexp, skip it instead."
1656 (cond ((and (not (bobp)) 1660 (cond ((and (not (bobp))
1657 (python-info-current-line-empty-p)) 1661 (python-info-current-line-empty-p))
1658 (python-util-forward-comment dir) 1662 (python-util-forward-comment dir)
1659 (python-nav--forward-sexp dir)) 1663 (python-nav--forward-sexp dir safe skip-parens-p))
1660 ((eq context 'block-end) 1664 ((eq context 'block-end)
1661 (python-nav-beginning-of-block)) 1665 (python-nav-beginning-of-block))
1662 ((eq context 'statement-end) 1666 ((eq context 'statement-end)
@@ -1674,47 +1678,69 @@ errors when at end of sexp, skip it instead."
1674 (python-nav-beginning-of-statement)) 1678 (python-nav-beginning-of-statement))
1675 (t (goto-char next-sexp-pos)))))))))) 1679 (t (goto-char next-sexp-pos))))))))))
1676 1680
1677(defun python-nav-forward-sexp (&optional arg) 1681(defun python-nav-forward-sexp (&optional arg safe skip-parens-p)
1678 "Move forward across expressions. 1682 "Move forward across expressions.
1679With ARG, do it that many times. Negative arg -N means move 1683With ARG, do it that many times. Negative arg -N means move
1680backward N times." 1684backward N times. When optional argument SAFE is non-nil do not
1685throw errors when at end of sexp, skip it instead. With optional
1686argument SKIP-PARENS-P force sexp motion to ignore parenthised
1687expressions when looking at them in either direction (forced to t
1688in interactive calls)."
1681 (interactive "^p") 1689 (interactive "^p")
1682 (or arg (setq arg 1)) 1690 (or arg (setq arg 1))
1691 ;; Do not follow parens on interactive calls. This hack to detect
1692 ;; if the function was called interactively copes with the way
1693 ;; `forward-sexp' works by calling `forward-sexp-function', losing
1694 ;; interactive detection by checking `current-prefix-arg'. The
1695 ;; reason to make this distinction is that lisp functions like
1696 ;; `blink-matching-open' get confused causing issues like the one in
1697 ;; Bug#16191. With this approach the user gets a simmetric behavior
1698 ;; when working interactively while called functions expecting
1699 ;; paren-based sexp motion work just fine.
1700 (or
1701 skip-parens-p
1702 (setq skip-parens-p
1703 (memq real-this-command
1704 (list
1705 #'forward-sexp #'backward-sexp
1706 #'python-nav-forward-sexp #'python-nav-backward-sexp
1707 #'python-nav-forward-sexp-safe #'python-nav-backward-sexp))))
1683 (while (> arg 0) 1708 (while (> arg 0)
1684 (python-nav--forward-sexp 1) 1709 (python-nav--forward-sexp 1 safe skip-parens-p)
1685 (setq arg (1- arg))) 1710 (setq arg (1- arg)))
1686 (while (< arg 0) 1711 (while (< arg 0)
1687 (python-nav--forward-sexp -1) 1712 (python-nav--forward-sexp -1 safe skip-parens-p)
1688 (setq arg (1+ arg)))) 1713 (setq arg (1+ arg))))
1689 1714
1690(defun python-nav-backward-sexp (&optional arg) 1715(defun python-nav-backward-sexp (&optional arg safe skip-parens-p)
1691 "Move backward across expressions. 1716 "Move backward across expressions.
1692With ARG, do it that many times. Negative arg -N means move 1717With ARG, do it that many times. Negative arg -N means move
1693forward N times." 1718forward N times. When optional argument SAFE is non-nil do not
1719throw errors when at end of sexp, skip it instead. With optional
1720argument SKIP-PARENS-P force sexp motion to ignore parenthised
1721expressions when looking at them in either direction (forced to t
1722in interactive calls)."
1694 (interactive "^p") 1723 (interactive "^p")
1695 (or arg (setq arg 1)) 1724 (or arg (setq arg 1))
1696 (python-nav-forward-sexp (- arg))) 1725 (python-nav-forward-sexp (- arg) safe skip-parens-p))
1697 1726
1698(defun python-nav-forward-sexp-safe (&optional arg) 1727(defun python-nav-forward-sexp-safe (&optional arg skip-parens-p)
1699 "Move forward safely across expressions. 1728 "Move forward safely across expressions.
1700With ARG, do it that many times. Negative arg -N means move 1729With ARG, do it that many times. Negative arg -N means move
1701backward N times." 1730backward N times. With optional argument SKIP-PARENS-P force
1731sexp motion to ignore parenthised expressions when looking at
1732them in either direction (forced to t in interactive calls)."
1702 (interactive "^p") 1733 (interactive "^p")
1703 (or arg (setq arg 1)) 1734 (python-nav-forward-sexp arg t skip-parens-p))
1704 (while (> arg 0)
1705 (python-nav--forward-sexp 1 t)
1706 (setq arg (1- arg)))
1707 (while (< arg 0)
1708 (python-nav--forward-sexp -1 t)
1709 (setq arg (1+ arg))))
1710 1735
1711(defun python-nav-backward-sexp-safe (&optional arg) 1736(defun python-nav-backward-sexp-safe (&optional arg skip-parens-p)
1712 "Move backward safely across expressions. 1737 "Move backward safely across expressions.
1713With ARG, do it that many times. Negative arg -N means move 1738With ARG, do it that many times. Negative arg -N means move
1714forward N times." 1739forward N times. With optional argument SKIP-PARENS-P force sexp
1740motion to ignore parenthised expressions when looking at them in
1741either direction (forced to t in interactive calls)."
1715 (interactive "^p") 1742 (interactive "^p")
1716 (or arg (setq arg 1)) 1743 (python-nav-backward-sexp arg t skip-parens-p))
1717 (python-nav-forward-sexp-safe (- arg)))
1718 1744
1719(defun python-nav--up-list (&optional dir) 1745(defun python-nav--up-list (&optional dir)
1720 "Internal implementation of `python-nav-up-list'. 1746 "Internal implementation of `python-nav-up-list'.