diff options
| author | Chong Yidong | 2010-08-24 16:20:21 -0400 |
|---|---|---|
| committer | Chong Yidong | 2010-08-24 16:20:21 -0400 |
| commit | edfd00fa82735b6930c714d32884093718c4a951 (patch) | |
| tree | 69cb917a306c3b5a837c0e1eb810173cd6637acd | |
| parent | 1c409d0b963ebdb1f48b90ddce85c56d989bee5f (diff) | |
| download | emacs-edfd00fa82735b6930c714d32884093718c4a951.tar.gz emacs-edfd00fa82735b6930c714d32884093718c4a951.zip | |
* lisp/progmodes/python.el: Add Ipython support (Bug#5390).
Based on a patch by Fabian Ezequiel Gallina.
(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).
(python-send-region): Send a different Python command if Ipython is in use.
(python-check-version): Use a Python command to find the version.
| -rw-r--r-- | lisp/ChangeLog | 20 | ||||
| -rw-r--r-- | lisp/progmodes/python.el | 95 |
2 files changed, 91 insertions, 24 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 79b5f6583a0..b273f017b7d 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,5 +1,25 @@ | |||
| 1 | 2010-08-24 Chong Yidong <cyd@stupidchicken.com> | 1 | 2010-08-24 Chong Yidong <cyd@stupidchicken.com> |
| 2 | 2 | ||
| 3 | * progmodes/python.el: Add Ipython support (Bug#5390). | ||
| 4 | (python-shell-prompt-alist) | ||
| 5 | (python-shell-continuation-prompt-alist): New options. | ||
| 6 | (python--set-prompt-regexp): New function. | ||
| 7 | (inferior-python-mode, run-python, python-shell): Require | ||
| 8 | ansi-color. Use python--set-prompt-regexp to set the comint | ||
| 9 | prompt based on the Python interpreter. | ||
| 10 | (python--prompt-regexp): New var. | ||
| 11 | (python-check-comint-prompt) | ||
| 12 | (python-comint-output-filter-function): Use it. | ||
| 13 | (run-python): Use a pipe (Bug#5694). | ||
| 14 | |||
| 15 | 2010-08-24 Fabian Ezequiel Gallina <galli.87@gmail.com> (tiny change) | ||
| 16 | |||
| 17 | * progmodes/python.el (python-send-region): Send a different | ||
| 18 | Python command if Ipython is in use. | ||
| 19 | (python-check-version): Use a Python command to find the version. | ||
| 20 | |||
| 21 | 2010-08-24 Chong Yidong <cyd@stupidchicken.com> | ||
| 22 | |||
| 3 | * mouse.el (mouse-yank-primary): Avoid setting primary when | 23 | * mouse.el (mouse-yank-primary): Avoid setting primary when |
| 4 | deactivating the mark (Bug#6872). | 24 | deactivating the mark (Bug#6872). |
| 5 | 25 | ||
diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el index 2b09e346331..849951a633a 100644 --- a/lisp/progmodes/python.el +++ b/lisp/progmodes/python.el | |||
| @@ -579,6 +579,33 @@ having to restart the program." | |||
| 579 | "Queue of Python temp files awaiting execution. | 579 | "Queue of Python temp files awaiting execution. |
| 580 | Currently-active file is at the head of the list.") | 580 | Currently-active file is at the head of the list.") |
| 581 | 581 | ||
| 582 | (defcustom python-shell-prompt-alist | ||
| 583 | '(("ipython" . "^In \\[[0-9]+\\]: *") | ||
| 584 | (t . "^>>> ")) | ||
| 585 | "Alist of Python input prompts. | ||
| 586 | Each element has the form (PROGRAM . REGEXP), where PROGRAM is | ||
| 587 | the value of `python-python-command' for the python process and | ||
| 588 | REGEXP is a regular expression matching the Python prompt. | ||
| 589 | PROGRAM can also be t, which specifies the default when no other | ||
| 590 | element matches `python-python-command'." | ||
| 591 | :type 'string | ||
| 592 | :group 'python | ||
| 593 | :version "24.1") | ||
| 594 | |||
| 595 | (defcustom python-shell-continuation-prompt-alist | ||
| 596 | '(("ipython" . "^ [.][.][.]+: *") | ||
| 597 | (t . "^[.][.][.] ")) | ||
| 598 | "Alist of Python continued-line prompts. | ||
| 599 | Each element has the form (PROGRAM . REGEXP), where PROGRAM is | ||
| 600 | the value of `python-python-command' for the python process and | ||
| 601 | REGEXP is a regular expression matching the Python prompt for | ||
| 602 | continued lines. | ||
| 603 | PROGRAM can also be t, which specifies the default when no other | ||
| 604 | element matches `python-python-command'." | ||
| 605 | :type 'string | ||
| 606 | :group 'python | ||
| 607 | :version "24.1") | ||
| 608 | |||
| 582 | (defvar python-pdbtrack-is-tracking-p nil) | 609 | (defvar python-pdbtrack-is-tracking-p nil) |
| 583 | 610 | ||
| 584 | (defconst python-pdbtrack-stack-entry-regexp | 611 | (defconst python-pdbtrack-stack-entry-regexp |
| @@ -1311,13 +1338,9 @@ See `python-check-command' for the default." | |||
| 1311 | 1338 | ||
| 1312 | ;;;; Inferior mode stuff (following cmuscheme). | 1339 | ;;;; Inferior mode stuff (following cmuscheme). |
| 1313 | 1340 | ||
| 1314 | ;; Fixme: Make sure we can work with IPython. | ||
| 1315 | |||
| 1316 | (defcustom python-python-command "python" | 1341 | (defcustom python-python-command "python" |
| 1317 | "Shell command to run Python interpreter. | 1342 | "Shell command to run Python interpreter. |
| 1318 | Any arguments can't contain whitespace. | 1343 | Any arguments can't contain whitespace." |
| 1319 | Note that IPython may not work properly; it must at least be used | ||
| 1320 | with the `-cl' flag, i.e. use `ipython -cl'." | ||
| 1321 | :group 'python | 1344 | :group 'python |
| 1322 | :type 'string) | 1345 | :type 'string) |
| 1323 | 1346 | ||
| @@ -1395,6 +1418,23 @@ local value.") | |||
| 1395 | ;; Autoloaded. | 1418 | ;; Autoloaded. |
| 1396 | (declare-function compilation-shell-minor-mode "compile" (&optional arg)) | 1419 | (declare-function compilation-shell-minor-mode "compile" (&optional arg)) |
| 1397 | 1420 | ||
| 1421 | (defvar python--prompt-regexp nil) | ||
| 1422 | |||
| 1423 | (defun python--set-prompt-regexp () | ||
| 1424 | (let ((prompt (cdr-safe (or (assoc python-python-command | ||
| 1425 | python-shell-prompt-alist) | ||
| 1426 | (assq t python-shell-prompt-alist)))) | ||
| 1427 | (cprompt (cdr-safe (or (assoc python-python-command | ||
| 1428 | python-shell-continuation-prompt-alist) | ||
| 1429 | (assq t python-shell-continuation-prompt-alist))))) | ||
| 1430 | (set (make-local-variable 'comint-prompt-regexp) | ||
| 1431 | (concat "\\(" | ||
| 1432 | (mapconcat 'identity | ||
| 1433 | (delq nil (list prompt cprompt "^([Pp]db) ")) | ||
| 1434 | "\\|") | ||
| 1435 | "\\)")) | ||
| 1436 | (set (make-local-variable 'python--prompt-regexp) prompt))) | ||
| 1437 | |||
| 1398 | ;; Fixme: This should inherit some stuff from `python-mode', but I'm | 1438 | ;; Fixme: This should inherit some stuff from `python-mode', but I'm |
| 1399 | ;; not sure how much: at least some keybindings, like C-c C-f; | 1439 | ;; not sure how much: at least some keybindings, like C-c C-f; |
| 1400 | ;; syntax?; font-locking, e.g. for triple-quoted strings? | 1440 | ;; syntax?; font-locking, e.g. for triple-quoted strings? |
| @@ -1417,14 +1457,12 @@ For running multiple processes in multiple buffers, see `run-python' and | |||
| 1417 | 1457 | ||
| 1418 | \\{inferior-python-mode-map}" | 1458 | \\{inferior-python-mode-map}" |
| 1419 | :group 'python | 1459 | :group 'python |
| 1460 | (require 'ansi-color) ; for ipython | ||
| 1420 | (setq mode-line-process '(":%s")) | 1461 | (setq mode-line-process '(":%s")) |
| 1421 | (set (make-local-variable 'comint-input-filter) 'python-input-filter) | 1462 | (set (make-local-variable 'comint-input-filter) 'python-input-filter) |
| 1422 | (add-hook 'comint-preoutput-filter-functions #'python-preoutput-filter | 1463 | (add-hook 'comint-preoutput-filter-functions #'python-preoutput-filter |
| 1423 | nil t) | 1464 | nil t) |
| 1424 | ;; Still required by `comint-redirect-send-command', for instance | 1465 | (python--set-prompt-regexp) |
| 1425 | ;; (and we need to match things like `>>> ... >>> '): | ||
| 1426 | (set (make-local-variable 'comint-prompt-regexp) | ||
| 1427 | (rx line-start (1+ (and (or (repeat 3 (any ">.")) "(Pdb)") " ")))) | ||
| 1428 | (set (make-local-variable 'compilation-error-regexp-alist) | 1466 | (set (make-local-variable 'compilation-error-regexp-alist) |
| 1429 | python-compilation-regexp-alist) | 1467 | python-compilation-regexp-alist) |
| 1430 | (compilation-shell-minor-mode 1)) | 1468 | (compilation-shell-minor-mode 1)) |
| @@ -1521,12 +1559,12 @@ Don't save anything for STR matching `inferior-python-filter-regexp'." | |||
| 1521 | cmd))) | 1559 | cmd))) |
| 1522 | (unless (shell-command-to-string cmd) | 1560 | (unless (shell-command-to-string cmd) |
| 1523 | (error "Can't run Python command `%s'" cmd)) | 1561 | (error "Can't run Python command `%s'" cmd)) |
| 1524 | (let* ((res (shell-command-to-string (concat cmd " --version")))) | 1562 | (let* ((res (shell-command-to-string |
| 1525 | (string-match "Python \\([0-9]\\)\\.\\([0-9]\\)" res) | 1563 | (concat cmd |
| 1526 | (unless (and (equal "2" (match-string 1 res)) | 1564 | " -c \"from sys import version_info;\ |
| 1527 | (match-beginning 2) | 1565 | print version_info >= (2, 2) and version_info < (3, 0)\"")))) |
| 1528 | (>= (string-to-number (match-string 2 res)) 2)) | 1566 | (unless (string-match "True" res) |
| 1529 | (error "Only Python versions >= 2.2 and < 3.0 supported"))) | 1567 | (error "Only Python versions >= 2.2 and < 3.0 are supported"))) |
| 1530 | (setq python-version-checked t))) | 1568 | (setq python-version-checked t))) |
| 1531 | 1569 | ||
| 1532 | ;;;###autoload | 1570 | ;;;###autoload |
| @@ -1549,6 +1587,7 @@ buffer for a list of commands.)" | |||
| 1549 | (interactive (if current-prefix-arg | 1587 | (interactive (if current-prefix-arg |
| 1550 | (list (read-string "Run Python: " python-command) nil t) | 1588 | (list (read-string "Run Python: " python-command) nil t) |
| 1551 | (list python-command))) | 1589 | (list python-command))) |
| 1590 | (require 'ansi-color) ; for ipython | ||
| 1552 | (unless cmd (setq cmd python-command)) | 1591 | (unless cmd (setq cmd python-command)) |
| 1553 | (python-check-version cmd) | 1592 | (python-check-version cmd) |
| 1554 | (setq python-command cmd) | 1593 | (setq python-command cmd) |
| @@ -1566,8 +1605,10 @@ buffer for a list of commands.)" | |||
| 1566 | (if path (concat path path-separator)) | 1605 | (if path (concat path path-separator)) |
| 1567 | data-directory) | 1606 | data-directory) |
| 1568 | process-environment)) | 1607 | process-environment)) |
| 1569 | ;; Suppress use of pager for help output: | 1608 | ;; If we use a pipe, unicode characters are not printed |
| 1570 | (process-connection-type nil)) | 1609 | ;; correctly (Bug#5794) and IPython does not work at |
| 1610 | ;; all (Bug#5390). | ||
| 1611 | (process-connection-type t)) | ||
| 1571 | (apply 'make-comint-in-buffer "Python" | 1612 | (apply 'make-comint-in-buffer "Python" |
| 1572 | (generate-new-buffer "*Python*") | 1613 | (generate-new-buffer "*Python*") |
| 1573 | (car cmdlist) nil (cdr cmdlist))) | 1614 | (car cmdlist) nil (cdr cmdlist))) |
| @@ -1623,7 +1664,12 @@ buffer for a list of commands.)" | |||
| 1623 | ;; non-ASCII. | 1664 | ;; non-ASCII. |
| 1624 | (interactive "r") | 1665 | (interactive "r") |
| 1625 | (let* ((f (make-temp-file "py")) | 1666 | (let* ((f (make-temp-file "py")) |
| 1626 | (command (format "emacs.eexecfile(%S)" f)) | 1667 | (command |
| 1668 | ;; IPython puts the FakeModule module into __main__ so | ||
| 1669 | ;; emacs.eexecfile becomes useless. | ||
| 1670 | (if (string-match "^ipython" python-command) | ||
| 1671 | (format "execfile %S" f) | ||
| 1672 | (format "emacs.eexecfile(%S)" f))) | ||
| 1627 | (orig-start (copy-marker start))) | 1673 | (orig-start (copy-marker start))) |
| 1628 | (when (save-excursion | 1674 | (when (save-excursion |
| 1629 | (goto-char start) | 1675 | (goto-char start) |
| @@ -1823,7 +1869,9 @@ If there isn't, it's probably not appropriate to send input to return Eldoc | |||
| 1823 | information etc. If PROC is non-nil, check the buffer for that process." | 1869 | information etc. If PROC is non-nil, check the buffer for that process." |
| 1824 | (with-current-buffer (process-buffer (or proc (python-proc))) | 1870 | (with-current-buffer (process-buffer (or proc (python-proc))) |
| 1825 | (save-excursion | 1871 | (save-excursion |
| 1826 | (save-match-data (re-search-backward ">>> \\=" nil t))))) | 1872 | (save-match-data |
| 1873 | (re-search-backward (concat python--prompt-regexp " *\\=") | ||
| 1874 | nil t))))) | ||
| 1827 | 1875 | ||
| 1828 | ;; Fixme: Is there anything reasonable we can do with random methods? | 1876 | ;; Fixme: Is there anything reasonable we can do with random methods? |
| 1829 | ;; (Currently only works with functions.) | 1877 | ;; (Currently only works with functions.) |
| @@ -2539,9 +2587,7 @@ Runs `jython-mode-hook' after `python-mode-hook'." | |||
| 2539 | "Watch output for Python prompt and exec next file waiting in queue. | 2587 | "Watch output for Python prompt and exec next file waiting in queue. |
| 2540 | This function is appropriate for `comint-output-filter-functions'." | 2588 | This function is appropriate for `comint-output-filter-functions'." |
| 2541 | ;; TBD: this should probably use split-string | 2589 | ;; TBD: this should probably use split-string |
| 2542 | (when (and (or (string-equal string ">>> ") | 2590 | (when (and (string-match python--prompt-regexp string) |
| 2543 | (and (>= (length string) 5) | ||
| 2544 | (string-equal (substring string -5) "\n>>> "))) | ||
| 2545 | python-file-queue) | 2591 | python-file-queue) |
| 2546 | (condition-case nil | 2592 | (condition-case nil |
| 2547 | (delete-file (car python-file-queue)) | 2593 | (delete-file (car python-file-queue)) |
| @@ -2753,6 +2799,7 @@ comint believe the user typed this string so that | |||
| 2753 | (funcall (process-filter proc) proc msg)) | 2799 | (funcall (process-filter proc) proc msg)) |
| 2754 | (set-buffer curbuf)) | 2800 | (set-buffer curbuf)) |
| 2755 | (process-send-string proc cmd))) | 2801 | (process-send-string proc cmd))) |
| 2802 | |||
| 2756 | ;;;###autoload | 2803 | ;;;###autoload |
| 2757 | (defun python-shell (&optional argprompt) | 2804 | (defun python-shell (&optional argprompt) |
| 2758 | "Start an interactive Python interpreter in another window. | 2805 | "Start an interactive Python interpreter in another window. |
| @@ -2792,6 +2839,7 @@ interaction between undo and process filters; the same problem exists in | |||
| 2792 | non-Python process buffers using the default (Emacs-supplied) process | 2839 | non-Python process buffers using the default (Emacs-supplied) process |
| 2793 | filter." | 2840 | filter." |
| 2794 | (interactive "P") | 2841 | (interactive "P") |
| 2842 | (require 'ansi-color) ; For ipython | ||
| 2795 | ;; Set the default shell if not already set | 2843 | ;; Set the default shell if not already set |
| 2796 | (when (null python-which-shell) | 2844 | (when (null python-which-shell) |
| 2797 | (python-toggle-shells python-default-interpreter)) | 2845 | (python-toggle-shells python-default-interpreter)) |
| @@ -2808,10 +2856,9 @@ filter." | |||
| 2808 | )))) | 2856 | )))) |
| 2809 | (switch-to-buffer-other-window | 2857 | (switch-to-buffer-other-window |
| 2810 | (apply 'make-comint python-which-bufname python-which-shell nil args)) | 2858 | (apply 'make-comint python-which-bufname python-which-shell nil args)) |
| 2811 | (make-local-variable 'comint-prompt-regexp) | ||
| 2812 | (set-process-sentinel (get-buffer-process (current-buffer)) | 2859 | (set-process-sentinel (get-buffer-process (current-buffer)) |
| 2813 | 'python-sentinel) | 2860 | 'python-sentinel) |
| 2814 | (setq comint-prompt-regexp "^>>> \\|^[.][.][.] \\|^(pdb) ") | 2861 | (python--set-prompt-regexp) |
| 2815 | (add-hook 'comint-output-filter-functions | 2862 | (add-hook 'comint-output-filter-functions |
| 2816 | 'python-comint-output-filter-function nil t) | 2863 | 'python-comint-output-filter-function nil t) |
| 2817 | ;; pdbtrack | 2864 | ;; pdbtrack |