aboutsummaryrefslogtreecommitdiffstats
path: root/lisp/progmodes/python.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/progmodes/python.el')
-rw-r--r--lisp/progmodes/python.el732
1 files changed, 463 insertions, 269 deletions
diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el
index f5e4bffd598..ff805d64024 100644
--- a/lisp/progmodes/python.el
+++ b/lisp/progmodes/python.el
@@ -229,12 +229,9 @@
229(defvar python-mode-map 229(defvar python-mode-map
230 (let ((map (make-sparse-keymap))) 230 (let ((map (make-sparse-keymap)))
231 ;; Movement 231 ;; Movement
232 (substitute-key-definition 'backward-sentence 232 (define-key map [remap backward-sentence] 'python-nav-backward-block)
233 'python-nav-backward-block 233 (define-key map [remap forward-sentence] 'python-nav-forward-block)
234 map global-map) 234 (define-key map [remap backward-up-list] 'python-nav-backward-up-list)
235 (substitute-key-definition 'forward-sentence
236 'python-nav-forward-block
237 map global-map)
238 (define-key map "\C-c\C-j" 'imenu) 235 (define-key map "\C-c\C-j" 'imenu)
239 ;; Indent specific 236 ;; Indent specific
240 (define-key map "\177" 'python-indent-dedent-line-backspace) 237 (define-key map "\177" 'python-indent-dedent-line-backspace)
@@ -337,19 +334,28 @@
337 "==" ">=" "is" "not"))) 334 "==" ">=" "is" "not")))
338 ;; FIXME: Use regexp-opt. 335 ;; FIXME: Use regexp-opt.
339 (assignment-operator . ,(rx (or "=" "+=" "-=" "*=" "/=" "//=" "%=" "**=" 336 (assignment-operator . ,(rx (or "=" "+=" "-=" "*=" "/=" "//=" "%=" "**="
340 ">>=" "<<=" "&=" "^=" "|=")))) 337 ">>=" "<<=" "&=" "^=" "|=")))
341 "Additional Python specific sexps for `python-rx'")) 338 (string-delimiter . ,(rx (and
342 339 ;; Match even number of backslashes.
343(defmacro python-rx (&rest regexps) 340 (or (not (any ?\\ ?\' ?\")) point
344 "Python mode specialized rx macro. 341 ;; Quotes might be preceded by a escaped quote.
342 (and (or (not (any ?\\)) point) ?\\
343 (* ?\\ ?\\) (any ?\' ?\")))
344 (* ?\\ ?\\)
345 ;; Match single or triple quotes of any kind.
346 (group (or "\"" "\"\"\"" "'" "'''"))))))
347 "Additional Python specific sexps for `python-rx'")
348
349 (defmacro python-rx (&rest regexps)
350 "Python mode specialized rx macro.
345This variant of `rx' supports common python named REGEXPS." 351This variant of `rx' supports common python named REGEXPS."
346 (let ((rx-constituents (append python-rx-constituents rx-constituents))) 352 (let ((rx-constituents (append python-rx-constituents rx-constituents)))
347 (cond ((null regexps) 353 (cond ((null regexps)
348 (error "No regexp")) 354 (error "No regexp"))
349 ((cdr regexps) 355 ((cdr regexps)
350 (rx-to-string `(and ,@regexps) t)) 356 (rx-to-string `(and ,@regexps) t))
351 (t 357 (t
352 (rx-to-string (car regexps) t))))) 358 (rx-to-string (car regexps) t))))))
353 359
354 360
355;;; Font-lock and syntax 361;;; Font-lock and syntax
@@ -498,16 +504,7 @@ The type returned can be `comment', `string' or `paren'."
498 504
499(defconst python-syntax-propertize-function 505(defconst python-syntax-propertize-function
500 (syntax-propertize-rules 506 (syntax-propertize-rules
501 ((rx 507 ((python-rx string-delimiter)
502 (and
503 ;; Match even number of backslashes.
504 (or (not (any ?\\ ?\' ?\")) point
505 ;; Quotes might be preceeded by a escaped quote.
506 (and (or (not (any ?\\)) point) ?\\
507 (* ?\\ ?\\) (any ?\' ?\")))
508 (* ?\\ ?\\)
509 ;; Match single or triple quotes of any kind.
510 (group (or "\"" "\"\"\"" "'" "'''"))))
511 (0 (ignore (python-syntax-stringify)))))) 508 (0 (ignore (python-syntax-stringify))))))
512 509
513(defsubst python-syntax-count-quotes (quote-char &optional point limit) 510(defsubst python-syntax-count-quotes (quote-char &optional point limit)
@@ -676,12 +673,12 @@ START is the buffer position where the sexp starts."
676 (goto-char (line-beginning-position)) 673 (goto-char (line-beginning-position))
677 (bobp)) 674 (bobp))
678 'no-indent) 675 'no-indent)
679 ;; Inside a paren
680 ((setq start (python-syntax-context 'paren ppss))
681 'inside-paren)
682 ;; Inside string 676 ;; Inside string
683 ((setq start (python-syntax-context 'string ppss)) 677 ((setq start (python-syntax-context 'string ppss))
684 'inside-string) 678 'inside-string)
679 ;; Inside a paren
680 ((setq start (python-syntax-context 'paren ppss))
681 'inside-paren)
685 ;; After backslash 682 ;; After backslash
686 ((setq start (when (not (or (python-syntax-context 'string ppss) 683 ((setq start (when (not (or (python-syntax-context 'string ppss)
687 (python-syntax-context 'comment ppss))) 684 (python-syntax-context 'comment ppss)))
@@ -710,7 +707,7 @@ START is the buffer position where the sexp starts."
710 ;; After normal line 707 ;; After normal line
711 ((setq start (save-excursion 708 ((setq start (save-excursion
712 (back-to-indentation) 709 (back-to-indentation)
713 (python-util-forward-comment -1) 710 (skip-chars-backward (rx (or whitespace ?\n)))
714 (python-nav-beginning-of-statement) 711 (python-nav-beginning-of-statement)
715 (point-marker))) 712 (point-marker)))
716 'after-line) 713 'after-line)
@@ -973,7 +970,16 @@ Called from a program, START and END specify the region to indent."
973 (back-to-indentation) 970 (back-to-indentation)
974 (setq word (current-word)) 971 (setq word (current-word))
975 (forward-line 1) 972 (forward-line 1)
976 (when word 973 (when (and word
974 ;; Don't mess with strings, unless it's the
975 ;; enclosing set of quotes.
976 (or (not (python-syntax-context 'string))
977 (eq
978 (syntax-after
979 (+ (1- (point))
980 (current-indentation)
981 (python-syntax-count-quotes (char-after) (point))))
982 (string-to-syntax "|"))))
977 (beginning-of-line) 983 (beginning-of-line)
978 (delete-horizontal-space) 984 (delete-horizontal-space)
979 (indent-to (python-indent-calculate-indentation))))) 985 (indent-to (python-indent-calculate-indentation)))))
@@ -1160,7 +1166,8 @@ Returns nil if point is not in a def or class."
1160 (python-info-line-ends-backslash-p)) 1166 (python-info-line-ends-backslash-p))
1161 (python-syntax-context 'string) 1167 (python-syntax-context 'string)
1162 (python-syntax-context 'paren)) 1168 (python-syntax-context 'paren))
1163 (forward-line -1))))) 1169 (forward-line -1))))
1170 (point-marker))
1164 1171
1165(defun python-nav-end-of-statement () 1172(defun python-nav-end-of-statement ()
1166 "Move to end of current statement." 1173 "Move to end of current statement."
@@ -1171,7 +1178,8 @@ Returns nil if point is not in a def or class."
1171 (python-info-line-ends-backslash-p) 1178 (python-info-line-ends-backslash-p)
1172 (python-syntax-context 'string) 1179 (python-syntax-context 'string)
1173 (python-syntax-context 'paren)) 1180 (python-syntax-context 'paren))
1174 (forward-line 1))))) 1181 (forward-line 1))))
1182 (point-marker))
1175 1183
1176(defun python-nav-backward-statement (&optional arg) 1184(defun python-nav-backward-statement (&optional arg)
1177 "Move backward to previous statement. 1185 "Move backward to previous statement.
@@ -1286,151 +1294,104 @@ When ARG > 0 move forward, else if ARG is < 0."
1286 (while (and (funcall search-fn paren-regexp nil t) 1294 (while (and (funcall search-fn paren-regexp nil t)
1287 (python-syntax-context 'paren))))))) 1295 (python-syntax-context 'paren)))))))
1288 1296
1289(defun python-nav--forward-sexp () 1297(defun python-nav--forward-sexp (&optional dir)
1290 "Move to forward sexp." 1298 "Move to forward sexp.
1291 (case (python-syntax-context-type) 1299With positive Optional argument DIR direction move forward, else
1292 (string 1300backwards."
1293 ;; Inside of a string, get out of it. 1301 (setq dir (or dir 1))
1294 (while (and (re-search-forward "[\"']" nil t) 1302 (unless (= dir 0)
1295 (python-syntax-context 'string)))) 1303 (let* ((forward-p (if (> dir 0)
1296 (comment 1304 (and (setq dir 1) t)
1297 ;; Inside of a comment, just move forward. 1305 (and (setq dir -1) nil)))
1298 (python-util-forward-comment)) 1306 (re-search-fn (if forward-p
1299 (paren 1307 're-search-forward
1300 (python-nav-lisp-forward-sexp-safe 1)) 1308 're-search-backward))
1301 (t 1309 (context-type (python-syntax-context-type)))
1302 (if (and (not (eobp)) 1310 (cond
1303 (= (syntax-class (syntax-after (point))) 4)) 1311 ((eq context-type 'string)
1304 ;; Looking an open-paren 1312 ;; Inside of a string, get out of it.
1305 (python-nav-lisp-forward-sexp-safe 1) 1313 (while (and (funcall re-search-fn "[\"']" nil t)
1306 (let ((block-starting-pos 1314 (python-syntax-context 'string))))
1307 (save-excursion (python-nav-beginning-of-block))) 1315 ((eq context-type 'comment)
1308 (block-ending-pos 1316 ;; Inside of a comment, just move forward.
1309 (save-excursion (python-nav-end-of-block))) 1317 (python-util-forward-comment dir))
1310 (next-block-starting-pos 1318 ((or (eq context-type 'paren)
1311 (save-excursion (python-nav-forward-block)))) 1319 (and forward-p (looking-at (python-rx open-paren)))
1312 (cond 1320 (and (not forward-p)
1313 ((not block-starting-pos) 1321 (eq (syntax-class (syntax-after (1- (point))))
1314 ;; Not inside a block, move to closest one. 1322 (car (string-to-syntax ")")))))
1315 (and next-block-starting-pos 1323 ;; Inside a paren or looking at it, lisp knows what to do.
1316 (goto-char next-block-starting-pos))) 1324 (python-nav-lisp-forward-sexp-safe dir))
1317 ((= (point) block-starting-pos) 1325 (t
1318 ;; Point is at beginning of block 1326 ;; This part handles the lispy feel of
1319 (if (and next-block-starting-pos 1327 ;; `python-nav-forward-sexp'. Knowing everything about the
1320 (< next-block-starting-pos block-ending-pos)) 1328 ;; current context and the context of the next sexp tries to
1321 ;; Beginning of next block is closer than current's 1329 ;; follow the lisp sexp motion commands in a symmetric manner.
1322 ;; end, move to it. 1330 (let* ((context
1323 (goto-char next-block-starting-pos) 1331 (cond
1324 (goto-char block-ending-pos))) 1332 ((python-info-beginning-of-block-p) 'block-start)
1325 ((= block-ending-pos (point)) 1333 ((python-info-end-of-block-p) 'block-end)
1326 ;; Point is at end of current block 1334 ((python-info-beginning-of-statement-p) 'statement-start)
1327 (let ((parent-block-end-pos 1335 ((python-info-end-of-statement-p) 'statement-end)))
1328 (save-excursion 1336 (next-sexp-pos
1329 (python-util-forward-comment) 1337 (save-excursion
1330 (python-nav-beginning-of-block) 1338 (python-nav-lisp-forward-sexp-safe dir)
1331 (python-nav-end-of-block)))) 1339 (point)))
1332 (if (and parent-block-end-pos 1340 (next-sexp-context
1333 (or (not next-block-starting-pos) 1341 (save-excursion
1334 (> next-block-starting-pos parent-block-end-pos))) 1342 (goto-char next-sexp-pos)
1335 ;; If the parent block ends before next block 1343 (cond
1336 ;; starts move to it. 1344 ((python-info-beginning-of-block-p) 'block-start)
1337 (goto-char parent-block-end-pos) 1345 ((python-info-end-of-block-p) 'block-end)
1338 (and next-block-starting-pos 1346 ((python-info-beginning-of-statement-p) 'statement-start)
1339 (goto-char next-block-starting-pos))))) 1347 ((python-info-end-of-statement-p) 'statement-end)
1340 (t (python-nav-end-of-block)))))))) 1348 ((python-info-statement-starts-block-p) 'starts-block)
1349 ((python-info-statement-ends-block-p) 'ends-block)))))
1350 (if forward-p
1351 (cond ((and (not (eobp))
1352 (python-info-current-line-empty-p))
1353 (python-util-forward-comment dir)
1354 (python-nav--forward-sexp dir))
1355 ((eq context 'block-start)
1356 (python-nav-end-of-block))
1357 ((eq context 'statement-start)
1358 (python-nav-end-of-statement))
1359 ((and (memq context '(statement-end block-end))
1360 (eq next-sexp-context 'ends-block))
1361 (goto-char next-sexp-pos)
1362 (python-nav-end-of-block))
1363 ((and (memq context '(statement-end block-end))
1364 (eq next-sexp-context 'starts-block))
1365 (goto-char next-sexp-pos)
1366 (python-nav-end-of-block))
1367 ((memq context '(statement-end block-end))
1368 (goto-char next-sexp-pos)
1369 (python-nav-end-of-statement))
1370 (t (goto-char next-sexp-pos)))
1371 (cond ((and (not (bobp))
1372 (python-info-current-line-empty-p))
1373 (python-util-forward-comment dir)
1374 (python-nav--forward-sexp dir))
1375 ((eq context 'block-end)
1376 (python-nav-beginning-of-block))
1377 ((eq context 'statement-end)
1378 (python-nav-beginning-of-statement))
1379 ((and (memq context '(statement-start block-start))
1380 (eq next-sexp-context 'starts-block))
1381 (goto-char next-sexp-pos)
1382 (python-nav-beginning-of-block))
1383 ((and (memq context '(statement-start block-start))
1384 (eq next-sexp-context 'ends-block))
1385 (goto-char next-sexp-pos)
1386 (python-nav-beginning-of-block))
1387 ((memq context '(statement-start block-start))
1388 (goto-char next-sexp-pos)
1389 (python-nav-beginning-of-statement))
1390 (t (goto-char next-sexp-pos))))))))))
1341 1391
1342(defun python-nav--backward-sexp () 1392(defun python-nav--backward-sexp ()
1343 "Move to backward sexp." 1393 "Move to backward sexp."
1344 (case (python-syntax-context-type) 1394 (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 1395
1435(defun python-nav-forward-sexp (&optional arg) 1396(defun python-nav-forward-sexp (&optional arg)
1436 "Move forward across one block of code. 1397 "Move forward across one block of code.
@@ -1445,6 +1406,67 @@ move backward N times."
1445 (python-nav--backward-sexp) 1406 (python-nav--backward-sexp)
1446 (setq arg (1+ arg)))) 1407 (setq arg (1+ arg))))
1447 1408
1409(defun python-nav--up-list (&optional dir)
1410 "Internal implementation of `python-nav-up-list'.
1411DIR is always 1 or -1 and comes sanitized from
1412`python-nav-up-list' calls."
1413 (let ((context (python-syntax-context-type))
1414 (forward-p (> dir 0)))
1415 (cond
1416 ((memq context '(string comment)))
1417 ((eq context 'paren)
1418 (let ((forward-sexp-function))
1419 (up-list dir)))
1420 ((and forward-p (python-info-end-of-block-p))
1421 (let ((parent-end-pos
1422 (save-excursion
1423 (let ((indentation (and
1424 (python-nav-beginning-of-block)
1425 (current-indentation))))
1426 (while (and indentation
1427 (> indentation 0)
1428 (>= (current-indentation) indentation)
1429 (python-nav-backward-block)))
1430 (python-nav-end-of-block)))))
1431 (and (> (or parent-end-pos (point)) (point))
1432 (goto-char parent-end-pos))))
1433 (forward-p (python-nav-end-of-block))
1434 ((and (not forward-p)
1435 (> (current-indentation) 0)
1436 (python-info-beginning-of-block-p))
1437 (let ((prev-block-pos
1438 (save-excursion
1439 (let ((indentation (current-indentation)))
1440 (while (and (python-nav-backward-block)
1441 (>= (current-indentation) indentation))))
1442 (point))))
1443 (and (> (point) prev-block-pos)
1444 (goto-char prev-block-pos))))
1445 ((not forward-p) (python-nav-beginning-of-block)))))
1446
1447(defun python-nav-up-list (&optional arg)
1448 "Move forward out of one level of parentheses (or blocks).
1449With ARG, do this that many times.
1450A negative argument means move backward but still to a less deep spot.
1451This command assumes point is not in a string or comment."
1452 (interactive "^p")
1453 (or arg (setq arg 1))
1454 (while (> arg 0)
1455 (python-nav--up-list 1)
1456 (setq arg (1- arg)))
1457 (while (< arg 0)
1458 (python-nav--up-list -1)
1459 (setq arg (1+ arg))))
1460
1461(defun python-nav-backward-up-list (&optional arg)
1462 "Move backward out of one level of parentheses (or blocks).
1463With ARG, do this that many times.
1464A negative argument means move backward but still to a less deep spot.
1465This command assumes point is not in a string or comment."
1466 (interactive "^p")
1467 (or arg (setq arg 1))
1468 (python-nav-up-list (- arg)))
1469
1448 1470
1449;;; Shell integration 1471;;; Shell integration
1450 1472
@@ -1643,6 +1665,22 @@ uniqueness for different types of configurations."
1643OUTPUT is a string with the contents of the buffer." 1665OUTPUT is a string with the contents of the buffer."
1644 (ansi-color-filter-apply output)) 1666 (ansi-color-filter-apply output))
1645 1667
1668(defvar python-shell--parent-buffer nil)
1669
1670(defvar python-shell-output-syntax-table
1671 (let ((table (make-syntax-table python-dotty-syntax-table)))
1672 (modify-syntax-entry ?\' "." table)
1673 (modify-syntax-entry ?\" "." table)
1674 (modify-syntax-entry ?\( "." table)
1675 (modify-syntax-entry ?\[ "." table)
1676 (modify-syntax-entry ?\{ "." table)
1677 (modify-syntax-entry ?\) "." table)
1678 (modify-syntax-entry ?\] "." table)
1679 (modify-syntax-entry ?\} "." table)
1680 table)
1681 "Syntax table for shell output.
1682It makes parens and quotes be treated as punctuation chars.")
1683
1646(define-derived-mode inferior-python-mode comint-mode "Inferior Python" 1684(define-derived-mode inferior-python-mode comint-mode "Inferior Python"
1647 "Major mode for Python inferior process. 1685 "Major mode for Python inferior process.
1648Runs a Python interpreter as a subprocess of Emacs, with Python 1686Runs a Python interpreter as a subprocess of Emacs, with Python
@@ -1665,12 +1703,13 @@ initialization of the interpreter via `python-shell-setup-codes'
1665variable. 1703variable.
1666 1704
1667\(Type \\[describe-mode] in the process buffer for a list of commands.)" 1705\(Type \\[describe-mode] in the process buffer for a list of commands.)"
1668 (set-syntax-table python-mode-syntax-table) 1706 (and python-shell--parent-buffer
1669 (setq mode-line-process '(":%s")) 1707 (python-util-clone-local-variables python-shell--parent-buffer))
1670 (setq comint-prompt-regexp (format "^\\(?:%s\\|%s\\|%s\\)" 1708 (setq comint-prompt-regexp (format "^\\(?:%s\\|%s\\|%s\\)"
1671 python-shell-prompt-regexp 1709 python-shell-prompt-regexp
1672 python-shell-prompt-block-regexp 1710 python-shell-prompt-block-regexp
1673 python-shell-prompt-pdb-regexp)) 1711 python-shell-prompt-pdb-regexp))
1712 (setq mode-line-process '(":%s"))
1674 (make-local-variable 'comint-output-filter-functions) 1713 (make-local-variable 'comint-output-filter-functions)
1675 (add-hook 'comint-output-filter-functions 1714 (add-hook 'comint-output-filter-functions
1676 'python-comint-output-filter-function) 1715 'python-comint-output-filter-function)
@@ -1690,10 +1729,21 @@ variable.
1690 (make-local-variable 'python-pdbtrack-tracked-buffer) 1729 (make-local-variable 'python-pdbtrack-tracked-buffer)
1691 (make-local-variable 'python-shell-internal-last-output) 1730 (make-local-variable 'python-shell-internal-last-output)
1692 (when python-shell-enable-font-lock 1731 (when python-shell-enable-font-lock
1732 (set-syntax-table python-mode-syntax-table)
1693 (set (make-local-variable 'font-lock-defaults) 1733 (set (make-local-variable 'font-lock-defaults)
1694 '(python-font-lock-keywords nil nil nil nil)) 1734 '(python-font-lock-keywords nil nil nil nil))
1695 (set (make-local-variable 'syntax-propertize-function) 1735 (set (make-local-variable 'syntax-propertize-function)
1696 python-syntax-propertize-function)) 1736 (syntax-propertize-rules
1737 (comint-prompt-regexp
1738 (0 (ignore
1739 (put-text-property
1740 comint-last-input-start end 'syntax-table
1741 python-shell-output-syntax-table)
1742 (font-lock-unfontify-region comint-last-input-start end))))
1743 ((python-rx string-delimiter)
1744 (0 (ignore
1745 (and (not (eq (get-text-property start 'field) 'output))
1746 (python-syntax-stringify))))))))
1697 (compilation-shell-minor-mode 1)) 1747 (compilation-shell-minor-mode 1))
1698 1748
1699(defun python-shell-make-comint (cmd proc-name &optional pop internal) 1749(defun python-shell-make-comint (cmd proc-name &optional pop internal)
@@ -1716,11 +1766,10 @@ killed."
1716 (let* ((cmdlist (split-string-and-unquote cmd)) 1766 (let* ((cmdlist (split-string-and-unquote cmd))
1717 (buffer (apply #'make-comint-in-buffer proc-name proc-buffer-name 1767 (buffer (apply #'make-comint-in-buffer proc-name proc-buffer-name
1718 (car cmdlist) nil (cdr cmdlist))) 1768 (car cmdlist) nil (cdr cmdlist)))
1719 (current-buffer (current-buffer)) 1769 (python-shell--parent-buffer (current-buffer))
1720 (process (get-buffer-process buffer))) 1770 (process (get-buffer-process buffer)))
1721 (with-current-buffer buffer 1771 (with-current-buffer buffer
1722 (inferior-python-mode) 1772 (inferior-python-mode))
1723 (python-util-clone-local-variables current-buffer))
1724 (accept-process-output process) 1773 (accept-process-output process)
1725 (and pop (pop-to-buffer buffer t)) 1774 (and pop (pop-to-buffer buffer t))
1726 (and internal (set-process-query-on-exit-flag process nil)))) 1775 (and internal (set-process-query-on-exit-flag process nil))))
@@ -1861,26 +1910,41 @@ When MSG is non-nil messages the first line of STRING."
1861 (string-match "\n[ \t].*\n?$" string)) 1910 (string-match "\n[ \t].*\n?$" string))
1862 (comint-send-string process "\n"))))) 1911 (comint-send-string process "\n")))))
1863 1912
1864;; Shell output catching stolen from gud-gdb 1913(defvar python-shell-output-filter-in-progress nil)
1865(defvar python-shell-fetch-lines-in-progress nil) 1914(defvar python-shell-output-filter-buffer nil)
1866(defvar python-shell-fetch-lines-string nil) 1915
1867(defvar python-shell-fetched-lines nil) 1916(defun python-shell-output-filter (string)
1868 1917 "Filter used in `python-shell-send-string-no-output' to grab output.
1869(defun python-shell-fetch-lines-filter (string) 1918STRING is the output received to this point from the process.
1870 "Filter used to read the list of lines output by a command. 1919This filter saves received output from the process in
1871STRING is the output to filter." 1920`python-shell-output-filter-buffer' and stops receiving it after
1872 (setq string (concat python-shell-fetch-lines-string string)) 1921detecting a prompt at the end of the buffer."
1873 (while (string-match "\n" string) 1922 (setq
1874 (push (substring string 0 (match-beginning 0)) 1923 string (ansi-color-filter-apply string)
1875 python-shell-fetched-lines) 1924 python-shell-output-filter-buffer
1876 (setq string (substring string (match-end 0)))) 1925 (concat python-shell-output-filter-buffer string))
1877 (if (equal (string-match comint-prompt-regexp string) 0) 1926 (when (string-match
1878 (progn 1927 ;; XXX: It seems on OSX an extra carriage return is attached
1879 (setq python-shell-fetch-lines-in-progress nil) 1928 ;; at the end of output, this handles that too.
1880 string) 1929 (format "\r?\n\\(?:%s\\|%s\\|%s\\)$"
1881 (progn 1930 python-shell-prompt-regexp
1882 (setq python-shell-fetch-lines-string string) 1931 python-shell-prompt-block-regexp
1883 ""))) 1932 python-shell-prompt-pdb-regexp)
1933 python-shell-output-filter-buffer)
1934 ;; Output ends when `python-shell-output-filter-buffer' contains
1935 ;; the prompt attached at the end of it.
1936 (setq python-shell-output-filter-in-progress nil
1937 python-shell-output-filter-buffer
1938 (substring python-shell-output-filter-buffer
1939 0 (match-beginning 0)))
1940 (when (and (> (length python-shell-prompt-output-regexp) 0)
1941 (string-match (concat "^" python-shell-prompt-output-regexp)
1942 python-shell-output-filter-buffer))
1943 ;; Some shells, like iPython might append a prompt before the
1944 ;; output, clean that.
1945 (setq python-shell-output-filter-buffer
1946 (substring python-shell-output-filter-buffer (match-end 0)))))
1947 "")
1884 1948
1885(defun python-shell-send-string-no-output (string &optional process msg) 1949(defun python-shell-send-string-no-output (string &optional process msg)
1886 "Send STRING to PROCESS and inhibit output. 1950 "Send STRING to PROCESS and inhibit output.
@@ -1888,18 +1952,20 @@ When MSG is non-nil messages the first line of STRING. Return
1888the output." 1952the output."
1889 (let ((process (or process (python-shell-get-or-create-process))) 1953 (let ((process (or process (python-shell-get-or-create-process)))
1890 (comint-preoutput-filter-functions 1954 (comint-preoutput-filter-functions
1891 '(python-shell-fetch-lines-filter)) 1955 '(python-shell-output-filter))
1892 (python-shell-fetch-lines-in-progress t) 1956 (python-shell-output-filter-in-progress t)
1893 (inhibit-quit t)) 1957 (inhibit-quit t))
1894 (or 1958 (or
1895 (with-local-quit 1959 (with-local-quit
1896 (python-shell-send-string string process msg) 1960 (python-shell-send-string string process msg)
1897 (while python-shell-fetch-lines-in-progress 1961 (while python-shell-output-filter-in-progress
1962 ;; `python-shell-output-filter' takes care of setting
1963 ;; `python-shell-output-filter-in-progress' to NIL after it
1964 ;; detects end of output.
1898 (accept-process-output process)) 1965 (accept-process-output process))
1899 (prog1 1966 (prog1
1900 (mapconcat #'identity 1967 python-shell-output-filter-buffer
1901 (reverse python-shell-fetched-lines) "\n") 1968 (setq python-shell-output-filter-buffer nil)))
1902 (setq python-shell-fetched-lines nil)))
1903 (with-current-buffer (process-buffer process) 1969 (with-current-buffer (process-buffer process)
1904 (comint-interrupt-subjob))))) 1970 (comint-interrupt-subjob)))))
1905 1971
@@ -2264,37 +2330,105 @@ inferior python process is updated properly."
2264 2330
2265(defcustom python-fill-comment-function 'python-fill-comment 2331(defcustom python-fill-comment-function 'python-fill-comment
2266 "Function to fill comments. 2332 "Function to fill comments.
2267This is the function used by `python-fill-paragraph-function' to 2333This is the function used by `python-fill-paragraph' to
2268fill comments." 2334fill comments."
2269 :type 'symbol 2335 :type 'symbol
2270 :group 'python 2336 :group 'python)
2271 :safe 'symbolp)
2272 2337
2273(defcustom python-fill-string-function 'python-fill-string 2338(defcustom python-fill-string-function 'python-fill-string
2274 "Function to fill strings. 2339 "Function to fill strings.
2275This is the function used by `python-fill-paragraph-function' to 2340This is the function used by `python-fill-paragraph' to
2276fill strings." 2341fill strings."
2277 :type 'symbol 2342 :type 'symbol
2278 :group 'python 2343 :group 'python)
2279 :safe 'symbolp)
2280 2344
2281(defcustom python-fill-decorator-function 'python-fill-decorator 2345(defcustom python-fill-decorator-function 'python-fill-decorator
2282 "Function to fill decorators. 2346 "Function to fill decorators.
2283This is the function used by `python-fill-paragraph-function' to 2347This is the function used by `python-fill-paragraph' to
2284fill decorators." 2348fill decorators."
2285 :type 'symbol 2349 :type 'symbol
2286 :group 'python 2350 :group 'python)
2287 :safe 'symbolp)
2288 2351
2289(defcustom python-fill-paren-function 'python-fill-paren 2352(defcustom python-fill-paren-function 'python-fill-paren
2290 "Function to fill parens. 2353 "Function to fill parens.
2291This is the function used by `python-fill-paragraph-function' to 2354This is the function used by `python-fill-paragraph' to
2292fill parens." 2355fill parens."
2293 :type 'symbol 2356 :type 'symbol
2357 :group 'python)
2358
2359(defcustom python-fill-docstring-style 'pep-257
2360 "Style used to fill docstrings.
2361This affects `python-fill-string' behavior with regards to
2362triple quotes positioning.
2363
2364Possible values are DJANGO, ONETWO, PEP-257, PEP-257-NN,
2365SYMMETRIC, and NIL. A value of NIL won't care about quotes
2366position and will treat docstrings a normal string, any other
2367value may result in one of the following docstring styles:
2368
2369DJANGO:
2370
2371 \"\"\"
2372 Process foo, return bar.
2373 \"\"\"
2374
2375 \"\"\"
2376 Process foo, return bar.
2377
2378 If processing fails throw ProcessingError.
2379 \"\"\"
2380
2381ONETWO:
2382
2383 \"\"\"Process foo, return bar.\"\"\"
2384
2385 \"\"\"
2386 Process foo, return bar.
2387
2388 If processing fails throw ProcessingError.
2389
2390 \"\"\"
2391
2392PEP-257:
2393
2394 \"\"\"Process foo, return bar.\"\"\"
2395
2396 \"\"\"Process foo, return bar.
2397
2398 If processing fails throw ProcessingError.
2399
2400 \"\"\"
2401
2402PEP-257-NN:
2403
2404 \"\"\"Process foo, return bar.\"\"\"
2405
2406 \"\"\"Process foo, return bar.
2407
2408 If processing fails throw ProcessingError.
2409 \"\"\"
2410
2411SYMMETRIC:
2412
2413 \"\"\"Process foo, return bar.\"\"\"
2414
2415 \"\"\"
2416 Process foo, return bar.
2417
2418 If processing fails throw ProcessingError.
2419 \"\"\""
2420 :type '(choice
2421 (const :tag "Don't format docstrings" nil)
2422 (const :tag "Django's coding standards style." django)
2423 (const :tag "One newline and start and Two at end style." onetwo)
2424 (const :tag "PEP-257 with 2 newlines at end of string." pep-257)
2425 (const :tag "PEP-257 with 1 newline at end of string." pep-257-nn)
2426 (const :tag "Symmetric style." symmetric))
2294 :group 'python 2427 :group 'python
2295 :safe 'symbolp) 2428 :safe (lambda (val)
2429 (memq val '(django onetwo pep-257 pep-257-nn symmetric nil))))
2296 2430
2297(defun python-fill-paragraph-function (&optional justify) 2431(defun python-fill-paragraph (&optional justify)
2298 "`fill-paragraph-function' handling multi-line strings and possibly comments. 2432 "`fill-paragraph-function' handling multi-line strings and possibly comments.
2299If any of the current line is in or at the end of a multi-line string, 2433If any of the current line is in or at the end of a multi-line string,
2300fill the string or the paragraph of it that point is in, preserving 2434fill the string or the paragraph of it that point is in, preserving
@@ -2302,18 +2436,18 @@ the string's indentation.
2302Optional argument JUSTIFY defines if the paragraph should be justified." 2436Optional argument JUSTIFY defines if the paragraph should be justified."
2303 (interactive "P") 2437 (interactive "P")
2304 (save-excursion 2438 (save-excursion
2305 (back-to-indentation)
2306 (cond 2439 (cond
2307 ;; Comments 2440 ;; Comments
2308 ((funcall python-fill-comment-function justify)) 2441 ((python-syntax-context 'comment)
2442 (funcall python-fill-comment-function justify))
2309 ;; Strings/Docstrings 2443 ;; Strings/Docstrings
2310 ((save-excursion (skip-chars-forward "\"'uUrR") 2444 ((save-excursion (or (python-syntax-context 'string)
2311 (python-syntax-context 'string)) 2445 (equal (string-to-syntax "|")
2446 (syntax-after (point)))))
2312 (funcall python-fill-string-function justify)) 2447 (funcall python-fill-string-function justify))
2313 ;; Decorators 2448 ;; Decorators
2314 ((equal (char-after (save-excursion 2449 ((equal (char-after (save-excursion
2315 (back-to-indentation) 2450 (python-nav-beginning-of-statement))) ?@)
2316 (point-marker))) ?@)
2317 (funcall python-fill-decorator-function justify)) 2451 (funcall python-fill-decorator-function justify))
2318 ;; Parens 2452 ;; Parens
2319 ((or (python-syntax-context 'paren) 2453 ((or (python-syntax-context 'paren)
@@ -2325,58 +2459,87 @@ Optional argument JUSTIFY defines if the paragraph should be justified."
2325 (t t)))) 2459 (t t))))
2326 2460
2327(defun python-fill-comment (&optional justify) 2461(defun python-fill-comment (&optional justify)
2328 "Comment fill function for `python-fill-paragraph-function'. 2462 "Comment fill function for `python-fill-paragraph'.
2329JUSTIFY should be used (if applicable) as in `fill-paragraph'." 2463JUSTIFY should be used (if applicable) as in `fill-paragraph'."
2330 (fill-comment-paragraph justify)) 2464 (fill-comment-paragraph justify))
2331 2465
2332(defun python-fill-string (&optional justify) 2466(defun python-fill-string (&optional justify)
2333 "String fill function for `python-fill-paragraph-function'. 2467 "String fill function for `python-fill-paragraph'.
2334JUSTIFY should be used (if applicable) as in `fill-paragraph'." 2468JUSTIFY should be used (if applicable) as in `fill-paragraph'."
2335 (let ((marker (point-marker)) 2469 (let* ((marker (point-marker))
2336 (string-start-marker 2470 (str-start-pos
2337 (progn 2471 (let ((m (make-marker)))
2338 (skip-chars-forward "\"'uUrR") 2472 (setf (marker-position m)
2339 (goto-char (python-syntax-context 'string)) 2473 (or (python-syntax-context 'string)
2340 (skip-chars-forward "\"'uUrR") 2474 (and (equal (string-to-syntax "|")
2341 (point-marker))) 2475 (syntax-after (point)))
2342 (reg-start (line-beginning-position)) 2476 (point)))) m))
2343 (string-end-marker 2477 (num-quotes (python-syntax-count-quotes
2344 (progn 2478 (char-after str-start-pos) str-start-pos))
2345 (while (python-syntax-context 'string) 2479 (str-end-pos
2346 (goto-char (1+ (point-marker)))) 2480 (save-excursion
2347 (skip-chars-backward "\"'") 2481 (goto-char (+ str-start-pos num-quotes))
2348 (point-marker))) 2482 (or (re-search-forward (rx (syntax string-delimiter)) nil t)
2349 (reg-end (line-end-position)) 2483 (goto-char (point-max)))
2350 (fill-paragraph-function)) 2484 (point-marker)))
2485 (multi-line-p
2486 ;; Docstring styles may vary for oneliners and multi-liners.
2487 (> (count-matches "\n" str-start-pos str-end-pos) 0))
2488 (delimiters-style
2489 (case python-fill-docstring-style
2490 ;; delimiters-style is a cons cell with the form
2491 ;; (START-NEWLINES . END-NEWLINES). When any of the sexps
2492 ;; is NIL means to not add any newlines for start or end
2493 ;; of docstring. See `python-fill-docstring-style' for a
2494 ;; graphic idea of each style.
2495 (django (cons 1 1))
2496 (onetwo (and multi-line-p (cons 1 2)))
2497 (pep-257 (and multi-line-p (cons nil 2)))
2498 (pep-257-nn (and multi-line-p (cons nil 1)))
2499 (symmetric (and multi-line-p (cons 1 1)))))
2500 (docstring-p (save-excursion
2501 ;; Consider docstrings those strings which
2502 ;; start on a line by themselves.
2503 (python-nav-beginning-of-statement)
2504 (and (= (point) str-start-pos))))
2505 (fill-paragraph-function))
2351 (save-restriction 2506 (save-restriction
2352 (narrow-to-region reg-start reg-end) 2507 (narrow-to-region str-start-pos str-end-pos)
2353 (save-excursion 2508 (fill-paragraph justify))
2354 (goto-char string-start-marker) 2509 (save-excursion
2355 (delete-region (point-marker) (progn 2510 (when (and docstring-p python-fill-docstring-style)
2356 (skip-syntax-forward "> ") 2511 ;; Add the number of newlines indicated by the selected style
2357 (point-marker))) 2512 ;; at the start of the docstring.
2358 (goto-char string-end-marker) 2513 (goto-char (+ str-start-pos num-quotes))
2359 (delete-region (point-marker) (progn 2514 (delete-region (point) (progn
2360 (skip-syntax-backward "> ") 2515 (skip-syntax-forward "> ")
2361 (point-marker))) 2516 (point)))
2362 (save-excursion 2517 (and (car delimiters-style)
2363 (goto-char marker) 2518 (or (newline (car delimiters-style)) t)
2364 (fill-paragraph justify)) 2519 ;; Indent only if a newline is added.
2365 ;; If there is a newline in the docstring lets put triple 2520 (indent-according-to-mode))
2366 ;; quote in it's own line to follow pep 8 2521 ;; Add the number of newlines indicated by the selected style
2367 (when (save-excursion 2522 ;; at the end of the docstring.
2368 (re-search-backward "\n" string-start-marker t)) 2523 (goto-char (if (not (= str-end-pos (point-max)))
2369 (newline) 2524 (- str-end-pos num-quotes)
2370 (newline-and-indent)) 2525 str-end-pos))
2371 (fill-paragraph justify)))) t) 2526 (delete-region (point) (progn
2527 (skip-syntax-backward "> ")
2528 (point)))
2529 (and (cdr delimiters-style)
2530 ;; Add newlines only if string ends.
2531 (not (= str-end-pos (point-max)))
2532 (or (newline (cdr delimiters-style)) t)
2533 ;; Again indent only if a newline is added.
2534 (indent-according-to-mode))))) t)
2372 2535
2373(defun python-fill-decorator (&optional justify) 2536(defun python-fill-decorator (&optional justify)
2374 "Decorator fill function for `python-fill-paragraph-function'. 2537 "Decorator fill function for `python-fill-paragraph'.
2375JUSTIFY should be used (if applicable) as in `fill-paragraph'." 2538JUSTIFY should be used (if applicable) as in `fill-paragraph'."
2376 t) 2539 t)
2377 2540
2378(defun python-fill-paren (&optional justify) 2541(defun python-fill-paren (&optional justify)
2379 "Paren fill function for `python-fill-paragraph-function'. 2542 "Paren fill function for `python-fill-paragraph'.
2380JUSTIFY should be used (if applicable) as in `fill-paragraph'." 2543JUSTIFY should be used (if applicable) as in `fill-paragraph'."
2381 (save-restriction 2544 (save-restriction
2382 (narrow-to-region (progn 2545 (narrow-to-region (progn
@@ -2766,12 +2929,43 @@ parent defun name."
2766 ".") ".") 2929 ".") ".")
2767 name))))))) 2930 name)))))))
2768 2931
2769(defsubst python-info-beginning-of-block-statement-p () 2932(defun python-info-statement-starts-block-p ()
2770 "Return non-nil if current statement opens a block." 2933 "Return non-nil if current statement opens a block."
2771 (save-excursion 2934 (save-excursion
2772 (python-nav-beginning-of-statement) 2935 (python-nav-beginning-of-statement)
2773 (looking-at (python-rx block-start)))) 2936 (looking-at (python-rx block-start))))
2774 2937
2938(defun python-info-statement-ends-block-p ()
2939 "Return non-nil if point is at end of block."
2940 (let ((end-of-block-pos (save-excursion
2941 (python-nav-end-of-block)))
2942 (end-of-statement-pos (save-excursion
2943 (python-nav-end-of-statement))))
2944 (and end-of-block-pos end-of-statement-pos
2945 (= end-of-block-pos end-of-statement-pos))))
2946
2947(defun python-info-beginning-of-statement-p ()
2948 "Return non-nil if point is at beginning of statement."
2949 (= (point) (save-excursion
2950 (python-nav-beginning-of-statement)
2951 (point))))
2952
2953(defun python-info-end-of-statement-p ()
2954 "Return non-nil if point is at end of statement."
2955 (= (point) (save-excursion
2956 (python-nav-end-of-statement)
2957 (point))))
2958
2959(defun python-info-beginning-of-block-p ()
2960 "Return non-nil if point is at beginning of block."
2961 (and (python-info-beginning-of-statement-p)
2962 (python-info-statement-starts-block-p)))
2963
2964(defun python-info-end-of-block-p ()
2965 "Return non-nil if point is at end of block."
2966 (and (python-info-end-of-statement-p)
2967 (python-info-statement-ends-block-p)))
2968
2775(defun python-info-closing-block () 2969(defun python-info-closing-block ()
2776 "Return the point of the block the current line closes." 2970 "Return the point of the block the current line closes."
2777 (let ((closing-word (save-excursion 2971 (let ((closing-word (save-excursion
@@ -2996,7 +3190,7 @@ if that value is non-nil."
2996 3190
2997 (set (make-local-variable 'paragraph-start) "\\s-*$") 3191 (set (make-local-variable 'paragraph-start) "\\s-*$")
2998 (set (make-local-variable 'fill-paragraph-function) 3192 (set (make-local-variable 'fill-paragraph-function)
2999 'python-fill-paragraph-function) 3193 'python-fill-paragraph)
3000 3194
3001 (set (make-local-variable 'beginning-of-defun-function) 3195 (set (make-local-variable 'beginning-of-defun-function)
3002 #'python-beginning-of-defun-function) 3196 #'python-beginning-of-defun-function)