diff options
Diffstat (limited to 'lisp/progmodes/python.el')
| -rw-r--r-- | lisp/progmodes/python.el | 137 |
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." | |||
| 1074 | The name of the defun should be grouped so it can be retrieved | 1074 | The name of the defun should be grouped so it can be retrieved |
| 1075 | via `match-string'.") | 1075 | via `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'. |
| 1079 | With positive ARG move search backwards. With negative do the | 1079 | With positive ARG search backwards, else search forwards." |
| 1080 | same but forward. When ARG is nil or 0 defaults to 1. This is | ||
| 1081 | the main part of `python-beginning-of-defun-function'. Return | ||
| 1082 | non-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'. |
| 1110 | With positive ARG move that number of functions backwards. With | 1121 | With positive ARG search backwards else search forward. When ARG |
| 1111 | negative do the same but forward. When ARG is nil or 0 defaults | 1122 | is nil or 0 defaults to 1. When searching backwards nested |
| 1112 | to 1. Return non-nil if point is moved to `beginning-of-defun'." | 1123 | defuns are handled with care depending on current point |
| 1124 | position. 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. |
| 1126 | Returns nil if point is not in a def or class." | 1139 | Returns 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. | |||
| 2879 | This function is compatible to be used as | 2878 | This 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 |
| 2881 | not inside a defun." | 2880 | not 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 | ||