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).
This commit is contained in:
Chong Yidong 2010-11-21 12:04:43 -05:00
parent 1d851570a6
commit ae3da38afc
2 changed files with 85 additions and 24 deletions

View file

@ -1,3 +1,17 @@
2010-11-21 Chong Yidong <cyd@stupidchicken.com>
* 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).
2010-11-21 Chong Yidong <cyd@stupidchicken.com>
* progmodes/python.el (run-python): Doc fix.

View file

@ -570,6 +570,33 @@ having to restart the program."
"Queue of Python temp files awaiting execution.
Currently-active file is at the head of the list.")
(defcustom python-shell-prompt-alist
'(("ipython" . "^In \\[[0-9]+\\]: *")
(t . "^>>> "))
"Alist of Python input prompts.
Each element has the form (PROGRAM . REGEXP), where PROGRAM is
the value of `python-python-command' for the python process and
REGEXP is a regular expression matching the Python prompt.
PROGRAM can also be t, which specifies the default when no other
element matches `python-python-command'."
:type 'string
:group 'python
:version "24.1")
(defcustom python-shell-continuation-prompt-alist
'(("ipython" . "^ [.][.][.]+: *")
(t . "^[.][.][.] "))
"Alist of Python continued-line prompts.
Each element has the form (PROGRAM . REGEXP), where PROGRAM is
the value of `python-python-command' for the python process and
REGEXP is a regular expression matching the Python prompt for
continued lines.
PROGRAM can also be t, which specifies the default when no other
element matches `python-python-command'."
:type 'string
:group 'python
:version "24.1")
(defvar python-pdbtrack-is-tracking-p nil)
(defconst python-pdbtrack-stack-entry-regexp
@ -1302,13 +1329,9 @@ See `python-check-command' for the default."
;;;; Inferior mode stuff (following cmuscheme).
;; Fixme: Make sure we can work with IPython.
(defcustom python-python-command "python"
"Shell command to run Python interpreter.
Any arguments can't contain whitespace.
Note that IPython may not work properly; it must at least be used
with the `-cl' flag, i.e. use `ipython -cl'."
Any arguments can't contain whitespace."
:group 'python
:type 'string)
@ -1386,6 +1409,23 @@ local value.")
;; Autoloaded.
(declare-function compilation-shell-minor-mode "compile" (&optional arg))
(defvar python--prompt-regexp nil)
(defun python--set-prompt-regexp ()
(let ((prompt (cdr-safe (or (assoc python-python-command
python-shell-prompt-alist)
(assq t python-shell-prompt-alist))))
(cprompt (cdr-safe (or (assoc python-python-command
python-shell-continuation-prompt-alist)
(assq t python-shell-continuation-prompt-alist)))))
(set (make-local-variable 'comint-prompt-regexp)
(concat "\\("
(mapconcat 'identity
(delq nil (list prompt cprompt "^([Pp]db) "))
"\\|")
"\\)"))
(set (make-local-variable 'python--prompt-regexp) prompt)))
;; Fixme: This should inherit some stuff from `python-mode', but I'm
;; not sure how much: at least some keybindings, like C-c C-f;
;; syntax?; font-locking, e.g. for triple-quoted strings?
@ -1408,14 +1448,12 @@ For running multiple processes in multiple buffers, see `run-python' and
\\{inferior-python-mode-map}"
:group 'python
(require 'ansi-color) ; for ipython
(setq mode-line-process '(":%s"))
(set (make-local-variable 'comint-input-filter) 'python-input-filter)
(add-hook 'comint-preoutput-filter-functions #'python-preoutput-filter
nil t)
;; Still required by `comint-redirect-send-command', for instance
;; (and we need to match things like `>>> ... >>> '):
(set (make-local-variable 'comint-prompt-regexp)
(rx line-start (1+ (and (or (repeat 3 (any ">.")) "(Pdb)") " "))))
(python--set-prompt-regexp)
(set (make-local-variable 'compilation-error-regexp-alist)
python-compilation-regexp-alist)
(compilation-shell-minor-mode 1))
@ -1522,12 +1560,12 @@ Don't save anything for STR matching `inferior-python-filter-regexp'."
cmd)))
(unless (shell-command-to-string cmd)
(error "Can't run Python command `%s'" cmd))
(let* ((res (shell-command-to-string (concat cmd " --version"))))
(string-match "Python \\([0-9]\\)\\.\\([0-9]\\)" res)
(unless (and (equal "2" (match-string 1 res))
(match-beginning 2)
(>= (string-to-number (match-string 2 res)) 2))
(error "Only Python versions >= 2.2 and < 3.0 supported")))
(let* ((res (shell-command-to-string
(concat cmd
" -c \"from sys import version_info;\
print version_info >= (2, 2) and version_info < (3, 0)\""))))
(unless (string-match "True" res)
(error "Only Python versions >= 2.2 and < 3.0 are supported")))
(setq python-version-checked t)))
;;;###autoload
@ -1554,6 +1592,7 @@ behavior, change `python-remove-cwd-from-path' to nil."
(interactive (if current-prefix-arg
(list (read-string "Run Python: " python-command) nil t)
(list python-command)))
(require 'ansi-color) ; for ipython
(unless cmd (setq cmd python-command))
(python-check-version cmd)
(setq python-command cmd)
@ -1572,8 +1611,10 @@ behavior, change `python-remove-cwd-from-path' to nil."
(if path (concat path path-separator))
data-directory)
process-environment))
;; Suppress use of pager for help output:
(process-connection-type nil))
;; If we use a pipe, unicode characters are not printed
;; correctly (Bug#5794) and IPython does not work at
;; all (Bug#5390).
(process-connection-type t))
(apply 'make-comint-in-buffer "Python"
(generate-new-buffer "*Python*")
(car cmdlist) nil (cdr cmdlist)))
@ -1629,7 +1670,12 @@ behavior, change `python-remove-cwd-from-path' to nil."
;; non-ASCII.
(interactive "r")
(let* ((f (make-temp-file "py"))
(command (format "emacs.eexecfile(%S)" f))
(command
;; IPython puts the FakeModule module into __main__ so
;; emacs.eexecfile becomes useless.
(if (string-match "^ipython" python-command)
(format "execfile %S" f)
(format "emacs.eexecfile(%S)" f)))
(orig-start (copy-marker start)))
(when (save-excursion
(goto-char start)
@ -1829,7 +1875,9 @@ If there isn't, it's probably not appropriate to send input to return Eldoc
information etc. If PROC is non-nil, check the buffer for that process."
(with-current-buffer (process-buffer (or proc (python-proc)))
(save-excursion
(save-match-data (re-search-backward ">>> \\=" nil t)))))
(save-match-data
(re-search-backward (concat python--prompt-regexp " *\\=")
nil t)))))
;; Fixme: Is there anything reasonable we can do with random methods?
;; (Currently only works with functions.)
@ -2545,9 +2593,7 @@ Runs `jython-mode-hook' after `python-mode-hook'."
"Watch output for Python prompt and exec next file waiting in queue.
This function is appropriate for `comint-output-filter-functions'."
;; TBD: this should probably use split-string
(when (and (or (string-equal string ">>> ")
(and (>= (length string) 5)
(string-equal (substring string -5) "\n>>> ")))
(when (and (string-match python--prompt-regexp string)
python-file-queue)
(condition-case nil
(delete-file (car python-file-queue))
@ -2759,6 +2805,7 @@ comint believe the user typed this string so that
(funcall (process-filter proc) proc msg))
(set-buffer curbuf))
(process-send-string proc cmd)))
;;;###autoload
(defun python-shell (&optional argprompt)
"Start an interactive Python interpreter in another window.
@ -2798,6 +2845,7 @@ interaction between undo and process filters; the same problem exists in
non-Python process buffers using the default (Emacs-supplied) process
filter."
(interactive "P")
(require 'ansi-color) ; For ipython
;; Set the default shell if not already set
(when (null python-which-shell)
(python-toggle-shells python-default-interpreter))
@ -2814,10 +2862,9 @@ filter."
))))
(switch-to-buffer-other-window
(apply 'make-comint python-which-bufname python-which-shell nil args))
(make-local-variable 'comint-prompt-regexp)
(set-process-sentinel (get-buffer-process (current-buffer))
'python-sentinel)
(setq comint-prompt-regexp "^>>> \\|^[.][.][.] \\|^(pdb) ")
(python--set-prompt-regexp)
(add-hook 'comint-output-filter-functions
'python-comint-output-filter-function nil t)
;; pdbtrack