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.el186
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.
2937This function is compatible to be used as 2947This 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
2939not inside a defun." 2949not 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."
3198Return 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)