diff options
Diffstat (limited to 'lisp/progmodes/python.el')
| -rw-r--r-- | lisp/progmodes/python.el | 186 |
1 files changed, 109 insertions, 77 deletions
diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el index 0e5f4c82090..f0f67d01845 100644 --- a/lisp/progmodes/python.el +++ b/lisp/progmodes/python.el | |||
| @@ -54,8 +54,13 @@ | |||
| 54 | ;; `python-nav-beginning-of-statement', `python-nav-end-of-statement', | 54 | ;; `python-nav-beginning-of-statement', `python-nav-end-of-statement', |
| 55 | ;; `python-nav-beginning-of-block' and `python-nav-end-of-block' are | 55 | ;; `python-nav-beginning-of-block' and `python-nav-end-of-block' are |
| 56 | ;; included but no bound to any key. At last but not least the | 56 | ;; included but no bound to any key. At last but not least the |
| 57 | ;; specialized `python-nav-forward-sexp' allows easy | 57 | ;; specialized `python-nav-forward-sexp' allows easy navigation |
| 58 | ;; navigation between code blocks. | 58 | ;; between code blocks. If you prefer `cc-mode'-like `forward-sexp' |
| 59 | ;; movement, setting `forward-sexp-function' to nil is enough, You can | ||
| 60 | ;; do that using the `python-mode-hook': | ||
| 61 | |||
| 62 | ;; (add-hook 'python-mode-hook | ||
| 63 | ;; (lambda () (setq forward-sexp-function nil))) | ||
| 59 | 64 | ||
| 60 | ;; Shell interaction: is provided and allows you to execute easily any | 65 | ;; Shell interaction: is provided and allows you to execute easily any |
| 61 | ;; block of code of your current buffer in an inferior Python process. | 66 | ;; block of code of your current buffer in an inferior Python process. |
| @@ -155,7 +160,10 @@ | |||
| 155 | ;; dabbrev. If you have `dabbrev-mode' activated and | 160 | ;; dabbrev. If you have `dabbrev-mode' activated and |
| 156 | ;; `python-skeleton-autoinsert' is set to t, then whenever you type | 161 | ;; `python-skeleton-autoinsert' is set to t, then whenever you type |
| 157 | ;; the name of any of those defined and hit SPC, they will be | 162 | ;; the name of any of those defined and hit SPC, they will be |
| 158 | ;; automatically expanded. | 163 | ;; automatically expanded. As an alternative you can use the defined |
| 164 | ;; skeleton commands: `python-skeleton-class', `python-skeleton-def' | ||
| 165 | ;; `python-skeleton-for', `python-skeleton-if', `python-skeleton-try' | ||
| 166 | ;; and `python-skeleton-while'. | ||
| 159 | 167 | ||
| 160 | ;; FFAP: You can find the filename for a given module when using ffap | 168 | ;; FFAP: You can find the filename for a given module when using ffap |
| 161 | ;; out of the box. This feature needs an inferior python shell | 169 | ;; out of the box. This feature needs an inferior python shell |
| @@ -700,10 +708,9 @@ START is the buffer position where the sexp starts." | |||
| 700 | ;; After backslash | 708 | ;; After backslash |
| 701 | ((setq start (when (not (or (python-syntax-context 'string ppss) | 709 | ((setq start (when (not (or (python-syntax-context 'string ppss) |
| 702 | (python-syntax-context 'comment ppss))) | 710 | (python-syntax-context 'comment ppss))) |
| 703 | (let ((line-beg-pos (line-beginning-position))) | 711 | (let ((line-beg-pos (line-number-at-pos))) |
| 704 | (when (python-info-line-ends-backslash-p | 712 | (python-info-line-ends-backslash-p |
| 705 | (1- line-beg-pos)) | 713 | (1- line-beg-pos))))) |
| 706 | (- line-beg-pos 2))))) | ||
| 707 | 'after-backslash) | 714 | 'after-backslash) |
| 708 | ;; After beginning of block | 715 | ;; After beginning of block |
| 709 | ((setq start (save-excursion | 716 | ((setq start (save-excursion |
| @@ -1346,13 +1353,10 @@ backwards." | |||
| 1346 | 're-search-backward)) | 1353 | 're-search-backward)) |
| 1347 | (context-type (python-syntax-context-type))) | 1354 | (context-type (python-syntax-context-type))) |
| 1348 | (cond | 1355 | (cond |
| 1349 | ((eq context-type 'string) | 1356 | ((memq context-type '(string comment)) |
| 1350 | ;; Inside of a string, get out of it. | 1357 | ;; Inside of a string, get out of it. |
| 1351 | (while (and (funcall re-search-fn "[\"']" nil t) | 1358 | (let ((forward-sexp-function)) |
| 1352 | (python-syntax-context 'string)))) | 1359 | (forward-sexp dir))) |
| 1353 | ((eq context-type 'comment) | ||
| 1354 | ;; Inside of a comment, just move forward. | ||
| 1355 | (python-util-forward-comment dir)) | ||
| 1356 | ((or (eq context-type 'paren) | 1360 | ((or (eq context-type 'paren) |
| 1357 | (and forward-p (looking-at (python-rx open-paren))) | 1361 | (and forward-p (looking-at (python-rx open-paren))) |
| 1358 | (and (not forward-p) | 1362 | (and (not forward-p) |
| @@ -1375,16 +1379,16 @@ backwards." | |||
| 1375 | (save-excursion | 1379 | (save-excursion |
| 1376 | (python-nav-lisp-forward-sexp-safe dir) | 1380 | (python-nav-lisp-forward-sexp-safe dir) |
| 1377 | (point))) | 1381 | (point))) |
| 1378 | (next-sexp-context | 1382 | (next-sexp-context |
| 1379 | (save-excursion | 1383 | (save-excursion |
| 1380 | (goto-char next-sexp-pos) | 1384 | (goto-char next-sexp-pos) |
| 1381 | (cond | 1385 | (cond |
| 1382 | ((python-info-beginning-of-block-p) 'block-start) | 1386 | ((python-info-beginning-of-block-p) 'block-start) |
| 1383 | ((python-info-end-of-block-p) 'block-end) | 1387 | ((python-info-end-of-block-p) 'block-end) |
| 1384 | ((python-info-beginning-of-statement-p) 'statement-start) | 1388 | ((python-info-beginning-of-statement-p) 'statement-start) |
| 1385 | ((python-info-end-of-statement-p) 'statement-end) | 1389 | ((python-info-end-of-statement-p) 'statement-end) |
| 1386 | ((python-info-statement-starts-block-p) 'starts-block) | 1390 | ((python-info-statement-starts-block-p) 'starts-block) |
| 1387 | ((python-info-statement-ends-block-p) 'ends-block))))) | 1391 | ((python-info-statement-ends-block-p) 'ends-block))))) |
| 1388 | (if forward-p | 1392 | (if forward-p |
| 1389 | (cond ((and (not (eobp)) | 1393 | (cond ((and (not (eobp)) |
| 1390 | (python-info-current-line-empty-p)) | 1394 | (python-info-current-line-empty-p)) |
| @@ -1408,8 +1412,8 @@ backwards." | |||
| 1408 | (t (goto-char next-sexp-pos))) | 1412 | (t (goto-char next-sexp-pos))) |
| 1409 | (cond ((and (not (bobp)) | 1413 | (cond ((and (not (bobp)) |
| 1410 | (python-info-current-line-empty-p)) | 1414 | (python-info-current-line-empty-p)) |
| 1411 | (python-util-forward-comment dir) | 1415 | (python-util-forward-comment dir) |
| 1412 | (python-nav--forward-sexp dir)) | 1416 | (python-nav--forward-sexp dir)) |
| 1413 | ((eq context 'block-end) | 1417 | ((eq context 'block-end) |
| 1414 | (python-nav-beginning-of-block)) | 1418 | (python-nav-beginning-of-block)) |
| 1415 | ((eq context 'statement-end) | 1419 | ((eq context 'statement-end) |
| @@ -1661,7 +1665,11 @@ uniqueness for different types of configurations." | |||
| 1661 | 1665 | ||
| 1662 | (defun python-shell-parse-command () | 1666 | (defun python-shell-parse-command () |
| 1663 | "Calculate the string used to execute the inferior Python process." | 1667 | "Calculate the string used to execute the inferior Python process." |
| 1664 | (format "%s %s" python-shell-interpreter python-shell-interpreter-args)) | 1668 | (let ((process-environment (python-shell-calculate-process-environment)) |
| 1669 | (exec-path (python-shell-calculate-exec-path))) | ||
| 1670 | (format "%s %s" | ||
| 1671 | (executable-find python-shell-interpreter) | ||
| 1672 | python-shell-interpreter-args))) | ||
| 1665 | 1673 | ||
| 1666 | (defun python-shell-calculate-process-environment () | 1674 | (defun python-shell-calculate-process-environment () |
| 1667 | "Calculate process environment given `python-shell-virtualenv-path'." | 1675 | "Calculate process environment given `python-shell-virtualenv-path'." |
| @@ -2320,15 +2328,17 @@ Argument OUTPUT is a string with the output from the comint process." | |||
| 2320 | (file-name | 2328 | (file-name |
| 2321 | (with-temp-buffer | 2329 | (with-temp-buffer |
| 2322 | (insert full-output) | 2330 | (insert full-output) |
| 2323 | (goto-char (point-min)) | 2331 | ;; When the debugger encounters a pdb.set_trace() |
| 2324 | ;; OK, this sucked but now it became a cool hack. The | 2332 | ;; command, it prints a single stack frame. Sometimes |
| 2325 | ;; stacktrace information normally is on the first line | 2333 | ;; it prints a bit of extra information about the |
| 2326 | ;; but in some cases (like when doing a step-in) it is | 2334 | ;; arguments of the present function. When ipdb |
| 2327 | ;; on the second. | 2335 | ;; encounters an exception, it prints the _entire_ stack |
| 2328 | (when (or (looking-at python-pdbtrack-stacktrace-info-regexp) | 2336 | ;; trace. To handle all of these cases, we want to find |
| 2329 | (and | 2337 | ;; the _last_ stack frame printed in the most recent |
| 2330 | (forward-line) | 2338 | ;; batch of output, then jump to the corresponding |
| 2331 | (looking-at python-pdbtrack-stacktrace-info-regexp))) | 2339 | ;; file/line number. |
| 2340 | (goto-char (point-max)) | ||
| 2341 | (when (re-search-backward python-pdbtrack-stacktrace-info-regexp nil t) | ||
| 2332 | (setq line-number (string-to-number | 2342 | (setq line-number (string-to-number |
| 2333 | (match-string-no-properties 2))) | 2343 | (match-string-no-properties 2))) |
| 2334 | (match-string-no-properties 1))))) | 2344 | (match-string-no-properties 1))))) |
| @@ -2937,40 +2947,62 @@ Optional argument INCLUDE-TYPE indicates to include the type of the defun. | |||
| 2937 | This function is compatible to be used as | 2947 | This function is compatible to be used as |
| 2938 | `add-log-current-defun-function' since it returns nil if point is | 2948 | `add-log-current-defun-function' since it returns nil if point is |
| 2939 | not inside a defun." | 2949 | not inside a defun." |
| 2940 | (save-restriction | 2950 | (save-restriction |
| 2941 | (widen) | 2951 | (widen) |
| 2942 | (save-excursion | 2952 | (save-excursion |
| 2943 | (end-of-line 1) | 2953 | (end-of-line 1) |
| 2944 | (let ((names) | 2954 | (let ((names) |
| 2945 | (starting-indentation | 2955 | (starting-indentation (current-indentation)) |
| 2946 | (save-excursion | 2956 | (starting-pos (point)) |
| 2947 | (and | 2957 | (first-run t) |
| 2948 | (python-nav-beginning-of-defun 1) | 2958 | (last-indent) |
| 2949 | ;; This extra number is just for checking code | 2959 | (type)) |
| 2950 | ;; against indentation to work well on first run. | 2960 | (catch 'exit |
| 2951 | (+ (current-indentation) 4)))) | 2961 | (while (python-nav-beginning-of-defun 1) |
| 2952 | (starting-point (point))) | 2962 | (when (save-match-data |
| 2953 | ;; Check point is inside a defun. | 2963 | (and |
| 2954 | (when (and starting-indentation | 2964 | (or (not last-indent) |
| 2955 | (< starting-point | 2965 | (< (current-indentation) last-indent)) |
| 2966 | (or | ||
| 2967 | (and first-run | ||
| 2968 | (save-excursion | ||
| 2969 | ;; If this is the first run, we may add | ||
| 2970 | ;; the current defun at point. | ||
| 2971 | (setq first-run nil) | ||
| 2972 | (goto-char starting-pos) | ||
| 2973 | (python-nav-beginning-of-statement) | ||
| 2974 | (beginning-of-line 1) | ||
| 2975 | (looking-at-p | ||
| 2976 | python-nav-beginning-of-defun-regexp))) | ||
| 2977 | (< starting-pos | ||
| 2956 | (save-excursion | 2978 | (save-excursion |
| 2957 | (python-nav-end-of-defun) | 2979 | (let ((min-indent |
| 2958 | (point)))) | 2980 | (+ (current-indentation) |
| 2959 | (catch 'exit | 2981 | python-indent-offset))) |
| 2960 | (while (python-nav-beginning-of-defun 1) | 2982 | (if (< starting-indentation min-indent) |
| 2961 | (when (< (current-indentation) starting-indentation) | 2983 | ;; If the starting indentation is not |
| 2962 | (setq starting-indentation (current-indentation)) | 2984 | ;; within the min defun indent make the |
| 2963 | (setq names | 2985 | ;; check fail. |
| 2964 | (cons | 2986 | starting-pos |
| 2965 | (if (not include-type) | 2987 | ;; Else go to the end of defun and add |
| 2966 | (match-string-no-properties 1) | 2988 | ;; up the current indentation to the |
| 2967 | (mapconcat 'identity | 2989 | ;; ending position. |
| 2968 | (split-string | 2990 | (python-nav-end-of-defun) |
| 2969 | (match-string-no-properties 0)) " ")) | 2991 | (+ (point) |
| 2970 | names))) | 2992 | (if (>= (current-indentation) min-indent) |
| 2971 | (and (= (current-indentation) 0) (throw 'exit t))))) | 2993 | (1+ (current-indentation)) |
| 2972 | (and names | 2994 | 0))))))))) |
| 2973 | (mapconcat (lambda (string) string) names ".")))))) | 2995 | (save-match-data (setq last-indent (current-indentation))) |
| 2996 | (if (or (not include-type) type) | ||
| 2997 | (setq names (cons (match-string-no-properties 1) names)) | ||
| 2998 | (let ((match (split-string (match-string-no-properties 0)))) | ||
| 2999 | (setq type (car match)) | ||
| 3000 | (setq names (cons (cadr match) names))))) | ||
| 3001 | ;; Stop searching ASAP. | ||
| 3002 | (and (= (current-indentation) 0) (throw 'exit t)))) | ||
| 3003 | (and names | ||
| 3004 | (concat (and type (format "%s " type)) | ||
| 3005 | (mapconcat 'identity names "."))))))) | ||
| 2974 | 3006 | ||
| 2975 | (defun python-info-current-symbol (&optional replace-self) | 3007 | (defun python-info-current-symbol (&optional replace-self) |
| 2976 | "Return current symbol using dotty syntax. | 3008 | "Return current symbol using dotty syntax. |
| @@ -3083,7 +3115,7 @@ With optional argument LINE-NUMBER, check that line instead." | |||
| 3083 | (save-restriction | 3115 | (save-restriction |
| 3084 | (widen) | 3116 | (widen) |
| 3085 | (when line-number | 3117 | (when line-number |
| 3086 | (goto-char line-number)) | 3118 | (python-util-goto-line line-number)) |
| 3087 | (while (and (not (eobp)) | 3119 | (while (and (not (eobp)) |
| 3088 | (goto-char (line-end-position)) | 3120 | (goto-char (line-end-position)) |
| 3089 | (python-syntax-context 'paren) | 3121 | (python-syntax-context 'paren) |
| @@ -3099,7 +3131,7 @@ Optional argument LINE-NUMBER forces the line number to check against." | |||
| 3099 | (save-restriction | 3131 | (save-restriction |
| 3100 | (widen) | 3132 | (widen) |
| 3101 | (when line-number | 3133 | (when line-number |
| 3102 | (goto-char line-number)) | 3134 | (python-util-goto-line line-number)) |
| 3103 | (when (python-info-line-ends-backslash-p) | 3135 | (when (python-info-line-ends-backslash-p) |
| 3104 | (while (save-excursion | 3136 | (while (save-excursion |
| 3105 | (goto-char (line-beginning-position)) | 3137 | (goto-char (line-beginning-position)) |
| @@ -3178,7 +3210,9 @@ operator." | |||
| 3178 | 3210 | ||
| 3179 | (defun python-info-current-line-comment-p () | 3211 | (defun python-info-current-line-comment-p () |
| 3180 | "Check if current line is a comment line." | 3212 | "Check if current line is a comment line." |
| 3181 | (char-equal (or (char-after (+ (point) (current-indentation))) ?_) ?#)) | 3213 | (char-equal |
| 3214 | (or (char-after (+ (line-beginning-position) (current-indentation))) ?_) | ||
| 3215 | ?#)) | ||
| 3182 | 3216 | ||
| 3183 | (defun python-info-current-line-empty-p () | 3217 | (defun python-info-current-line-empty-p () |
| 3184 | "Check if current line is empty, ignoring whitespace." | 3218 | "Check if current line is empty, ignoring whitespace." |
| @@ -3193,12 +3227,10 @@ operator." | |||
| 3193 | 3227 | ||
| 3194 | ;;; Utility functions | 3228 | ;;; Utility functions |
| 3195 | 3229 | ||
| 3196 | (defun python-util-position (item seq) | 3230 | (defun python-util-goto-line (line-number) |
| 3197 | "Find the first occurrence of ITEM in SEQ. | 3231 | "Move point to LINE-NUMBER." |
| 3198 | Return the index of the matching item, or nil if not found." | 3232 | (goto-char (point-min)) |
| 3199 | (let ((member-result (member item seq))) | 3233 | (forward-line (1- line-number))) |
| 3200 | (when member-result | ||
| 3201 | (- (length seq) (length member-result))))) | ||
| 3202 | 3234 | ||
| 3203 | ;; Stolen from org-mode | 3235 | ;; Stolen from org-mode |
| 3204 | (defun python-util-clone-local-variables (from-buffer &optional regexp) | 3236 | (defun python-util-clone-local-variables (from-buffer &optional regexp) |