aboutsummaryrefslogtreecommitdiffstats
path: root/lisp/progmodes/python.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/progmodes/python.el')
-rw-r--r--lisp/progmodes/python.el112
1 files changed, 79 insertions, 33 deletions
diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el
index aeee179c7e7..0646eade780 100644
--- a/lisp/progmodes/python.el
+++ b/lisp/progmodes/python.el
@@ -1279,15 +1279,21 @@ nested definitions."
1279(defun python-nav-beginning-of-statement () 1279(defun python-nav-beginning-of-statement ()
1280 "Move to start of current statement." 1280 "Move to start of current statement."
1281 (interactive "^") 1281 (interactive "^")
1282 (while (and (or (back-to-indentation) t) 1282 (back-to-indentation)
1283 (not (bobp)) 1283 (let* ((ppss (syntax-ppss))
1284 (when (or 1284 (context-point
1285 (save-excursion 1285 (or
1286 (forward-line -1) 1286 (python-syntax-context 'paren ppss)
1287 (python-info-line-ends-backslash-p)) 1287 (python-syntax-context 'string ppss))))
1288 (python-syntax-context 'string) 1288 (cond ((bobp))
1289 (python-syntax-context 'paren)) 1289 (context-point
1290 (forward-line -1)))) 1290 (goto-char context-point)
1291 (python-nav-beginning-of-statement))
1292 ((save-excursion
1293 (forward-line -1)
1294 (python-info-line-ends-backslash-p))
1295 (forward-line -1)
1296 (python-nav-beginning-of-statement))))
1291 (point-marker)) 1297 (point-marker))
1292 1298
1293(defun python-nav-end-of-statement (&optional noend) 1299(defun python-nav-end-of-statement (&optional noend)
@@ -1418,25 +1424,36 @@ backward to previous block."
1418 (and (goto-char starting-pos) nil) 1424 (and (goto-char starting-pos) nil)
1419 (and (not (= (point) starting-pos)) (point-marker))))) 1425 (and (not (= (point) starting-pos)) (point-marker)))))
1420 1426
1421(defun python-nav-lisp-forward-sexp-safe (&optional arg) 1427(defun python-nav--lisp-forward-sexp (&optional arg)
1422 "Safe version of standard `forward-sexp'. 1428 "Standard version `forward-sexp'.
1423When ARG > 0 move forward, else if ARG is < 0." 1429It ignores completely the value of `forward-sexp-function' by
1424 (or arg (setq arg 1)) 1430setting it to nil before calling `forward-sexp'. With positive
1431ARG move forward only one sexp, else move backwards."
1425 (let ((forward-sexp-function) 1432 (let ((forward-sexp-function)
1426 (paren-regexp 1433 (arg (if (or (not arg) (> arg 0)) 1 -1)))
1427 (if (> arg 0) (python-rx close-paren) (python-rx open-paren))) 1434 (forward-sexp arg)))
1428 (search-fn 1435
1429 (if (> arg 0) #'re-search-forward #'re-search-backward))) 1436(defun python-nav--lisp-forward-sexp-safe (&optional arg)
1437 "Safe version of standard `forward-sexp'.
1438When at end of sexp (i.e. looking at a opening/closing paren)
1439skips it instead of throwing an error. With positive ARG move
1440forward only one sexp, else move backwards."
1441 (let* ((arg (if (or (not arg) (> arg 0)) 1 -1))
1442 (paren-regexp
1443 (if (> arg 0) (python-rx close-paren) (python-rx open-paren)))
1444 (search-fn
1445 (if (> arg 0) #'re-search-forward #'re-search-backward)))
1430 (condition-case nil 1446 (condition-case nil
1431 (forward-sexp arg) 1447 (python-nav--lisp-forward-sexp arg)
1432 (error 1448 (error
1433 (while (and (funcall search-fn paren-regexp nil t) 1449 (while (and (funcall search-fn paren-regexp nil t)
1434 (python-syntax-context 'paren))))))) 1450 (python-syntax-context 'paren)))))))
1435 1451
1436(defun python-nav--forward-sexp (&optional dir) 1452(defun python-nav--forward-sexp (&optional dir safe)
1437 "Move to forward sexp. 1453 "Move to forward sexp.
1438With positive Optional argument DIR direction move forward, else 1454With positive optional argument DIR direction move forward, else
1439backwards." 1455backwards. When optional argument SAFE is non-nil do not throw
1456errors when at end of sexp, skip it instead."
1440 (setq dir (or dir 1)) 1457 (setq dir (or dir 1))
1441 (unless (= dir 0) 1458 (unless (= dir 0)
1442 (let* ((forward-p (if (> dir 0) 1459 (let* ((forward-p (if (> dir 0)
@@ -1454,7 +1471,9 @@ backwards."
1454 (eq (syntax-class (syntax-after (1- (point)))) 1471 (eq (syntax-class (syntax-after (1- (point))))
1455 (car (string-to-syntax ")"))))) 1472 (car (string-to-syntax ")")))))
1456 ;; Inside a paren or looking at it, lisp knows what to do. 1473 ;; Inside a paren or looking at it, lisp knows what to do.
1457 (python-nav-lisp-forward-sexp-safe dir)) 1474 (if safe
1475 (python-nav--lisp-forward-sexp-safe dir)
1476 (python-nav--lisp-forward-sexp dir)))
1458 (t 1477 (t
1459 ;; This part handles the lispy feel of 1478 ;; This part handles the lispy feel of
1460 ;; `python-nav-forward-sexp'. Knowing everything about the 1479 ;; `python-nav-forward-sexp'. Knowing everything about the
@@ -1468,7 +1487,9 @@ backwards."
1468 ((python-info-end-of-statement-p) 'statement-end))) 1487 ((python-info-end-of-statement-p) 'statement-end)))
1469 (next-sexp-pos 1488 (next-sexp-pos
1470 (save-excursion 1489 (save-excursion
1471 (python-nav-lisp-forward-sexp-safe dir) 1490 (if safe
1491 (python-nav--lisp-forward-sexp-safe dir)
1492 (python-nav--lisp-forward-sexp dir))
1472 (point))) 1493 (point)))
1473 (next-sexp-context 1494 (next-sexp-context
1474 (save-excursion 1495 (save-excursion
@@ -1522,23 +1543,48 @@ backwards."
1522 (python-nav-beginning-of-statement)) 1543 (python-nav-beginning-of-statement))
1523 (t (goto-char next-sexp-pos)))))))))) 1544 (t (goto-char next-sexp-pos))))))))))
1524 1545
1525(defun python-nav--backward-sexp ()
1526 "Move to backward sexp."
1527 (python-nav--forward-sexp -1))
1528
1529(defun python-nav-forward-sexp (&optional arg) 1546(defun python-nav-forward-sexp (&optional arg)
1530 "Move forward across one block of code. 1547 "Move forward across expressions.
1531With ARG, do it that many times. Negative arg -N means 1548With ARG, do it that many times. Negative arg -N means move
1532move backward N times." 1549backward N times."
1533 (interactive "^p") 1550 (interactive "^p")
1534 (or arg (setq arg 1)) 1551 (or arg (setq arg 1))
1535 (while (> arg 0) 1552 (while (> arg 0)
1536 (python-nav--forward-sexp) 1553 (python-nav--forward-sexp 1)
1537 (setq arg (1- arg))) 1554 (setq arg (1- arg)))
1538 (while (< arg 0) 1555 (while (< arg 0)
1539 (python-nav--backward-sexp) 1556 (python-nav--forward-sexp -1)
1540 (setq arg (1+ arg)))) 1557 (setq arg (1+ arg))))
1541 1558
1559(defun python-nav-backward-sexp (&optional arg)
1560 "Move backward across expressions.
1561With ARG, do it that many times. Negative arg -N means move
1562backward N times."
1563 (interactive "^p")
1564 (or arg (setq arg 1))
1565 (python-nav-forward-sexp (- arg)))
1566
1567(defun python-nav-forward-sexp-safe (&optional arg)
1568 "Move forward safely across expressions.
1569With ARG, do it that many times. Negative arg -N means move
1570backward N times."
1571 (interactive "^p")
1572 (or arg (setq arg 1))
1573 (while (> arg 0)
1574 (python-nav--forward-sexp 1 t)
1575 (setq arg (1- arg)))
1576 (while (< arg 0)
1577 (python-nav--forward-sexp -1 t)
1578 (setq arg (1+ arg))))
1579
1580(defun python-nav-backward-sexp-safe (&optional arg)
1581 "Move backward safely across expressions.
1582With ARG, do it that many times. Negative arg -N means move
1583backward N times."
1584 (interactive "^p")
1585 (or arg (setq arg 1))
1586 (python-nav-forward-sexp-safe (- arg)))
1587
1542(defun python-nav--up-list (&optional dir) 1588(defun python-nav--up-list (&optional dir)
1543 "Internal implementation of `python-nav-up-list'. 1589 "Internal implementation of `python-nav-up-list'.
1544DIR is always 1 or -1 and comes sanitized from 1590DIR is always 1 or -1 and comes sanitized from
@@ -2206,7 +2252,7 @@ the python shell:
2206 (save-excursion 2252 (save-excursion
2207 (when (python-nav-if-name-main) 2253 (when (python-nav-if-name-main)
2208 (cons (point) 2254 (cons (point)
2209 (progn (python-nav-forward-sexp) 2255 (progn (python-nav-forward-sexp-safe)
2210 (point))))))) 2256 (point)))))))
2211 ;; Oh destructuring bind, how I miss you. 2257 ;; Oh destructuring bind, how I miss you.
2212 (if-name-main-start (car if-name-main-start-end)) 2258 (if-name-main-start (car if-name-main-start-end))