aboutsummaryrefslogtreecommitdiffstats
path: root/lisp/progmodes/python.el
diff options
context:
space:
mode:
authorJoakim Verona2012-08-15 21:49:40 +0200
committerJoakim Verona2012-08-15 21:49:40 +0200
commitb648c26ec642a1dc58c0bd7e59d6011b964dbe37 (patch)
treef0f3b38ffa9054702f475fc53622e28da14f97b1 /lisp/progmodes/python.el
parentc8b0fc1999006af5a4317b44068fac13d9592143 (diff)
parent94c9ece10275f8ca9323c38f93607f1046035c79 (diff)
downloademacs-b648c26ec642a1dc58c0bd7e59d6011b964dbe37.tar.gz
emacs-b648c26ec642a1dc58c0bd7e59d6011b964dbe37.zip
upstream
Diffstat (limited to 'lisp/progmodes/python.el')
-rw-r--r--lisp/progmodes/python.el610
1 files changed, 357 insertions, 253 deletions
diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el
index f946509d6e0..601850ed0fb 100644
--- a/lisp/progmodes/python.el
+++ b/lisp/progmodes/python.el
@@ -54,7 +54,7 @@
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-function' allows easy 57;; specialized `python-nav-forward-sexp' allows easy
58;; navigation between code blocks. 58;; navigation between code blocks.
59 59
60;; Shell interaction: is provided and allows you to execute easily any 60;; Shell interaction: is provided and allows you to execute easily any
@@ -353,6 +353,40 @@ This variant of `rx' supports common python named REGEXPS."
353 353
354 354
355;;; 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
356(defvar python-font-lock-keywords 390(defvar python-font-lock-keywords
357 ;; Keywords 391 ;; Keywords
358 `(,(rx symbol-start 392 `(,(rx symbol-start
@@ -439,9 +473,9 @@ This variant of `rx' supports common python named REGEXPS."
439 (? ?\[ (+ (not (any ?\]))) ?\]) (* space) 473 (? ?\[ (+ (not (any ?\]))) ?\]) (* space)
440 assignment-operator))) 474 assignment-operator)))
441 (when (re-search-forward re limit t) 475 (when (re-search-forward re limit t)
442 (while (and (python-info-ppss-context 'paren) 476 (while (and (python-syntax-context 'paren)
443 (re-search-forward re limit t))) 477 (re-search-forward re limit t)))
444 (if (and (not (python-info-ppss-context 'paren)) 478 (if (and (not (python-syntax-context 'paren))
445 (not (equal (char-after (point-marker)) ?=))) 479 (not (equal (char-after (point-marker)) ?=)))
446 t 480 t
447 (set-match-data nil))))) 481 (set-match-data nil)))))
@@ -454,10 +488,10 @@ This variant of `rx' supports common python named REGEXPS."
454 assignment-operator))) 488 assignment-operator)))
455 (when (and (re-search-forward re limit t) 489 (when (and (re-search-forward re limit t)
456 (goto-char (nth 3 (match-data)))) 490 (goto-char (nth 3 (match-data))))
457 (while (and (python-info-ppss-context 'paren) 491 (while (and (python-syntax-context 'paren)
458 (re-search-forward re limit t)) 492 (re-search-forward re limit t))
459 (goto-char (nth 3 (match-data)))) 493 (goto-char (nth 3 (match-data))))
460 (if (not (python-info-ppss-context 'paren)) 494 (if (not (python-syntax-context 'paren))
461 t 495 t
462 (set-match-data nil))))) 496 (set-match-data nil)))))
463 (1 font-lock-variable-name-face nil nil)))) 497 (1 font-lock-variable-name-face nil nil))))
@@ -554,10 +588,10 @@ It makes underscores and dots word constituent chars.")
554 :safe 'booleanp) 588 :safe 'booleanp)
555 589
556(define-obsolete-variable-alias 590(define-obsolete-variable-alias
557 'python-indent 'python-indent-offset "24.2") 591 'python-indent 'python-indent-offset "24.3")
558 592
559(define-obsolete-variable-alias 593(define-obsolete-variable-alias
560 'python-guess-indent 'python-indent-guess-indent-offset "24.2") 594 'python-guess-indent 'python-indent-guess-indent-offset "24.3")
561 595
562(defvar python-indent-current-level 0 596(defvar python-indent-current-level 0
563 "Current indentation level `python-indent-line-function' is using.") 597 "Current indentation level `python-indent-line-function' is using.")
@@ -582,7 +616,7 @@ These make `python-indent-calculate-indentation' subtract the value of
582 (re-search-forward 616 (re-search-forward
583 (python-rx line-start block-start) nil t)) 617 (python-rx line-start block-start) nil t))
584 (when (and 618 (when (and
585 (not (python-info-ppss-context-type)) 619 (not (python-syntax-context-type))
586 (progn 620 (progn
587 (goto-char (line-end-position)) 621 (goto-char (line-end-position))
588 (python-util-forward-comment -1) 622 (python-util-forward-comment -1)
@@ -632,14 +666,14 @@ START is the buffer position where the sexp starts."
632 (bobp)) 666 (bobp))
633 'no-indent) 667 'no-indent)
634 ;; Inside a paren 668 ;; Inside a paren
635 ((setq start (python-info-ppss-context 'paren ppss)) 669 ((setq start (python-syntax-context 'paren ppss))
636 'inside-paren) 670 'inside-paren)
637 ;; Inside string 671 ;; Inside string
638 ((setq start (python-info-ppss-context 'string ppss)) 672 ((setq start (python-syntax-context 'string ppss))
639 'inside-string) 673 'inside-string)
640 ;; After backslash 674 ;; After backslash
641 ((setq start (when (not (or (python-info-ppss-context 'string ppss) 675 ((setq start (when (not (or (python-syntax-context 'string ppss)
642 (python-info-ppss-context 'comment ppss))) 676 (python-syntax-context 'comment ppss)))
643 (let ((line-beg-pos (line-beginning-position))) 677 (let ((line-beg-pos (line-beginning-position)))
644 (when (python-info-line-ends-backslash-p 678 (when (python-info-line-ends-backslash-p
645 (1- line-beg-pos)) 679 (1- line-beg-pos))
@@ -657,7 +691,7 @@ START is the buffer position where the sexp starts."
657 (while (and (re-search-backward 691 (while (and (re-search-backward
658 (python-rx block-start) nil t) 692 (python-rx block-start) nil t)
659 (or 693 (or
660 (python-info-ppss-context-type) 694 (python-syntax-context-type)
661 (python-info-continuation-line-p)))) 695 (python-info-continuation-line-p))))
662 (when (looking-at (python-rx block-start)) 696 (when (looking-at (python-rx block-start))
663 (point-marker))))) 697 (point-marker)))))
@@ -721,13 +755,13 @@ START is the buffer position where the sexp starts."
721 (while (prog2 755 (while (prog2
722 (forward-line -1) 756 (forward-line -1)
723 (and (not (bobp)) 757 (and (not (bobp))
724 (python-info-ppss-context 'paren)))) 758 (python-syntax-context 'paren))))
725 (goto-char (line-end-position)) 759 (goto-char (line-end-position))
726 (while (and (re-search-backward 760 (while (and (re-search-backward
727 "\\." (line-beginning-position) t) 761 "\\." (line-beginning-position) t)
728 (python-info-ppss-context-type))) 762 (python-syntax-context-type)))
729 (if (and (looking-at "\\.") 763 (if (and (looking-at "\\.")
730 (not (python-info-ppss-context-type))) 764 (not (python-syntax-context-type)))
731 ;; The indentation is the same column of the 765 ;; The indentation is the same column of the
732 ;; first matching dot that's not inside a 766 ;; first matching dot that's not inside a
733 ;; comment, a string or a paren 767 ;; comment, a string or a paren
@@ -783,7 +817,7 @@ START is the buffer position where the sexp starts."
783 (when (and (looking-at (regexp-opt '(")" "]" "}"))) 817 (when (and (looking-at (regexp-opt '(")" "]" "}")))
784 (progn 818 (progn
785 (forward-char 1) 819 (forward-char 1)
786 (not (python-info-ppss-context 'paren)))) 820 (not (python-syntax-context 'paren))))
787 (goto-char context-start) 821 (goto-char context-start)
788 (current-indentation)))) 822 (current-indentation))))
789 ;; 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
@@ -883,7 +917,7 @@ See `python-indent-line' for details."
883(defun python-indent-dedent-line () 917(defun python-indent-dedent-line ()
884 "De-indent current line." 918 "De-indent current line."
885 (interactive "*") 919 (interactive "*")
886 (when (and (not (python-info-ppss-comment-or-string-p)) 920 (when (and (not (python-syntax-comment-or-string-p))
887 (<= (point-marker) (save-excursion 921 (<= (point-marker) (save-excursion
888 (back-to-indentation) 922 (back-to-indentation)
889 (point-marker))) 923 (point-marker)))
@@ -974,7 +1008,7 @@ With numeric ARG, just insert that many colons. With
974 (when (and (not arg) 1008 (when (and (not arg)
975 (eolp) 1009 (eolp)
976 (not (equal ?: (char-after (- (point-marker) 2)))) 1010 (not (equal ?: (char-after (- (point-marker) 2))))
977 (not (python-info-ppss-comment-or-string-p))) 1011 (not (python-syntax-comment-or-string-p)))
978 (let ((indentation (current-indentation)) 1012 (let ((indentation (current-indentation))
979 (calculated-indentation (python-indent-calculate-indentation))) 1013 (calculated-indentation (python-indent-calculate-indentation)))
980 (python-info-closing-block-message) 1014 (python-info-closing-block-message)
@@ -998,7 +1032,7 @@ automatically if needed."
998 (goto-char (line-beginning-position)) 1032 (goto-char (line-beginning-position))
999 ;; If after going to the beginning of line the point 1033 ;; If after going to the beginning of line the point
1000 ;; 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
1001 (when (python-info-ppss-context 'paren) 1035 (when (python-syntax-context 'paren)
1002 (let ((indentation (python-indent-calculate-indentation))) 1036 (let ((indentation (python-indent-calculate-indentation)))
1003 (when (< (current-indentation) indentation) 1037 (when (< (current-indentation) indentation)
1004 (indent-line-to indentation))))))) 1038 (indent-line-to indentation)))))))
@@ -1032,7 +1066,7 @@ non-nil if point is moved to `beginning-of-defun'."
1032 (end-of-line 1)) 1066 (end-of-line 1))
1033 (while (and (funcall re-search-fn 1067 (while (and (funcall re-search-fn
1034 python-nav-beginning-of-defun-regexp nil t) 1068 python-nav-beginning-of-defun-regexp nil t)
1035 (python-info-ppss-context-type))) 1069 (python-syntax-context-type)))
1036 (and (python-info-looking-at-beginning-of-defun) 1070 (and (python-info-looking-at-beginning-of-defun)
1037 (or (not (= (line-number-at-pos pos) 1071 (or (not (= (line-number-at-pos pos)
1038 (line-number-at-pos))) 1072 (line-number-at-pos)))
@@ -1082,15 +1116,15 @@ Returns nil if point is not in a def or class."
1082 (equal (char-after (+ (point) (current-indentation))) ?#) 1116 (equal (char-after (+ (point) (current-indentation))) ?#)
1083 (<= (current-indentation) beg-defun-indent) 1117 (<= (current-indentation) beg-defun-indent)
1084 (looking-at (python-rx decorator)) 1118 (looking-at (python-rx decorator))
1085 (python-info-ppss-context-type)))) 1119 (python-syntax-context-type))))
1086 (forward-line 1) 1120 (forward-line 1)
1087 ;; 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
1088 ;; 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)
1089 (let ((context-type (python-info-ppss-context-type))) 1123 (let ((context-type (python-syntax-context-type)))
1090 (when (memq context-type '(paren string)) 1124 (when (memq context-type '(paren string))
1091 ;; Slow but safe. 1125 ;; Slow but safe.
1092 (while (and (not (eobp)) 1126 (while (and (not (eobp))
1093 (python-info-ppss-context-type)) 1127 (python-syntax-context-type))
1094 (forward-line 1))))))) 1128 (forward-line 1)))))))
1095 1129
1096(defun python-nav-beginning-of-statement () 1130(defun python-nav-beginning-of-statement ()
@@ -1102,8 +1136,8 @@ Returns nil if point is not in a def or class."
1102 (save-excursion 1136 (save-excursion
1103 (forward-line -1) 1137 (forward-line -1)
1104 (python-info-line-ends-backslash-p)) 1138 (python-info-line-ends-backslash-p))
1105 (python-info-ppss-context 'string) 1139 (python-syntax-context 'string)
1106 (python-info-ppss-context 'paren)) 1140 (python-syntax-context 'paren))
1107 (forward-line -1))))) 1141 (forward-line -1)))))
1108 1142
1109(defun python-nav-end-of-statement () 1143(defun python-nav-end-of-statement ()
@@ -1113,8 +1147,8 @@ Returns nil if point is not in a def or class."
1113 (not (eobp)) 1147 (not (eobp))
1114 (when (or 1148 (when (or
1115 (python-info-line-ends-backslash-p) 1149 (python-info-line-ends-backslash-p)
1116 (python-info-ppss-context 'string) 1150 (python-syntax-context 'string)
1117 (python-info-ppss-context 'paren)) 1151 (python-syntax-context 'paren))
1118 (forward-line 1))))) 1152 (forward-line 1)))))
1119 1153
1120(defun python-nav-backward-statement (&optional arg) 1154(defun python-nav-backward-statement (&optional arg)
@@ -1202,96 +1236,191 @@ backward to previous block."
1202 (python-nav-end-of-statement) 1236 (python-nav-end-of-statement)
1203 (while (and 1237 (while (and
1204 (re-search-forward block-start-regexp nil t) 1238 (re-search-forward block-start-regexp nil t)
1205 (python-info-ppss-context-type))) 1239 (python-syntax-context-type)))
1206 (setq arg (1- arg))) 1240 (setq arg (1- arg)))
1207 (while (< arg 0) 1241 (while (< arg 0)
1208 (python-nav-beginning-of-statement) 1242 (python-nav-beginning-of-statement)
1209 (while (and 1243 (while (and
1210 (re-search-backward block-start-regexp nil t) 1244 (re-search-backward block-start-regexp nil t)
1211 (python-info-ppss-context-type))) 1245 (python-syntax-context-type)))
1212 (setq arg (1+ arg))) 1246 (setq arg (1+ arg)))
1213 (python-nav-beginning-of-statement) 1247 (python-nav-beginning-of-statement)
1214 (if (not (looking-at (python-rx block-start))) 1248 (if (not (looking-at (python-rx block-start)))
1215 (and (goto-char starting-pos) nil) 1249 (and (goto-char starting-pos) nil)
1216 (and (not (= (point) starting-pos)) (point-marker))))) 1250 (and (not (= (point) starting-pos)) (point-marker)))))
1217 1251
1218(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)
1219 "Move forward across one block of code. 1414 "Move forward across one block of code.
1220With ARG, do it that many times. Negative arg -N means 1415With ARG, do it that many times. Negative arg -N means
1221move backward N times." 1416move backward N times."
1222 (interactive "^p") 1417 (interactive "^p")
1223 (or arg (setq arg 1)) 1418 (or arg (setq arg 1))
1224 (while (> arg 0) 1419 (while (> arg 0)
1225 (let ((block-starting-pos 1420 (python-nav--forward-sexp)
1226 (save-excursion (python-nav-beginning-of-block))) 1421 (setq arg (1- arg)))
1227 (block-ending-pos
1228 (save-excursion (python-nav-end-of-block)))
1229 (next-block-starting-pos
1230 (save-excursion (python-nav-forward-block))))
1231 (cond ((not block-starting-pos)
1232 (python-nav-forward-block))
1233 ((= (point) block-starting-pos)
1234 (if (or (not next-block-starting-pos)
1235 (< block-ending-pos next-block-starting-pos))
1236 (python-nav-end-of-block)
1237 (python-nav-forward-block)))
1238 ((= block-ending-pos (point))
1239 (let ((parent-block-end-pos
1240 (save-excursion
1241 (python-util-forward-comment)
1242 (python-nav-beginning-of-block)
1243 (python-nav-end-of-block))))
1244 (if (and parent-block-end-pos
1245 (or (not next-block-starting-pos)
1246 (> next-block-starting-pos parent-block-end-pos)))
1247 (goto-char parent-block-end-pos)
1248 (python-nav-forward-block))))
1249 (t (python-nav-end-of-block))))
1250 (setq arg (1- arg)))
1251 (while (< arg 0) 1422 (while (< arg 0)
1252 (let* ((block-starting-pos 1423 (python-nav--backward-sexp)
1253 (save-excursion (python-nav-beginning-of-block)))
1254 (block-ending-pos
1255 (save-excursion (python-nav-end-of-block)))
1256 (prev-block-ending-pos
1257 (save-excursion (when (python-nav-backward-block)
1258 (python-nav-end-of-block))))
1259 (prev-block-parent-ending-pos
1260 (save-excursion
1261 (when prev-block-ending-pos
1262 (goto-char prev-block-ending-pos)
1263 (python-util-forward-comment)
1264 (python-nav-beginning-of-block)
1265 (python-nav-end-of-block)))))
1266 (cond ((not block-ending-pos)
1267 (and (python-nav-backward-block)
1268 (python-nav-end-of-block)))
1269 ((= (point) block-ending-pos)
1270 (let ((candidates))
1271 (dolist (name
1272 '(prev-block-parent-ending-pos
1273 prev-block-ending-pos
1274 block-ending-pos
1275 block-starting-pos))
1276 (when (and (symbol-value name)
1277 (< (symbol-value name) (point)))
1278 (add-to-list 'candidates (symbol-value name))))
1279 (goto-char (apply 'max candidates))))
1280 ((> (point) block-ending-pos)
1281 (python-nav-end-of-block))
1282 ((= (point) block-starting-pos)
1283 (if (not (> (point) (or prev-block-ending-pos (point))))
1284 (python-nav-backward-block)
1285 (goto-char prev-block-ending-pos)
1286 (let ((parent-block-ending-pos
1287 (save-excursion
1288 (python-nav-forward-sexp-function)
1289 (and (not (looking-at (python-rx block-start)))
1290 (point)))))
1291 (when (and parent-block-ending-pos
1292 (> parent-block-ending-pos prev-block-ending-pos))
1293 (goto-char parent-block-ending-pos)))))
1294 (t (python-nav-beginning-of-block))))
1295 (setq arg (1+ arg)))) 1424 (setq arg (1+ arg))))
1296 1425
1297 1426
@@ -1420,16 +1549,12 @@ virtualenv."
1420If 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
1421returns a string with the form 1550returns a string with the form
1422`python-shell-buffer-name'[variable `buffer-file-name'] else 1551`python-shell-buffer-name'[variable `buffer-file-name'] else
1423returns the value of `python-shell-buffer-name'. After 1552returns the value of `python-shell-buffer-name'."
1424calculating the process name adds the buffer name for the process
1425in the `same-window-buffer-names' list."
1426 (let ((process-name 1553 (let ((process-name
1427 (if (and dedicated 1554 (if (and dedicated
1428 buffer-file-name) 1555 buffer-file-name)
1429 (format "%s[%s]" python-shell-buffer-name buffer-file-name) 1556 (format "%s[%s]" python-shell-buffer-name buffer-file-name)
1430 (format "%s" python-shell-buffer-name)))) 1557 (format "%s" python-shell-buffer-name))))
1431 (add-to-list 'same-window-buffer-names (purecopy
1432 (format "*%s*" process-name)))
1433 process-name)) 1558 process-name))
1434 1559
1435(defun python-shell-internal-get-process-name () 1560(defun python-shell-internal-get-process-name ()
@@ -1539,6 +1664,9 @@ variable.
1539 'python-shell-completion-complete-at-point) 1664 'python-shell-completion-complete-at-point)
1540 (define-key inferior-python-mode-map "\t" 1665 (define-key inferior-python-mode-map "\t"
1541 '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)
1542 (when python-shell-enable-font-lock 1670 (when python-shell-enable-font-lock
1543 (set (make-local-variable 'font-lock-defaults) 1671 (set (make-local-variable 'font-lock-defaults)
1544 '(python-font-lock-keywords nil nil nil nil)) 1672 '(python-font-lock-keywords nil nil nil nil))
@@ -1546,26 +1674,34 @@ variable.
1546 python-syntax-propertize-function)) 1674 python-syntax-propertize-function))
1547 (compilation-shell-minor-mode 1)) 1675 (compilation-shell-minor-mode 1))
1548 1676
1549(defun python-shell-make-comint (cmd proc-name &optional pop) 1677(defun python-shell-make-comint (cmd proc-name &optional pop internal)
1550 "Create a python shell comint buffer. 1678 "Create a python shell comint buffer.
1551CMD 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
1552process name the comint buffer will get. After the comint buffer 1680process name the comint buffer will get. After the comint buffer
1553is created the `inferior-python-mode' is activated. If POP is 1681is created the `inferior-python-mode' is activated. When
1554non-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."
1555 (save-excursion 1688 (save-excursion
1556 (let* ((proc-buffer-name (format "*%s*" proc-name)) 1689 (let* ((proc-buffer-name
1690 (format (if (not internal) "*%s*" " *%s*") proc-name))
1557 (process-environment (python-shell-calculate-process-environment)) 1691 (process-environment (python-shell-calculate-process-environment))
1558 (exec-path (python-shell-calculate-exec-path))) 1692 (exec-path (python-shell-calculate-exec-path)))
1559 (when (not (comint-check-proc proc-buffer-name)) 1693 (when (not (comint-check-proc proc-buffer-name))
1560 (let* ((cmdlist (split-string-and-unquote cmd)) 1694 (let* ((cmdlist (split-string-and-unquote cmd))
1561 (buffer (apply 'make-comint proc-name (car cmdlist) nil 1695 (buffer (apply #'make-comint-in-buffer proc-name proc-buffer-name
1562 (cdr cmdlist))) 1696 (car cmdlist) nil (cdr cmdlist)))
1563 (current-buffer (current-buffer))) 1697 (current-buffer (current-buffer))
1698 (process (get-buffer-process buffer)))
1564 (with-current-buffer buffer 1699 (with-current-buffer buffer
1565 (inferior-python-mode) 1700 (inferior-python-mode)
1566 (python-util-clone-local-variables current-buffer)) 1701 (python-util-clone-local-variables current-buffer))
1567 (accept-process-output (get-buffer-process buffer)))) 1702 (accept-process-output process)
1568 (and pop (pop-to-buffer proc-buffer-name t)) 1703 (and pop (pop-to-buffer buffer t))
1704 (and internal (set-process-query-on-exit-flag process nil))))
1569 proc-buffer-name))) 1705 proc-buffer-name)))
1570 1706
1571;;;###autoload 1707;;;###autoload
@@ -1611,11 +1747,10 @@ are set to nil for these shells, so setup codes are not sent at
1611startup." 1747startup."
1612 (let ((python-shell-enable-font-lock nil) 1748 (let ((python-shell-enable-font-lock nil)
1613 (inferior-python-mode-hook nil)) 1749 (inferior-python-mode-hook nil))
1614 (set-process-query-on-exit-flag 1750 (get-buffer-process
1615 (get-buffer-process 1751 (python-shell-make-comint
1616 (python-shell-make-comint 1752 (python-shell-parse-command)
1617 (python-shell-parse-command) 1753 (python-shell-internal-get-process-name) nil t))))
1618 (python-shell-internal-get-process-name))) nil)))
1619 1754
1620(defun python-shell-get-process () 1755(defun python-shell-get-process ()
1621 "Get inferior Python process for current buffer and return it." 1756 "Get inferior Python process for current buffer and return it."
@@ -1651,18 +1786,16 @@ startup."
1651 "Current internal shell buffer for the current buffer. 1786 "Current internal shell buffer for the current buffer.
1652This 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
1653there for compatibility with CEDET.") 1788there for compatibility with CEDET.")
1654(make-variable-buffer-local 'python-shell-internal-buffer)
1655 1789
1656(defvar python-shell-internal-last-output nil 1790(defvar python-shell-internal-last-output nil
1657 "Last output captured by the internal shell. 1791 "Last output captured by the internal shell.
1658This is really not necessary at all for the code to work but it's 1792This is really not necessary at all for the code to work but it's
1659there for compatibility with CEDET.") 1793there for compatibility with CEDET.")
1660(make-variable-buffer-local 'python-shell-internal-last-output)
1661 1794
1662(defun python-shell-internal-get-or-create-process () 1795(defun python-shell-internal-get-or-create-process ()
1663 "Get or create an inferior Internal Python process." 1796 "Get or create an inferior Internal Python process."
1664 (let* ((proc-name (python-shell-internal-get-process-name)) 1797 (let* ((proc-name (python-shell-internal-get-process-name))
1665 (proc-buffer-name (format "*%s*" proc-name))) 1798 (proc-buffer-name (format " *%s*" proc-name)))
1666 (when (not (process-live-p proc-name)) 1799 (when (not (process-live-p proc-name))
1667 (run-python-internal) 1800 (run-python-internal)
1668 (setq python-shell-internal-buffer proc-buffer-name) 1801 (setq python-shell-internal-buffer proc-buffer-name)
@@ -1675,13 +1808,13 @@ there for compatibility with CEDET.")
1675 (get-buffer-process proc-buffer-name))) 1808 (get-buffer-process proc-buffer-name)))
1676 1809
1677(define-obsolete-function-alias 1810(define-obsolete-function-alias
1678 'python-proc 'python-shell-internal-get-or-create-process "24.2") 1811 'python-proc 'python-shell-internal-get-or-create-process "24.3")
1679 1812
1680(define-obsolete-variable-alias 1813(define-obsolete-variable-alias
1681 'python-buffer 'python-shell-internal-buffer "24.2") 1814 'python-buffer 'python-shell-internal-buffer "24.3")
1682 1815
1683(define-obsolete-variable-alias 1816(define-obsolete-variable-alias
1684 'python-preoutput-result 'python-shell-internal-last-output "24.2") 1817 'python-preoutput-result 'python-shell-internal-last-output "24.3")
1685 1818
1686(defun python-shell-send-string (string &optional process msg) 1819(defun python-shell-send-string (string &optional process msg)
1687 "Send STRING to inferior Python PROCESS. 1820 "Send STRING to inferior Python PROCESS.
@@ -1689,8 +1822,7 @@ When MSG is non-nil messages the first line of STRING."
1689 (interactive "sPython command: ") 1822 (interactive "sPython command: ")
1690 (let ((process (or process (python-shell-get-or-create-process))) 1823 (let ((process (or process (python-shell-get-or-create-process)))
1691 (lines (split-string string "\n" t))) 1824 (lines (split-string string "\n" t)))
1692 (when msg 1825 (and msg (message "Sent: %s..." (nth 0 lines)))
1693 (message (format "Sent: %s..." (nth 0 lines))))
1694 (if (> (length lines) 1) 1826 (if (> (length lines) 1)
1695 (let* ((temp-file-name (make-temp-file "py")) 1827 (let* ((temp-file-name (make-temp-file "py"))
1696 (file-name (or (buffer-file-name) temp-file-name))) 1828 (file-name (or (buffer-file-name) temp-file-name)))
@@ -1744,10 +1876,10 @@ Returns the output. See `python-shell-send-string-no-output'."
1744 (python-shell-internal-get-or-create-process) nil))) 1876 (python-shell-internal-get-or-create-process) nil)))
1745 1877
1746(define-obsolete-function-alias 1878(define-obsolete-function-alias
1747 'python-send-receive 'python-shell-internal-send-string "24.2") 1879 'python-send-receive 'python-shell-internal-send-string "24.3")
1748 1880
1749(define-obsolete-function-alias 1881(define-obsolete-function-alias
1750 'python-send-string 'python-shell-internal-send-string "24.2") 1882 'python-send-string 'python-shell-internal-send-string "24.3")
1751 1883
1752(defun python-shell-send-region (start end) 1884(defun python-shell-send-region (start end)
1753 "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."
@@ -1820,11 +1952,10 @@ FILE-NAME."
1820 "Send all setup code for shell. 1952 "Send all setup code for shell.
1821This function takes the list of setup code to send from the 1953This function takes the list of setup code to send from the
1822`python-shell-setup-codes' list." 1954`python-shell-setup-codes' list."
1823 (let ((msg "Sent %s") 1955 (let ((process (get-buffer-process (current-buffer))))
1824 (process (get-buffer-process (current-buffer))))
1825 (dolist (code python-shell-setup-codes) 1956 (dolist (code python-shell-setup-codes)
1826 (when code 1957 (when code
1827 (message (format msg code)) 1958 (message "Sent %s" code)
1828 (python-shell-send-string 1959 (python-shell-send-string
1829 (symbol-value code) process))))) 1960 (symbol-value code) process)))))
1830 1961
@@ -1885,27 +2016,71 @@ and use the following as the value of this variable:
1885 :type 'string 2016 :type 'string
1886 :group 'python) 2017 :group 'python)
1887 2018
1888(defun python-shell-completion--get-completions (input process completion-code) 2019(defun python-shell-completion-get-completions (process line input)
1889 "Retrieve available completions for INPUT using PROCESS. 2020 "Do completion at point for PROCESS.
1890Argument COMPLETION-CODE is the python code used to get 2021LINE is used to detect the context on how to complete given
1891completions on the current context." 2022INPUT."
1892 (with-current-buffer (process-buffer process) 2023 (let* ((prompt
1893 (let ((completions (python-shell-send-string-no-output 2024 ;; Get the last prompt for the inferior process
1894 (format completion-code input) process))) 2025 ;; buffer. This is used for the completion code selection
1895 (when (> (length completions) 2) 2026 ;; heuristic.
1896 (split-string completions "^'\\|^\"\\|;\\|'$\\|\"$" t))))) 2027 (with-current-buffer (process-buffer process)
1897 2028 (buffer-substring-no-properties
1898(defun python-shell-completion--do-completion-at-point (process) 2029 (overlay-start comint-last-prompt-overlay)
1899 "Do completion at point for PROCESS." 2030 (overlay-end comint-last-prompt-overlay))))
1900 (with-syntax-table python-dotty-syntax-table 2031 (completion-context
1901 (let* ((beg 2032 ;; Check whether a prompt matches a pdb string, an import
1902 (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
1903 (let* ((paren-depth (car (syntax-ppss))) 2076 (let* ((paren-depth (car (syntax-ppss)))
1904 (syntax-string "w_") 2077 (syntax-string "w_")
1905 (syntax-list (string-to-syntax syntax-string))) 2078 (syntax-list (string-to-syntax syntax-string)))
1906 ;; Stop scanning for the beginning of the completion subject 2079 ;; Stop scanning for the beginning of the completion
1907 ;; after the char before point matches a delimiter 2080 ;; subject after the char before point matches a
1908 (while (member (car (syntax-after (1- (point)))) syntax-list) 2081 ;; delimiter
2082 (while (member
2083 (car (syntax-after (1- (point)))) syntax-list)
1909 (skip-syntax-backward syntax-string) 2084 (skip-syntax-backward syntax-string)
1910 (when (or (equal (char-before) ?\)) 2085 (when (or (equal (char-before) ?\))
1911 (equal (char-before) ?\")) 2086 (equal (char-before) ?\"))
@@ -1913,59 +2088,16 @@ completions on the current context."
1913 (while (or 2088 (while (or
1914 ;; honor initial paren depth 2089 ;; honor initial paren depth
1915 (> (car (syntax-ppss)) paren-depth) 2090 (> (car (syntax-ppss)) paren-depth)
1916 (python-info-ppss-context 'string)) 2091 (python-syntax-context 'string))
1917 (forward-char -1)))) 2092 (forward-char -1)))
1918 (point))) 2093 (point)))))
1919 (end (point)) 2094 (end (point)))
1920 (line (buffer-substring-no-properties (point-at-bol) end)) 2095 (list start end
1921 (input (buffer-substring-no-properties beg end)) 2096 (completion-table-dynamic
1922 ;; Get the last prompt for the inferior process buffer. This is 2097 (apply-partially
1923 ;; used for the completion code selection heuristic. 2098 #'python-shell-completion-get-completions
1924 (prompt 2099 process (buffer-substring-no-properties
1925 (with-current-buffer (process-buffer process) 2100 (line-beginning-position) end))))))
1926 (buffer-substring-no-properties
1927 (overlay-start comint-last-prompt-overlay)
1928 (overlay-end comint-last-prompt-overlay))))
1929 (completion-context
1930 ;; Check whether a prompt matches a pdb string, an import statement
1931 ;; or just the standard prompt and use the correct
1932 ;; python-shell-completion-*-code string
1933 (cond ((and (> (length python-shell-completion-pdb-string-code) 0)
1934 (string-match
1935 (concat "^" python-shell-prompt-pdb-regexp) prompt))
1936 'pdb)
1937 ((and (>
1938 (length python-shell-completion-module-string-code) 0)
1939 (string-match
1940 (concat "^" python-shell-prompt-regexp) prompt)
1941 (string-match "^[ \t]*\\(from\\|import\\)[ \t]" line))
1942 'import)
1943 ((string-match
1944 (concat "^" python-shell-prompt-regexp) prompt)
1945 'default)
1946 (t nil)))
1947 (completion-code
1948 (case completion-context
1949 ('pdb python-shell-completion-pdb-string-code)
1950 ('import python-shell-completion-module-string-code)
1951 ('default python-shell-completion-string-code)
1952 (t nil)))
1953 (input
1954 (if (eq completion-context 'import)
1955 (replace-regexp-in-string "^[ \t]+" "" line)
1956 input))
1957 (completions
1958 (and completion-code (> (length input) 0)
1959 (python-shell-completion--get-completions
1960 input process completion-code))))
1961 (list beg end completions))))
1962
1963(defun python-shell-completion-complete-at-point ()
1964 "Perform completion at point in inferior Python process."
1965 (and comint-last-prompt-overlay
1966 (> (point-marker) (overlay-end comint-last-prompt-overlay))
1967 (python-shell-completion--do-completion-at-point
1968 (get-buffer-process (current-buffer)))))
1969 2101
1970(defun python-shell-completion-complete-or-indent () 2102(defun python-shell-completion-complete-or-indent ()
1971 "Complete or indent depending on the context. 2103 "Complete or indent depending on the context.
@@ -1999,11 +2131,9 @@ Used to extract the current line and module being inspected."
1999 "Variable containing the value of the current tracked buffer. 2131 "Variable containing the value of the current tracked buffer.
2000Never set this variable directly, use 2132Never set this variable directly, use
2001`python-pdbtrack-set-tracked-buffer' instead.") 2133`python-pdbtrack-set-tracked-buffer' instead.")
2002(make-variable-buffer-local 'python-pdbtrack-tracked-buffer)
2003 2134
2004(defvar python-pdbtrack-buffers-to-kill nil 2135(defvar python-pdbtrack-buffers-to-kill nil
2005 "List of buffers to be deleted after tracking finishes.") 2136 "List of buffers to be deleted after tracking finishes.")
2006(make-variable-buffer-local 'python-pdbtrack-buffers-to-kill)
2007 2137
2008(defun python-pdbtrack-set-tracked-buffer (file-name) 2138(defun python-pdbtrack-set-tracked-buffer (file-name)
2009 "Set the buffer for FILE-NAME as the tracked buffer. 2139 "Set the buffer for FILE-NAME as the tracked buffer.
@@ -2079,7 +2209,7 @@ inferior python process is updated properly."
2079 (let ((process (python-shell-get-process))) 2209 (let ((process (python-shell-get-process)))
2080 (if (not process) 2210 (if (not process)
2081 (error "Completion needs an inferior Python process running") 2211 (error "Completion needs an inferior Python process running")
2082 (python-shell-completion--do-completion-at-point process)))) 2212 (python-shell-completion-complete-at-point process))))
2083 2213
2084(add-to-list 'debug-ignored-errors 2214(add-to-list 'debug-ignored-errors
2085 "^Completion needs an inferior Python process running.") 2215 "^Completion needs an inferior Python process running.")
@@ -2133,7 +2263,7 @@ Optional argument JUSTIFY defines if the paragraph should be justified."
2133 ((funcall python-fill-comment-function justify)) 2263 ((funcall python-fill-comment-function justify))
2134 ;; Strings/Docstrings 2264 ;; Strings/Docstrings
2135 ((save-excursion (skip-chars-forward "\"'uUrR") 2265 ((save-excursion (skip-chars-forward "\"'uUrR")
2136 (python-info-ppss-context 'string)) 2266 (python-syntax-context 'string))
2137 (funcall python-fill-string-function justify)) 2267 (funcall python-fill-string-function justify))
2138 ;; Decorators 2268 ;; Decorators
2139 ((equal (char-after (save-excursion 2269 ((equal (char-after (save-excursion
@@ -2141,7 +2271,7 @@ Optional argument JUSTIFY defines if the paragraph should be justified."
2141 (point-marker))) ?@) 2271 (point-marker))) ?@)
2142 (funcall python-fill-decorator-function justify)) 2272 (funcall python-fill-decorator-function justify))
2143 ;; Parens 2273 ;; Parens
2144 ((or (python-info-ppss-context 'paren) 2274 ((or (python-syntax-context 'paren)
2145 (looking-at (python-rx open-paren)) 2275 (looking-at (python-rx open-paren))
2146 (save-excursion 2276 (save-excursion
2147 (skip-syntax-forward "^(" (line-end-position)) 2277 (skip-syntax-forward "^(" (line-end-position))
@@ -2161,13 +2291,13 @@ JUSTIFY should be used (if applicable) as in `fill-paragraph'."
2161 (string-start-marker 2291 (string-start-marker
2162 (progn 2292 (progn
2163 (skip-chars-forward "\"'uUrR") 2293 (skip-chars-forward "\"'uUrR")
2164 (goto-char (python-info-ppss-context 'string)) 2294 (goto-char (python-syntax-context 'string))
2165 (skip-chars-forward "\"'uUrR") 2295 (skip-chars-forward "\"'uUrR")
2166 (point-marker))) 2296 (point-marker)))
2167 (reg-start (line-beginning-position)) 2297 (reg-start (line-beginning-position))
2168 (string-end-marker 2298 (string-end-marker
2169 (progn 2299 (progn
2170 (while (python-info-ppss-context 'string) 2300 (while (python-syntax-context 'string)
2171 (goto-char (1+ (point-marker)))) 2301 (goto-char (1+ (point-marker))))
2172 (skip-chars-backward "\"'") 2302 (skip-chars-backward "\"'")
2173 (point-marker))) 2303 (point-marker)))
@@ -2205,16 +2335,16 @@ JUSTIFY should be used (if applicable) as in `fill-paragraph'."
2205JUSTIFY should be used (if applicable) as in `fill-paragraph'." 2335JUSTIFY should be used (if applicable) as in `fill-paragraph'."
2206 (save-restriction 2336 (save-restriction
2207 (narrow-to-region (progn 2337 (narrow-to-region (progn
2208 (while (python-info-ppss-context 'paren) 2338 (while (python-syntax-context 'paren)
2209 (goto-char (1- (point-marker)))) 2339 (goto-char (1- (point-marker))))
2210 (point-marker) 2340 (point-marker)
2211 (line-beginning-position)) 2341 (line-beginning-position))
2212 (progn 2342 (progn
2213 (when (not (python-info-ppss-context 'paren)) 2343 (when (not (python-syntax-context 'paren))
2214 (end-of-line) 2344 (end-of-line)
2215 (when (not (python-info-ppss-context 'paren)) 2345 (when (not (python-syntax-context 'paren))
2216 (skip-syntax-backward "^)"))) 2346 (skip-syntax-backward "^)")))
2217 (while (python-info-ppss-context 'paren) 2347 (while (python-syntax-context 'paren)
2218 (goto-char (1+ (point-marker)))) 2348 (goto-char (1+ (point-marker))))
2219 (point-marker))) 2349 (point-marker)))
2220 (let ((paragraph-start "\f\\|[ \t]*$") 2350 (let ((paragraph-start "\f\\|[ \t]*$")
@@ -2239,7 +2369,7 @@ the if condition."
2239 :safe 'booleanp) 2369 :safe 'booleanp)
2240 2370
2241(define-obsolete-variable-alias 2371(define-obsolete-variable-alias
2242 'python-use-skeletons 'python-skeleton-autoinsert "24.2") 2372 'python-use-skeletons 'python-skeleton-autoinsert "24.3")
2243 2373
2244(defvar python-skeleton-available '() 2374(defvar python-skeleton-available '()
2245 "Internal list of available skeletons.") 2375 "Internal list of available skeletons.")
@@ -2252,7 +2382,7 @@ the if condition."
2252 ;; Only expand in code. 2382 ;; Only expand in code.
2253 :enable-function (lambda () 2383 :enable-function (lambda ()
2254 (and 2384 (and
2255 (not (python-info-ppss-comment-or-string-p)) 2385 (not (python-syntax-comment-or-string-p))
2256 python-skeleton-autoinsert))) 2386 python-skeleton-autoinsert)))
2257 2387
2258(defmacro python-skeleton-define (name doc &rest skel) 2388(defmacro python-skeleton-define (name doc &rest skel)
@@ -2572,7 +2702,7 @@ not inside a defun."
2572With optional argument REPLACE-SELF convert \"self\" to current 2702With optional argument REPLACE-SELF convert \"self\" to current
2573parent defun name." 2703parent defun name."
2574 (let ((name 2704 (let ((name
2575 (and (not (python-info-ppss-comment-or-string-p)) 2705 (and (not (python-syntax-comment-or-string-p))
2576 (with-syntax-table python-dotty-syntax-table 2706 (with-syntax-table python-dotty-syntax-table
2577 (let ((sym (symbol-at-point))) 2707 (let ((sym (symbol-at-point)))
2578 (and sym 2708 (and sym
@@ -2650,7 +2780,7 @@ With optional argument LINE-NUMBER, check that line instead."
2650 (goto-char line-number)) 2780 (goto-char line-number))
2651 (while (and (not (eobp)) 2781 (while (and (not (eobp))
2652 (goto-char (line-end-position)) 2782 (goto-char (line-end-position))
2653 (python-info-ppss-context 'paren) 2783 (python-syntax-context 'paren)
2654 (not (equal (char-before (point)) ?\\))) 2784 (not (equal (char-before (point)) ?\\)))
2655 (forward-line 1)) 2785 (forward-line 1))
2656 (when (equal (char-before) ?\\) 2786 (when (equal (char-before) ?\\)
@@ -2667,7 +2797,7 @@ Optional argument LINE-NUMBER forces the line number to check against."
2667 (when (python-info-line-ends-backslash-p) 2797 (when (python-info-line-ends-backslash-p)
2668 (while (save-excursion 2798 (while (save-excursion
2669 (goto-char (line-beginning-position)) 2799 (goto-char (line-beginning-position))
2670 (python-info-ppss-context 'paren)) 2800 (python-syntax-context 'paren))
2671 (forward-line -1)) 2801 (forward-line -1))
2672 (back-to-indentation) 2802 (back-to-indentation)
2673 (point-marker))))) 2803 (point-marker)))))
@@ -2681,10 +2811,10 @@ where the continued line ends."
2681 (widen) 2811 (widen)
2682 (let* ((context-type (progn 2812 (let* ((context-type (progn
2683 (back-to-indentation) 2813 (back-to-indentation)
2684 (python-info-ppss-context-type))) 2814 (python-syntax-context-type)))
2685 (line-start (line-number-at-pos)) 2815 (line-start (line-number-at-pos))
2686 (context-start (when context-type 2816 (context-start (when context-type
2687 (python-info-ppss-context context-type)))) 2817 (python-syntax-context context-type))))
2688 (cond ((equal context-type 'paren) 2818 (cond ((equal context-type 'paren)
2689 ;; Lines inside a paren are always a continuation line 2819 ;; Lines inside a paren are always a continuation line
2690 ;; (except the first one). 2820 ;; (except the first one).
@@ -2729,41 +2859,13 @@ operator."
2729 assignment-operator 2859 assignment-operator
2730 not-simple-operator) 2860 not-simple-operator)
2731 (line-end-position) t) 2861 (line-end-position) t)
2732 (not (python-info-ppss-context-type)))) 2862 (not (python-syntax-context-type))))
2733 (skip-syntax-forward "\s") 2863 (skip-syntax-forward "\s")
2734 (point-marker))))) 2864 (point-marker)))))
2735 2865
2736(defun python-info-ppss-context (type &optional syntax-ppss)
2737 "Return non-nil if point is on TYPE using SYNTAX-PPSS.
2738TYPE can be `comment', `string' or `paren'. It returns the start
2739character address of the specified TYPE."
2740 (let ((ppss (or syntax-ppss (syntax-ppss))))
2741 (case type
2742 (comment
2743 (and (nth 4 ppss)
2744 (nth 8 ppss)))
2745 (string
2746 (and (not (nth 4 ppss))
2747 (nth 8 ppss)))
2748 (paren
2749 (nth 1 ppss))
2750 (t nil))))
2751
2752(defun python-info-ppss-context-type (&optional syntax-ppss)
2753 "Return the context type using SYNTAX-PPSS.
2754The type returned can be `comment', `string' or `paren'."
2755 (let ((ppss (or syntax-ppss (syntax-ppss))))
2756 (cond
2757 ((nth 8 ppss) (if (nth 4 ppss) 'comment 'string))
2758 ((nth 1 ppss) 'paren))))
2759
2760(defsubst python-info-ppss-comment-or-string-p ()
2761 "Return non-nil if point is inside 'comment or 'string."
2762 (nth 8 (syntax-ppss)))
2763
2764(defun python-info-looking-at-beginning-of-defun (&optional syntax-ppss) 2866(defun python-info-looking-at-beginning-of-defun (&optional syntax-ppss)
2765 "Check if point is at `beginning-of-defun' using SYNTAX-PPSS." 2867 "Check if point is at `beginning-of-defun' using SYNTAX-PPSS."
2766 (and (not (python-info-ppss-context-type (or syntax-ppss (syntax-ppss)))) 2868 (and (not (python-syntax-context-type (or syntax-ppss (syntax-ppss))))
2767 (save-excursion 2869 (save-excursion
2768 (beginning-of-line 1) 2870 (beginning-of-line 1)
2769 (looking-at python-nav-beginning-of-defun-regexp)))) 2871 (looking-at python-nav-beginning-of-defun-regexp))))
@@ -2809,7 +2911,7 @@ to \"^python-\"."
2809(defun python-util-forward-comment (&optional direction) 2911(defun python-util-forward-comment (&optional direction)
2810 "Python mode specific version of `forward-comment'. 2912 "Python mode specific version of `forward-comment'.
2811Optional argument DIRECTION defines the direction to move to." 2913Optional argument DIRECTION defines the direction to move to."
2812 (let ((comment-start (python-info-ppss-context 'comment)) 2914 (let ((comment-start (python-syntax-context 'comment))
2813 (factor (if (< (or direction 0) 0) 2915 (factor (if (< (or direction 0) 0)
2814 -99999 2916 -99999
2815 99999))) 2917 99999)))
@@ -2835,7 +2937,7 @@ if that value is non-nil."
2835 (set (make-local-variable 'parse-sexp-ignore-comments) t) 2937 (set (make-local-variable 'parse-sexp-ignore-comments) t)
2836 2938
2837 (set (make-local-variable 'forward-sexp-function) 2939 (set (make-local-variable 'forward-sexp-function)
2838 'python-nav-forward-sexp-function) 2940 'python-nav-forward-sexp)
2839 2941
2840 (set (make-local-variable 'font-lock-defaults) 2942 (set (make-local-variable 'font-lock-defaults)
2841 '(python-font-lock-keywords nil nil nil nil)) 2943 '(python-font-lock-keywords nil nil nil nil))
@@ -2896,6 +2998,8 @@ if that value is non-nil."
2896 2998
2897 (python-skeleton-add-menu-items) 2999 (python-skeleton-add-menu-items)
2898 3000
3001 (make-local-variable 'python-shell-internal-buffer)
3002
2899 (when python-indent-guess-indent-offset 3003 (when python-indent-guess-indent-offset
2900 (python-indent-guess-indent-offset))) 3004 (python-indent-guess-indent-offset)))
2901 3005