diff options
Diffstat (limited to 'lisp/progmodes/python.el')
| -rw-r--r-- | lisp/progmodes/python.el | 170 |
1 files changed, 92 insertions, 78 deletions
diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el index 1279c38b68b..3b0b418899c 100644 --- a/lisp/progmodes/python.el +++ b/lisp/progmodes/python.el | |||
| @@ -1010,84 +1010,86 @@ automatically if needed." | |||
| 1010 | The name of the defun should be grouped so it can be retrieved | 1010 | The name of the defun should be grouped so it can be retrieved |
| 1011 | via `match-string'.") | 1011 | via `match-string'.") |
| 1012 | 1012 | ||
| 1013 | (defun python-nav-beginning-of-defun (&optional nodecorators) | 1013 | (defun python-nav-beginning-of-defun (&optional arg) |
| 1014 | "Move point to `beginning-of-defun'. | 1014 | "Move point to `beginning-of-defun'. |
| 1015 | When NODECORATORS is non-nil decorators are not included. This | 1015 | With positive ARG move search backwards. With negative do the |
| 1016 | is the main part of`python-beginning-of-defun-function' | 1016 | same but forward. When ARG is nil or 0 defaults to 1. This is |
| 1017 | implementation. Return non-nil if point is moved to the | 1017 | the main part of `python-beginning-of-defun-function'. Return |
| 1018 | `beginning-of-defun'." | 1018 | non-nil if point is moved to `beginning-of-defun'." |
| 1019 | (let ((indent-pos (save-excursion | 1019 | (when (or (null arg) (= arg 0)) (setq arg 1)) |
| 1020 | (back-to-indentation) | 1020 | (let* ((re-search-fn (if (> arg 0) |
| 1021 | (point-marker))) | 1021 | #'re-search-backward |
| 1022 | (found) | 1022 | #'re-search-forward)) |
| 1023 | (include-decorators | 1023 | (line-beg-pos (line-beginning-position)) |
| 1024 | (lambda () | 1024 | (line-content-start (+ line-beg-pos (current-indentation))) |
| 1025 | (when (not nodecorators) | 1025 | (pos (point-marker)) |
| 1026 | (when (save-excursion | 1026 | (found |
| 1027 | (forward-line -1) | 1027 | (progn |
| 1028 | (looking-at (python-rx decorator))) | 1028 | (when (and (< arg 0) |
| 1029 | (while (and (not (bobp)) | 1029 | (python-info-looking-at-beginning-of-defun)) |
| 1030 | (forward-line -1) | 1030 | (end-of-line 1)) |
| 1031 | (looking-at (python-rx decorator)))) | 1031 | (while (and (funcall re-search-fn |
| 1032 | (when (not (bobp)) (forward-line 1))))))) | 1032 | python-nav-beginning-of-defun-regexp nil t) |
| 1033 | (if (and (> (point) indent-pos) | 1033 | (python-info-ppss-context-type))) |
| 1034 | (save-excursion | 1034 | (and (python-info-looking-at-beginning-of-defun) |
| 1035 | (goto-char (line-beginning-position)) | 1035 | (or (not (= (line-number-at-pos pos) |
| 1036 | (looking-at python-nav-beginning-of-defun-regexp))) | 1036 | (line-number-at-pos))) |
| 1037 | (progn | 1037 | (and (>= (point) line-beg-pos) |
| 1038 | (goto-char (line-beginning-position)) | 1038 | (<= (point) line-content-start) |
| 1039 | (funcall include-decorators) | 1039 | (> pos line-content-start))))))) |
| 1040 | (setq found t)) | 1040 | (if found |
| 1041 | (goto-char (line-beginning-position)) | 1041 | (or (beginning-of-line 1) t) |
| 1042 | (when (re-search-backward python-nav-beginning-of-defun-regexp nil t) | 1042 | (and (goto-char pos) nil)))) |
| 1043 | (setq found t)) | 1043 | |
| 1044 | (goto-char (or (python-info-ppss-context 'string) (point))) | 1044 | (defun python-beginning-of-defun-function (&optional arg) |
| 1045 | (funcall include-decorators)) | ||
| 1046 | found)) | ||
| 1047 | |||
| 1048 | (defun python-beginning-of-defun-function (&optional arg nodecorators) | ||
| 1049 | "Move point to the beginning of def or class. | 1045 | "Move point to the beginning of def or class. |
| 1050 | With positive ARG move that number of functions forward. With | 1046 | With positive ARG move that number of functions backwards. With |
| 1051 | negative do the same but backwards. When NODECORATORS is non-nil | 1047 | negative do the same but forward. When ARG is nil or 0 defaults |
| 1052 | decorators are not included. Return non-nil if point is moved to the | 1048 | to 1. Return non-nil if point is moved to `beginning-of-defun'." |
| 1053 | `beginning-of-defun'." | ||
| 1054 | (when (or (null arg) (= arg 0)) (setq arg 1)) | 1049 | (when (or (null arg) (= arg 0)) (setq arg 1)) |
| 1055 | (cond ((and (eq this-command 'mark-defun) | 1050 | (let ((found)) |
| 1056 | (looking-at python-nav-beginning-of-defun-regexp))) | 1051 | (cond ((and (eq this-command 'mark-defun) |
| 1057 | ((> arg 0) | 1052 | (python-info-looking-at-beginning-of-defun))) |
| 1058 | (dotimes (i arg (python-nav-beginning-of-defun nodecorators)))) | 1053 | (t |
| 1059 | (t | 1054 | (dotimes (i (if (> arg 0) arg (- arg))) |
| 1060 | (let ((found)) | 1055 | (when (and (python-nav-beginning-of-defun arg) |
| 1061 | (dotimes (i (- arg) found) | 1056 | (not found)) |
| 1062 | (python-end-of-defun-function) | 1057 | (setq found t))))) |
| 1063 | (python-util-forward-comment) | 1058 | found)) |
| 1064 | (goto-char (line-end-position)) | ||
| 1065 | (when (not (eobp)) | ||
| 1066 | (setq found | ||
| 1067 | (python-nav-beginning-of-defun nodecorators)))))))) | ||
| 1068 | 1059 | ||
| 1069 | (defun python-end-of-defun-function () | 1060 | (defun python-end-of-defun-function () |
| 1070 | "Move point to the end of def or class. | 1061 | "Move point to the end of def or class. |
| 1071 | Returns nil if point is not in a def or class." | 1062 | Returns nil if point is not in a def or class." |
| 1072 | (interactive) | 1063 | (interactive) |
| 1073 | (let ((beg-defun-indent) | 1064 | (let ((beg-defun-indent)) |
| 1074 | (decorator-regexp "[[:space:]]*@")) | 1065 | (when (or (python-info-looking-at-beginning-of-defun) |
| 1075 | (when (looking-at decorator-regexp) | 1066 | (python-beginning-of-defun-function 1) |
| 1076 | (while (and (not (eobp)) | 1067 | (python-beginning-of-defun-function -1)) |
| 1077 | (forward-line 1) | 1068 | (setq beg-defun-indent (current-indentation)) |
| 1078 | (looking-at decorator-regexp)))) | 1069 | (forward-line 1) |
| 1079 | (when (not (looking-at python-nav-beginning-of-defun-regexp)) | 1070 | ;; Go as forward as possible |
| 1080 | (python-beginning-of-defun-function)) | 1071 | (while (and (or |
| 1081 | (setq beg-defun-indent (current-indentation)) | 1072 | (python-nav-beginning-of-defun -1) |
| 1082 | (forward-line 1) | 1073 | (and (goto-char (point-max)) nil)) |
| 1083 | (while (and (forward-line 1) | 1074 | (> (current-indentation) beg-defun-indent))) |
| 1084 | (not (eobp)) | 1075 | (beginning-of-line 1) |
| 1085 | (or (not (current-word)) | 1076 | ;; Go as backwards as possible |
| 1086 | (equal (char-after (+ (point) (current-indentation))) ?#) | 1077 | (while (and (forward-line -1) |
| 1087 | (> (current-indentation) beg-defun-indent) | 1078 | (not (bobp)) |
| 1088 | (not (looking-at python-nav-beginning-of-defun-regexp))))) | 1079 | (or (not (current-word)) |
| 1089 | (python-util-forward-comment) | 1080 | (equal (char-after (+ (point) (current-indentation))) ?#) |
| 1090 | (goto-char (line-beginning-position)))) | 1081 | (<= (current-indentation) beg-defun-indent) |
| 1082 | (looking-at (python-rx decorator)) | ||
| 1083 | (python-info-ppss-context-type)))) | ||
| 1084 | (forward-line 1) | ||
| 1085 | ;; If point falls inside a paren or string context the point is | ||
| 1086 | ;; forwarded at the end of it (or end of buffer if its not closed) | ||
| 1087 | (let ((context-type (python-info-ppss-context-type))) | ||
| 1088 | (when (memq context-type '(paren string)) | ||
| 1089 | ;; Slow but safe. | ||
| 1090 | (while (and (not (eobp)) | ||
| 1091 | (python-info-ppss-context-type)) | ||
| 1092 | (forward-line 1))))))) | ||
| 1091 | 1093 | ||
| 1092 | (defun python-nav-sentence-start () | 1094 | (defun python-nav-sentence-start () |
| 1093 | "Move to start of current sentence." | 1095 | "Move to start of current sentence." |
| @@ -1166,7 +1168,7 @@ list of defun is regenerated again." | |||
| 1166 | (defun python-nav-read-defun (&optional rescan) | 1168 | (defun python-nav-read-defun (&optional rescan) |
| 1167 | "Read a defun name of current buffer and return its point marker. | 1169 | "Read a defun name of current buffer and return its point marker. |
| 1168 | A cons cell with the form (DEFUN-NAME . POINT-MARKER) is returned | 1170 | A cons cell with the form (DEFUN-NAME . POINT-MARKER) is returned |
| 1169 | when defun is completed, else nil. With optional argument RESCAN | 1171 | when defun is completed, else nil. With optional argument RESCAN |
| 1170 | forces `python-nav-list-defun-positions' to invalidate its | 1172 | forces `python-nav-list-defun-positions' to invalidate its |
| 1171 | cache." | 1173 | cache." |
| 1172 | (let ((defs (python-nav-list-defun-positions nil rescan))) | 1174 | (let ((defs (python-nav-list-defun-positions nil rescan))) |
| @@ -1650,17 +1652,23 @@ With prefix arg include lines protected by \"if __name__ == '__main__':\"" | |||
| 1650 | 1652 | ||
| 1651 | (defun python-shell-send-defun (arg) | 1653 | (defun python-shell-send-defun (arg) |
| 1652 | "Send the current defun to inferior Python process. | 1654 | "Send the current defun to inferior Python process. |
| 1653 | When argument ARG is non-nil sends the innermost defun." | 1655 | When argument ARG is non-nil do not include decorators." |
| 1654 | (interactive "P") | 1656 | (interactive "P") |
| 1655 | (save-excursion | 1657 | (save-excursion |
| 1656 | (python-shell-send-region | 1658 | (python-shell-send-region |
| 1657 | (progn | 1659 | (progn |
| 1658 | (or (python-beginning-of-defun-function) | 1660 | (end-of-line 1) |
| 1659 | (beginning-of-line)) | 1661 | (while (and (or (python-beginning-of-defun-function) |
| 1662 | (beginning-of-line 1)) | ||
| 1663 | (> (current-indentation) 0))) | ||
| 1664 | (when (not arg) | ||
| 1665 | (while (and (forward-line -1) | ||
| 1666 | (looking-at (python-rx decorator)))) | ||
| 1667 | (forward-line 1)) | ||
| 1660 | (point-marker)) | 1668 | (point-marker)) |
| 1661 | (progn | 1669 | (progn |
| 1662 | (or (python-end-of-defun-function) | 1670 | (or (python-end-of-defun-function) |
| 1663 | (end-of-line)) | 1671 | (end-of-line 1)) |
| 1664 | (point-marker))))) | 1672 | (point-marker))))) |
| 1665 | 1673 | ||
| 1666 | (defun python-shell-send-file (file-name &optional process temp-file-name) | 1674 | (defun python-shell-send-file (file-name &optional process temp-file-name) |
| @@ -2553,10 +2561,9 @@ not inside a defun." | |||
| 2553 | (save-restriction | 2561 | (save-restriction |
| 2554 | (widen) | 2562 | (widen) |
| 2555 | (save-excursion | 2563 | (save-excursion |
| 2556 | (goto-char (line-end-position)) | 2564 | (end-of-line 1) |
| 2557 | (python-util-forward-comment -1) | ||
| 2558 | (setq min-indent (current-indentation)) | 2565 | (setq min-indent (current-indentation)) |
| 2559 | (while (python-beginning-of-defun-function 1 t) | 2566 | (while (python-beginning-of-defun-function 1) |
| 2560 | (when (or (< (current-indentation) min-indent) | 2567 | (when (or (< (current-indentation) min-indent) |
| 2561 | first-run) | 2568 | first-run) |
| 2562 | (setq first-run nil) | 2569 | (setq first-run nil) |
| @@ -2742,6 +2749,13 @@ The type returned can be 'comment, 'string or 'paren." | |||
| 2742 | 'paren) | 2749 | 'paren) |
| 2743 | (t nil)))) | 2750 | (t nil)))) |
| 2744 | 2751 | ||
| 2752 | (defun python-info-looking-at-beginning-of-defun (&optional syntax-ppss) | ||
| 2753 | "Return nil of point is at `beginning-of-defun'." | ||
| 2754 | (and (not (python-info-ppss-context-type)) | ||
| 2755 | (save-excursion | ||
| 2756 | (beginning-of-line 1) | ||
| 2757 | (looking-at python-nav-beginning-of-defun-regexp)))) | ||
| 2758 | |||
| 2745 | 2759 | ||
| 2746 | ;;; Utility functions | 2760 | ;;; Utility functions |
| 2747 | 2761 | ||