Mercurial > emacs
comparison lisp/progmodes/python.el @ 111753:f84b2c2c0b1b
Backport fixes for Bug#5390 and Bug#5694 from trunk.
* progmodes/python.el: Add Ipython support (Bug#5390).
(python-shell-prompt-alist)
(python-shell-continuation-prompt-alist): New options.
(python--set-prompt-regexp): New function.
(inferior-python-mode, run-python, python-shell): Require
ansi-color. Use python--set-prompt-regexp to set the comint
prompt based on the Python interpreter.
(python--prompt-regexp): New var.
(python-check-comint-prompt)
(python-comint-output-filter-function): Use it.
(run-python): Use a pipe (Bug#5694).
| author | Chong Yidong <cyd@stupidchicken.com> |
|---|---|
| date | Sun, 21 Nov 2010 12:04:43 -0500 |
| parents | 3776ded7f730 |
| children | 141d3f14d8c3 376148b31b5e |
comparison
equal
deleted
inserted
replaced
| 111752:3776ded7f730 | 111753:f84b2c2c0b1b |
|---|---|
| 567 | 567 |
| 568 ;; Bind python-file-queue before installing the kill-emacs-hook. | 568 ;; Bind python-file-queue before installing the kill-emacs-hook. |
| 569 (defvar python-file-queue nil | 569 (defvar python-file-queue nil |
| 570 "Queue of Python temp files awaiting execution. | 570 "Queue of Python temp files awaiting execution. |
| 571 Currently-active file is at the head of the list.") | 571 Currently-active file is at the head of the list.") |
| 572 | |
| 573 (defcustom python-shell-prompt-alist | |
| 574 '(("ipython" . "^In \\[[0-9]+\\]: *") | |
| 575 (t . "^>>> ")) | |
| 576 "Alist of Python input prompts. | |
| 577 Each element has the form (PROGRAM . REGEXP), where PROGRAM is | |
| 578 the value of `python-python-command' for the python process and | |
| 579 REGEXP is a regular expression matching the Python prompt. | |
| 580 PROGRAM can also be t, which specifies the default when no other | |
| 581 element matches `python-python-command'." | |
| 582 :type 'string | |
| 583 :group 'python | |
| 584 :version "24.1") | |
| 585 | |
| 586 (defcustom python-shell-continuation-prompt-alist | |
| 587 '(("ipython" . "^ [.][.][.]+: *") | |
| 588 (t . "^[.][.][.] ")) | |
| 589 "Alist of Python continued-line prompts. | |
| 590 Each element has the form (PROGRAM . REGEXP), where PROGRAM is | |
| 591 the value of `python-python-command' for the python process and | |
| 592 REGEXP is a regular expression matching the Python prompt for | |
| 593 continued lines. | |
| 594 PROGRAM can also be t, which specifies the default when no other | |
| 595 element matches `python-python-command'." | |
| 596 :type 'string | |
| 597 :group 'python | |
| 598 :version "24.1") | |
| 572 | 599 |
| 573 (defvar python-pdbtrack-is-tracking-p nil) | 600 (defvar python-pdbtrack-is-tracking-p nil) |
| 574 | 601 |
| 575 (defconst python-pdbtrack-stack-entry-regexp | 602 (defconst python-pdbtrack-stack-entry-regexp |
| 576 "^> \\(.*\\)(\\([0-9]+\\))\\([?a-zA-Z0-9_<>]+\\)()" | 603 "^> \\(.*\\)(\\([0-9]+\\))\\([?a-zA-Z0-9_<>]+\\)()" |
| 1300 compilation-error-regexp-alist))) | 1327 compilation-error-regexp-alist))) |
| 1301 (compilation-start command))) | 1328 (compilation-start command))) |
| 1302 | 1329 |
| 1303 ;;;; Inferior mode stuff (following cmuscheme). | 1330 ;;;; Inferior mode stuff (following cmuscheme). |
| 1304 | 1331 |
| 1305 ;; Fixme: Make sure we can work with IPython. | |
| 1306 | |
| 1307 (defcustom python-python-command "python" | 1332 (defcustom python-python-command "python" |
| 1308 "Shell command to run Python interpreter. | 1333 "Shell command to run Python interpreter. |
| 1309 Any arguments can't contain whitespace. | 1334 Any arguments can't contain whitespace." |
| 1310 Note that IPython may not work properly; it must at least be used | |
| 1311 with the `-cl' flag, i.e. use `ipython -cl'." | |
| 1312 :group 'python | 1335 :group 'python |
| 1313 :type 'string) | 1336 :type 'string) |
| 1314 | 1337 |
| 1315 (defcustom python-jython-command "jython" | 1338 (defcustom python-jython-command "jython" |
| 1316 "Shell command to run Jython interpreter. | 1339 "Shell command to run Jython interpreter. |
| 1384 st)) | 1407 st)) |
| 1385 | 1408 |
| 1386 ;; Autoloaded. | 1409 ;; Autoloaded. |
| 1387 (declare-function compilation-shell-minor-mode "compile" (&optional arg)) | 1410 (declare-function compilation-shell-minor-mode "compile" (&optional arg)) |
| 1388 | 1411 |
| 1412 (defvar python--prompt-regexp nil) | |
| 1413 | |
| 1414 (defun python--set-prompt-regexp () | |
| 1415 (let ((prompt (cdr-safe (or (assoc python-python-command | |
| 1416 python-shell-prompt-alist) | |
| 1417 (assq t python-shell-prompt-alist)))) | |
| 1418 (cprompt (cdr-safe (or (assoc python-python-command | |
| 1419 python-shell-continuation-prompt-alist) | |
| 1420 (assq t python-shell-continuation-prompt-alist))))) | |
| 1421 (set (make-local-variable 'comint-prompt-regexp) | |
| 1422 (concat "\\(" | |
| 1423 (mapconcat 'identity | |
| 1424 (delq nil (list prompt cprompt "^([Pp]db) ")) | |
| 1425 "\\|") | |
| 1426 "\\)")) | |
| 1427 (set (make-local-variable 'python--prompt-regexp) prompt))) | |
| 1428 | |
| 1389 ;; Fixme: This should inherit some stuff from `python-mode', but I'm | 1429 ;; Fixme: This should inherit some stuff from `python-mode', but I'm |
| 1390 ;; not sure how much: at least some keybindings, like C-c C-f; | 1430 ;; not sure how much: at least some keybindings, like C-c C-f; |
| 1391 ;; syntax?; font-locking, e.g. for triple-quoted strings? | 1431 ;; syntax?; font-locking, e.g. for triple-quoted strings? |
| 1392 (define-derived-mode inferior-python-mode comint-mode "Inferior Python" | 1432 (define-derived-mode inferior-python-mode comint-mode "Inferior Python" |
| 1393 "Major mode for interacting with an inferior Python process. | 1433 "Major mode for interacting with an inferior Python process. |
| 1406 For running multiple processes in multiple buffers, see `run-python' and | 1446 For running multiple processes in multiple buffers, see `run-python' and |
| 1407 `python-buffer'. | 1447 `python-buffer'. |
| 1408 | 1448 |
| 1409 \\{inferior-python-mode-map}" | 1449 \\{inferior-python-mode-map}" |
| 1410 :group 'python | 1450 :group 'python |
| 1451 (require 'ansi-color) ; for ipython | |
| 1411 (setq mode-line-process '(":%s")) | 1452 (setq mode-line-process '(":%s")) |
| 1412 (set (make-local-variable 'comint-input-filter) 'python-input-filter) | 1453 (set (make-local-variable 'comint-input-filter) 'python-input-filter) |
| 1413 (add-hook 'comint-preoutput-filter-functions #'python-preoutput-filter | 1454 (add-hook 'comint-preoutput-filter-functions #'python-preoutput-filter |
| 1414 nil t) | 1455 nil t) |
| 1415 ;; Still required by `comint-redirect-send-command', for instance | 1456 (python--set-prompt-regexp) |
| 1416 ;; (and we need to match things like `>>> ... >>> '): | |
| 1417 (set (make-local-variable 'comint-prompt-regexp) | |
| 1418 (rx line-start (1+ (and (or (repeat 3 (any ">.")) "(Pdb)") " ")))) | |
| 1419 (set (make-local-variable 'compilation-error-regexp-alist) | 1457 (set (make-local-variable 'compilation-error-regexp-alist) |
| 1420 python-compilation-regexp-alist) | 1458 python-compilation-regexp-alist) |
| 1421 (compilation-shell-minor-mode 1)) | 1459 (compilation-shell-minor-mode 1)) |
| 1422 | 1460 |
| 1423 (defcustom inferior-python-filter-regexp "\\`\\s-*\\S-?\\S-?\\s-*\\'" | 1461 (defcustom inferior-python-filter-regexp "\\`\\s-*\\S-?\\S-?\\s-*\\'" |
| 1520 (unless (or python-version-checked | 1558 (unless (or python-version-checked |
| 1521 (equal 0 (string-match (regexp-quote python-python-command) | 1559 (equal 0 (string-match (regexp-quote python-python-command) |
| 1522 cmd))) | 1560 cmd))) |
| 1523 (unless (shell-command-to-string cmd) | 1561 (unless (shell-command-to-string cmd) |
| 1524 (error "Can't run Python command `%s'" cmd)) | 1562 (error "Can't run Python command `%s'" cmd)) |
| 1525 (let* ((res (shell-command-to-string (concat cmd " --version")))) | 1563 (let* ((res (shell-command-to-string |
| 1526 (string-match "Python \\([0-9]\\)\\.\\([0-9]\\)" res) | 1564 (concat cmd |
| 1527 (unless (and (equal "2" (match-string 1 res)) | 1565 " -c \"from sys import version_info;\ |
| 1528 (match-beginning 2) | 1566 print version_info >= (2, 2) and version_info < (3, 0)\"")))) |
| 1529 (>= (string-to-number (match-string 2 res)) 2)) | 1567 (unless (string-match "True" res) |
| 1530 (error "Only Python versions >= 2.2 and < 3.0 supported"))) | 1568 (error "Only Python versions >= 2.2 and < 3.0 are supported"))) |
| 1531 (setq python-version-checked t))) | 1569 (setq python-version-checked t))) |
| 1532 | 1570 |
| 1533 ;;;###autoload | 1571 ;;;###autoload |
| 1534 (defun run-python (&optional cmd noshow new) | 1572 (defun run-python (&optional cmd noshow new) |
| 1535 "Run an inferior Python process, input and output via buffer *Python*. | 1573 "Run an inferior Python process, input and output via buffer *Python*. |
| 1552 current working directory, for security reasons. To disable this | 1590 current working directory, for security reasons. To disable this |
| 1553 behavior, change `python-remove-cwd-from-path' to nil." | 1591 behavior, change `python-remove-cwd-from-path' to nil." |
| 1554 (interactive (if current-prefix-arg | 1592 (interactive (if current-prefix-arg |
| 1555 (list (read-string "Run Python: " python-command) nil t) | 1593 (list (read-string "Run Python: " python-command) nil t) |
| 1556 (list python-command))) | 1594 (list python-command))) |
| 1595 (require 'ansi-color) ; for ipython | |
| 1557 (unless cmd (setq cmd python-command)) | 1596 (unless cmd (setq cmd python-command)) |
| 1558 (python-check-version cmd) | 1597 (python-check-version cmd) |
| 1559 (setq python-command cmd) | 1598 (setq python-command cmd) |
| 1560 ;; Fixme: Consider making `python-buffer' buffer-local as a buffer | 1599 ;; Fixme: Consider making `python-buffer' buffer-local as a buffer |
| 1561 ;; (not a name) in Python buffers from which `run-python' &c is | 1600 ;; (not a name) in Python buffers from which `run-python' &c is |
| 1570 (process-environment ; to import emacs.py | 1609 (process-environment ; to import emacs.py |
| 1571 (cons (concat "PYTHONPATH=" | 1610 (cons (concat "PYTHONPATH=" |
| 1572 (if path (concat path path-separator)) | 1611 (if path (concat path path-separator)) |
| 1573 data-directory) | 1612 data-directory) |
| 1574 process-environment)) | 1613 process-environment)) |
| 1575 ;; Suppress use of pager for help output: | 1614 ;; If we use a pipe, unicode characters are not printed |
| 1576 (process-connection-type nil)) | 1615 ;; correctly (Bug#5794) and IPython does not work at |
| 1616 ;; all (Bug#5390). | |
| 1617 (process-connection-type t)) | |
| 1577 (apply 'make-comint-in-buffer "Python" | 1618 (apply 'make-comint-in-buffer "Python" |
| 1578 (generate-new-buffer "*Python*") | 1619 (generate-new-buffer "*Python*") |
| 1579 (car cmdlist) nil (cdr cmdlist))) | 1620 (car cmdlist) nil (cdr cmdlist))) |
| 1580 (setq-default python-buffer (current-buffer)) | 1621 (setq-default python-buffer (current-buffer)) |
| 1581 (setq python-buffer (current-buffer)) | 1622 (setq python-buffer (current-buffer)) |
| 1627 ;; | 1668 ;; |
| 1628 ;; Fixme: Write a `coding' header to the temp file if the region is | 1669 ;; Fixme: Write a `coding' header to the temp file if the region is |
| 1629 ;; non-ASCII. | 1670 ;; non-ASCII. |
| 1630 (interactive "r") | 1671 (interactive "r") |
| 1631 (let* ((f (make-temp-file "py")) | 1672 (let* ((f (make-temp-file "py")) |
| 1632 (command (format "emacs.eexecfile(%S)" f)) | 1673 (command |
| 1674 ;; IPython puts the FakeModule module into __main__ so | |
| 1675 ;; emacs.eexecfile becomes useless. | |
| 1676 (if (string-match "^ipython" python-command) | |
| 1677 (format "execfile %S" f) | |
| 1678 (format "emacs.eexecfile(%S)" f))) | |
| 1633 (orig-start (copy-marker start))) | 1679 (orig-start (copy-marker start))) |
| 1634 (when (save-excursion | 1680 (when (save-excursion |
| 1635 (goto-char start) | 1681 (goto-char start) |
| 1636 (/= 0 (current-indentation))) ; need dummy block | 1682 (/= 0 (current-indentation))) ; need dummy block |
| 1637 (save-excursion | 1683 (save-excursion |
| 1827 "Return non-nil if and only if there's a normal prompt in the inferior buffer. | 1873 "Return non-nil if and only if there's a normal prompt in the inferior buffer. |
| 1828 If there isn't, it's probably not appropriate to send input to return Eldoc | 1874 If there isn't, it's probably not appropriate to send input to return Eldoc |
| 1829 information etc. If PROC is non-nil, check the buffer for that process." | 1875 information etc. If PROC is non-nil, check the buffer for that process." |
| 1830 (with-current-buffer (process-buffer (or proc (python-proc))) | 1876 (with-current-buffer (process-buffer (or proc (python-proc))) |
| 1831 (save-excursion | 1877 (save-excursion |
| 1832 (save-match-data (re-search-backward ">>> \\=" nil t))))) | 1878 (save-match-data |
| 1879 (re-search-backward (concat python--prompt-regexp " *\\=") | |
| 1880 nil t))))) | |
| 1833 | 1881 |
| 1834 ;; Fixme: Is there anything reasonable we can do with random methods? | 1882 ;; Fixme: Is there anything reasonable we can do with random methods? |
| 1835 ;; (Currently only works with functions.) | 1883 ;; (Currently only works with functions.) |
| 1836 (defun python-eldoc-function () | 1884 (defun python-eldoc-function () |
| 1837 "`eldoc-documentation-function' for Python. | 1885 "`eldoc-documentation-function' for Python. |
| 2543 | 2591 |
| 2544 (defun python-comint-output-filter-function (string) | 2592 (defun python-comint-output-filter-function (string) |
| 2545 "Watch output for Python prompt and exec next file waiting in queue. | 2593 "Watch output for Python prompt and exec next file waiting in queue. |
| 2546 This function is appropriate for `comint-output-filter-functions'." | 2594 This function is appropriate for `comint-output-filter-functions'." |
| 2547 ;; TBD: this should probably use split-string | 2595 ;; TBD: this should probably use split-string |
| 2548 (when (and (or (string-equal string ">>> ") | 2596 (when (and (string-match python--prompt-regexp string) |
| 2549 (and (>= (length string) 5) | |
| 2550 (string-equal (substring string -5) "\n>>> "))) | |
| 2551 python-file-queue) | 2597 python-file-queue) |
| 2552 (condition-case nil | 2598 (condition-case nil |
| 2553 (delete-file (car python-file-queue)) | 2599 (delete-file (car python-file-queue)) |
| 2554 (error nil)) | 2600 (error nil)) |
| 2555 (setq python-file-queue (cdr python-file-queue)) | 2601 (setq python-file-queue (cdr python-file-queue)) |
| 2757 (goto-char (point-max)) | 2803 (goto-char (point-max)) |
| 2758 (move-marker (process-mark proc) (point)) | 2804 (move-marker (process-mark proc) (point)) |
| 2759 (funcall (process-filter proc) proc msg)) | 2805 (funcall (process-filter proc) proc msg)) |
| 2760 (set-buffer curbuf)) | 2806 (set-buffer curbuf)) |
| 2761 (process-send-string proc cmd))) | 2807 (process-send-string proc cmd))) |
| 2808 | |
| 2762 ;;;###autoload | 2809 ;;;###autoload |
| 2763 (defun python-shell (&optional argprompt) | 2810 (defun python-shell (&optional argprompt) |
| 2764 "Start an interactive Python interpreter in another window. | 2811 "Start an interactive Python interpreter in another window. |
| 2765 This is like Shell mode, except that Python is running in the window | 2812 This is like Shell mode, except that Python is running in the window |
| 2766 instead of a shell. See the `Interactive Shell' and `Shell Mode' | 2813 instead of a shell. See the `Interactive Shell' and `Shell Mode' |
| 2796 be lost if you do. This appears to be an Emacs bug, an unfortunate | 2843 be lost if you do. This appears to be an Emacs bug, an unfortunate |
| 2797 interaction between undo and process filters; the same problem exists in | 2844 interaction between undo and process filters; the same problem exists in |
| 2798 non-Python process buffers using the default (Emacs-supplied) process | 2845 non-Python process buffers using the default (Emacs-supplied) process |
| 2799 filter." | 2846 filter." |
| 2800 (interactive "P") | 2847 (interactive "P") |
| 2848 (require 'ansi-color) ; For ipython | |
| 2801 ;; Set the default shell if not already set | 2849 ;; Set the default shell if not already set |
| 2802 (when (null python-which-shell) | 2850 (when (null python-which-shell) |
| 2803 (python-toggle-shells python-default-interpreter)) | 2851 (python-toggle-shells python-default-interpreter)) |
| 2804 (let ((args python-which-args)) | 2852 (let ((args python-which-args)) |
| 2805 (when (and argprompt | 2853 (when (and argprompt |
| 2812 (concat | 2860 (concat |
| 2813 (mapconcat 'identity python-which-args " ") " ") | 2861 (mapconcat 'identity python-which-args " ") " ") |
| 2814 )))) | 2862 )))) |
| 2815 (switch-to-buffer-other-window | 2863 (switch-to-buffer-other-window |
| 2816 (apply 'make-comint python-which-bufname python-which-shell nil args)) | 2864 (apply 'make-comint python-which-bufname python-which-shell nil args)) |
| 2817 (make-local-variable 'comint-prompt-regexp) | |
| 2818 (set-process-sentinel (get-buffer-process (current-buffer)) | 2865 (set-process-sentinel (get-buffer-process (current-buffer)) |
| 2819 'python-sentinel) | 2866 'python-sentinel) |
| 2820 (setq comint-prompt-regexp "^>>> \\|^[.][.][.] \\|^(pdb) ") | 2867 (python--set-prompt-regexp) |
| 2821 (add-hook 'comint-output-filter-functions | 2868 (add-hook 'comint-output-filter-functions |
| 2822 'python-comint-output-filter-function nil t) | 2869 'python-comint-output-filter-function nil t) |
| 2823 ;; pdbtrack | 2870 ;; pdbtrack |
| 2824 (set-syntax-table python-mode-syntax-table) | 2871 (set-syntax-table python-mode-syntax-table) |
| 2825 (use-local-map python-shell-map))) | 2872 (use-local-map python-shell-map))) |
