aboutsummaryrefslogtreecommitdiffstats
path: root/lisp/progmodes/python.el
diff options
context:
space:
mode:
authorKenichi Handa2012-08-16 21:25:17 +0900
committerKenichi Handa2012-08-16 21:25:17 +0900
commitd75ffb4ed0b2e72a9361a07d16a5c884a9459728 (patch)
tree8ac5a6a8ae033fef7fbc7fb7b09a703ef4b0ed5b /lisp/progmodes/python.el
parent69c41c4070c86baac11a627e9c3d366420aeb7cc (diff)
parent250c8ab9b8f6322959fa3122db83944c30c3894b (diff)
downloademacs-d75ffb4ed0b2e72a9361a07d16a5c884a9459728.tar.gz
emacs-d75ffb4ed0b2e72a9361a07d16a5c884a9459728.zip
merge trunk
Diffstat (limited to 'lisp/progmodes/python.el')
-rw-r--r--lisp/progmodes/python.el930
1 files changed, 527 insertions, 403 deletions
diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el
index e0a58d1523e..601850ed0fb 100644
--- a/lisp/progmodes/python.el
+++ b/lisp/progmodes/python.el
@@ -1,4 +1,4 @@
1;;; python.el --- Python's flying circus support for Emacs -*- coding: utf-8 -*- 1;;; python.el --- Python's flying circus support for Emacs
2 2
3;; Copyright (C) 2003-2012 Free Software Foundation, Inc. 3;; Copyright (C) 2003-2012 Free Software Foundation, Inc.
4 4
@@ -50,9 +50,12 @@
50;; `python-nav-forward-block', `python-nav-backward-block' 50;; `python-nav-forward-block', `python-nav-backward-block'
51;; respectively which navigate between beginning of blocks of code. 51;; respectively which navigate between beginning of blocks of code.
52;; Extra functions `python-nav-forward-statement', 52;; Extra functions `python-nav-forward-statement',
53;; `python-nav-backward-statement', `python-nav-statement-start', 53;; `python-nav-backward-statement',
54;; `python-nav-statement-end', `python-nav-block-start' and 54;; `python-nav-beginning-of-statement', `python-nav-end-of-statement',
55;; `python-nav-block-end' are included but no bound to any key. 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
57;; specialized `python-nav-forward-sexp' allows easy
58;; navigation between code blocks.
56 59
57;; Shell interaction: is provided and allows you to execute easily any 60;; Shell interaction: is provided and allows you to execute easily any
58;; block of code of your current buffer in an inferior Python process. 61;; block of code of your current buffer in an inferior Python process.
@@ -247,6 +250,7 @@
247 (define-key map "\C-c\C-tt" 'python-skeleton-try) 250 (define-key map "\C-c\C-tt" 'python-skeleton-try)
248 (define-key map "\C-c\C-tw" 'python-skeleton-while) 251 (define-key map "\C-c\C-tw" 'python-skeleton-while)
249 ;; Shell interaction 252 ;; Shell interaction
253 (define-key map "\C-c\C-p" 'run-python)
250 (define-key map "\C-c\C-s" 'python-shell-send-string) 254 (define-key map "\C-c\C-s" 'python-shell-send-string)
251 (define-key map "\C-c\C-r" 'python-shell-send-region) 255 (define-key map "\C-c\C-r" 'python-shell-send-region)
252 (define-key map "\C-\M-x" 'python-shell-send-defun) 256 (define-key map "\C-\M-x" 'python-shell-send-defun)
@@ -349,6 +353,40 @@ This variant of `rx' supports common python named REGEXPS."
349 353
350 354
351;;; Font-lock and syntax 355;;; Font-lock and syntax
356
357(defun python-syntax-context (type &optional syntax-ppss)
358 "Return non-nil if point is on TYPE using SYNTAX-PPSS.
359TYPE can be `comment', `string' or `paren'. It returns the start
360character address of the specified TYPE."
361 (let ((ppss (or syntax-ppss (syntax-ppss))))
362 (case type
363 (comment (and (nth 4 ppss) (nth 8 ppss)))
364 (string (and (not (nth 4 ppss)) (nth 8 ppss)))
365 (paren (nth 1 ppss))
366 (t nil))))
367
368(defun python-syntax-context-type (&optional syntax-ppss)
369 "Return the context type using SYNTAX-PPSS.
370The type returned can be `comment', `string' or `paren'."
371 (let ((ppss (or syntax-ppss (syntax-ppss))))
372 (cond
373 ((nth 8 ppss) (if (nth 4 ppss) 'comment 'string))
374 ((nth 1 ppss) 'paren))))
375
376(defsubst python-syntax-comment-or-string-p ()
377 "Return non-nil if point is inside 'comment or 'string."
378 (nth 8 (syntax-ppss)))
379
380(define-obsolete-function-alias
381 'python-info-ppss-context #'python-syntax-context "24.3")
382
383(define-obsolete-function-alias
384 'python-info-ppss-context-type #'python-syntax-context-type "24.3")
385
386(define-obsolete-function-alias
387 'python-info-ppss-comment-or-string-p
388 #'python-syntax-comment-or-string-p "24.3")
389
352(defvar python-font-lock-keywords 390(defvar python-font-lock-keywords
353 ;; Keywords 391 ;; Keywords
354 `(,(rx symbol-start 392 `(,(rx symbol-start
@@ -435,9 +473,9 @@ This variant of `rx' supports common python named REGEXPS."
435 (? ?\[ (+ (not (any ?\]))) ?\]) (* space) 473 (? ?\[ (+ (not (any ?\]))) ?\]) (* space)
436 assignment-operator))) 474 assignment-operator)))
437 (when (re-search-forward re limit t) 475 (when (re-search-forward re limit t)
438 (while (and (python-info-ppss-context 'paren) 476 (while (and (python-syntax-context 'paren)
439 (re-search-forward re limit t))) 477 (re-search-forward re limit t)))
440 (if (and (not (python-info-ppss-context 'paren)) 478 (if (and (not (python-syntax-context 'paren))
441 (not (equal (char-after (point-marker)) ?=))) 479 (not (equal (char-after (point-marker)) ?=)))
442 t 480 t
443 (set-match-data nil))))) 481 (set-match-data nil)))))
@@ -450,10 +488,10 @@ This variant of `rx' supports common python named REGEXPS."
450 assignment-operator))) 488 assignment-operator)))
451 (when (and (re-search-forward re limit t) 489 (when (and (re-search-forward re limit t)
452 (goto-char (nth 3 (match-data)))) 490 (goto-char (nth 3 (match-data))))
453 (while (and (python-info-ppss-context 'paren) 491 (while (and (python-syntax-context 'paren)
454 (re-search-forward re limit t)) 492 (re-search-forward re limit t))
455 (goto-char (nth 3 (match-data)))) 493 (goto-char (nth 3 (match-data))))
456 (if (not (python-info-ppss-context 'paren)) 494 (if (not (python-syntax-context 'paren))
457 t 495 t
458 (set-match-data nil))))) 496 (set-match-data nil)))))
459 (1 font-lock-variable-name-face nil nil)))) 497 (1 font-lock-variable-name-face nil nil))))
@@ -550,10 +588,10 @@ It makes underscores and dots word constituent chars.")
550 :safe 'booleanp) 588 :safe 'booleanp)
551 589
552(define-obsolete-variable-alias 590(define-obsolete-variable-alias
553 'python-indent 'python-indent-offset "24.2") 591 'python-indent 'python-indent-offset "24.3")
554 592
555(define-obsolete-variable-alias 593(define-obsolete-variable-alias
556 'python-guess-indent 'python-indent-guess-indent-offset "24.2") 594 'python-guess-indent 'python-indent-guess-indent-offset "24.3")
557 595
558(defvar python-indent-current-level 0 596(defvar python-indent-current-level 0
559 "Current indentation level `python-indent-line-function' is using.") 597 "Current indentation level `python-indent-line-function' is using.")
@@ -578,7 +616,7 @@ These make `python-indent-calculate-indentation' subtract the value of
578 (re-search-forward 616 (re-search-forward
579 (python-rx line-start block-start) nil t)) 617 (python-rx line-start block-start) nil t))
580 (when (and 618 (when (and
581 (not (python-info-ppss-context-type)) 619 (not (python-syntax-context-type))
582 (progn 620 (progn
583 (goto-char (line-end-position)) 621 (goto-char (line-end-position))
584 (python-util-forward-comment -1) 622 (python-util-forward-comment -1)
@@ -628,14 +666,14 @@ START is the buffer position where the sexp starts."
628 (bobp)) 666 (bobp))
629 'no-indent) 667 'no-indent)
630 ;; Inside a paren 668 ;; Inside a paren
631 ((setq start (python-info-ppss-context 'paren ppss)) 669 ((setq start (python-syntax-context 'paren ppss))
632 'inside-paren) 670 'inside-paren)
633 ;; Inside string 671 ;; Inside string
634 ((setq start (python-info-ppss-context 'string ppss)) 672 ((setq start (python-syntax-context 'string ppss))
635 'inside-string) 673 'inside-string)
636 ;; After backslash 674 ;; After backslash
637 ((setq start (when (not (or (python-info-ppss-context 'string ppss) 675 ((setq start (when (not (or (python-syntax-context 'string ppss)
638 (python-info-ppss-context 'comment ppss))) 676 (python-syntax-context 'comment ppss)))
639 (let ((line-beg-pos (line-beginning-position))) 677 (let ((line-beg-pos (line-beginning-position)))
640 (when (python-info-line-ends-backslash-p 678 (when (python-info-line-ends-backslash-p
641 (1- line-beg-pos)) 679 (1- line-beg-pos))
@@ -653,9 +691,7 @@ START is the buffer position where the sexp starts."
653 (while (and (re-search-backward 691 (while (and (re-search-backward
654 (python-rx block-start) nil t) 692 (python-rx block-start) nil t)
655 (or 693 (or
656 (python-info-ppss-context 'string) 694 (python-syntax-context-type)
657 (python-info-ppss-context 'comment)
658 (python-info-ppss-context 'paren)
659 (python-info-continuation-line-p)))) 695 (python-info-continuation-line-p))))
660 (when (looking-at (python-rx block-start)) 696 (when (looking-at (python-rx block-start))
661 (point-marker))))) 697 (point-marker)))))
@@ -664,7 +700,7 @@ START is the buffer position where the sexp starts."
664 ((setq start (save-excursion 700 ((setq start (save-excursion
665 (back-to-indentation) 701 (back-to-indentation)
666 (python-util-forward-comment -1) 702 (python-util-forward-comment -1)
667 (python-nav-statement-start) 703 (python-nav-beginning-of-statement)
668 (point-marker))) 704 (point-marker)))
669 'after-line) 705 'after-line)
670 ;; Do not indent 706 ;; Do not indent
@@ -719,17 +755,13 @@ START is the buffer position where the sexp starts."
719 (while (prog2 755 (while (prog2
720 (forward-line -1) 756 (forward-line -1)
721 (and (not (bobp)) 757 (and (not (bobp))
722 (python-info-ppss-context 'paren)))) 758 (python-syntax-context 'paren))))
723 (goto-char (line-end-position)) 759 (goto-char (line-end-position))
724 (while (and (re-search-backward 760 (while (and (re-search-backward
725 "\\." (line-beginning-position) t) 761 "\\." (line-beginning-position) t)
726 (or (python-info-ppss-context 'comment) 762 (python-syntax-context-type)))
727 (python-info-ppss-context 'string)
728 (python-info-ppss-context 'paren))))
729 (if (and (looking-at "\\.") 763 (if (and (looking-at "\\.")
730 (not (or (python-info-ppss-context 'comment) 764 (not (python-syntax-context-type)))
731 (python-info-ppss-context 'string)
732 (python-info-ppss-context 'paren))))
733 ;; The indentation is the same column of the 765 ;; The indentation is the same column of the
734 ;; first matching dot that's not inside a 766 ;; first matching dot that's not inside a
735 ;; comment, a string or a paren 767 ;; comment, a string or a paren
@@ -785,7 +817,7 @@ START is the buffer position where the sexp starts."
785 (when (and (looking-at (regexp-opt '(")" "]" "}"))) 817 (when (and (looking-at (regexp-opt '(")" "]" "}")))
786 (progn 818 (progn
787 (forward-char 1) 819 (forward-char 1)
788 (not (python-info-ppss-context 'paren)))) 820 (not (python-syntax-context 'paren))))
789 (goto-char context-start) 821 (goto-char context-start)
790 (current-indentation)))) 822 (current-indentation))))
791 ;; If open paren is contained on a line by itself add another 823 ;; If open paren is contained on a line by itself add another
@@ -885,8 +917,7 @@ See `python-indent-line' for details."
885(defun python-indent-dedent-line () 917(defun python-indent-dedent-line ()
886 "De-indent current line." 918 "De-indent current line."
887 (interactive "*") 919 (interactive "*")
888 (when (and (not (or (python-info-ppss-context 'string) 920 (when (and (not (python-syntax-comment-or-string-p))
889 (python-info-ppss-context 'comment)))
890 (<= (point-marker) (save-excursion 921 (<= (point-marker) (save-excursion
891 (back-to-indentation) 922 (back-to-indentation)
892 (point-marker))) 923 (point-marker)))
@@ -977,8 +1008,7 @@ With numeric ARG, just insert that many colons. With
977 (when (and (not arg) 1008 (when (and (not arg)
978 (eolp) 1009 (eolp)
979 (not (equal ?: (char-after (- (point-marker) 2)))) 1010 (not (equal ?: (char-after (- (point-marker) 2))))
980 (not (or (python-info-ppss-context 'string) 1011 (not (python-syntax-comment-or-string-p)))
981 (python-info-ppss-context 'comment))))
982 (let ((indentation (current-indentation)) 1012 (let ((indentation (current-indentation))
983 (calculated-indentation (python-indent-calculate-indentation))) 1013 (calculated-indentation (python-indent-calculate-indentation)))
984 (python-info-closing-block-message) 1014 (python-info-closing-block-message)
@@ -1002,7 +1032,7 @@ automatically if needed."
1002 (goto-char (line-beginning-position)) 1032 (goto-char (line-beginning-position))
1003 ;; If after going to the beginning of line the point 1033 ;; If after going to the beginning of line the point
1004 ;; is still inside a paren it's ok to do the trick 1034 ;; is still inside a paren it's ok to do the trick
1005 (when (python-info-ppss-context 'paren) 1035 (when (python-syntax-context 'paren)
1006 (let ((indentation (python-indent-calculate-indentation))) 1036 (let ((indentation (python-indent-calculate-indentation)))
1007 (when (< (current-indentation) indentation) 1037 (when (< (current-indentation) indentation)
1008 (indent-line-to indentation))))))) 1038 (indent-line-to indentation)))))))
@@ -1036,7 +1066,7 @@ non-nil if point is moved to `beginning-of-defun'."
1036 (end-of-line 1)) 1066 (end-of-line 1))
1037 (while (and (funcall re-search-fn 1067 (while (and (funcall re-search-fn
1038 python-nav-beginning-of-defun-regexp nil t) 1068 python-nav-beginning-of-defun-regexp nil t)
1039 (python-info-ppss-context-type))) 1069 (python-syntax-context-type)))
1040 (and (python-info-looking-at-beginning-of-defun) 1070 (and (python-info-looking-at-beginning-of-defun)
1041 (or (not (= (line-number-at-pos pos) 1071 (or (not (= (line-number-at-pos pos)
1042 (line-number-at-pos))) 1072 (line-number-at-pos)))
@@ -1086,18 +1116,18 @@ Returns nil if point is not in a def or class."
1086 (equal (char-after (+ (point) (current-indentation))) ?#) 1116 (equal (char-after (+ (point) (current-indentation))) ?#)
1087 (<= (current-indentation) beg-defun-indent) 1117 (<= (current-indentation) beg-defun-indent)
1088 (looking-at (python-rx decorator)) 1118 (looking-at (python-rx decorator))
1089 (python-info-ppss-context-type)))) 1119 (python-syntax-context-type))))
1090 (forward-line 1) 1120 (forward-line 1)
1091 ;; If point falls inside a paren or string context the point is 1121 ;; If point falls inside a paren or string context the point is
1092 ;; forwarded at the end of it (or end of buffer if its not closed) 1122 ;; forwarded at the end of it (or end of buffer if its not closed)
1093 (let ((context-type (python-info-ppss-context-type))) 1123 (let ((context-type (python-syntax-context-type)))
1094 (when (memq context-type '(paren string)) 1124 (when (memq context-type '(paren string))
1095 ;; Slow but safe. 1125 ;; Slow but safe.
1096 (while (and (not (eobp)) 1126 (while (and (not (eobp))
1097 (python-info-ppss-context-type)) 1127 (python-syntax-context-type))
1098 (forward-line 1))))))) 1128 (forward-line 1)))))))
1099 1129
1100(defun python-nav-statement-start () 1130(defun python-nav-beginning-of-statement ()
1101 "Move to start of current statement." 1131 "Move to start of current statement."
1102 (interactive "^") 1132 (interactive "^")
1103 (while (and (or (back-to-indentation) t) 1133 (while (and (or (back-to-indentation) t)
@@ -1106,19 +1136,19 @@ Returns nil if point is not in a def or class."
1106 (save-excursion 1136 (save-excursion
1107 (forward-line -1) 1137 (forward-line -1)
1108 (python-info-line-ends-backslash-p)) 1138 (python-info-line-ends-backslash-p))
1109 (python-info-ppss-context 'string) 1139 (python-syntax-context 'string)
1110 (python-info-ppss-context 'paren)) 1140 (python-syntax-context 'paren))
1111 (forward-line -1))))) 1141 (forward-line -1)))))
1112 1142
1113(defun python-nav-statement-end () 1143(defun python-nav-end-of-statement ()
1114 "Move to end of current statement." 1144 "Move to end of current statement."
1115 (interactive "^") 1145 (interactive "^")
1116 (while (and (goto-char (line-end-position)) 1146 (while (and (goto-char (line-end-position))
1117 (not (eobp)) 1147 (not (eobp))
1118 (when (or 1148 (when (or
1119 (python-info-line-ends-backslash-p) 1149 (python-info-line-ends-backslash-p)
1120 (python-info-ppss-context 'string) 1150 (python-syntax-context 'string)
1121 (python-info-ppss-context 'paren)) 1151 (python-syntax-context 'paren))
1122 (forward-line 1))))) 1152 (forward-line 1)))))
1123 1153
1124(defun python-nav-backward-statement (&optional arg) 1154(defun python-nav-backward-statement (&optional arg)
@@ -1135,29 +1165,29 @@ backward to previous statement."
1135 (interactive "^p") 1165 (interactive "^p")
1136 (or arg (setq arg 1)) 1166 (or arg (setq arg 1))
1137 (while (> arg 0) 1167 (while (> arg 0)
1138 (python-nav-statement-end) 1168 (python-nav-end-of-statement)
1139 (python-util-forward-comment) 1169 (python-util-forward-comment)
1140 (python-nav-statement-start) 1170 (python-nav-beginning-of-statement)
1141 (setq arg (1- arg))) 1171 (setq arg (1- arg)))
1142 (while (< arg 0) 1172 (while (< arg 0)
1143 (python-nav-statement-start) 1173 (python-nav-beginning-of-statement)
1144 (python-util-forward-comment -1) 1174 (python-util-forward-comment -1)
1145 (python-nav-statement-start) 1175 (python-nav-beginning-of-statement)
1146 (setq arg (1+ arg)))) 1176 (setq arg (1+ arg))))
1147 1177
1148(defun python-nav-block-start () 1178(defun python-nav-beginning-of-block ()
1149 "Move to start of current block." 1179 "Move to start of current block."
1150 (interactive "^") 1180 (interactive "^")
1151 (let ((starting-pos (point)) 1181 (let ((starting-pos (point))
1152 (block-regexp (python-rx 1182 (block-regexp (python-rx
1153 line-start (* whitespace) block-start))) 1183 line-start (* whitespace) block-start)))
1154 (if (progn 1184 (if (progn
1155 (python-nav-statement-start) 1185 (python-nav-beginning-of-statement)
1156 (looking-at (python-rx block-start))) 1186 (looking-at (python-rx block-start)))
1157 (point-marker) 1187 (point-marker)
1158 ;; Go to first line beginning a statement 1188 ;; Go to first line beginning a statement
1159 (while (and (not (bobp)) 1189 (while (and (not (bobp))
1160 (or (and (python-nav-statement-start) nil) 1190 (or (and (python-nav-beginning-of-statement) nil)
1161 (python-info-current-line-comment-p) 1191 (python-info-current-line-comment-p)
1162 (python-info-current-line-empty-p))) 1192 (python-info-current-line-empty-p)))
1163 (forward-line -1)) 1193 (forward-line -1))
@@ -1171,16 +1201,16 @@ backward to previous statement."
1171 (point-marker) 1201 (point-marker)
1172 (and (goto-char starting-pos) nil)))))) 1202 (and (goto-char starting-pos) nil))))))
1173 1203
1174(defun python-nav-block-end () 1204(defun python-nav-end-of-block ()
1175 "Move to end of current block." 1205 "Move to end of current block."
1176 (interactive "^") 1206 (interactive "^")
1177 (when (python-nav-block-start) 1207 (when (python-nav-beginning-of-block)
1178 (let ((block-indentation (current-indentation))) 1208 (let ((block-indentation (current-indentation)))
1179 (python-nav-statement-end) 1209 (python-nav-end-of-statement)
1180 (while (and (forward-line 1) 1210 (while (and (forward-line 1)
1181 (not (eobp)) 1211 (not (eobp))
1182 (or (and (> (current-indentation) block-indentation) 1212 (or (and (> (current-indentation) block-indentation)
1183 (or (python-nav-statement-end) t)) 1213 (or (python-nav-end-of-statement) t))
1184 (python-info-current-line-comment-p) 1214 (python-info-current-line-comment-p)
1185 (python-info-current-line-empty-p)))) 1215 (python-info-current-line-empty-p))))
1186 (python-util-forward-comment -1) 1216 (python-util-forward-comment -1)
@@ -1203,103 +1233,194 @@ backward to previous block."
1203 (python-rx line-start (* whitespace) block-start)) 1233 (python-rx line-start (* whitespace) block-start))
1204 (starting-pos (point))) 1234 (starting-pos (point)))
1205 (while (> arg 0) 1235 (while (> arg 0)
1206 (python-nav-statement-end) 1236 (python-nav-end-of-statement)
1207 (while (and 1237 (while (and
1208 (re-search-forward block-start-regexp nil t) 1238 (re-search-forward block-start-regexp nil t)
1209 (or (python-info-ppss-context 'string) 1239 (python-syntax-context-type)))
1210 (python-info-ppss-context 'comment)
1211 (python-info-ppss-context 'paren))))
1212 (setq arg (1- arg))) 1240 (setq arg (1- arg)))
1213 (while (< arg 0) 1241 (while (< arg 0)
1214 (python-nav-statement-start) 1242 (python-nav-beginning-of-statement)
1215 (while (and 1243 (while (and
1216 (re-search-backward block-start-regexp nil t) 1244 (re-search-backward block-start-regexp nil t)
1217 (or (python-info-ppss-context 'string) 1245 (python-syntax-context-type)))
1218 (python-info-ppss-context 'comment)
1219 (python-info-ppss-context 'paren))))
1220 (setq arg (1+ arg))) 1246 (setq arg (1+ arg)))
1221 (python-nav-statement-start) 1247 (python-nav-beginning-of-statement)
1222 (if (not (looking-at (python-rx block-start))) 1248 (if (not (looking-at (python-rx block-start)))
1223 (and (goto-char starting-pos) nil) 1249 (and (goto-char starting-pos) nil)
1224 (and (not (= (point) starting-pos)) (point-marker))))) 1250 (and (not (= (point) starting-pos)) (point-marker)))))
1225 1251
1226(defun python-nav-forward-sexp-function (&optional arg) 1252(defun python-nav-lisp-forward-sexp-safe (&optional arg)
1253 "Safe version of standard `forward-sexp'.
1254When ARG > 0 move forward, else if ARG is < 0."
1255 (or arg (setq arg 1))
1256 (let ((forward-sexp-function nil)
1257 (paren-regexp
1258 (if (> arg 0) (python-rx close-paren) (python-rx open-paren)))
1259 (search-fn
1260 (if (> arg 0) #'re-search-forward #'re-search-backward)))
1261 (condition-case nil
1262 (forward-sexp arg)
1263 (error
1264 (while (and (funcall search-fn paren-regexp nil t)
1265 (python-syntax-context 'paren)))))))
1266
1267(defun python-nav--forward-sexp ()
1268 "Move to forward sexp."
1269 (case (python-syntax-context-type)
1270 (string
1271 ;; Inside of a string, get out of it.
1272 (while (and (re-search-forward "[\"']" nil t)
1273 (python-syntax-context 'string))))
1274 (comment
1275 ;; Inside of a comment, just move forward.
1276 (python-util-forward-comment))
1277 (paren
1278 (python-nav-lisp-forward-sexp-safe 1))
1279 (t
1280 (if (and (not (eobp))
1281 (= (syntax-class (syntax-after (point))) 4))
1282 ;; Looking an open-paren
1283 (python-nav-lisp-forward-sexp-safe 1)
1284 (let ((block-starting-pos
1285 (save-excursion (python-nav-beginning-of-block)))
1286 (block-ending-pos
1287 (save-excursion (python-nav-end-of-block)))
1288 (next-block-starting-pos
1289 (save-excursion (python-nav-forward-block))))
1290 (cond
1291 ((not block-starting-pos)
1292 ;; Not inside a block, move to closest one.
1293 (and next-block-starting-pos
1294 (goto-char next-block-starting-pos)))
1295 ((= (point) block-starting-pos)
1296 ;; Point is at beginning of block
1297 (if (and next-block-starting-pos
1298 (< next-block-starting-pos block-ending-pos))
1299 ;; Beginning of next block is closer than current's
1300 ;; end, move to it.
1301 (goto-char next-block-starting-pos)
1302 (goto-char block-ending-pos)))
1303 ((= block-ending-pos (point))
1304 ;; Point is at end of current block
1305 (let ((parent-block-end-pos
1306 (save-excursion
1307 (python-util-forward-comment)
1308 (python-nav-beginning-of-block)
1309 (python-nav-end-of-block))))
1310 (if (and parent-block-end-pos
1311 (or (not next-block-starting-pos)
1312 (> next-block-starting-pos parent-block-end-pos)))
1313 ;; If the parent block ends before next block
1314 ;; starts move to it.
1315 (goto-char parent-block-end-pos)
1316 (and next-block-starting-pos
1317 (goto-char next-block-starting-pos)))))
1318 (t (python-nav-end-of-block))))))))
1319
1320(defun python-nav--backward-sexp ()
1321 "Move to backward sexp."
1322 (case (python-syntax-context-type)
1323 (string
1324 ;; Inside of a string, get out of it.
1325 (while (and (re-search-backward "[\"']" nil t)
1326 (python-syntax-context 'string))))
1327 (comment
1328 ;; Inside of a comment, just move backward.
1329 (python-util-forward-comment -1))
1330 (paren
1331 ;; Handle parens like we are lisp.
1332 (python-nav-lisp-forward-sexp-safe -1))
1333 (t
1334 (let* ((block-starting-pos
1335 (save-excursion (python-nav-beginning-of-block)))
1336 (block-ending-pos
1337 (save-excursion (python-nav-end-of-block)))
1338 (prev-block-ending-pos
1339 (save-excursion (when (python-nav-backward-block)
1340 (python-nav-end-of-block))))
1341 (prev-block-parent-ending-pos
1342 (save-excursion
1343 (when prev-block-ending-pos
1344 (goto-char prev-block-ending-pos)
1345 (python-util-forward-comment)
1346 (python-nav-beginning-of-block)
1347 (python-nav-end-of-block)))))
1348 (if (and (not (bobp))
1349 (= (syntax-class (syntax-after (1- (point)))) 5))
1350 ;; Char before point is a paren closing char, handle it
1351 ;; like we are lisp.
1352 (python-nav-lisp-forward-sexp-safe -1)
1353 (cond
1354 ((not block-ending-pos)
1355 ;; Not in and ending pos, move to end of previous block.
1356 (and (python-nav-backward-block)
1357 (python-nav-end-of-block)))
1358 ((= (point) block-ending-pos)
1359 ;; In ending pos, we need to search backwards for the
1360 ;; closest point looking the list of candidates from here.
1361 (let ((candidates))
1362 (dolist (name
1363 '(prev-block-parent-ending-pos
1364 prev-block-ending-pos
1365 block-ending-pos
1366 block-starting-pos))
1367 (when (and (symbol-value name)
1368 (< (symbol-value name) (point)))
1369 (add-to-list 'candidates (symbol-value name))))
1370 (goto-char (apply 'max candidates))))
1371 ((> (point) block-ending-pos)
1372 ;; After an ending position, move to it.
1373 (goto-char block-ending-pos))
1374 ((= (point) block-starting-pos)
1375 ;; On a block starting position.
1376 (if (not (> (point) (or prev-block-ending-pos (point))))
1377 ;; Point is after the end position of the block that
1378 ;; wraps the current one, just move a block backward.
1379 (python-nav-backward-block)
1380 ;; If we got here we are facing a case like this one:
1381 ;;
1382 ;; try:
1383 ;; return here()
1384 ;; except Exception as e:
1385 ;;
1386 ;; Where point is on the "except" and must move to the
1387 ;; end of "here()".
1388 (goto-char prev-block-ending-pos)
1389 (let ((parent-block-ending-pos
1390 (save-excursion
1391 (python-nav-forward-sexp)
1392 (and (not (looking-at (python-rx block-start)))
1393 (point)))))
1394 (when (and parent-block-ending-pos
1395 (> parent-block-ending-pos prev-block-ending-pos))
1396 ;; If we got here we are facing a case like this one:
1397 ;;
1398 ;; except ImportError:
1399 ;; if predicate():
1400 ;; processing()
1401 ;; here()
1402 ;; except AttributeError:
1403 ;;
1404 ;; Where point is on the "except" and must move to
1405 ;; the end of "here()". Without this extra step we'd
1406 ;; just get to the end of processing().
1407 (goto-char parent-block-ending-pos)))))
1408 (t
1409 (if (and prev-block-ending-pos (< prev-block-ending-pos (point)))
1410 (goto-char prev-block-ending-pos)
1411 (python-nav-beginning-of-block)))))))))
1412
1413(defun python-nav-forward-sexp (&optional arg)
1227 "Move forward across one block of code. 1414 "Move forward across one block of code.
1228With ARG, do it that many times. Negative arg -N means 1415With ARG, do it that many times. Negative arg -N means
1229move backward N times." 1416move backward N times."
1230 (interactive "^p") 1417 (interactive "^p")
1231 (or arg (setq arg 1)) 1418 (or arg (setq arg 1))
1232 (while (> arg 0) 1419 (while (> arg 0)
1233 (let ((block-starting-pos 1420 (python-nav--forward-sexp)
1234 (save-excursion (python-nav-block-start))) 1421 (setq arg (1- arg)))
1235 (block-ending-pos
1236 (save-excursion (python-nav-block-end)))
1237 (next-block-starting-pos
1238 (save-excursion (python-nav-forward-block))))
1239 (cond ((not block-starting-pos)
1240 (python-nav-forward-block))
1241 ((= (point) block-starting-pos)
1242 (if (or (not next-block-starting-pos)
1243 (< block-ending-pos next-block-starting-pos))
1244 (python-nav-block-end)
1245 (python-nav-forward-block)))
1246 ((= block-ending-pos (point))
1247 (let ((parent-block-end-pos
1248 (save-excursion
1249 (python-util-forward-comment)
1250 (python-nav-block-start)
1251 (python-nav-block-end))))
1252 (if (and parent-block-end-pos
1253 (or (not next-block-starting-pos)
1254 (> next-block-starting-pos parent-block-end-pos)))
1255 (goto-char parent-block-end-pos)
1256 (python-nav-forward-block))))
1257 (t (python-nav-block-end))))
1258 (setq arg (1- arg)))
1259 (while (< arg 0) 1422 (while (< arg 0)
1260 (let* ((block-starting-pos 1423 (python-nav--backward-sexp)
1261 (save-excursion (python-nav-block-start)))
1262 (block-ending-pos
1263 (save-excursion (python-nav-block-end)))
1264 (prev-block-ending-pos
1265 (save-excursion (when (python-nav-backward-block)
1266 (python-nav-block-end))))
1267 (prev-block-parent-ending-pos
1268 (save-excursion
1269 (when prev-block-ending-pos
1270 (goto-char prev-block-ending-pos)
1271 (python-util-forward-comment)
1272 (python-nav-block-start)
1273 (python-nav-block-end)))))
1274 (cond ((not block-ending-pos)
1275 (and (python-nav-backward-block)
1276 (python-nav-block-end)))
1277 ((= (point) block-ending-pos)
1278 (let ((candidates))
1279 (dolist (name
1280 '(prev-block-parent-ending-pos
1281 prev-block-ending-pos
1282 block-ending-pos
1283 block-starting-pos))
1284 (when (and (symbol-value name)
1285 (< (symbol-value name) (point)))
1286 (add-to-list 'candidates (symbol-value name))))
1287 (goto-char (apply 'max candidates))))
1288 ((> (point) block-ending-pos)
1289 (python-nav-block-end))
1290 ((= (point) block-starting-pos)
1291 (if (not (> (point) (or prev-block-ending-pos (point))))
1292 (python-nav-backward-block)
1293 (goto-char prev-block-ending-pos)
1294 (let ((parent-block-ending-pos
1295 (save-excursion
1296 (python-nav-forward-sexp-function)
1297 (and (not (looking-at (python-rx block-start)))
1298 (point)))))
1299 (when (and parent-block-ending-pos
1300 (> parent-block-ending-pos prev-block-ending-pos))
1301 (goto-char parent-block-ending-pos)))))
1302 (t (python-nav-block-start))))
1303 (setq arg (1+ arg)))) 1424 (setq arg (1+ arg))))
1304 1425
1305 1426
@@ -1362,14 +1483,6 @@ Restart the python shell after changing this variable for it to take effect."
1362 :group 'python 1483 :group 'python
1363 :safe 'booleanp) 1484 :safe 'booleanp)
1364 1485
1365(defcustom python-shell-send-setup-max-wait 5
1366 "Seconds to wait for process output before code setup.
1367If output is received before the specified time then control is
1368returned in that moment and not after waiting."
1369 :type 'integer
1370 :group 'python
1371 :safe 'integerp)
1372
1373(defcustom python-shell-process-environment nil 1486(defcustom python-shell-process-environment nil
1374 "List of environment variables for Python shell. 1487 "List of environment variables for Python shell.
1375This variable follows the same rules as `process-environment' 1488This variable follows the same rules as `process-environment'
@@ -1436,16 +1549,12 @@ virtualenv."
1436If DEDICATED is t and the variable `buffer-file-name' is non-nil 1549If DEDICATED is t and the variable `buffer-file-name' is non-nil
1437returns a string with the form 1550returns a string with the form
1438`python-shell-buffer-name'[variable `buffer-file-name'] else 1551`python-shell-buffer-name'[variable `buffer-file-name'] else
1439returns the value of `python-shell-buffer-name'. After 1552returns the value of `python-shell-buffer-name'."
1440calculating the process name adds the buffer name for the process
1441in the `same-window-buffer-names' list."
1442 (let ((process-name 1553 (let ((process-name
1443 (if (and dedicated 1554 (if (and dedicated
1444 buffer-file-name) 1555 buffer-file-name)
1445 (format "%s[%s]" python-shell-buffer-name buffer-file-name) 1556 (format "%s[%s]" python-shell-buffer-name buffer-file-name)
1446 (format "%s" python-shell-buffer-name)))) 1557 (format "%s" python-shell-buffer-name))))
1447 (add-to-list 'same-window-buffer-names (purecopy
1448 (format "*%s*" process-name)))
1449 process-name)) 1558 process-name))
1450 1559
1451(defun python-shell-internal-get-process-name () 1560(defun python-shell-internal-get-process-name ()
@@ -1553,8 +1662,11 @@ variable.
1553 'python-shell-completion-complete-at-point nil 'local) 1662 'python-shell-completion-complete-at-point nil 'local)
1554 (add-to-list (make-local-variable 'comint-dynamic-complete-functions) 1663 (add-to-list (make-local-variable 'comint-dynamic-complete-functions)
1555 'python-shell-completion-complete-at-point) 1664 'python-shell-completion-complete-at-point)
1556 (define-key inferior-python-mode-map (kbd "<tab>") 1665 (define-key inferior-python-mode-map "\t"
1557 'python-shell-completion-complete-or-indent) 1666 'python-shell-completion-complete-or-indent)
1667 (make-local-variable 'python-pdbtrack-buffers-to-kill)
1668 (make-local-variable 'python-pdbtrack-tracked-buffer)
1669 (make-local-variable 'python-shell-internal-last-output)
1558 (when python-shell-enable-font-lock 1670 (when python-shell-enable-font-lock
1559 (set (make-local-variable 'font-lock-defaults) 1671 (set (make-local-variable 'font-lock-defaults)
1560 '(python-font-lock-keywords nil nil nil nil)) 1672 '(python-font-lock-keywords nil nil nil nil))
@@ -1562,70 +1674,83 @@ variable.
1562 python-syntax-propertize-function)) 1674 python-syntax-propertize-function))
1563 (compilation-shell-minor-mode 1)) 1675 (compilation-shell-minor-mode 1))
1564 1676
1565(defun python-shell-make-comint (cmd proc-name &optional pop) 1677(defun python-shell-make-comint (cmd proc-name &optional pop internal)
1566 "Create a python shell comint buffer. 1678 "Create a python shell comint buffer.
1567CMD is the python command to be executed and PROC-NAME is the 1679CMD is the python command to be executed and PROC-NAME is the
1568process name the comint buffer will get. After the comint buffer 1680process name the comint buffer will get. After the comint buffer
1569is created the `inferior-python-mode' is activated. If POP is 1681is created the `inferior-python-mode' is activated. When
1570non-nil the buffer is shown." 1682optional argument POP is non-nil the buffer is shown. When
1683optional argument INTERNAL is non-nil this process is run on a
1684buffer with a name that starts with a space, following the Emacs
1685convention for temporary/internal buffers, and also makes sure
1686the user is not queried for confirmation when the process is
1687killed."
1571 (save-excursion 1688 (save-excursion
1572 (let* ((proc-buffer-name (format "*%s*" proc-name)) 1689 (let* ((proc-buffer-name
1690 (format (if (not internal) "*%s*" " *%s*") proc-name))
1573 (process-environment (python-shell-calculate-process-environment)) 1691 (process-environment (python-shell-calculate-process-environment))
1574 (exec-path (python-shell-calculate-exec-path))) 1692 (exec-path (python-shell-calculate-exec-path)))
1575 (when (not (comint-check-proc proc-buffer-name)) 1693 (when (not (comint-check-proc proc-buffer-name))
1576 (let* ((cmdlist (split-string-and-unquote cmd)) 1694 (let* ((cmdlist (split-string-and-unquote cmd))
1577 (buffer (apply 'make-comint proc-name (car cmdlist) nil 1695 (buffer (apply #'make-comint-in-buffer proc-name proc-buffer-name
1578 (cdr cmdlist))) 1696 (car cmdlist) nil (cdr cmdlist)))
1579 (current-buffer (current-buffer))) 1697 (current-buffer (current-buffer))
1698 (process (get-buffer-process buffer)))
1580 (with-current-buffer buffer 1699 (with-current-buffer buffer
1581 (inferior-python-mode) 1700 (inferior-python-mode)
1582 (python-util-clone-local-variables current-buffer)))) 1701 (python-util-clone-local-variables current-buffer))
1583 (when pop 1702 (accept-process-output process)
1584 (pop-to-buffer proc-buffer-name)) 1703 (and pop (pop-to-buffer buffer t))
1704 (and internal (set-process-query-on-exit-flag process nil))))
1585 proc-buffer-name))) 1705 proc-buffer-name)))
1586 1706
1587(defun run-python (dedicated cmd) 1707;;;###autoload
1708(defun run-python (cmd &optional dedicated show)
1588 "Run an inferior Python process. 1709 "Run an inferior Python process.
1589Input and output via buffer named after 1710Input and output via buffer named after
1590`python-shell-buffer-name'. If there is a process already 1711`python-shell-buffer-name'. If there is a process already
1591running in that buffer, just switch to it. 1712running in that buffer, just switch to it.
1592With argument, allows you to define DEDICATED, so a dedicated 1713
1593process for the current buffer is open, and define CMD so you can 1714With argument, allows you to define CMD so you can edit the
1594edit the command used to call the interpreter (default is value 1715command used to call the interpreter and define DEDICATED, so a
1595of `python-shell-interpreter' and arguments defined in 1716dedicated process for the current buffer is open. When numeric
1596`python-shell-interpreter-args'). Runs the hook 1717prefix arg is other than 0 or 4 do not SHOW.
1597`inferior-python-mode-hook' (after the `comint-mode-hook' is 1718
1598run). 1719Runs the hook `inferior-python-mode-hook' (after the
1599\(Type \\[describe-mode] in the process buffer for a list of commands.)" 1720`comint-mode-hook' is run). \(Type \\[describe-mode] in the
1721process buffer for a list of commands.)"
1600 (interactive 1722 (interactive
1601 (if current-prefix-arg 1723 (if current-prefix-arg
1602 (list 1724 (list
1725 (read-string "Run Python: " (python-shell-parse-command))
1603 (y-or-n-p "Make dedicated process? ") 1726 (y-or-n-p "Make dedicated process? ")
1604 (read-string "Run Python: " (python-shell-parse-command))) 1727 (= (prefix-numeric-value current-prefix-arg) 4))
1605 (list nil (python-shell-parse-command)))) 1728 (list (python-shell-parse-command) nil t)))
1606 (python-shell-make-comint cmd (python-shell-get-process-name dedicated)) 1729 (python-shell-make-comint
1730 cmd (python-shell-get-process-name dedicated) show)
1607 dedicated) 1731 dedicated)
1608 1732
1609(defun run-python-internal () 1733(defun run-python-internal ()
1610 "Run an inferior Internal Python process. 1734 "Run an inferior Internal Python process.
1611Input and output via buffer named after 1735Input and output via buffer named after
1612`python-shell-internal-buffer-name' and what 1736`python-shell-internal-buffer-name' and what
1613`python-shell-internal-get-process-name' returns. This new kind 1737`python-shell-internal-get-process-name' returns.
1614of shell is intended to be used for generic communication related 1738
1615to defined configurations. The main difference with global or 1739This new kind of shell is intended to be used for generic
1616dedicated shells is that these ones are attached to a 1740communication related to defined configurations, the main
1617configuration, not a buffer. This means that can be used for 1741difference with global or dedicated shells is that these ones are
1618example to retrieve the sys.path and other stuff, without messing 1742attached to a configuration, not a buffer. This means that can
1619with user shells. Runs the hook 1743be used for example to retrieve the sys.path and other stuff,
1620`inferior-python-mode-hook' (after the `comint-mode-hook' is 1744without messing with user shells. Note that
1621run). \(Type \\[describe-mode] in the process buffer for a list 1745`python-shell-enable-font-lock' and `inferior-python-mode-hook'
1622of commands.)" 1746are set to nil for these shells, so setup codes are not sent at
1623 (interactive) 1747startup."
1624 (set-process-query-on-exit-flag 1748 (let ((python-shell-enable-font-lock nil)
1625 (get-buffer-process 1749 (inferior-python-mode-hook nil))
1626 (python-shell-make-comint 1750 (get-buffer-process
1627 (python-shell-parse-command) 1751 (python-shell-make-comint
1628 (python-shell-internal-get-process-name))) nil)) 1752 (python-shell-parse-command)
1753 (python-shell-internal-get-process-name) nil t))))
1629 1754
1630(defun python-shell-get-process () 1755(defun python-shell-get-process ()
1631 "Get inferior Python process for current buffer and return it." 1756 "Get inferior Python process for current buffer and return it."
@@ -1647,7 +1772,7 @@ of commands.)"
1647 (global-proc-buffer-name (format "*%s*" global-proc-name)) 1772 (global-proc-buffer-name (format "*%s*" global-proc-name))
1648 (dedicated-running (comint-check-proc dedicated-proc-buffer-name)) 1773 (dedicated-running (comint-check-proc dedicated-proc-buffer-name))
1649 (global-running (comint-check-proc global-proc-buffer-name)) 1774 (global-running (comint-check-proc global-proc-buffer-name))
1650 (current-prefix-arg 4)) 1775 (current-prefix-arg 16))
1651 (when (and (not dedicated-running) (not global-running)) 1776 (when (and (not dedicated-running) (not global-running))
1652 (if (call-interactively 'run-python) 1777 (if (call-interactively 'run-python)
1653 (setq dedicated-running t) 1778 (setq dedicated-running t)
@@ -1661,21 +1786,35 @@ of commands.)"
1661 "Current internal shell buffer for the current buffer. 1786 "Current internal shell buffer for the current buffer.
1662This is really not necessary at all for the code to work but it's 1787This is really not necessary at all for the code to work but it's
1663there for compatibility with CEDET.") 1788there for compatibility with CEDET.")
1664(make-variable-buffer-local 'python-shell-internal-buffer) 1789
1790(defvar python-shell-internal-last-output nil
1791 "Last output captured by the internal shell.
1792This is really not necessary at all for the code to work but it's
1793there for compatibility with CEDET.")
1665 1794
1666(defun python-shell-internal-get-or-create-process () 1795(defun python-shell-internal-get-or-create-process ()
1667 "Get or create an inferior Internal Python process." 1796 "Get or create an inferior Internal Python process."
1668 (let* ((proc-name (python-shell-internal-get-process-name)) 1797 (let* ((proc-name (python-shell-internal-get-process-name))
1669 (proc-buffer-name (format "*%s*" proc-name))) 1798 (proc-buffer-name (format " *%s*" proc-name)))
1670 (run-python-internal) 1799 (when (not (process-live-p proc-name))
1671 (setq python-shell-internal-buffer proc-buffer-name) 1800 (run-python-internal)
1801 (setq python-shell-internal-buffer proc-buffer-name)
1802 ;; XXX: Why is this `sit-for' needed?
1803 ;; `python-shell-make-comint' calls `accept-process-output'
1804 ;; already but it is not helping to get proper output on
1805 ;; 'gnu/linux when the internal shell process is not running and
1806 ;; a call to `python-shell-internal-send-string' is issued.
1807 (sit-for 0.1 t))
1672 (get-buffer-process proc-buffer-name))) 1808 (get-buffer-process proc-buffer-name)))
1673 1809
1674(define-obsolete-function-alias 1810(define-obsolete-function-alias
1675 'python-proc 'python-shell-internal-get-or-create-process "24.2") 1811 'python-proc 'python-shell-internal-get-or-create-process "24.3")
1812
1813(define-obsolete-variable-alias
1814 'python-buffer 'python-shell-internal-buffer "24.3")
1676 1815
1677(define-obsolete-variable-alias 1816(define-obsolete-variable-alias
1678 'python-buffer 'python-shell-internal-buffer "24.2") 1817 'python-preoutput-result 'python-shell-internal-last-output "24.3")
1679 1818
1680(defun python-shell-send-string (string &optional process msg) 1819(defun python-shell-send-string (string &optional process msg)
1681 "Send STRING to inferior Python PROCESS. 1820 "Send STRING to inferior Python PROCESS.
@@ -1683,8 +1822,7 @@ When MSG is non-nil messages the first line of STRING."
1683 (interactive "sPython command: ") 1822 (interactive "sPython command: ")
1684 (let ((process (or process (python-shell-get-or-create-process))) 1823 (let ((process (or process (python-shell-get-or-create-process)))
1685 (lines (split-string string "\n" t))) 1824 (lines (split-string string "\n" t)))
1686 (when msg 1825 (and msg (message "Sent: %s..." (nth 0 lines)))
1687 (message (format "Sent: %s..." (nth 0 lines))))
1688 (if (> (length lines) 1) 1826 (if (> (length lines) 1)
1689 (let* ((temp-file-name (make-temp-file "py")) 1827 (let* ((temp-file-name (make-temp-file "py"))
1690 (file-name (or (buffer-file-name) temp-file-name))) 1828 (file-name (or (buffer-file-name) temp-file-name)))
@@ -1701,39 +1839,47 @@ When MSG is non-nil messages the first line of STRING."
1701 "Send STRING to PROCESS and inhibit output. 1839 "Send STRING to PROCESS and inhibit output.
1702When MSG is non-nil messages the first line of STRING. Return 1840When MSG is non-nil messages the first line of STRING. Return
1703the output." 1841the output."
1704 (let* ((output-buffer) 1842 (let* ((output-buffer "")
1705 (process (or process (python-shell-get-or-create-process))) 1843 (process (or process (python-shell-get-or-create-process)))
1706 (comint-preoutput-filter-functions 1844 (comint-preoutput-filter-functions
1707 (append comint-preoutput-filter-functions 1845 (append comint-preoutput-filter-functions
1708 '(ansi-color-filter-apply 1846 '(ansi-color-filter-apply
1709 (lambda (string) 1847 (lambda (string)
1710 (setq output-buffer (concat output-buffer string)) 1848 (setq output-buffer (concat output-buffer string))
1711 ""))))) 1849 ""))))
1712 (python-shell-send-string string process msg) 1850 (inhibit-quit t))
1713 (accept-process-output process) 1851 (or
1714 (replace-regexp-in-string 1852 (with-local-quit
1715 (if (> (length python-shell-prompt-output-regexp) 0) 1853 (python-shell-send-string string process msg)
1716 (format "\n*%s$\\|^%s\\|\n$" 1854 (accept-process-output process)
1717 python-shell-prompt-regexp 1855 (replace-regexp-in-string
1718 (or python-shell-prompt-output-regexp "")) 1856 (if (> (length python-shell-prompt-output-regexp) 0)
1719 (format "\n*$\\|^%s\\|\n$" 1857 (format "\n*%s$\\|^%s\\|\n$"
1720 python-shell-prompt-regexp)) 1858 python-shell-prompt-regexp
1721 "" output-buffer))) 1859 (or python-shell-prompt-output-regexp ""))
1860 (format "\n*$\\|^%s\\|\n$"
1861 python-shell-prompt-regexp))
1862 "" output-buffer))
1863 (with-current-buffer (process-buffer process)
1864 (comint-interrupt-subjob)))))
1722 1865
1723(defun python-shell-internal-send-string (string) 1866(defun python-shell-internal-send-string (string)
1724 "Send STRING to the Internal Python interpreter. 1867 "Send STRING to the Internal Python interpreter.
1725Returns the output. See `python-shell-send-string-no-output'." 1868Returns the output. See `python-shell-send-string-no-output'."
1726 (python-shell-send-string-no-output 1869 ;; XXX Remove `python-shell-internal-last-output' once CEDET is
1727 ;; Makes this function compatible with the old 1870 ;; updated to support this new mode.
1728 ;; python-send-receive. (At least for CEDET). 1871 (setq python-shell-internal-last-output
1729 (replace-regexp-in-string "_emacs_out +" "" string) 1872 (python-shell-send-string-no-output
1730 (python-shell-internal-get-or-create-process) nil)) 1873 ;; Makes this function compatible with the old
1874 ;; python-send-receive. (At least for CEDET).
1875 (replace-regexp-in-string "_emacs_out +" "" string)
1876 (python-shell-internal-get-or-create-process) nil)))
1731 1877
1732(define-obsolete-function-alias 1878(define-obsolete-function-alias
1733 'python-send-receive 'python-shell-internal-send-string "24.2") 1879 'python-send-receive 'python-shell-internal-send-string "24.3")
1734 1880
1735(define-obsolete-function-alias 1881(define-obsolete-function-alias
1736 'python-send-string 'python-shell-internal-send-string "24.2") 1882 'python-send-string 'python-shell-internal-send-string "24.3")
1737 1883
1738(defun python-shell-send-region (start end) 1884(defun python-shell-send-region (start end)
1739 "Send the region delimited by START and END to inferior Python process." 1885 "Send the region delimited by START and END to inferior Python process."
@@ -1806,12 +1952,10 @@ FILE-NAME."
1806 "Send all setup code for shell. 1952 "Send all setup code for shell.
1807This function takes the list of setup code to send from the 1953This function takes the list of setup code to send from the
1808`python-shell-setup-codes' list." 1954`python-shell-setup-codes' list."
1809 (let ((msg "Sent %s") 1955 (let ((process (get-buffer-process (current-buffer))))
1810 (process (get-buffer-process (current-buffer))))
1811 (accept-process-output process python-shell-send-setup-max-wait)
1812 (dolist (code python-shell-setup-codes) 1956 (dolist (code python-shell-setup-codes)
1813 (when code 1957 (when code
1814 (message (format msg code)) 1958 (message "Sent %s" code)
1815 (python-shell-send-string 1959 (python-shell-send-string
1816 (symbol-value code) process))))) 1960 (symbol-value code) process)))))
1817 1961
@@ -1872,27 +2016,71 @@ and use the following as the value of this variable:
1872 :type 'string 2016 :type 'string
1873 :group 'python) 2017 :group 'python)
1874 2018
1875(defun python-shell-completion--get-completions (input process completion-code) 2019(defun python-shell-completion-get-completions (process line input)
1876 "Retrieve available completions for INPUT using PROCESS. 2020 "Do completion at point for PROCESS.
1877Argument COMPLETION-CODE is the python code used to get 2021LINE is used to detect the context on how to complete given
1878completions on the current context." 2022INPUT."
1879 (with-current-buffer (process-buffer process) 2023 (let* ((prompt
1880 (let ((completions (python-shell-send-string-no-output 2024 ;; Get the last prompt for the inferior process
1881 (format completion-code input) process))) 2025 ;; buffer. This is used for the completion code selection
1882 (when (> (length completions) 2) 2026 ;; heuristic.
1883 (split-string completions "^'\\|^\"\\|;\\|'$\\|\"$" t))))) 2027 (with-current-buffer (process-buffer process)
1884 2028 (buffer-substring-no-properties
1885(defun python-shell-completion--do-completion-at-point (process) 2029 (overlay-start comint-last-prompt-overlay)
1886 "Do completion at point for PROCESS." 2030 (overlay-end comint-last-prompt-overlay))))
1887 (with-syntax-table python-dotty-syntax-table 2031 (completion-context
1888 (let* ((beg 2032 ;; Check whether a prompt matches a pdb string, an import
1889 (save-excursion 2033 ;; statement or just the standard prompt and use the
2034 ;; correct python-shell-completion-*-code string
2035 (cond ((and (> (length python-shell-completion-pdb-string-code) 0)
2036 (string-match
2037 (concat "^" python-shell-prompt-pdb-regexp) prompt))
2038 'pdb)
2039 ((and (>
2040 (length python-shell-completion-module-string-code) 0)
2041 (string-match
2042 (concat "^" python-shell-prompt-regexp) prompt)
2043 (string-match "^[ \t]*\\(from\\|import\\)[ \t]" line))
2044 'import)
2045 ((string-match
2046 (concat "^" python-shell-prompt-regexp) prompt)
2047 'default)
2048 (t nil)))
2049 (completion-code
2050 (case completion-context
2051 (pdb python-shell-completion-pdb-string-code)
2052 (import python-shell-completion-module-string-code)
2053 (default python-shell-completion-string-code)
2054 (t nil)))
2055 (input
2056 (if (eq completion-context 'import)
2057 (replace-regexp-in-string "^[ \t]+" "" line)
2058 input)))
2059 (and completion-code
2060 (> (length input) 0)
2061 (with-current-buffer (process-buffer process)
2062 (let ((completions (python-shell-send-string-no-output
2063 (format completion-code input) process)))
2064 (and (> (length completions) 2)
2065 (split-string completions
2066 "^'\\|^\"\\|;\\|'$\\|\"$" t)))))))
2067
2068(defun python-shell-completion-complete-at-point (&optional process)
2069 "Perform completion at point in inferior Python.
2070Optional argument PROCESS forces completions to be retrieved
2071using that one instead of current buffer's process."
2072 (setq process (or process (get-buffer-process (current-buffer))))
2073 (let* ((start
2074 (save-excursion
2075 (with-syntax-table python-dotty-syntax-table
1890 (let* ((paren-depth (car (syntax-ppss))) 2076 (let* ((paren-depth (car (syntax-ppss)))
1891 (syntax-string "w_") 2077 (syntax-string "w_")
1892 (syntax-list (string-to-syntax syntax-string))) 2078 (syntax-list (string-to-syntax syntax-string)))
1893 ;; Stop scanning for the beginning of the completion subject 2079 ;; Stop scanning for the beginning of the completion
1894 ;; after the char before point matches a delimiter 2080 ;; subject after the char before point matches a
1895 (while (member (car (syntax-after (1- (point)))) syntax-list) 2081 ;; delimiter
2082 (while (member
2083 (car (syntax-after (1- (point)))) syntax-list)
1896 (skip-syntax-backward syntax-string) 2084 (skip-syntax-backward syntax-string)
1897 (when (or (equal (char-before) ?\)) 2085 (when (or (equal (char-before) ?\))
1898 (equal (char-before) ?\")) 2086 (equal (char-before) ?\"))
@@ -1900,60 +2088,16 @@ completions on the current context."
1900 (while (or 2088 (while (or
1901 ;; honor initial paren depth 2089 ;; honor initial paren depth
1902 (> (car (syntax-ppss)) paren-depth) 2090 (> (car (syntax-ppss)) paren-depth)
1903 (python-info-ppss-context 'string)) 2091 (python-syntax-context 'string))
1904 (forward-char -1)))) 2092 (forward-char -1)))
1905 (point))) 2093 (point)))))
1906 (end (point)) 2094 (end (point)))
1907 (line (buffer-substring-no-properties (point-at-bol) end)) 2095 (list start end
1908 (input (buffer-substring-no-properties beg end)) 2096 (completion-table-dynamic
1909 ;; Get the last prompt for the inferior process buffer. This is 2097 (apply-partially
1910 ;; used for the completion code selection heuristic. 2098 #'python-shell-completion-get-completions
1911 (prompt 2099 process (buffer-substring-no-properties
1912 (with-current-buffer (process-buffer process) 2100 (line-beginning-position) end))))))
1913 (buffer-substring-no-properties
1914 (overlay-start comint-last-prompt-overlay)
1915 (overlay-end comint-last-prompt-overlay))))
1916 (completion-context
1917 ;; Check whether a prompt matches a pdb string, an import statement
1918 ;; or just the standard prompt and use the correct
1919 ;; python-shell-completion-*-code string
1920 (cond ((and (> (length python-shell-completion-pdb-string-code) 0)
1921 (string-match
1922 (concat "^" python-shell-prompt-pdb-regexp) prompt))
1923 'pdb)
1924 ((and (>
1925 (length python-shell-completion-module-string-code) 0)
1926 (string-match
1927 (concat "^" python-shell-prompt-regexp) prompt)
1928 (string-match "^[ \t]*\\(from\\|import\\)[ \t]" line))
1929 'import)
1930 ((string-match
1931 (concat "^" python-shell-prompt-regexp) prompt)
1932 'default)
1933 (t nil)))
1934 (completion-code
1935 (case completion-context
1936 ('pdb python-shell-completion-pdb-string-code)
1937 ('import python-shell-completion-module-string-code)
1938 ('default python-shell-completion-string-code)
1939 (t nil)))
1940 (input
1941 (if (eq completion-context 'import)
1942 (replace-regexp-in-string "^[ \t]+" "" line)
1943 input))
1944 (completions
1945 (and completion-code (> (length input) 0)
1946 (python-shell-completion--get-completions
1947 input process completion-code))))
1948 (list beg end completions))))
1949
1950(defun python-shell-completion-complete-at-point ()
1951 "Perform completion at point in inferior Python process."
1952 (interactive)
1953 (and comint-last-prompt-overlay
1954 (> (point-marker) (overlay-end comint-last-prompt-overlay))
1955 (python-shell-completion--do-completion-at-point
1956 (get-buffer-process (current-buffer)))))
1957 2101
1958(defun python-shell-completion-complete-or-indent () 2102(defun python-shell-completion-complete-or-indent ()
1959 "Complete or indent depending on the context. 2103 "Complete or indent depending on the context.
@@ -1987,11 +2131,9 @@ Used to extract the current line and module being inspected."
1987 "Variable containing the value of the current tracked buffer. 2131 "Variable containing the value of the current tracked buffer.
1988Never set this variable directly, use 2132Never set this variable directly, use
1989`python-pdbtrack-set-tracked-buffer' instead.") 2133`python-pdbtrack-set-tracked-buffer' instead.")
1990(make-variable-buffer-local 'python-pdbtrack-tracked-buffer)
1991 2134
1992(defvar python-pdbtrack-buffers-to-kill nil 2135(defvar python-pdbtrack-buffers-to-kill nil
1993 "List of buffers to be deleted after tracking finishes.") 2136 "List of buffers to be deleted after tracking finishes.")
1994(make-variable-buffer-local 'python-pdbtrack-buffers-to-kill)
1995 2137
1996(defun python-pdbtrack-set-tracked-buffer (file-name) 2138(defun python-pdbtrack-set-tracked-buffer (file-name)
1997 "Set the buffer for FILE-NAME as the tracked buffer. 2139 "Set the buffer for FILE-NAME as the tracked buffer.
@@ -2064,11 +2206,10 @@ Argument OUTPUT is a string with the output from the comint process."
2064For this to work the best as possible you should call 2206For this to work the best as possible you should call
2065`python-shell-send-buffer' from time to time so context in 2207`python-shell-send-buffer' from time to time so context in
2066inferior python process is updated properly." 2208inferior python process is updated properly."
2067 (interactive)
2068 (let ((process (python-shell-get-process))) 2209 (let ((process (python-shell-get-process)))
2069 (if (not process) 2210 (if (not process)
2070 (error "Completion needs an inferior Python process running") 2211 (error "Completion needs an inferior Python process running")
2071 (python-shell-completion--do-completion-at-point process)))) 2212 (python-shell-completion-complete-at-point process))))
2072 2213
2073(add-to-list 'debug-ignored-errors 2214(add-to-list 'debug-ignored-errors
2074 "^Completion needs an inferior Python process running.") 2215 "^Completion needs an inferior Python process running.")
@@ -2122,7 +2263,7 @@ Optional argument JUSTIFY defines if the paragraph should be justified."
2122 ((funcall python-fill-comment-function justify)) 2263 ((funcall python-fill-comment-function justify))
2123 ;; Strings/Docstrings 2264 ;; Strings/Docstrings
2124 ((save-excursion (skip-chars-forward "\"'uUrR") 2265 ((save-excursion (skip-chars-forward "\"'uUrR")
2125 (python-info-ppss-context 'string)) 2266 (python-syntax-context 'string))
2126 (funcall python-fill-string-function justify)) 2267 (funcall python-fill-string-function justify))
2127 ;; Decorators 2268 ;; Decorators
2128 ((equal (char-after (save-excursion 2269 ((equal (char-after (save-excursion
@@ -2130,7 +2271,7 @@ Optional argument JUSTIFY defines if the paragraph should be justified."
2130 (point-marker))) ?@) 2271 (point-marker))) ?@)
2131 (funcall python-fill-decorator-function justify)) 2272 (funcall python-fill-decorator-function justify))
2132 ;; Parens 2273 ;; Parens
2133 ((or (python-info-ppss-context 'paren) 2274 ((or (python-syntax-context 'paren)
2134 (looking-at (python-rx open-paren)) 2275 (looking-at (python-rx open-paren))
2135 (save-excursion 2276 (save-excursion
2136 (skip-syntax-forward "^(" (line-end-position)) 2277 (skip-syntax-forward "^(" (line-end-position))
@@ -2150,13 +2291,13 @@ JUSTIFY should be used (if applicable) as in `fill-paragraph'."
2150 (string-start-marker 2291 (string-start-marker
2151 (progn 2292 (progn
2152 (skip-chars-forward "\"'uUrR") 2293 (skip-chars-forward "\"'uUrR")
2153 (goto-char (python-info-ppss-context 'string)) 2294 (goto-char (python-syntax-context 'string))
2154 (skip-chars-forward "\"'uUrR") 2295 (skip-chars-forward "\"'uUrR")
2155 (point-marker))) 2296 (point-marker)))
2156 (reg-start (line-beginning-position)) 2297 (reg-start (line-beginning-position))
2157 (string-end-marker 2298 (string-end-marker
2158 (progn 2299 (progn
2159 (while (python-info-ppss-context 'string) 2300 (while (python-syntax-context 'string)
2160 (goto-char (1+ (point-marker)))) 2301 (goto-char (1+ (point-marker))))
2161 (skip-chars-backward "\"'") 2302 (skip-chars-backward "\"'")
2162 (point-marker))) 2303 (point-marker)))
@@ -2194,16 +2335,16 @@ JUSTIFY should be used (if applicable) as in `fill-paragraph'."
2194JUSTIFY should be used (if applicable) as in `fill-paragraph'." 2335JUSTIFY should be used (if applicable) as in `fill-paragraph'."
2195 (save-restriction 2336 (save-restriction
2196 (narrow-to-region (progn 2337 (narrow-to-region (progn
2197 (while (python-info-ppss-context 'paren) 2338 (while (python-syntax-context 'paren)
2198 (goto-char (1- (point-marker)))) 2339 (goto-char (1- (point-marker))))
2199 (point-marker) 2340 (point-marker)
2200 (line-beginning-position)) 2341 (line-beginning-position))
2201 (progn 2342 (progn
2202 (when (not (python-info-ppss-context 'paren)) 2343 (when (not (python-syntax-context 'paren))
2203 (end-of-line) 2344 (end-of-line)
2204 (when (not (python-info-ppss-context 'paren)) 2345 (when (not (python-syntax-context 'paren))
2205 (skip-syntax-backward "^)"))) 2346 (skip-syntax-backward "^)")))
2206 (while (python-info-ppss-context 'paren) 2347 (while (python-syntax-context 'paren)
2207 (goto-char (1+ (point-marker)))) 2348 (goto-char (1+ (point-marker))))
2208 (point-marker))) 2349 (point-marker)))
2209 (let ((paragraph-start "\f\\|[ \t]*$") 2350 (let ((paragraph-start "\f\\|[ \t]*$")
@@ -2228,7 +2369,7 @@ the if condition."
2228 :safe 'booleanp) 2369 :safe 'booleanp)
2229 2370
2230(define-obsolete-variable-alias 2371(define-obsolete-variable-alias
2231 'python-use-skeletons 'python-skeleton-autoinsert "24.2") 2372 'python-use-skeletons 'python-skeleton-autoinsert "24.3")
2232 2373
2233(defvar python-skeleton-available '() 2374(defvar python-skeleton-available '()
2234 "Internal list of available skeletons.") 2375 "Internal list of available skeletons.")
@@ -2241,8 +2382,7 @@ the if condition."
2241 ;; Only expand in code. 2382 ;; Only expand in code.
2242 :enable-function (lambda () 2383 :enable-function (lambda ()
2243 (and 2384 (and
2244 (not (or (python-info-ppss-context 'string) 2385 (not (python-syntax-comment-or-string-p))
2245 (python-info-ppss-context 'comment)))
2246 python-skeleton-autoinsert))) 2386 python-skeleton-autoinsert)))
2247 2387
2248(defmacro python-skeleton-define (name doc &rest skel) 2388(defmacro python-skeleton-define (name doc &rest skel)
@@ -2254,7 +2394,7 @@ be added to `python-mode-abbrev-table'."
2254 (function-name (intern (concat "python-skeleton-" name)))) 2394 (function-name (intern (concat "python-skeleton-" name))))
2255 `(progn 2395 `(progn
2256 (define-abbrev python-mode-abbrev-table ,name "" ',function-name 2396 (define-abbrev python-mode-abbrev-table ,name "" ',function-name
2257 :system t) 2397 :system t)
2258 (setq python-skeleton-available 2398 (setq python-skeleton-available
2259 (cons ',function-name python-skeleton-available)) 2399 (cons ',function-name python-skeleton-available))
2260 (define-skeleton ,function-name 2400 (define-skeleton ,function-name
@@ -2479,46 +2619,19 @@ Runs COMMAND, a shell command, as if by `compile'. See
2479 2619
2480(defun python-eldoc--get-doc-at-point (&optional force-input force-process) 2620(defun python-eldoc--get-doc-at-point (&optional force-input force-process)
2481 "Internal implementation to get documentation at point. 2621 "Internal implementation to get documentation at point.
2482If not FORCE-INPUT is passed then what `current-word' returns 2622If not FORCE-INPUT is passed then what
2483will be used. If not FORCE-PROCESS is passed what 2623`python-info-current-symbol' returns will be used. If not
2484`python-shell-get-process' returns is used." 2624FORCE-PROCESS is passed what `python-shell-get-process' returns
2625is used."
2485 (let ((process (or force-process (python-shell-get-process)))) 2626 (let ((process (or force-process (python-shell-get-process))))
2486 (if (not process) 2627 (if (not process)
2487 "Eldoc needs an inferior Python process running." 2628 (error "Eldoc needs an inferior Python process running")
2488 (let* ((current-defun (python-info-current-defun)) 2629 (let ((input (or force-input
2489 (input (or force-input 2630 (python-info-current-symbol t))))
2490 (with-syntax-table python-dotty-syntax-table 2631 (and input
2491 (if (not current-defun) 2632 (python-shell-send-string-no-output
2492 (current-word) 2633 (format python-eldoc-string-code input)
2493 (concat current-defun "." (current-word)))))) 2634 process))))))
2494 (ppss (syntax-ppss))
2495 (help (when (and
2496 input
2497 (not (string= input (concat current-defun ".")))
2498 (not (or (python-info-ppss-context 'string ppss)
2499 (python-info-ppss-context 'comment ppss))))
2500 (when (string-match
2501 (concat
2502 (regexp-quote (concat current-defun "."))
2503 "self\\.") input)
2504 (with-temp-buffer
2505 (insert input)
2506 (goto-char (point-min))
2507 (forward-word)
2508 (forward-char)
2509 (delete-region
2510 (point-marker) (search-forward "self."))
2511 (setq input (buffer-substring
2512 (point-min) (point-max)))))
2513 (python-shell-send-string-no-output
2514 (format python-eldoc-string-code input) process))))
2515 (with-current-buffer (process-buffer process)
2516 (when comint-last-prompt-overlay
2517 (delete-region comint-last-input-end
2518 (overlay-start comint-last-prompt-overlay))))
2519 (when (and help
2520 (not (string= help "\n")))
2521 help)))))
2522 2635
2523(defun python-eldoc-function () 2636(defun python-eldoc-function ()
2524 "`eldoc-documentation-function' for Python. 2637 "`eldoc-documentation-function' for Python.
@@ -2531,17 +2644,16 @@ inferior python process is updated properly."
2531 "Get help on SYMBOL using `help'. 2644 "Get help on SYMBOL using `help'.
2532Interactively, prompt for symbol." 2645Interactively, prompt for symbol."
2533 (interactive 2646 (interactive
2534 (let ((symbol (with-syntax-table python-dotty-syntax-table 2647 (let ((symbol (python-info-current-symbol t))
2535 (current-word)))
2536 (enable-recursive-minibuffers t)) 2648 (enable-recursive-minibuffers t))
2537 (list (read-string (if symbol 2649 (list (read-string (if symbol
2538 (format "Describe symbol (default %s): " symbol) 2650 (format "Describe symbol (default %s): " symbol)
2539 "Describe symbol: ") 2651 "Describe symbol: ")
2540 nil nil symbol)))) 2652 nil nil symbol))))
2541 (let ((process (python-shell-get-process))) 2653 (message (python-eldoc--get-doc-at-point symbol)))
2542 (if (not process) 2654
2543 (message "Eldoc needs an inferior Python process running.") 2655(add-to-list 'debug-ignored-errors
2544 (message (python-eldoc--get-doc-at-point symbol process))))) 2656 "^Eldoc needs an inferior Python process running.")
2545 2657
2546 2658
2547;;; Misc helpers 2659;;; Misc helpers
@@ -2553,18 +2665,27 @@ This function is compatible to be used as
2553`add-log-current-defun-function' since it returns nil if point is 2665`add-log-current-defun-function' since it returns nil if point is
2554not inside a defun." 2666not inside a defun."
2555 (let ((names '()) 2667 (let ((names '())
2556 (min-indent) 2668 (starting-indentation)
2669 (starting-point)
2557 (first-run t)) 2670 (first-run t))
2558 (save-restriction 2671 (save-restriction
2559 (widen) 2672 (widen)
2560 (save-excursion 2673 (save-excursion
2674 (setq starting-point (point-marker))
2675 (setq starting-indentation (save-excursion
2676 (python-nav-beginning-of-statement)
2677 (current-indentation)))
2561 (end-of-line 1) 2678 (end-of-line 1)
2562 (setq min-indent (current-indentation))
2563 (while (python-beginning-of-defun-function 1) 2679 (while (python-beginning-of-defun-function 1)
2564 (when (or (< (current-indentation) min-indent) 2680 (when (or (< (current-indentation) starting-indentation)
2565 first-run) 2681 (and first-run
2682 (<
2683 starting-point
2684 (save-excursion
2685 (python-end-of-defun-function)
2686 (point-marker)))))
2566 (setq first-run nil) 2687 (setq first-run nil)
2567 (setq min-indent (current-indentation)) 2688 (setq starting-indentation (current-indentation))
2568 (looking-at python-nav-beginning-of-defun-regexp) 2689 (looking-at python-nav-beginning-of-defun-regexp)
2569 (setq names (cons 2690 (setq names (cons
2570 (if (not include-type) 2691 (if (not include-type)
@@ -2576,6 +2697,36 @@ not inside a defun."
2576 (when names 2697 (when names
2577 (mapconcat (lambda (string) string) names ".")))) 2698 (mapconcat (lambda (string) string) names "."))))
2578 2699
2700(defun python-info-current-symbol (&optional replace-self)
2701 "Return current symbol using dotty syntax.
2702With optional argument REPLACE-SELF convert \"self\" to current
2703parent defun name."
2704 (let ((name
2705 (and (not (python-syntax-comment-or-string-p))
2706 (with-syntax-table python-dotty-syntax-table
2707 (let ((sym (symbol-at-point)))
2708 (and sym
2709 (substring-no-properties (symbol-name sym))))))))
2710 (when name
2711 (if (not replace-self)
2712 name
2713 (let ((current-defun (python-info-current-defun)))
2714 (if (not current-defun)
2715 name
2716 (replace-regexp-in-string
2717 (python-rx line-start word-start "self" word-end ?.)
2718 (concat
2719 (mapconcat 'identity
2720 (butlast (split-string current-defun "\\."))
2721 ".") ".")
2722 name)))))))
2723
2724(defsubst python-info-beginning-of-block-statement-p ()
2725 "Return non-nil if current statement opens a block."
2726 (save-excursion
2727 (python-nav-beginning-of-statement)
2728 (looking-at (python-rx block-start))))
2729
2579(defun python-info-closing-block () 2730(defun python-info-closing-block ()
2580 "Return the point of the block the current line closes." 2731 "Return the point of the block the current line closes."
2581 (let ((closing-word (save-excursion 2732 (let ((closing-word (save-excursion
@@ -2629,7 +2780,7 @@ With optional argument LINE-NUMBER, check that line instead."
2629 (goto-char line-number)) 2780 (goto-char line-number))
2630 (while (and (not (eobp)) 2781 (while (and (not (eobp))
2631 (goto-char (line-end-position)) 2782 (goto-char (line-end-position))
2632 (python-info-ppss-context 'paren) 2783 (python-syntax-context 'paren)
2633 (not (equal (char-before (point)) ?\\))) 2784 (not (equal (char-before (point)) ?\\)))
2634 (forward-line 1)) 2785 (forward-line 1))
2635 (when (equal (char-before) ?\\) 2786 (when (equal (char-before) ?\\)
@@ -2646,7 +2797,7 @@ Optional argument LINE-NUMBER forces the line number to check against."
2646 (when (python-info-line-ends-backslash-p) 2797 (when (python-info-line-ends-backslash-p)
2647 (while (save-excursion 2798 (while (save-excursion
2648 (goto-char (line-beginning-position)) 2799 (goto-char (line-beginning-position))
2649 (python-info-ppss-context 'paren)) 2800 (python-syntax-context 'paren))
2650 (forward-line -1)) 2801 (forward-line -1))
2651 (back-to-indentation) 2802 (back-to-indentation)
2652 (point-marker))))) 2803 (point-marker)))))
@@ -2660,31 +2811,27 @@ where the continued line ends."
2660 (widen) 2811 (widen)
2661 (let* ((context-type (progn 2812 (let* ((context-type (progn
2662 (back-to-indentation) 2813 (back-to-indentation)
2663 (python-info-ppss-context-type))) 2814 (python-syntax-context-type)))
2664 (line-start (line-number-at-pos)) 2815 (line-start (line-number-at-pos))
2665 (context-start (when context-type 2816 (context-start (when context-type
2666 (python-info-ppss-context context-type)))) 2817 (python-syntax-context context-type))))
2667 (cond ((equal context-type 'paren) 2818 (cond ((equal context-type 'paren)
2668 ;; Lines inside a paren are always a continuation line 2819 ;; Lines inside a paren are always a continuation line
2669 ;; (except the first one). 2820 ;; (except the first one).
2670 (when (equal (python-info-ppss-context-type) 'paren) 2821 (python-util-forward-comment -1)
2671 (python-util-forward-comment -1) 2822 (point-marker))
2672 (python-util-forward-comment -1) 2823 ((member context-type '(string comment))
2673 (point-marker)))
2674 ((or (equal context-type 'comment)
2675 (equal context-type 'string))
2676 ;; move forward an roll again 2824 ;; move forward an roll again
2677 (goto-char context-start) 2825 (goto-char context-start)
2678 (python-util-forward-comment) 2826 (python-util-forward-comment)
2679 (python-info-continuation-line-p)) 2827 (python-info-continuation-line-p))
2680 (t 2828 (t
2681 ;; Not within a paren, string or comment, the only way we are 2829 ;; Not within a paren, string or comment, the only way
2682 ;; dealing with a continuation line is that previous line 2830 ;; we are dealing with a continuation line is that
2683 ;; contains a backslash, and this can only be the previous line 2831 ;; previous line contains a backslash, and this can
2684 ;; from current 2832 ;; only be the previous line from current
2685 (back-to-indentation) 2833 (back-to-indentation)
2686 (python-util-forward-comment -1) 2834 (python-util-forward-comment -1)
2687 (python-util-forward-comment -1)
2688 (when (and (equal (1- line-start) (line-number-at-pos)) 2835 (when (and (equal (1- line-start) (line-number-at-pos))
2689 (python-info-line-ends-backslash-p)) 2836 (python-info-line-ends-backslash-p))
2690 (point-marker)))))))) 2837 (point-marker))))))))
@@ -2712,44 +2859,13 @@ operator."
2712 assignment-operator 2859 assignment-operator
2713 not-simple-operator) 2860 not-simple-operator)
2714 (line-end-position) t) 2861 (line-end-position) t)
2715 (not (or (python-info-ppss-context 'string) 2862 (not (python-syntax-context-type))))
2716 (python-info-ppss-context 'paren)
2717 (python-info-ppss-context 'comment)))))
2718 (skip-syntax-forward "\s") 2863 (skip-syntax-forward "\s")
2719 (point-marker))))) 2864 (point-marker)))))
2720 2865
2721(defun python-info-ppss-context (type &optional syntax-ppss)
2722 "Return non-nil if point is on TYPE using SYNTAX-PPSS.
2723TYPE can be 'comment, 'string or 'paren. It returns the start
2724character address of the specified TYPE."
2725 (let ((ppss (or syntax-ppss (syntax-ppss))))
2726 (case type
2727 ('comment
2728 (and (nth 4 ppss)
2729 (nth 8 ppss)))
2730 ('string
2731 (nth 8 ppss))
2732 ('paren
2733 (nth 1 ppss))
2734 (t nil))))
2735
2736(defun python-info-ppss-context-type (&optional syntax-ppss)
2737 "Return the context type using SYNTAX-PPSS.
2738The type returned can be 'comment, 'string or 'paren."
2739 (let ((ppss (or syntax-ppss (syntax-ppss))))
2740 (cond
2741 ((and (nth 4 ppss)
2742 (nth 8 ppss))
2743 'comment)
2744 ((nth 8 ppss)
2745 'string)
2746 ((nth 1 ppss)
2747 'paren)
2748 (t nil))))
2749
2750(defun python-info-looking-at-beginning-of-defun (&optional syntax-ppss) 2866(defun python-info-looking-at-beginning-of-defun (&optional syntax-ppss)
2751 "Check if point is at `beginning-of-defun' using SYNTAX-PPSS." 2867 "Check if point is at `beginning-of-defun' using SYNTAX-PPSS."
2752 (and (not (python-info-ppss-context-type (or syntax-ppss (syntax-ppss)))) 2868 (and (not (python-syntax-context-type (or syntax-ppss (syntax-ppss))))
2753 (save-excursion 2869 (save-excursion
2754 (beginning-of-line 1) 2870 (beginning-of-line 1)
2755 (looking-at python-nav-beginning-of-defun-regexp)))) 2871 (looking-at python-nav-beginning-of-defun-regexp))))
@@ -2795,7 +2911,7 @@ to \"^python-\"."
2795(defun python-util-forward-comment (&optional direction) 2911(defun python-util-forward-comment (&optional direction)
2796 "Python mode specific version of `forward-comment'. 2912 "Python mode specific version of `forward-comment'.
2797Optional argument DIRECTION defines the direction to move to." 2913Optional argument DIRECTION defines the direction to move to."
2798 (let ((comment-start (python-info-ppss-context 'comment)) 2914 (let ((comment-start (python-syntax-context 'comment))
2799 (factor (if (< (or direction 0) 0) 2915 (factor (if (< (or direction 0) 0)
2800 -99999 2916 -99999
2801 99999))) 2917 99999)))
@@ -2821,7 +2937,7 @@ if that value is non-nil."
2821 (set (make-local-variable 'parse-sexp-ignore-comments) t) 2937 (set (make-local-variable 'parse-sexp-ignore-comments) t)
2822 2938
2823 (set (make-local-variable 'forward-sexp-function) 2939 (set (make-local-variable 'forward-sexp-function)
2824 'python-nav-forward-sexp-function) 2940 'python-nav-forward-sexp)
2825 2941
2826 (set (make-local-variable 'font-lock-defaults) 2942 (set (make-local-variable 'font-lock-defaults)
2827 '(python-font-lock-keywords nil nil nil nil)) 2943 '(python-font-lock-keywords nil nil nil nil))
@@ -2882,9 +2998,17 @@ if that value is non-nil."
2882 2998
2883 (python-skeleton-add-menu-items) 2999 (python-skeleton-add-menu-items)
2884 3000
3001 (make-local-variable 'python-shell-internal-buffer)
3002
2885 (when python-indent-guess-indent-offset 3003 (when python-indent-guess-indent-offset
2886 (python-indent-guess-indent-offset))) 3004 (python-indent-guess-indent-offset)))
2887 3005
2888 3006
2889(provide 'python) 3007(provide 'python)
3008
3009;; Local Variables:
3010;; coding: utf-8
3011;; indent-tabs-mode: nil
3012;; End:
3013
2890;;; python.el ends here 3014;;; python.el ends here