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.el170
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."
1010The name of the defun should be grouped so it can be retrieved 1010The name of the defun should be grouped so it can be retrieved
1011via `match-string'.") 1011via `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'.
1015When NODECORATORS is non-nil decorators are not included. This 1015With positive ARG move search backwards. With negative do the
1016is the main part of`python-beginning-of-defun-function' 1016same but forward. When ARG is nil or 0 defaults to 1. This is
1017implementation. Return non-nil if point is moved to the 1017the main part of `python-beginning-of-defun-function'. Return
1018`beginning-of-defun'." 1018non-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.
1050With positive ARG move that number of functions forward. With 1046With positive ARG move that number of functions backwards. With
1051negative do the same but backwards. When NODECORATORS is non-nil 1047negative do the same but forward. When ARG is nil or 0 defaults
1052decorators are not included. Return non-nil if point is moved to the 1048to 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.
1071Returns nil if point is not in a def or class." 1062Returns 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.
1168A cons cell with the form (DEFUN-NAME . POINT-MARKER) is returned 1170A cons cell with the form (DEFUN-NAME . POINT-MARKER) is returned
1169when defun is completed, else nil. With optional argument RESCAN 1171when defun is completed, else nil. With optional argument RESCAN
1170forces `python-nav-list-defun-positions' to invalidate its 1172forces `python-nav-list-defun-positions' to invalidate its
1171cache." 1173cache."
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.
1653When argument ARG is non-nil sends the innermost defun." 1655When 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