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.el137
1 files changed, 69 insertions, 68 deletions
diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el
index ee98feaef5e..949b0252bf1 100644
--- a/lisp/progmodes/python.el
+++ b/lisp/progmodes/python.el
@@ -1074,12 +1074,9 @@ automatically if needed."
1074The name of the defun should be grouped so it can be retrieved 1074The name of the defun should be grouped so it can be retrieved
1075via `match-string'.") 1075via `match-string'.")
1076 1076
1077(defun python-nav-beginning-of-defun (&optional arg) 1077(defun python-nav--beginning-of-defun (&optional arg)
1078 "Move point to `beginning-of-defun'. 1078 "Internal implementation of `python-nav-beginning-of-defun'.
1079With positive ARG move search backwards. With negative do the 1079With positive ARG search backwards, else search forwards."
1080same but forward. When ARG is nil or 0 defaults to 1. This is
1081the main part of `python-beginning-of-defun-function'. Return
1082non-nil if point is moved to `beginning-of-defun'."
1083 (when (or (null arg) (= arg 0)) (setq arg 1)) 1080 (when (or (null arg) (= arg 0)) (setq arg 1))
1084 (let* ((re-search-fn (if (> arg 0) 1081 (let* ((re-search-fn (if (> arg 0)
1085 #'re-search-backward 1082 #'re-search-backward
@@ -1087,6 +1084,15 @@ non-nil if point is moved to `beginning-of-defun'."
1087 (line-beg-pos (line-beginning-position)) 1084 (line-beg-pos (line-beginning-position))
1088 (line-content-start (+ line-beg-pos (current-indentation))) 1085 (line-content-start (+ line-beg-pos (current-indentation)))
1089 (pos (point-marker)) 1086 (pos (point-marker))
1087 (beg-indentation
1088 (and (> arg 0)
1089 (save-excursion
1090 (and (python-info-current-line-empty-p)
1091 (python-util-forward-comment -1))
1092 (python-nav-beginning-of-statement)
1093 (if (python-info-looking-at-beginning-of-defun)
1094 (+ (current-indentation) python-indent-offset)
1095 (current-indentation)))))
1090 (found 1096 (found
1091 (progn 1097 (progn
1092 (when (and (< arg 0) 1098 (when (and (< arg 0)
@@ -1094,7 +1100,12 @@ non-nil if point is moved to `beginning-of-defun'."
1094 (end-of-line 1)) 1100 (end-of-line 1))
1095 (while (and (funcall re-search-fn 1101 (while (and (funcall re-search-fn
1096 python-nav-beginning-of-defun-regexp nil t) 1102 python-nav-beginning-of-defun-regexp nil t)
1097 (python-syntax-context-type))) 1103 (or (python-syntax-context-type)
1104 ;; Handle nested defuns when moving
1105 ;; backwards by checking indentation.
1106 (and (> arg 0)
1107 (not (= (current-indentation) 0))
1108 (>= (current-indentation) beg-indentation)))))
1098 (and (python-info-looking-at-beginning-of-defun) 1109 (and (python-info-looking-at-beginning-of-defun)
1099 (or (not (= (line-number-at-pos pos) 1110 (or (not (= (line-number-at-pos pos)
1100 (line-number-at-pos))) 1111 (line-number-at-pos)))
@@ -1105,55 +1116,43 @@ non-nil if point is moved to `beginning-of-defun'."
1105 (or (beginning-of-line 1) t) 1116 (or (beginning-of-line 1) t)
1106 (and (goto-char pos) nil)))) 1117 (and (goto-char pos) nil))))
1107 1118
1108(defun python-beginning-of-defun-function (&optional arg) 1119(defun python-nav-beginning-of-defun (&optional arg)
1109 "Move point to the beginning of def or class. 1120 "Move point to `beginning-of-defun'.
1110With positive ARG move that number of functions backwards. With 1121With positive ARG search backwards else search forward. When ARG
1111negative do the same but forward. When ARG is nil or 0 defaults 1122is nil or 0 defaults to 1. When searching backwards nested
1112to 1. Return non-nil if point is moved to `beginning-of-defun'." 1123defuns are handled with care depending on current point
1124position. Return non-nil if point is moved to
1125`beginning-of-defun'."
1113 (when (or (null arg) (= arg 0)) (setq arg 1)) 1126 (when (or (null arg) (= arg 0)) (setq arg 1))
1114 (let ((found)) 1127 (let ((found))
1115 (cond ((and (eq this-command 'mark-defun) 1128 (cond ((and (eq this-command 'mark-defun)
1116 (python-info-looking-at-beginning-of-defun))) 1129 (python-info-looking-at-beginning-of-defun)))
1117 (t 1130 (t
1118 (dotimes (i (if (> arg 0) arg (- arg))) 1131 (dotimes (i (if (> arg 0) arg (- arg)))
1119 (when (and (python-nav-beginning-of-defun arg) 1132 (when (and (python-nav--beginning-of-defun arg)
1120 (not found)) 1133 (not found))
1121 (setq found t))))) 1134 (setq found t)))))
1122 found)) 1135 found))
1123 1136
1124(defun python-end-of-defun-function () 1137(defun python-nav-end-of-defun ()
1125 "Move point to the end of def or class. 1138 "Move point to the end of def or class.
1126Returns nil if point is not in a def or class." 1139Returns nil if point is not in a def or class."
1127 (interactive) 1140 (interactive)
1128 (let ((beg-defun-indent)) 1141 (let ((beg-defun-indent)
1142 (beg-pos (point)))
1129 (when (or (python-info-looking-at-beginning-of-defun) 1143 (when (or (python-info-looking-at-beginning-of-defun)
1130 (python-beginning-of-defun-function 1) 1144 (python-nav-beginning-of-defun 1)
1131 (python-beginning-of-defun-function -1)) 1145 (python-nav-beginning-of-defun -1))
1132 (setq beg-defun-indent (current-indentation)) 1146 (setq beg-defun-indent (current-indentation))
1147 (while (progn
1148 (python-nav-end-of-statement)
1149 (python-util-forward-comment 1)
1150 (and (> (current-indentation) beg-defun-indent)
1151 (not (eobp)))))
1152 (python-util-forward-comment -1)
1133 (forward-line 1) 1153 (forward-line 1)
1134 ;; Go as forward as possible 1154 ;; Ensure point moves forward.
1135 (while (and (or 1155 (and (> beg-pos (point)) (goto-char beg-pos)))))
1136 (python-nav-beginning-of-defun -1)
1137 (and (goto-char (point-max)) nil))
1138 (> (current-indentation) beg-defun-indent)))
1139 (beginning-of-line 1)
1140 ;; Go as backwards as possible
1141 (while (and (forward-line -1)
1142 (not (bobp))
1143 (or (not (current-word))
1144 (equal (char-after (+ (point) (current-indentation))) ?#)
1145 (<= (current-indentation) beg-defun-indent)
1146 (looking-at (python-rx decorator))
1147 (python-syntax-context-type))))
1148 (forward-line 1)
1149 ;; If point falls inside a paren or string context the point is
1150 ;; forwarded at the end of it (or end of buffer if its not closed)
1151 (let ((context-type (python-syntax-context-type)))
1152 (when (memq context-type '(paren string))
1153 ;; Slow but safe.
1154 (while (and (not (eobp))
1155 (python-syntax-context-type))
1156 (forward-line 1)))))))
1157 1156
1158(defun python-nav-beginning-of-statement () 1157(defun python-nav-beginning-of-statement ()
1159 "Move to start of current statement." 1158 "Move to start of current statement."
@@ -2022,7 +2021,7 @@ When argument ARG is non-nil do not include decorators."
2022 (python-shell-send-region 2021 (python-shell-send-region
2023 (progn 2022 (progn
2024 (end-of-line 1) 2023 (end-of-line 1)
2025 (while (and (or (python-beginning-of-defun-function) 2024 (while (and (or (python-nav-beginning-of-defun)
2026 (beginning-of-line 1)) 2025 (beginning-of-line 1))
2027 (> (current-indentation) 0))) 2026 (> (current-indentation) 0)))
2028 (when (not arg) 2027 (when (not arg)
@@ -2031,7 +2030,7 @@ When argument ARG is non-nil do not include decorators."
2031 (forward-line 1)) 2030 (forward-line 1))
2032 (point-marker)) 2031 (point-marker))
2033 (progn 2032 (progn
2034 (or (python-end-of-defun-function) 2033 (or (python-nav-end-of-defun)
2035 (end-of-line 1)) 2034 (end-of-line 1))
2036 (point-marker))))) 2035 (point-marker)))))
2037 2036
@@ -2879,38 +2878,40 @@ Optional argument INCLUDE-TYPE indicates to include the type of the defun.
2879This function is compatible to be used as 2878This function is compatible to be used as
2880`add-log-current-defun-function' since it returns nil if point is 2879`add-log-current-defun-function' since it returns nil if point is
2881not inside a defun." 2880not inside a defun."
2882 (let ((names '())
2883 (starting-indentation)
2884 (starting-point)
2885 (first-run t))
2886 (save-restriction 2881 (save-restriction
2887 (widen) 2882 (widen)
2888 (save-excursion 2883 (save-excursion
2889 (setq starting-point (point-marker))
2890 (setq starting-indentation (save-excursion
2891 (python-nav-beginning-of-statement)
2892 (current-indentation)))
2893 (end-of-line 1) 2884 (end-of-line 1)
2894 (while (python-beginning-of-defun-function 1) 2885 (let ((names)
2895 (when (or (< (current-indentation) starting-indentation) 2886 (starting-indentation
2896 (and first-run 2887 (save-excursion
2897 (< 2888 (and
2898 starting-point 2889 (python-nav-beginning-of-defun 1)
2899 (save-excursion 2890 ;; This extra number is just for checking code
2900 (python-end-of-defun-function) 2891 ;; against indentation to work well on first run.
2901 (point-marker))))) 2892 (+ (current-indentation) 4))))
2902 (setq first-run nil) 2893 (starting-point (point)))
2903 (setq starting-indentation (current-indentation)) 2894 ;; Check point is inside a defun.
2904 (looking-at python-nav-beginning-of-defun-regexp) 2895 (when (and starting-indentation
2905 (setq names (cons 2896 (< starting-point
2897 (save-excursion
2898 (python-nav-end-of-defun)
2899 (point))))
2900 (catch 'exit
2901 (while (python-nav-beginning-of-defun 1)
2902 (when (< (current-indentation) starting-indentation)
2903 (setq starting-indentation (current-indentation))
2904 (setq names
2905 (cons
2906 (if (not include-type) 2906 (if (not include-type)
2907 (match-string-no-properties 1) 2907 (match-string-no-properties 1)
2908 (mapconcat 'identity 2908 (mapconcat 'identity
2909 (split-string 2909 (split-string
2910 (match-string-no-properties 0)) " ")) 2910 (match-string-no-properties 0)) " "))
2911 names)))))) 2911 names)))
2912 (when names 2912 (and (= (current-indentation) 0) (throw 'exit t)))))
2913 (mapconcat (lambda (string) string) names ".")))) 2913 (and names
2914 (mapconcat (lambda (string) string) names "."))))))
2914 2915
2915(defun python-info-current-symbol (&optional replace-self) 2916(defun python-info-current-symbol (&optional replace-self)
2916 "Return current symbol using dotty syntax. 2917 "Return current symbol using dotty syntax.
@@ -3200,9 +3201,9 @@ if that value is non-nil."
3200 'python-fill-paragraph) 3201 'python-fill-paragraph)
3201 3202
3202 (set (make-local-variable 'beginning-of-defun-function) 3203 (set (make-local-variable 'beginning-of-defun-function)
3203 #'python-beginning-of-defun-function) 3204 #'python-nav-beginning-of-defun)
3204 (set (make-local-variable 'end-of-defun-function) 3205 (set (make-local-variable 'end-of-defun-function)
3205 #'python-end-of-defun-function) 3206 #'python-nav-end-of-defun)
3206 3207
3207 (add-hook 'completion-at-point-functions 3208 (add-hook 'completion-at-point-functions
3208 'python-completion-complete-at-point nil 'local) 3209 'python-completion-complete-at-point nil 'local)
@@ -3230,7 +3231,7 @@ if that value is non-nil."
3230 (add-to-list 'hs-special-modes-alist 3231 (add-to-list 'hs-special-modes-alist
3231 `(python-mode "^\\s-*\\(?:def\\|class\\)\\>" nil "#" 3232 `(python-mode "^\\s-*\\(?:def\\|class\\)\\>" nil "#"
3232 ,(lambda (arg) 3233 ,(lambda (arg)
3233 (python-end-of-defun-function)) nil)) 3234 (python-nav-end-of-defun)) nil))
3234 3235
3235 (set (make-local-variable 'mode-require-final-newline) t) 3236 (set (make-local-variable 'mode-require-final-newline) t)
3236 3237