;;; python.el --- silly walks for Python -*- coding: iso-8859-1 -*-
-;; Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
-;; Free Software Foundation, Inc.
+;; Copyright (C) 2003-2011 Free Software Foundation, Inc.
;; Author: Dave Love <fx@gnu.org>
;; Maintainer: FSF
(add-to-list 'interpreter-mode-alist (cons (purecopy "python") 'python-mode))
;;;###autoload
(add-to-list 'auto-mode-alist (cons (purecopy "\\.py\\'") 'python-mode))
-(add-to-list 'same-window-buffer-names (purecopy "*Python*"))
\f
;;;; Font lock
"import" "in" "is" "lambda" "not" "or" "pass" "print"
"raise" "return" "try" "while" "with" "yield"
;; Not real keywords, but close enough to be fontified as such
- "self" "True" "False")
+ "self" "True" "False"
+ ;; Python 3
+ "nonlocal")
symbol-end)
(,(rx symbol-start "None" symbol-end) ; see ยง Keywords in 2.7 manual
. font-lock-constant-face)
(1 font-lock-type-face))
;; Built-ins. (The next three blocks are from
;; `__builtin__.__dict__.keys()' in Python 2.7) These patterns
- ;; are debateable, but they at least help to spot possible
+ ;; are debatable, but they at least help to spot possible
;; shadowing of builtins.
(,(rx symbol-start (or
;; exceptions
:filter (lambda (&rest junk)
(abbrev-table-menu python-mode-abbrev-table)))
"-"
- ["Start interpreter" python-shell
+ ["Start interpreter" run-python
:help "Run `inferior' Python in separate buffer"]
["Import/reload file" python-load-file
:help "Load into inferior Python session"]
;; eric has items including: (un)indent, (un)comment, restart script,
;; run script, debug script; also things for profiling, unit testing.
-(defvar python-shell-map
- (let ((map (copy-keymap comint-mode-map)))
- (define-key map [tab] 'tab-to-tab-stop)
- (define-key map "\C-c-" 'py-up-exception)
- (define-key map "\C-c=" 'py-down-exception)
- map)
- "Keymap used in *Python* shell buffers.")
-
(defvar python-mode-syntax-table
(let ((table (make-syntax-table)))
;; Give punctuation syntax to ASCII that normally has symbol
:type 'integer)
-(defcustom python-default-interpreter 'cpython
- "*Which Python interpreter is used by default.
-The value for this variable can be either `cpython' or `jpython'.
-
-When the value is `cpython', the variables `python-python-command' and
-`python-python-command-args' are consulted to determine the interpreter
-and arguments to use.
-
-When the value is `jpython', the variables `python-jpython-command' and
-`python-jpython-command-args' are consulted to determine the interpreter
-and arguments to use.
-
-Note that this variable is consulted only the first time that a Python
-mode buffer is visited during an Emacs session. After that, use
-\\[python-toggle-shells] to change the interpreter shell."
- :type '(choice (const :tag "Python (a.k.a. CPython)" cpython)
- (const :tag "JPython" jpython))
- :group 'python)
-
-(defcustom python-python-command-args '("-i")
- "*List of string arguments to be used when starting a Python shell."
- :type '(repeat string)
- :group 'python)
-
-(defcustom python-jython-command-args '("-i")
- "*List of string arguments to be used when starting a Jython shell."
- :type '(repeat string)
- :group 'python
- :tag "JPython Command Args")
-
-;; for toggling between CPython and JPython
-(defvar python-which-shell nil)
-(defvar python-which-args python-python-command-args)
-(defvar python-which-bufname "Python")
-(make-variable-buffer-local 'python-which-shell)
-(make-variable-buffer-local 'python-which-args)
-(make-variable-buffer-local 'python-which-bufname)
-
(defcustom python-pdbtrack-do-tracking-p t
"*Controls whether the pdbtrack feature is enabled or not.
(push '(python-pdbtrack-is-tracking-p python-pdbtrack-minor-mode-string)
minor-mode-alist))
-;; Bind python-file-queue before installing the kill-emacs-hook.
-(defvar python-file-queue nil
- "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 . "^>>> "))
"^> \\(.*\\)(\\([0-9]+\\))\\([?a-zA-Z0-9_<>]+\\)()"
"Regular expression pdbtrack uses to find a stack trace entry.")
-(defconst python-pdbtrack-input-prompt "\n[(<]*[Pp]db[>)]+ "
+(defconst python-pdbtrack-input-prompt "\n[(<]*[Ii]?[Pp]db[>)]+ "
"Regular expression pdbtrack uses to recognize a pdb prompt.")
(defconst python-pdbtrack-track-range 10000
"Go to start of current statement.
Accounts for continuation lines, multi-line strings, and
multi-line bracketed expressions."
- (beginning-of-line)
- (python-beginning-of-string)
- (let (point)
- (while (and (python-continuation-line-p)
- (if point
- (< (point) point)
- t))
- (beginning-of-line)
+ (while
(if (python-backslash-continuation-line-p)
- (progn
- (forward-line -1)
- (while (python-backslash-continuation-line-p)
- (forward-line -1)))
- (python-beginning-of-string)
- (python-skip-out))
- (setq point (point))))
+ (progn (forward-line -1) t)
+ (beginning-of-line)
+ (or (python-beginning-of-string)
+ (python-skip-out))))
(back-to-indentation))
(defun python-skip-out (&optional forward syntax)
Skip forward if FORWARD is non-nil, else backward.
If SYNTAX is non-nil it is the state returned by `syntax-ppss' at point.
Return non-nil if and only if skipping was done."
+ ;; FIXME: Use syntax-ppss-toplevel-pos.
(let ((depth (syntax-ppss-depth (or syntax (syntax-ppss))))
(forward (if forward -1 1)))
(unless (zerop depth)
\f
;;;; Imenu.
-;; For possibily speeding this up, here's the top of the ELP profile
+;; For possibly speeding this up, here's the top of the ELP profile
;; for rescanning pydoc.py (2.2k lines, 90kb):
;; Function Name Call Count Elapsed Time Average Time
;; ==================================== ========== ============= ============
(define-key map "\C-c\C-l" 'python-load-file)
(define-key map "\C-c\C-v" 'python-check)
;; Note that we _can_ still use these commands which send to the
- ;; Python process even at the prompt iff we have a normal prompt,
+ ;; Python process even at the prompt if we have a normal prompt,
;; i.e. '>>> ' and not '... '. See the comment before
;; python-send-region. Fixme: uncomment these if we address that.
(if path (concat path path-separator))
data-directory)
process-environment))
- ;; If we use a pipe, unicode characters are not printed
+ ;; 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))
(declare-function info-lookup-maybe-add-help "info-look" (&rest arg))
+;;;###autoload
(defun python-after-info-look ()
"Set up info-look for Python.
Used with `eval-after-load'."
(autoload 'pymacs-load "pymacs" nil t)
(autoload 'brm-init "bikemacs")
+(defvar brm-menu)
;; I'm not sure how useful BRM really is, and it's certainly dangerous
;; the way it modifies files outside Emacs... Also note that the
(features (cons 'python-mode features))) ; and requires this
(brm-init) ; second line of normal recipe
(remove-hook 'python-mode-hook ; undo this from `brm-init'
- '(lambda () (easy-menu-add brm-menu)))
+ (lambda () (easy-menu-add brm-menu)))
(easy-menu-define
python-brm-menu python-mode-map
"Bicycle Repair Man"
(defvar python-mode-running) ;Dynamically scoped var.
;;;###autoload
-(define-derived-mode python-mode fundamental-mode "Python"
+(define-derived-mode python-mode prog-mode "Python"
"Major mode for editing Python files.
Turns on Font Lock mode unconditionally since it is currently required
for correct parsing of the source.
;; doesn't seem to work properly.
(add-to-list 'hs-special-modes-alist
`(python-mode "^\\s-*\\(?:def\\|class\\)\\>" nil "#"
- ,(lambda (arg)
+ ,(lambda (_arg)
(python-end-of-defun)
(skip-chars-backward " \t\n"))
nil))
;; pdbtrack features
-(defun python-comint-output-filter-function (string)
- "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 (string-match python--prompt-regexp string)
- python-file-queue)
- (condition-case nil
- (delete-file (car python-file-queue))
- (error nil))
- (setq python-file-queue (cdr python-file-queue))
- (if python-file-queue
- (let ((pyproc (get-buffer-process (current-buffer))))
- (python-execute-file pyproc (car python-file-queue))))))
-
(defun python-pdbtrack-overlay-arrow (activation)
"Activate or deactivate arrow at beginning-of-line in current buffer."
(if activation
(setq overlay-arrow-position nil
python-pdbtrack-is-tracking-p nil)))
-(defun python-pdbtrack-track-stack-file (text)
+(defun python-pdbtrack-track-stack-file (_text)
"Show the file indicated by the pdb stack entry line, in a separate window.
Activity is disabled if the buffer-local variable
most recently visited python-mode buffer which either has the
name of the current function or class, or which defines the
function or class. This is to provide for scripts not in the
-local filesytem (e.g., Zope's 'Script \(Python)', but it's not
+local file system (e.g., Zope's 'Script \(Python)', but it's not
Zope specific). If you put a copy of the script in a buffer
named for the script and activate python-mode, then pdbtrack will
find it."
(if (not (string-match (concat python-pdbtrack-input-prompt "$") block))
(python-pdbtrack-overlay-arrow nil)
+ (setq block (ansi-color-filter-apply block))
(setq target (python-pdbtrack-get-source-buffer block))
(if (stringp target)
)
)
-(defun python-pdbtrack-grub-for-buffer (funcname lineno)
- "Find recent python-mode buffer named, or having function named funcname."
+(defun python-pdbtrack-grub-for-buffer (funcname _lineno)
+ "Find recent Python mode buffer named, or having function named FUNCNAME."
(let ((buffers (buffer-list))
buf
got)
(setq got buf)))
got))
-(defun python-toggle-shells (arg)
- "Toggles between the CPython and JPython shells.
-
-With positive argument ARG (interactively \\[universal-argument]),
-uses the CPython shell, with negative ARG uses the JPython shell, and
-with a zero argument, toggles the shell.
-
-Programmatically, ARG can also be one of the symbols `cpython' or
-`jpython', equivalent to positive arg and negative arg respectively."
- (interactive "P")
- ;; default is to toggle
- (if (null arg)
- (setq arg 0))
- ;; preprocess arg
- (cond
- ((equal arg 0)
- ;; toggle
- (if (string-equal python-which-bufname "Python")
- (setq arg -1)
- (setq arg 1)))
- ((equal arg 'cpython) (setq arg 1))
- ((equal arg 'jpython) (setq arg -1)))
- (let (msg)
- (cond
- ((< 0 arg)
- ;; set to CPython
- (setq python-which-shell python-python-command
- python-which-args python-python-command-args
- python-which-bufname "Python"
- msg "CPython"
- mode-name "Python"))
- ((> 0 arg)
- (setq python-which-shell python-jython-command
- python-which-args python-jython-command-args
- python-which-bufname "JPython"
- msg "JPython"
- mode-name "JPython")))
- (message "Using the %s shell" msg)))
-
;; Python subprocess utilities and filters
(defun python-execute-file (proc filename)
"Send to Python interpreter process PROC \"execfile('FILENAME')\".
(set-buffer curbuf))
(process-send-string proc cmd)))
-;;;###autoload
-(defun python-shell (&optional argprompt)
- "Start an interactive Python interpreter in another window.
-This is like Shell mode, except that Python is running in the window
-instead of a shell. See the `Interactive Shell' and `Shell Mode'
-sections of the Emacs manual for details, especially for the key
-bindings active in the `*Python*' buffer.
-
-With optional \\[universal-argument], the user is prompted for the
-flags to pass to the Python interpreter. This has no effect when this
-command is used to switch to an existing process, only when a new
-process is started. If you use this, you will probably want to ensure
-that the current arguments are retained (they will be included in the
-prompt). This argument is ignored when this function is called
-programmatically.
-
-Note: You can toggle between using the CPython interpreter and the
-JPython interpreter by hitting \\[python-toggle-shells]. This toggles
-buffer local variables which control whether all your subshell
-interactions happen to the `*JPython*' or `*Python*' buffers (the
-latter is the name used for the CPython buffer).
-
-Warning: Don't use an interactive Python if you change sys.ps1 or
-sys.ps2 from their default values, or if you're running code that
-prints `>>> ' or `... ' at the start of a line. `python-mode' can't
-distinguish your output from Python's output, and assumes that `>>> '
-at the start of a line is a prompt from Python. Similarly, the Emacs
-Shell mode code assumes that both `>>> ' and `... ' at the start of a
-line are Python prompts. Bad things can happen if you fool either
-mode.
-
-Warning: If you do any editing *in* the process buffer *while* the
-buffer is accepting output from Python, do NOT attempt to `undo' the
-changes. Some of the output (nowhere near the parts you changed!) may
-be lost if you do. This appears to be an Emacs bug, an unfortunate
-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))
- (let ((args python-which-args))
- (when (and argprompt
- (called-interactively-p 'interactive)
- (fboundp 'split-string))
- ;; TBD: Perhaps force "-i" in the final list?
- (setq args (split-string
- (read-string (concat python-which-bufname
- " arguments: ")
- (concat
- (mapconcat 'identity python-which-args " ") " ")
- ))))
- (switch-to-buffer-other-window
- (apply 'make-comint python-which-bufname python-which-shell nil args))
- (set-process-sentinel (get-buffer-process (current-buffer))
- 'python-sentinel)
- (python--set-prompt-regexp)
- (add-hook 'comint-output-filter-functions
- 'python-comint-output-filter-function nil t)
- ;; pdbtrack
- (set-syntax-table python-mode-syntax-table)
- (use-local-map python-shell-map)))
-
(defun python-pdbtrack-toggle-stack-tracking (arg)
(interactive "P")
(if (not (get-buffer-process (current-buffer)))
(interactive)
(python-pdbtrack-toggle-stack-tracking 0))
-(defun python-sentinel (proc msg)
+(defun python-sentinel (_proc _msg)
(setq overlay-arrow-position nil))
+(defun python-unload-function ()
+ "Unload the Python library."
+ (remove-hook 'comint-output-filter-functions 'python-pdbtrack-track-stack-file)
+ (setq minor-mode-alist (assq-delete-all 'python-pdbtrack-is-tracking-p
+ minor-mode-alist))
+ (dolist (error '("^No symbol" "^Can't shift all lines enough"))
+ (setq debug-ignored-errors (delete error debug-ignored-errors)))
+ ;; continue standard unloading
+ nil)
+
(provide 'python)
(provide 'python-21)