Commit ae3da38a authored by Chong Yidong's avatar Chong Yidong
Browse files

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).
parent 1d851570
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> 2010-11-21 Chong Yidong <cyd@stupidchicken.com>
* progmodes/python.el (run-python): Doc fix. * progmodes/python.el (run-python): Doc fix.
......
...@@ -570,6 +570,33 @@ having to restart the program." ...@@ -570,6 +570,33 @@ having to restart the program."
"Queue of Python temp files awaiting execution. "Queue of Python temp files awaiting execution.
Currently-active file is at the head of the list.") 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) (defvar python-pdbtrack-is-tracking-p nil)
(defconst python-pdbtrack-stack-entry-regexp (defconst python-pdbtrack-stack-entry-regexp
...@@ -1302,13 +1329,9 @@ See `python-check-command' for the default." ...@@ -1302,13 +1329,9 @@ See `python-check-command' for the default."
;;;; Inferior mode stuff (following cmuscheme). ;;;; Inferior mode stuff (following cmuscheme).
;; Fixme: Make sure we can work with IPython.
(defcustom python-python-command "python" (defcustom python-python-command "python"
"Shell command to run Python interpreter. "Shell command to run Python interpreter.
Any arguments can't contain whitespace. 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'."
:group 'python :group 'python
:type 'string) :type 'string)
...@@ -1386,6 +1409,23 @@ local value.") ...@@ -1386,6 +1409,23 @@ local value.")
;; Autoloaded. ;; Autoloaded.
(declare-function compilation-shell-minor-mode "compile" (&optional arg)) (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 ;; 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; ;; not sure how much: at least some keybindings, like C-c C-f;
;; syntax?; font-locking, e.g. for triple-quoted strings? ;; syntax?; font-locking, e.g. for triple-quoted strings?
...@@ -1408,14 +1448,12 @@ For running multiple processes in multiple buffers, see `run-python' and ...@@ -1408,14 +1448,12 @@ For running multiple processes in multiple buffers, see `run-python' and
\\{inferior-python-mode-map}" \\{inferior-python-mode-map}"
:group 'python :group 'python
(require 'ansi-color) ; for ipython
(setq mode-line-process '(":%s")) (setq mode-line-process '(":%s"))
(set (make-local-variable 'comint-input-filter) 'python-input-filter) (set (make-local-variable 'comint-input-filter) 'python-input-filter)
(add-hook 'comint-preoutput-filter-functions #'python-preoutput-filter (add-hook 'comint-preoutput-filter-functions #'python-preoutput-filter
nil t) nil t)
;; Still required by `comint-redirect-send-command', for instance (python--set-prompt-regexp)
;; (and we need to match things like `>>> ... >>> '):
(set (make-local-variable 'comint-prompt-regexp)
(rx line-start (1+ (and (or (repeat 3 (any ">.")) "(Pdb)") " "))))
(set (make-local-variable 'compilation-error-regexp-alist) (set (make-local-variable 'compilation-error-regexp-alist)
python-compilation-regexp-alist) python-compilation-regexp-alist)
(compilation-shell-minor-mode 1)) (compilation-shell-minor-mode 1))
...@@ -1522,12 +1560,12 @@ Don't save anything for STR matching `inferior-python-filter-regexp'." ...@@ -1522,12 +1560,12 @@ Don't save anything for STR matching `inferior-python-filter-regexp'."
cmd))) cmd)))
(unless (shell-command-to-string cmd) (unless (shell-command-to-string cmd)
(error "Can't run Python command `%s'" cmd)) (error "Can't run Python command `%s'" cmd))
(let* ((res (shell-command-to-string (concat cmd " --version")))) (let* ((res (shell-command-to-string
(string-match "Python \\([0-9]\\)\\.\\([0-9]\\)" res) (concat cmd
(unless (and (equal "2" (match-string 1 res)) " -c \"from sys import version_info;\
(match-beginning 2) print version_info >= (2, 2) and version_info < (3, 0)\""))))
(>= (string-to-number (match-string 2 res)) 2)) (unless (string-match "True" res)
(error "Only Python versions >= 2.2 and < 3.0 supported"))) (error "Only Python versions >= 2.2 and < 3.0 are supported")))
(setq python-version-checked t))) (setq python-version-checked t)))
;;;###autoload ;;;###autoload
...@@ -1554,6 +1592,7 @@ behavior, change `python-remove-cwd-from-path' to nil." ...@@ -1554,6 +1592,7 @@ behavior, change `python-remove-cwd-from-path' to nil."
(interactive (if current-prefix-arg (interactive (if current-prefix-arg
(list (read-string "Run Python: " python-command) nil t) (list (read-string "Run Python: " python-command) nil t)
(list python-command))) (list python-command)))
(require 'ansi-color) ; for ipython
(unless cmd (setq cmd python-command)) (unless cmd (setq cmd python-command))
(python-check-version cmd) (python-check-version cmd)
(setq python-command cmd) (setq python-command cmd)
...@@ -1572,8 +1611,10 @@ behavior, change `python-remove-cwd-from-path' to nil." ...@@ -1572,8 +1611,10 @@ behavior, change `python-remove-cwd-from-path' to nil."
(if path (concat path path-separator)) (if path (concat path path-separator))
data-directory) data-directory)
process-environment)) process-environment))
;; Suppress use of pager for help output: ;; If we use a pipe, unicode characters are not printed
(process-connection-type nil)) ;; correctly (Bug#5794) and IPython does not work at
;; all (Bug#5390).
(process-connection-type t))
(apply 'make-comint-in-buffer "Python" (apply 'make-comint-in-buffer "Python"
(generate-new-buffer "*Python*") (generate-new-buffer "*Python*")
(car cmdlist) nil (cdr cmdlist))) (car cmdlist) nil (cdr cmdlist)))
...@@ -1629,7 +1670,12 @@ behavior, change `python-remove-cwd-from-path' to nil." ...@@ -1629,7 +1670,12 @@ behavior, change `python-remove-cwd-from-path' to nil."
;; non-ASCII. ;; non-ASCII.
(interactive "r") (interactive "r")
(let* ((f (make-temp-file "py")) (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))) (orig-start (copy-marker start)))
(when (save-excursion (when (save-excursion
(goto-char start) (goto-char start)
...@@ -1829,7 +1875,9 @@ If there isn't, it's probably not appropriate to send input to return Eldoc ...@@ -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." information etc. If PROC is non-nil, check the buffer for that process."
(with-current-buffer (process-buffer (or proc (python-proc))) (with-current-buffer (process-buffer (or proc (python-proc)))
(save-excursion (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? ;; Fixme: Is there anything reasonable we can do with random methods?
;; (Currently only works with functions.) ;; (Currently only works with functions.)
...@@ -2545,9 +2593,7 @@ Runs `jython-mode-hook' after `python-mode-hook'." ...@@ -2545,9 +2593,7 @@ Runs `jython-mode-hook' after `python-mode-hook'."
"Watch output for Python prompt and exec next file waiting in queue. "Watch output for Python prompt and exec next file waiting in queue.
This function is appropriate for `comint-output-filter-functions'." This function is appropriate for `comint-output-filter-functions'."
;; TBD: this should probably use split-string ;; TBD: this should probably use split-string
(when (and (or (string-equal string ">>> ") (when (and (string-match python--prompt-regexp string)
(and (>= (length string) 5)
(string-equal (substring string -5) "\n>>> ")))
python-file-queue) python-file-queue)
(condition-case nil (condition-case nil
(delete-file (car python-file-queue)) (delete-file (car python-file-queue))
...@@ -2759,6 +2805,7 @@ comint believe the user typed this string so that ...@@ -2759,6 +2805,7 @@ comint believe the user typed this string so that
(funcall (process-filter proc) proc msg)) (funcall (process-filter proc) proc msg))
(set-buffer curbuf)) (set-buffer curbuf))
(process-send-string proc cmd))) (process-send-string proc cmd)))
;;;###autoload ;;;###autoload
(defun python-shell (&optional argprompt) (defun python-shell (&optional argprompt)
"Start an interactive Python interpreter in another window. "Start an interactive Python interpreter in another window.
...@@ -2798,6 +2845,7 @@ interaction between undo and process filters; the same problem exists in ...@@ -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 non-Python process buffers using the default (Emacs-supplied) process
filter." filter."
(interactive "P") (interactive "P")
(require 'ansi-color) ; For ipython
;; Set the default shell if not already set ;; Set the default shell if not already set
(when (null python-which-shell) (when (null python-which-shell)
(python-toggle-shells python-default-interpreter)) (python-toggle-shells python-default-interpreter))
...@@ -2814,10 +2862,9 @@ filter." ...@@ -2814,10 +2862,9 @@ filter."
)))) ))))
(switch-to-buffer-other-window (switch-to-buffer-other-window
(apply 'make-comint python-which-bufname python-which-shell nil args)) (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)) (set-process-sentinel (get-buffer-process (current-buffer))
'python-sentinel) 'python-sentinel)
(setq comint-prompt-regexp "^>>> \\|^[.][.][.] \\|^(pdb) ") (python--set-prompt-regexp)
(add-hook 'comint-output-filter-functions (add-hook 'comint-output-filter-functions
'python-comint-output-filter-function nil t) 'python-comint-output-filter-function nil t)
;; pdbtrack ;; pdbtrack
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment