aboutsummaryrefslogtreecommitdiffstats
path: root/lisp/progmodes/python.el
diff options
context:
space:
mode:
authorEli Zaretskii2012-10-08 15:06:31 +0200
committerEli Zaretskii2012-10-08 15:06:31 +0200
commit7014794467aac02be3a935a093e1bfb8ad410c12 (patch)
tree0aa27b30dcdc8fc4e63c8d88d9b878d0b3ff9765 /lisp/progmodes/python.el
parentd6de17607045c1d33826a12983e33deb73426457 (diff)
parentc54ebba4e076caeb6105c6bb682252b139a169fa (diff)
downloademacs-7014794467aac02be3a935a093e1bfb8ad410c12.tar.gz
emacs-7014794467aac02be3a935a093e1bfb8ad410c12.zip
Merge from trunk after cygw32 commit, and resolve conflicts.
Diffstat (limited to 'lisp/progmodes/python.el')
-rw-r--r--lisp/progmodes/python.el312
1 files changed, 155 insertions, 157 deletions
diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el
index 726c0b2d542..6b0dc954ca7 100644
--- a/lisp/progmodes/python.el
+++ b/lisp/progmodes/python.el
@@ -676,12 +676,12 @@ START is the buffer position where the sexp starts."
676 (goto-char (line-beginning-position)) 676 (goto-char (line-beginning-position))
677 (bobp)) 677 (bobp))
678 'no-indent) 678 'no-indent)
679 ;; Inside a paren
680 ((setq start (python-syntax-context 'paren ppss))
681 'inside-paren)
682 ;; Inside string 679 ;; Inside string
683 ((setq start (python-syntax-context 'string ppss)) 680 ((setq start (python-syntax-context 'string ppss))
684 'inside-string) 681 'inside-string)
682 ;; Inside a paren
683 ((setq start (python-syntax-context 'paren ppss))
684 'inside-paren)
685 ;; After backslash 685 ;; After backslash
686 ((setq start (when (not (or (python-syntax-context 'string ppss) 686 ((setq start (when (not (or (python-syntax-context 'string ppss)
687 (python-syntax-context 'comment ppss))) 687 (python-syntax-context 'comment ppss)))
@@ -710,7 +710,7 @@ START is the buffer position where the sexp starts."
710 ;; After normal line 710 ;; After normal line
711 ((setq start (save-excursion 711 ((setq start (save-excursion
712 (back-to-indentation) 712 (back-to-indentation)
713 (python-util-forward-comment -1) 713 (skip-chars-backward (rx (or whitespace ?\n)))
714 (python-nav-beginning-of-statement) 714 (python-nav-beginning-of-statement)
715 (point-marker))) 715 (point-marker)))
716 'after-line) 716 'after-line)
@@ -973,7 +973,16 @@ Called from a program, START and END specify the region to indent."
973 (back-to-indentation) 973 (back-to-indentation)
974 (setq word (current-word)) 974 (setq word (current-word))
975 (forward-line 1) 975 (forward-line 1)
976 (when word 976 (when (and word
977 ;; Don't mess with strings, unless it's the
978 ;; enclosing set of quotes.
979 (or (not (python-syntax-context 'string))
980 (eq
981 (syntax-after
982 (+ (1- (point))
983 (current-indentation)
984 (python-syntax-count-quotes (char-after) (point))))
985 (string-to-syntax "|"))))
977 (beginning-of-line) 986 (beginning-of-line)
978 (delete-horizontal-space) 987 (delete-horizontal-space)
979 (indent-to (python-indent-calculate-indentation))))) 988 (indent-to (python-indent-calculate-indentation)))))
@@ -1160,7 +1169,8 @@ Returns nil if point is not in a def or class."
1160 (python-info-line-ends-backslash-p)) 1169 (python-info-line-ends-backslash-p))
1161 (python-syntax-context 'string) 1170 (python-syntax-context 'string)
1162 (python-syntax-context 'paren)) 1171 (python-syntax-context 'paren))
1163 (forward-line -1))))) 1172 (forward-line -1))))
1173 (point-marker))
1164 1174
1165(defun python-nav-end-of-statement () 1175(defun python-nav-end-of-statement ()
1166 "Move to end of current statement." 1176 "Move to end of current statement."
@@ -1171,7 +1181,8 @@ Returns nil if point is not in a def or class."
1171 (python-info-line-ends-backslash-p) 1181 (python-info-line-ends-backslash-p)
1172 (python-syntax-context 'string) 1182 (python-syntax-context 'string)
1173 (python-syntax-context 'paren)) 1183 (python-syntax-context 'paren))
1174 (forward-line 1))))) 1184 (forward-line 1))))
1185 (point-marker))
1175 1186
1176(defun python-nav-backward-statement (&optional arg) 1187(defun python-nav-backward-statement (&optional arg)
1177 "Move backward to previous statement. 1188 "Move backward to previous statement.
@@ -1286,151 +1297,104 @@ When ARG > 0 move forward, else if ARG is < 0."
1286 (while (and (funcall search-fn paren-regexp nil t) 1297 (while (and (funcall search-fn paren-regexp nil t)
1287 (python-syntax-context 'paren))))))) 1298 (python-syntax-context 'paren)))))))
1288 1299
1289(defun python-nav--forward-sexp () 1300(defun python-nav--forward-sexp (&optional dir)
1290 "Move to forward sexp." 1301 "Move to forward sexp.
1291 (case (python-syntax-context-type) 1302With positive Optional argument DIR direction move forward, else
1292 (string 1303backwards."
1293 ;; Inside of a string, get out of it. 1304 (setq dir (or dir 1))
1294 (while (and (re-search-forward "[\"']" nil t) 1305 (unless (= dir 0)
1295 (python-syntax-context 'string)))) 1306 (let* ((forward-p (if (> dir 0)
1296 (comment 1307 (and (setq dir 1) t)
1297 ;; Inside of a comment, just move forward. 1308 (and (setq dir -1) nil)))
1298 (python-util-forward-comment)) 1309 (re-search-fn (if forward-p
1299 (paren 1310 're-search-forward
1300 (python-nav-lisp-forward-sexp-safe 1)) 1311 're-search-backward))
1301 (t 1312 (context-type (python-syntax-context-type)))
1302 (if (and (not (eobp)) 1313 (cond
1303 (= (syntax-class (syntax-after (point))) 4)) 1314 ((eq context-type 'string)
1304 ;; Looking an open-paren 1315 ;; Inside of a string, get out of it.
1305 (python-nav-lisp-forward-sexp-safe 1) 1316 (while (and (funcall re-search-fn "[\"']" nil t)
1306 (let ((block-starting-pos 1317 (python-syntax-context 'string))))
1307 (save-excursion (python-nav-beginning-of-block))) 1318 ((eq context-type 'comment)
1308 (block-ending-pos 1319 ;; Inside of a comment, just move forward.
1309 (save-excursion (python-nav-end-of-block))) 1320 (python-util-forward-comment dir))
1310 (next-block-starting-pos 1321 ((or (eq context-type 'paren)
1311 (save-excursion (python-nav-forward-block)))) 1322 (and forward-p (looking-at (python-rx open-paren)))
1312 (cond 1323 (and (not forward-p)
1313 ((not block-starting-pos) 1324 (eq (syntax-class (syntax-after (1- (point))))
1314 ;; Not inside a block, move to closest one. 1325 (car (string-to-syntax ")")))))
1315 (and next-block-starting-pos 1326 ;; Inside a paren or looking at it, lisp knows what to do.
1316 (goto-char next-block-starting-pos))) 1327 (python-nav-lisp-forward-sexp-safe dir))
1317 ((= (point) block-starting-pos) 1328 (t
1318 ;; Point is at beginning of block 1329 ;; This part handles the lispy feel of
1319 (if (and next-block-starting-pos 1330 ;; `python-nav-forward-sexp'. Knowing everything about the
1320 (< next-block-starting-pos block-ending-pos)) 1331 ;; current context and the context of the next sexp tries to
1321 ;; Beginning of next block is closer than current's 1332 ;; follow the lisp sexp motion commands in a symmetric manner.
1322 ;; end, move to it. 1333 (let* ((context
1323 (goto-char next-block-starting-pos) 1334 (cond
1324 (goto-char block-ending-pos))) 1335 ((python-info-beginning-of-block-p) 'block-start)
1325 ((= block-ending-pos (point)) 1336 ((python-info-end-of-block-p) 'block-end)
1326 ;; Point is at end of current block 1337 ((python-info-beginning-of-statement-p) 'statement-start)
1327 (let ((parent-block-end-pos 1338 ((python-info-end-of-statement-p) 'statement-end)))
1328 (save-excursion 1339 (next-sexp-pos
1329 (python-util-forward-comment) 1340 (save-excursion
1330 (python-nav-beginning-of-block) 1341 (python-nav-lisp-forward-sexp-safe dir)
1331 (python-nav-end-of-block)))) 1342 (point)))
1332 (if (and parent-block-end-pos 1343 (next-sexp-context
1333 (or (not next-block-starting-pos) 1344 (save-excursion
1334 (> next-block-starting-pos parent-block-end-pos))) 1345 (goto-char next-sexp-pos)
1335 ;; If the parent block ends before next block 1346 (cond
1336 ;; starts move to it. 1347 ((python-info-beginning-of-block-p) 'block-start)
1337 (goto-char parent-block-end-pos) 1348 ((python-info-end-of-block-p) 'block-end)
1338 (and next-block-starting-pos 1349 ((python-info-beginning-of-statement-p) 'statement-start)
1339 (goto-char next-block-starting-pos))))) 1350 ((python-info-end-of-statement-p) 'statement-end)
1340 (t (python-nav-end-of-block)))))))) 1351 ((python-info-statement-starts-block-p) 'starts-block)
1352 ((python-info-statement-ends-block-p) 'ends-block)))))
1353 (if forward-p
1354 (cond ((and (not (eobp))
1355 (python-info-current-line-empty-p))
1356 (python-util-forward-comment dir)
1357 (python-nav--forward-sexp dir))
1358 ((eq context 'block-start)
1359 (python-nav-end-of-block))
1360 ((eq context 'statement-start)
1361 (python-nav-end-of-statement))
1362 ((and (memq context '(statement-end block-end))
1363 (eq next-sexp-context 'ends-block))
1364 (goto-char next-sexp-pos)
1365 (python-nav-end-of-block))
1366 ((and (memq context '(statement-end block-end))
1367 (eq next-sexp-context 'starts-block))
1368 (goto-char next-sexp-pos)
1369 (python-nav-end-of-block))
1370 ((memq context '(statement-end block-end))
1371 (goto-char next-sexp-pos)
1372 (python-nav-end-of-statement))
1373 (t (goto-char next-sexp-pos)))
1374 (cond ((and (not (bobp))
1375 (python-info-current-line-empty-p))
1376 (python-util-forward-comment dir)
1377 (python-nav--forward-sexp dir))
1378 ((eq context 'block-end)
1379 (python-nav-beginning-of-block))
1380 ((eq context 'statement-end)
1381 (python-nav-beginning-of-statement))
1382 ((and (memq context '(statement-start block-start))
1383 (eq next-sexp-context 'starts-block))
1384 (goto-char next-sexp-pos)
1385 (python-nav-beginning-of-block))
1386 ((and (memq context '(statement-start block-start))
1387 (eq next-sexp-context 'ends-block))
1388 (goto-char next-sexp-pos)
1389 (python-nav-beginning-of-block))
1390 ((memq context '(statement-start block-start))
1391 (goto-char next-sexp-pos)
1392 (python-nav-beginning-of-statement))
1393 (t (goto-char next-sexp-pos))))))))))
1341 1394
1342(defun python-nav--backward-sexp () 1395(defun python-nav--backward-sexp ()
1343 "Move to backward sexp." 1396 "Move to backward sexp."
1344 (case (python-syntax-context-type) 1397 (python-nav--forward-sexp -1))
1345 (string
1346 ;; Inside of a string, get out of it.
1347 (while (and (re-search-backward "[\"']" nil t)
1348 (python-syntax-context 'string))))
1349 (comment
1350 ;; Inside of a comment, just move backward.
1351 (python-util-forward-comment -1))
1352 (paren
1353 ;; Handle parens like we are lisp.
1354 (python-nav-lisp-forward-sexp-safe -1))
1355 (t
1356 (let* ((block-starting-pos
1357 (save-excursion (python-nav-beginning-of-block)))
1358 (block-ending-pos
1359 (save-excursion (python-nav-end-of-block)))
1360 (prev-block-ending-pos
1361 (save-excursion (when (python-nav-backward-block)
1362 (python-nav-end-of-block))))
1363 (prev-block-parent-ending-pos
1364 (save-excursion
1365 (when prev-block-ending-pos
1366 (goto-char prev-block-ending-pos)
1367 (python-util-forward-comment)
1368 (python-nav-beginning-of-block)
1369 (python-nav-end-of-block)))))
1370 (if (and (not (bobp))
1371 (= (syntax-class (syntax-after (1- (point)))) 5))
1372 ;; Char before point is a paren closing char, handle it
1373 ;; like we are lisp.
1374 (python-nav-lisp-forward-sexp-safe -1)
1375 (cond
1376 ((not block-ending-pos)
1377 ;; Not in and ending pos, move to end of previous block.
1378 (and (python-nav-backward-block)
1379 (python-nav-end-of-block)))
1380 ((= (point) block-ending-pos)
1381 ;; In ending pos, we need to search backwards for the
1382 ;; closest point looking the list of candidates from here.
1383 (let ((candidates))
1384 (dolist (name
1385 '(prev-block-parent-ending-pos
1386 prev-block-ending-pos
1387 block-ending-pos
1388 block-starting-pos))
1389 (when (and (symbol-value name)
1390 (< (symbol-value name) (point)))
1391 (add-to-list 'candidates (symbol-value name))))
1392 (goto-char (apply 'max candidates))))
1393 ((> (point) block-ending-pos)
1394 ;; After an ending position, move to it.
1395 (goto-char block-ending-pos))
1396 ((= (point) block-starting-pos)
1397 ;; On a block starting position.
1398 (if (not (> (point) (or prev-block-ending-pos (point))))
1399 ;; Point is after the end position of the block that
1400 ;; wraps the current one, just move a block backward.
1401 (python-nav-backward-block)
1402 ;; If we got here we are facing a case like this one:
1403 ;;
1404 ;; try:
1405 ;; return here()
1406 ;; except Exception as e:
1407 ;;
1408 ;; Where point is on the "except" and must move to the
1409 ;; end of "here()".
1410 (goto-char prev-block-ending-pos)
1411 (let ((parent-block-ending-pos
1412 (save-excursion
1413 (python-nav-forward-sexp)
1414 (and (not (looking-at (python-rx block-start)))
1415 (point)))))
1416 (when (and parent-block-ending-pos
1417 (> parent-block-ending-pos prev-block-ending-pos))
1418 ;; If we got here we are facing a case like this one:
1419 ;;
1420 ;; except ImportError:
1421 ;; if predicate():
1422 ;; processing()
1423 ;; here()
1424 ;; except AttributeError:
1425 ;;
1426 ;; Where point is on the "except" and must move to
1427 ;; the end of "here()". Without this extra step we'd
1428 ;; just get to the end of processing().
1429 (goto-char parent-block-ending-pos)))))
1430 (t
1431 (if (and prev-block-ending-pos (< prev-block-ending-pos (point)))
1432 (goto-char prev-block-ending-pos)
1433 (python-nav-beginning-of-block)))))))))
1434 1398
1435(defun python-nav-forward-sexp (&optional arg) 1399(defun python-nav-forward-sexp (&optional arg)
1436 "Move forward across one block of code. 1400 "Move forward across one block of code.
@@ -1643,6 +1607,8 @@ uniqueness for different types of configurations."
1643OUTPUT is a string with the contents of the buffer." 1607OUTPUT is a string with the contents of the buffer."
1644 (ansi-color-filter-apply output)) 1608 (ansi-color-filter-apply output))
1645 1609
1610(defvar python-shell--parent-buffer nil)
1611
1646(define-derived-mode inferior-python-mode comint-mode "Inferior Python" 1612(define-derived-mode inferior-python-mode comint-mode "Inferior Python"
1647 "Major mode for Python inferior process. 1613 "Major mode for Python inferior process.
1648Runs a Python interpreter as a subprocess of Emacs, with Python 1614Runs a Python interpreter as a subprocess of Emacs, with Python
@@ -1665,6 +1631,12 @@ initialization of the interpreter via `python-shell-setup-codes'
1665variable. 1631variable.
1666 1632
1667\(Type \\[describe-mode] in the process buffer for a list of commands.)" 1633\(Type \\[describe-mode] in the process buffer for a list of commands.)"
1634 (and python-shell--parent-buffer
1635 (python-util-clone-local-variables python-shell--parent-buffer))
1636 (setq comint-prompt-regexp (format "^\\(?:%s\\|%s\\|%s\\)"
1637 python-shell-prompt-regexp
1638 python-shell-prompt-block-regexp
1639 python-shell-prompt-pdb-regexp))
1668 (set-syntax-table python-mode-syntax-table) 1640 (set-syntax-table python-mode-syntax-table)
1669 (setq mode-line-process '(":%s")) 1641 (setq mode-line-process '(":%s"))
1670 (make-local-variable 'comint-output-filter-functions) 1642 (make-local-variable 'comint-output-filter-functions)
@@ -1712,15 +1684,10 @@ killed."
1712 (let* ((cmdlist (split-string-and-unquote cmd)) 1684 (let* ((cmdlist (split-string-and-unquote cmd))
1713 (buffer (apply #'make-comint-in-buffer proc-name proc-buffer-name 1685 (buffer (apply #'make-comint-in-buffer proc-name proc-buffer-name
1714 (car cmdlist) nil (cdr cmdlist))) 1686 (car cmdlist) nil (cdr cmdlist)))
1715 (current-buffer (current-buffer)) 1687 (python-shell--parent-buffer (current-buffer))
1716 (process (get-buffer-process buffer))) 1688 (process (get-buffer-process buffer)))
1717 (with-current-buffer buffer 1689 (with-current-buffer buffer
1718 (inferior-python-mode) 1690 (inferior-python-mode))
1719 (python-util-clone-local-variables current-buffer)
1720 (setq comint-prompt-regexp (format "^\\(?:%s\\|%s\\|%s\\)"
1721 python-shell-prompt-regexp
1722 python-shell-prompt-block-regexp
1723 python-shell-prompt-pdb-regexp)))
1724 (accept-process-output process) 1691 (accept-process-output process)
1725 (and pop (pop-to-buffer buffer t)) 1692 (and pop (pop-to-buffer buffer t))
1726 (and internal (set-process-query-on-exit-flag process nil)))) 1693 (and internal (set-process-query-on-exit-flag process nil))))
@@ -2879,12 +2846,43 @@ parent defun name."
2879 ".") ".") 2846 ".") ".")
2880 name))))))) 2847 name)))))))
2881 2848
2882(defsubst python-info-beginning-of-block-statement-p () 2849(defun python-info-statement-starts-block-p ()
2883 "Return non-nil if current statement opens a block." 2850 "Return non-nil if current statement opens a block."
2884 (save-excursion 2851 (save-excursion
2885 (python-nav-beginning-of-statement) 2852 (python-nav-beginning-of-statement)
2886 (looking-at (python-rx block-start)))) 2853 (looking-at (python-rx block-start))))
2887 2854
2855(defun python-info-statement-ends-block-p ()
2856 "Return non-nil if point is at end of block."
2857 (let ((end-of-block-pos (save-excursion
2858 (python-nav-end-of-block)))
2859 (end-of-statement-pos (save-excursion
2860 (python-nav-end-of-statement))))
2861 (and end-of-block-pos end-of-statement-pos
2862 (= end-of-block-pos end-of-statement-pos))))
2863
2864(defun python-info-beginning-of-statement-p ()
2865 "Return non-nil if point is at beginning of statement."
2866 (= (point) (save-excursion
2867 (python-nav-beginning-of-statement)
2868 (point))))
2869
2870(defun python-info-end-of-statement-p ()
2871 "Return non-nil if point is at end of statement."
2872 (= (point) (save-excursion
2873 (python-nav-end-of-statement)
2874 (point))))
2875
2876(defun python-info-beginning-of-block-p ()
2877 "Return non-nil if point is at beginning of block."
2878 (and (python-info-beginning-of-statement-p)
2879 (python-info-statement-starts-block-p)))
2880
2881(defun python-info-end-of-block-p ()
2882 "Return non-nil if point is at end of block."
2883 (and (python-info-end-of-statement-p)
2884 (python-info-statement-ends-block-p)))
2885
2888(defun python-info-closing-block () 2886(defun python-info-closing-block ()
2889 "Return the point of the block the current line closes." 2887 "Return the point of the block the current line closes."
2890 (let ((closing-word (save-excursion 2888 (let ((closing-word (save-excursion