"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
\f
;;;; 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)
;; 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?
\\{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))
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
(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)
(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)))
;; 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)
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.)
"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))
(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.
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))
))))
(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