diff options
| author | Fabián Ezequiel Gallina | 2013-12-25 15:07:31 -0300 |
|---|---|---|
| committer | Fabián Ezequiel Gallina | 2013-12-25 15:07:31 -0300 |
| commit | 0137922173eb3655aa0d9787991ecb62602e47c9 (patch) | |
| tree | dc87f15582fdd36b745acb750cb5e96004d8c5e3 /lisp/progmodes/python.el | |
| parent | 99e4926fcbee9f7e75ed19b194fa7a2aa59c98c1 (diff) | |
| download | emacs-0137922173eb3655aa0d9787991ecb62602e47c9.tar.gz emacs-0137922173eb3655aa0d9787991ecb62602e47c9.zip | |
* 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
Diffstat (limited to 'lisp/progmodes/python.el')
| -rw-r--r-- | lisp/progmodes/python.el | 88 |
1 files changed, 64 insertions, 24 deletions
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." | |||
| 1424 | (and (goto-char starting-pos) nil) | 1424 | (and (goto-char starting-pos) nil) |
| 1425 | (and (not (= (point) starting-pos)) (point-marker))))) | 1425 | (and (not (= (point) starting-pos)) (point-marker))))) |
| 1426 | 1426 | ||
| 1427 | (defun python-nav-lisp-forward-sexp-safe (&optional arg) | 1427 | (defun python-nav--lisp-forward-sexp (&optional arg) |
| 1428 | "Safe version of standard `forward-sexp'. | 1428 | "Standard version `forward-sexp'. |
| 1429 | When ARG > 0 move forward, else if ARG is < 0." | 1429 | It ignores completely the value of `forward-sexp-function' by |
| 1430 | (or arg (setq arg 1)) | 1430 | setting it to nil before calling `forward-sexp'. With positive |
| 1431 | ARG move forward only one sexp, else move backwards." | ||
| 1431 | (let ((forward-sexp-function) | 1432 | (let ((forward-sexp-function) |
| 1432 | (paren-regexp | 1433 | (arg (if (or (not arg) (> arg 0)) 1 -1))) |
| 1433 | (if (> arg 0) (python-rx close-paren) (python-rx open-paren))) | 1434 | (forward-sexp arg))) |
| 1434 | (search-fn | 1435 | |
| 1435 | (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'. | ||
| 1438 | When at end of sexp (i.e. looking at a opening/closing paren) | ||
| 1439 | skips it instead of throwing an error. With positive ARG move | ||
| 1440 | forward 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))) | ||
| 1436 | (condition-case nil | 1446 | (condition-case nil |
| 1437 | (forward-sexp arg) | 1447 | (python-nav--lisp-forward-sexp arg) |
| 1438 | (error | 1448 | (error |
| 1439 | (while (and (funcall search-fn paren-regexp nil t) | 1449 | (while (and (funcall search-fn paren-regexp nil t) |
| 1440 | (python-syntax-context 'paren))))))) | 1450 | (python-syntax-context 'paren))))))) |
| 1441 | 1451 | ||
| 1442 | (defun python-nav--forward-sexp (&optional dir) | 1452 | (defun python-nav--forward-sexp (&optional dir safe) |
| 1443 | "Move to forward sexp. | 1453 | "Move to forward sexp. |
| 1444 | With positive Optional argument DIR direction move forward, else | 1454 | With positive optional argument DIR direction move forward, else |
| 1445 | backwards." | 1455 | backwards. When optional argument SAFE is non-nil do not throw |
| 1456 | errors when at end of sexp, skip it instead." | ||
| 1446 | (setq dir (or dir 1)) | 1457 | (setq dir (or dir 1)) |
| 1447 | (unless (= dir 0) | 1458 | (unless (= dir 0) |
| 1448 | (let* ((forward-p (if (> dir 0) | 1459 | (let* ((forward-p (if (> dir 0) |
| @@ -1460,7 +1471,9 @@ backwards." | |||
| 1460 | (eq (syntax-class (syntax-after (1- (point)))) | 1471 | (eq (syntax-class (syntax-after (1- (point)))) |
| 1461 | (car (string-to-syntax ")"))))) | 1472 | (car (string-to-syntax ")"))))) |
| 1462 | ;; 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. |
| 1463 | (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))) | ||
| 1464 | (t | 1477 | (t |
| 1465 | ;; This part handles the lispy feel of | 1478 | ;; This part handles the lispy feel of |
| 1466 | ;; `python-nav-forward-sexp'. Knowing everything about the | 1479 | ;; `python-nav-forward-sexp'. Knowing everything about the |
| @@ -1474,7 +1487,9 @@ backwards." | |||
| 1474 | ((python-info-end-of-statement-p) 'statement-end))) | 1487 | ((python-info-end-of-statement-p) 'statement-end))) |
| 1475 | (next-sexp-pos | 1488 | (next-sexp-pos |
| 1476 | (save-excursion | 1489 | (save-excursion |
| 1477 | (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)) | ||
| 1478 | (point))) | 1493 | (point))) |
| 1479 | (next-sexp-context | 1494 | (next-sexp-context |
| 1480 | (save-excursion | 1495 | (save-excursion |
| @@ -1528,23 +1543,48 @@ backwards." | |||
| 1528 | (python-nav-beginning-of-statement)) | 1543 | (python-nav-beginning-of-statement)) |
| 1529 | (t (goto-char next-sexp-pos)))))))))) | 1544 | (t (goto-char next-sexp-pos)))))))))) |
| 1530 | 1545 | ||
| 1531 | (defun python-nav--backward-sexp () | ||
| 1532 | "Move to backward sexp." | ||
| 1533 | (python-nav--forward-sexp -1)) | ||
| 1534 | |||
| 1535 | (defun python-nav-forward-sexp (&optional arg) | 1546 | (defun python-nav-forward-sexp (&optional arg) |
| 1536 | "Move forward across one block of code. | 1547 | "Move forward across expressions. |
| 1537 | With ARG, do it that many times. Negative arg -N means | 1548 | With ARG, do it that many times. Negative arg -N means move |
| 1538 | move backward N times." | 1549 | backward N times." |
| 1550 | (interactive "^p") | ||
| 1551 | (or arg (setq arg 1)) | ||
| 1552 | (while (> arg 0) | ||
| 1553 | (python-nav--forward-sexp 1) | ||
| 1554 | (setq arg (1- arg))) | ||
| 1555 | (while (< arg 0) | ||
| 1556 | (python-nav--forward-sexp -1) | ||
| 1557 | (setq arg (1+ arg)))) | ||
| 1558 | |||
| 1559 | (defun python-nav-backward-sexp (&optional arg) | ||
| 1560 | "Move backward across expressions. | ||
| 1561 | With ARG, do it that many times. Negative arg -N means move | ||
| 1562 | backward 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. | ||
| 1569 | With ARG, do it that many times. Negative arg -N means move | ||
| 1570 | backward N times." | ||
| 1539 | (interactive "^p") | 1571 | (interactive "^p") |
| 1540 | (or arg (setq arg 1)) | 1572 | (or arg (setq arg 1)) |
| 1541 | (while (> arg 0) | 1573 | (while (> arg 0) |
| 1542 | (python-nav--forward-sexp) | 1574 | (python-nav--forward-sexp 1 t) |
| 1543 | (setq arg (1- arg))) | 1575 | (setq arg (1- arg))) |
| 1544 | (while (< arg 0) | 1576 | (while (< arg 0) |
| 1545 | (python-nav--backward-sexp) | 1577 | (python-nav--forward-sexp -1 t) |
| 1546 | (setq arg (1+ arg)))) | 1578 | (setq arg (1+ arg)))) |
| 1547 | 1579 | ||
| 1580 | (defun python-nav-backward-sexp-safe (&optional arg) | ||
| 1581 | "Move backward safely across expressions. | ||
| 1582 | With ARG, do it that many times. Negative arg -N means move | ||
| 1583 | backward N times." | ||
| 1584 | (interactive "^p") | ||
| 1585 | (or arg (setq arg 1)) | ||
| 1586 | (python-nav-forward-sexp-safe (- arg))) | ||
| 1587 | |||
| 1548 | (defun python-nav--up-list (&optional dir) | 1588 | (defun python-nav--up-list (&optional dir) |
| 1549 | "Internal implementation of `python-nav-up-list'. | 1589 | "Internal implementation of `python-nav-up-list'. |
| 1550 | DIR is always 1 or -1 and comes sanitized from | 1590 | DIR is always 1 or -1 and comes sanitized from |
| @@ -2212,7 +2252,7 @@ the python shell: | |||
| 2212 | (save-excursion | 2252 | (save-excursion |
| 2213 | (when (python-nav-if-name-main) | 2253 | (when (python-nav-if-name-main) |
| 2214 | (cons (point) | 2254 | (cons (point) |
| 2215 | (progn (python-nav-forward-sexp) | 2255 | (progn (python-nav-forward-sexp-safe) |
| 2216 | (point))))))) | 2256 | (point))))))) |
| 2217 | ;; Oh destructuring bind, how I miss you. | 2257 | ;; Oh destructuring bind, how I miss you. |
| 2218 | (if-name-main-start (car if-name-main-start-end)) | 2258 | (if-name-main-start (car if-name-main-start-end)) |