Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
27146 lines (22349 sloc) 982 KB
;;; python-mode.el --- Edit, debug, develop, run Python programs. -*- lexical-binding: t; -*-
;; Includes a minor mode for handling a Python/IPython shell,
;; and can take advantage of Pymacs when installed.
;; This file not shipped as part of GNU Emacs.
;; Keywords: languages, processes, python, oop
;; Version: "6.2.3"
;; URL:
;; Package-Requires: (emacs "24")
;; Copyright (C) 1992,1993,1994 Tim Peters
;; Author: 2015-2018
;; 2003-2014
;; 1995-2002 Barry A. Warsaw
;; 1992-1994 Tim Peters
;; Maintainer:
;; Created: Feb 1992
;; Keywords: python languages oop
;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with this program. If not, see <>.
;;; Commentary:
;; See documentation in,
;; Please report bugs at
;; available commands are documented in directory "doc" as
;; As for `py-add-abbrev':
;; Similar to `add-mode-abbrev', but uses
;; `py-partial-expression' before point for expansion to
;; store, not `word'. Also provides a proposal for new
;; abbrevs.
;; Proposal for an abbrev is composed from the downcased
;; initials of expansion - provided they are of char-class
;; [:alpha:]
;; For example code below would be recognised as a
;; `py-expression' composed by three
;; py-partial-expressions.
;; OrderedDict.popitem(last=True)
;; Putting the curser at the EOL, M-3 M-x py-add-abbrev
;; would prompt "op" for an abbrev to store, as first
;; `py-partial-expression' beginns with a "(", which is
;; not taken as proposal.
;;; Code:
(defgroup python-mode nil
"Support for the Python programming language, <>"
:group 'languages
:prefix "py-")
(defconst py-version "6.2.3")
(defvar py-install-directory "")
(defcustom py-install-directory ""
"Directory where python-mode.el and it's subdirectories should be installed.
Needed for completion and other environment stuff only."
:type 'string
:tag "py-install-directory"
:group 'python-mode)
(defcustom py-pythonpath ""
"Define $PYTHONPATH here, if needed.
Emacs doesn't read .bashrc"
:type 'string
:tag "py-pythonpath"
:group 'python-mode)
(when (string= "" py-install-directory)
(setq py-install-directory default-directory))
(defcustom python-mode-modeline-display "Py"
"String to display in Emacs modeline."
:type 'string
:tag "python-mode-modeline-display"
:group 'python-mode)
(defcustom py-extensions "py-extensions.el"
"File where extensions to python-mode.el should be installed.
Used by virtualenv support."
:type 'string
:tag "py-extensions"
:group 'python-mode)
(defcustom info-lookup-mode "python"
"Which Python documentation should be queried.
Make sure it's accessible from Emacs by \\<emacs-lisp-mode-map> \\[info] ...
:type 'string
:tag "info-lookup-mode"
:group 'python-mode)
(defcustom py-fast-process-p nil
"Use `py-fast-process'.
Commands prefixed \"py-fast-...\" suitable for large output
See: large output makes Emacs freeze, lp:1253907
Results arrive in output buffer, which is not in comint-mode"
:type 'boolean
:tag "py-fast-process-p"
:group 'python-mode)
(defcustom py-shift-require-transient-mark-mode-p t
"If py-shift commands on regions should require variable ‘transient-mark-mode’.
Default is t"
:type 'boolean
:group 'python-mode)
(defvar py-fast-output-buffer "*Py-Fast-Output-Buffer*"
"Default ‘buffer-name’ for fast-processes.")
(defvar py-this-result nil
"Internally used, store return-value.")
(defcustom py-comment-auto-fill-p nil
"When non-nil, fill comments.
Defaut is nil"
:type 'boolean
:group 'python-mode)
(defcustom py-sexp-use-expression-p nil
"If non-nil, ‘forward-sexp’ will call ‘py-forward-expression’.
Respective ‘backward-sexp’ will call ‘py-backward-expression’
Default is t"
:type 'boolean
:group 'python-mode)
(defcustom py-session-p t
"If commands would use an existing process.
See also `py-dedicated-process-p'"
:type 'boolean
:tag "py-session-p"
:group 'python-mode)
(defcustom py-max-help-buffer-p nil
"If \"\*Python-Help\*\"-buffer should appear as the only visible.
Default is nil. In ‘help-buffer’, \"q\" will close it."
:type 'boolean
:tag "py-max-help-buffer-p"
:group 'python-mode)
(defcustom py-highlight-error-source-p nil
"Respective code in source-buffer will be highlighted.
Default is nil.
\\<python-mode-map> `py-remove-overlays-at-point' removes that highlighting."
:type 'boolean
:tag "py-highlight-error-source-p"
:group 'python-mode)
(defcustom py-set-pager-cat-p nil
"If the shell environment variable $PAGER should set to `cat'.
Avoids lp:783828,
\"Terminal not fully functional\", for help('COMMAND') in python-shell
When non-nil, imports module `os'"
:type 'boolean
:tag "py-set-pager-cat-p"
:group 'python-mode)
(defcustom py-empty-line-closes-p nil
"When non-nil, dedent after empty line following block.
if True:
print(\"Part of the if-statement\")
print(\"Not part of the if-statement\")
Default is nil"
:type 'boolean
:tag "py-empty-line-closes-p"
:group 'python-mode)
(defcustom py-prompt-on-changed-p t
"Ask for save before a changed buffer is sent to interpreter.
Default is t"
:type 'boolean
:tag "py-prompt-on-changed-p"
:group 'python-mode)
(defcustom py-dedicated-process-p nil
"If commands executing code use a dedicated shell.
Default is nil
When non-nil and `py-session-p', an existing dedicated process is re-used instead of default - which allows executing stuff in parallel."
:type 'boolean
:tag "py-dedicated-process-p"
:group 'python-mode)
(defcustom py-store-result-p nil
"Put resulting string of `py-execute-...' into ‘kill-ring’.
Default is nil"
:type 'boolean
:tag "py-dedicated-process-p"
:group 'python-mode)
(defvar py-shell--font-lock-buffer " *PSFLB*"
"May contain the `py-buffer-name' currently fontified." )
(defvar py-return-result-p t
"Internally used.
When non-nil, return resulting string of `py-execute-...'.
Imports will use it with nil.
Default is t")
(defcustom py--execute-use-temp-file-p nil
"Assume execution at a remote machine.
where write-access is not given."
:type 'boolean
:group 'python-mode)
(defvar py--match-paren-forward-p nil
"Internally used by `py-match-paren'.")
(defvar py-new-session-p t
"Internally used. See lp:1393882.
Restart ‘py-shell’ once with new Emacs/‘python-mode’.")
(defcustom py-electric-close-active-p nil
"Close completion buffer if no longer needed.
Works around a bug in `choose-completion'.
Default is nil"
:type 'boolean
:group 'python-mode)
(defcustom py-update-gud-pdb-history-p t
"If pdb should provide suggestions WRT file to check and ‘py-pdb-path’.
Default is t
See lp:963253"
:type 'boolean
:tag "py-update-gud-pdb-history-p"
:group 'python-mode
:tag "py-update-gud-pdb-history-p")
(defcustom py-pdb-executable nil
"Indicate PATH/TO/pdb.
Default is nil
See lp:963253"
:type 'string
:tag "py-pdb-executable"
:group 'python-mode
:tag "py-pdb-executable")
(defcustom py-hide-show-minor-mode-p nil
"If hide-show minor-mode should be on, default is nil."
:type 'boolean
:tag "py-hide-show-minor-mode-p"
:group 'python-mode)
(defcustom py-load-skeletons-p nil
"If skeleton definitions should be loaded, default is nil.
If non-nil and variable ‘abbrev-mode’ on, block-skeletons will inserted.
Pressing \"if<SPACE>\" for example will prompt for the if-condition."
:type 'boolean
:tag "py-load-skeletons-p"
:group 'python-mode)
(defcustom py-if-name-main-permission-p t
"Allow execution of code inside blocks started.
by \"if __name__== '__main__':\".
Default is non-nil"
:type 'boolean
:tag "py-if-name-main-permission-p"
:group 'python-mode)
(defcustom py-use-font-lock-doc-face-p nil
"If documention string inside of def or class get `font-lock-doc-face'.
`font-lock-doc-face' inherits `font-lock-string-face'.
Call \\<emacs-lisp-mode-map> \\[customize-face] in order to have a visible effect."
:type 'boolean
:tag "py-use-font-lock-doc-face-p"
:group 'python-mode)
(defcustom py-empty-comment-line-separates-paragraph-p t
"Consider paragraph start/end lines with nothing inside but comment sign.
Default is non-nil"
:type 'boolean
:tag "py-empty-comment-line-separates-paragraph-p"
:group 'python-mode)
(defcustom py-indent-honors-inline-comment nil
"If non-nil, indents to column of inlined comment start.
Default is nil."
:type 'boolean
:tag "py-indent-honors-inline-comment"
:group 'python-mode)
(defcustom py-auto-fill-mode nil
"If ‘python-mode’ should set ‘fill-column’.
according to values
in `py-comment-fill-column' and `py-docstring-fill-column'.
Default is nil"
:type 'boolean
:tag "py-auto-fill-mode"
:group 'python-mode)
(defcustom py-error-markup-delay 4
"Seconds error's are highlighted in exception buffer."
:type 'integer
:tag "py-error-markup-delay"
:group 'python-mode)
(defcustom py-fast-completion-delay 0.1
"Used by ‘py--fast-send-string-intern’."
:type 'float
:tag "py-fast-completion-delay"
:group 'python-mode)
(defcustom py-new-shell-delay
(if (eq system-type 'windows-nt)
"If a new comint buffer is connected to Python, commands like completion might need some delay."
:type 'float
:tag "py-new-shell-delay"
:group 'python-mode)
(defcustom py-autofill-timer-delay 1
"Delay when idle before functions ajusting `py-docstring-fill-column', `py-comment-fill-column' are called."
:type 'integer
:tag "py-autofill-timer-delay"
:group 'python-mode)
(defcustom py-docstring-fill-column 72
"Value of `fill-column' to use when filling a docstring.
Any non-integer value means do not use a different value of
`fill-column' when filling docstrings."
:type '(choice (integer)
(const :tag "Use the current `fill-column'" t))
:tag "py-docstring-fill-column"
:group 'python-mode)
(defcustom py-comment-fill-column 79
"Value of `fill-column' to use when filling a comment.
Any non-integer value means do not use a different value of
`fill-column' when filling docstrings."
:type '(choice (integer)
(const :tag "Use the current `fill-column'" t))
:tag "py-comment-fill-column"
:group 'python-mode)
(defcustom py-fontify-shell-buffer-p nil
"If code in Python shell should be highlighted as in script buffer.
Default is nil.
If t, related vars like `comment-start' will be set too.
Seems convenient when playing with stuff in IPython shell
Might not be TRT when a lot of output arrives"
:type 'boolean
:tag "py-fontify-shell-buffer-p"
:group 'python-mode)
(defcustom py-modeline-display-full-path-p nil
"If the full PATH/TO/PYTHON should be displayed in shell modeline.
Default is nil. Note: when `py-shell-name' is specified with path, it's shown as an acronym in ‘buffer-name’ already."
:type 'boolean
:tag "py-modeline-display-full-path-p"
:group 'python-mode)
(defcustom py-modeline-acronym-display-home-p nil
"If the modeline acronym should contain chars indicating the home-directory.
Default is nil"
:type 'boolean
:tag "py-modeline-acronym-display-home-p"
:group 'python-mode)
(defun py-autopair-check ()
"Check, if ‘autopair-mode’ is available.
Give some hints, if not."
(if (featurep 'autopair)
(message "py-autopair-check: %s" "Don't see autopair.el. Make sure, it's installed. If not, maybe see source: URL:")
(defvar highlight-indent-active nil)
(defvar autopair-mode nil)
(defvar-local py-edit-docstring-orig-pos nil
"Internally used by `py-edit-docstring'.")
(defvar-local py--docbeg nil
"Internally used by `py-edit-docstring'")
(defvar-local py--docend nil
"Internally used by `py-edit-docstring'")
(defvar py--oldbuf nil
"Internally used by `py-edit-docstring'.")
(defvar py-edit-docstring-buffer "Edit docstring"
"Name of the temporary buffer to use when editing.")
(defvar py--edit-docstring-register nil)
(defvar py-result nil
"Internally used. May store result from Python process.")
(defvar py-error nil
"Internally used. Takes the error-messages from Python process.")
(defvar py-python-completions "*Python Completions*"
"Buffer name for Python-shell completions, internally used.")
(defvar py-ipython-completions "*IPython Completions*"
"Buffer name for IPython-shell completions, internally used.")
(defcustom py-timer-close-completions-p t
"If `py-timer-close-completion-buffer' should run, default is non-nil."
:type 'boolean
:tag "py-timer-close-completions-p"
:group 'python-mode)
(defcustom py-autopair-mode nil
"If ‘python-mode’ calls (autopair-mode-on)
Default is nil
Load `autopair-mode' written by Joao Tavora <joaotavora [at]>
:type 'boolean
:tag "py-autopair-mode"
:group 'python-mode)
(defcustom py-indent-no-completion-p nil
"If completion function should insert a TAB when no completion found.
Default is nil"
:type 'boolean
:tag "py-indent-no-completion-p"
:group 'python-mode)
(defcustom py-company-pycomplete-p nil
"Load company-pycomplete stuff. Default is nil."
:type 'boolean
:tag "py-company-pycomplete-p"
:group 'python-mode)
(defvar py-last-position nil
"Used by ‘py-help-at-point’.
Avoid repeated call at identic pos.")
(defvar py-auto-completion-mode-p nil
"Internally used by `py-auto-completion-mode'.")
(defvar py-complete-last-modified nil
"Internally used by `py-auto-completion-mode'.")
(defvar py--auto-complete-timer nil
"Internally used by `py-auto-completion-mode'.")
(defvar py-auto-completion-buffer nil
"Internally used by `py-auto-completion-mode'.")
(defvar py--auto-complete-timer-delay 1
"Seconds Emacs must be idle to trigger auto-completion.
See `py-auto-completion-mode'")
(defcustom py-auto-complete-p nil
"Run python-mode's built-in auto-completion via ‘py-complete-function’. Default is nil."
:type 'boolean
:tag "py-auto-complete-p"
:group 'python-mode)
(make-variable-buffer-local 'py-auto-complete-p)
(defcustom py-tab-shifts-region-p nil
"If t, TAB will indent/cycle the region, not just the current line.
Default is nil
See also `py-tab-indents-region-p'"
:type 'boolean
:tag "py-tab-shifts-region-p"
:group 'python-mode)
(defcustom py-tab-indents-region-p nil
"When t and first TAB doesn't shift, ‘indent-region’ is called.
Default is nil
See also `py-tab-shifts-region-p'"
:type 'boolean
:tag "py-tab-indents-region-p"
:group 'python-mode)
(defcustom py-block-comment-prefix-p t
"If py-comment inserts ‘py-block-comment-prefix’.
Default is t"
:type 'boolean
:tag "py-block-comment-prefix-p"
:group 'python-mode)
(defcustom py-org-cycle-p nil
"When non-nil, command `org-cycle' is available at shift-TAB, <backtab>.
Default is nil."
:type 'boolean
:tag "py-org-cycle-p"
:group 'python-mode)
(defcustom py-set-complete-keymap-p nil
"If `py-complete-initialize'.
Sets up enviroment for Pymacs based py-complete.
Should load it's keys into `python-mode-map'
Default is nil.
See also resp. edit `py-complete-set-keymap'"
:type 'boolean
:tag "py-set-complete-keymap-p"
:group 'python-mode)
(defcustom py-outline-minor-mode-p t
"If outline minor-mode should be on, default is t."
:type 'boolean
:tag "py-outline-minor-mode-p"
:group 'python-mode)
(defcustom py-guess-py-install-directory-p t
"If in cases, `py-install-directory' isn't set, `py-set-load-path'should guess it from variable `buffer-file-name'."
:type 'boolean
:tag "py-guess-py-install-directory-p"
:group 'python-mode)
(defcustom py-load-pymacs-p nil
"If Pymacs related stuff should be loaded.
Default is nil.
Pymacs has been written by François Pinard and many others.
See original source:"
:type 'boolean
:tag "py-load-pymacs-p"
:group 'python-mode)
(defcustom py-verbose-p nil
"If functions should report results.
Default is nil."
:type 'boolean
:tag "py-verbose-p"
:group 'python-mode)
(defcustom py-sexp-function nil
"Called instead of `forward-sexp', `backward-sexp'.
Default is nil."
:type '(choice
(const :tag "default" nil)
(const :tag "py-end-of-partial-expression" py-end-of-partial-expression)
(const :tag "py-end-of-expression" py-end-of-expression))
:tag "py-sexp-function"
:group 'python-mode)
(defcustom py-close-provides-newline t
"If a newline is inserted, when line after block isn't empty.
Default is non-nil.
When non-nil, `py-end-of-def' and related will work faster"
:type 'boolean
:tag "py-close-provides-newline"
:group 'python-mode)
(defcustom py-dedent-keep-relative-column t
"If point should follow dedent or kind of electric move to end of line. Default is t - keep relative position."
:type 'boolean
:tag "py-dedent-keep-relative-column"
:group 'python-mode)
(defcustom py-indent-honors-multiline-listing nil
"If t, indents to 1+ column of opening delimiter. If nil, indent adds one level to the beginning of statement. Default is nil."
:type 'boolean
:tag "py-indent-honors-multiline-listing"
:group 'python-mode)
(defcustom py-indent-paren-spanned-multilines-p t
"If non-nil, indents elements of list to first element.
def foo():
if (foo &&
If nil line up with first element:
def foo():
if (foo &&
Default is t"
:type 'boolean
:tag "py-indent-paren-spanned-multilines-p"
:group 'python-mode)
(defcustom py-closing-list-dedents-bos nil
"When non-nil, indent list's closing delimiter like start-column.
It will be lined up under the first character of
the line that starts the multi-line construct, as in:
my_list = [
1, 2, 3,
4, 5, 6
result = some_function_that_takes_arguments(
'a', 'b', 'c',
'd', 'e', 'f'
Default is nil, i.e.
my_list = [
1, 2, 3,
4, 5, 6
result = some_function_that_takes_arguments(
'a', 'b', 'c',
'd', 'e', 'f'
Examples from PEP8
:type 'boolean
:tag "py-closing-list-dedents-bos"
:group 'python-mode)
(defvar py-imenu-max-items 99)
(defcustom py-imenu-max-items 99
"Python-mode specific `imenu-max-items'."
:type 'number
:group 'python-mode)
(defcustom py-closing-list-space 1
"Number of chars, closing parenthesis outdent from opening, default is 1."
:type 'number
:tag "py-closing-list-space"
:group 'python-mode)
(defcustom py-max-specpdl-size 99
"Heuristic exit.
Limiting number of recursive calls by ‘py-forward-statement’ and related.
Default is ‘max-specpdl-size’.
This threshold is just an approximation. It might set far higher maybe.
See lp:1235375. In case code is not to navigate due to errors, variable `which-function-mode' and others might make Emacs hang. Rather exit than."
:type 'number
:tag "py-max-specpdl-size"
:group 'python-mode)
(defcustom py-closing-list-keeps-space nil
"If non-nil, closing parenthesis dedents onto column of opening plus `py-closing-list-space', default is nil."
:type 'boolean
:tag "py-closing-list-keeps-space"
:group 'python-mode)
(defcustom py-electric-kill-backward-p nil
"Affects `py-electric-backspace'. Default is nil.
If behind a delimited form of braces, brackets or parentheses,
backspace will kill it's contents
With when cursor after
In result cursor is insided emptied delimited form."
:type 'boolean
:tag "py-electric-kill-backward-p"
:group 'python-mode)
(defcustom py-electric-colon-active-p nil
"`py-electric-colon' feature.
Default is nil. See lp:837065 for discussions.
See also `py-electric-colon-bobl-only'"
:type 'boolean
:tag "py-electric-colon-active-p"
:group 'python-mode)
(defcustom py-electric-colon-bobl-only t
"When inserting a colon, do not indent lines unless at beginning of block.
See lp:1207405 resp. `py-electric-colon-active-p'"
:type 'boolean
:tag "py-electric-colon-bobl-only"
:group 'python-mode)
(defcustom py-electric-yank-active-p nil
"When non-nil, `yank' will be followed by an `indent-according-to-mode'.
Default is nil"
:type 'boolean
:tag "py-electric-yank-active-p"
:group 'python-mode)
(defcustom py-electric-colon-greedy-p nil
"If ‘py-electric-colon’ should indent to the outmost reasonable level.
If nil, default, it will not move from at any reasonable level."
:type 'boolean
:tag "py-electric-colon-greedy-p"
:group 'python-mode)
(defcustom py-electric-colon-newline-and-indent-p nil
"If non-nil, `py-electric-colon' will call `newline-and-indent'. Default is nil."
:type 'boolean
:tag "py-electric-colon-newline-and-indent-p"
:group 'python-mode)
(defcustom py-electric-comment-p nil
"If \"#\" should call `py-electric-comment'. Default is nil."
:type 'boolean
:tag "py-electric-comment-p"
:group 'python-mode)
(defcustom py-electric-comment-add-space-p nil
"If ‘py-electric-comment’ should add a space. Default is nil."
:type 'boolean
:tag "py-electric-comment-add-space-p"
:group 'python-mode)
(defcustom py-mark-decorators nil
"If ‘py-mark-def-or-class’ functions should mark decorators too. Default is nil."
:type 'boolean
:tag "py-mark-decorators"
:group 'python-mode)
(defcustom py-defun-use-top-level-p nil
"If ‘beginning-of-defun’, ‘end-of-defun’ calls function ‘top-level’ form.
Default is nil.
beginning-of defun, ‘end-of-defun’ forms use
commands `py-beginning-of-top-level', `py-end-of-top-level'
‘mark-defun’ marks function ‘top-level’ form at point etc."
:type 'boolean
:tag "py-defun-use-top-level-p"
:group 'python-mode)
(defcustom py-tab-indent t
"Non-nil means TAB in Python mode calls `py-indent-line'."
:type 'boolean
:tag "py-tab-indent"
:group 'python-mode)
(defcustom py-return-key 'newline
"Which command <return> should call."
:type '(choice
(const :tag "default" py-newline-and-indent)
(const :tag "newline" newline)
(const :tag "py-newline-and-indent" py-newline-and-indent)
(const :tag "py-newline-and-dedent" py-newline-and-dedent)
:tag "py-return-key"
:group 'python-mode)
(defcustom py-complete-function 'py-fast-complete
"When set, enforces function todo completion, default is `py-fast-complete'.
Might not affect IPython, as `py-shell-complete' is the only known working here.
Normally ‘python-mode’ knows best which function to use."
:type '(choice
(const :tag "default" nil)
(const :tag "Pymacs and company based py-complete" py-complete)
(const :tag "py-shell-complete" py-shell-complete)
(const :tag "py-indent-or-complete" py-indent-or-complete)
(const :tag "py-fast-complete" py-fast-complete)
:tag "py-complete-function"
:group 'python-mode)
(defcustom py-encoding-string " # -*- coding: utf-8 -*-"
"Default string specifying encoding of a Python file."
:type 'string
:tag "py-encoding-string"
:group 'python-mode)
(defcustom py-shebang-startstring "#! /bin/env"
"Detecting the shell in head of file."
:type 'string
:tag "py-shebang-startstring"
:group 'python-mode)
(defcustom py-flake8-command ""
"Which command to call flake8.
If empty, ‘python-mode’ will guess some"
:type 'string
:tag "py-flake8-command"
:group 'python-mode)
(defcustom py-flake8-command-args ""
"Arguments used by flake8.
Default is the empty string."
:type 'string
:tag "py-flake8-command-args"
:group 'python-mode)
(defvar py-flake8-history nil
"Used by flake8, resp. ‘py-flake8-command’.
Default is nil.")
(defcustom py-message-executing-temporary-file t
"If execute functions using a temporary file should message it.
Default is t.
Messaging increments the prompt counter of IPython shell."
:type 'boolean
:tag "py-message-executing-temporary-file"
:group 'python-mode)
(defcustom py-execute-no-temp-p nil
"Seems Emacs-24.3 provided a way executing stuff without temporary files."
:type 'boolean
:tag "py-execute-no-temp-p"
:group 'python-mode)
(defcustom py-lhs-inbound-indent 1
"When line starts a multiline-assignment: How many colums indent should be more than opening bracket, brace or parenthesis."
:type 'integer
:tag "py-lhs-inbound-indent"
:group 'python-mode)
(defcustom py-continuation-offset 2
"Additional amount of offset to give for some continuation lines.
Continuation lines are those that immediately follow a backslash
terminated line."
:type 'integer
:tag "py-continuation-offset"
:group 'python-mode)
(defcustom py-indent-tabs-mode nil
"Python-mode starts `indent-tabs-mode' with the value specified here, default is nil."
:type 'boolean
:tag "py-indent-tabs-mode"
:group 'python-mode)
(defcustom py-smart-indentation nil
"Guess `py-indent-offset'. Default is nil.
Setting it to t seems useful only in cases where customizing
`py-indent-offset' is no option - for example because the
indentation step is unknown or differs inside the code.
When this variable is non-nil, `py-indent-offset' is guessed from existing code in the buffer, which might slow down the proceeding."
:type 'boolean
:tag "py-smart-indentation"
:group 'python-mode)
(defcustom py-block-comment-prefix "##"
"String used by \\[comment-region] to comment out a block of code.
This should follow the convention for non-indenting comment lines so
that the indentation commands won't get confused (i.e., the string
should be of the form `#x...' where `x' is not a blank or a tab, and
`...' is arbitrary). However, this string should not end in whitespace."
:type 'string
:tag "py-block-comment-prefix"
:group 'python-mode)
(defcustom py-indent-offset 4
"Amount of offset per level of indentation.
`\\[py-guess-indent-offset]' can usually guess a good value when
you're editing someone else's Python code."
:type 'integer
:tag "py-indent-offset"
:group 'python-mode)
(make-variable-buffer-local 'py-indent-offset)
(defcustom py-backslashed-lines-indent-offset 5
"Amount of offset per level of indentation of backslashed.
No semantic indent, which diff to `py-indent-offset' indicates"
:type 'integer
:tag "py-backslashed-lines-indent-offset"
:group 'python-mode)
(defcustom py-pdb-path
(if (or (eq system-type 'ms-dos)(eq system-type 'windows-nt))
(quote c:/python27/python\ -i\ c:/python27/Lib/
"Where to find Edit this according to your system.
If you ignore the location `M-x py-guess-pdb-path' might display it."
:type 'variable
:tag "py-pdb-path"
:group 'python-mode)
(defvar py-python-ms-pdb-command ""
"MS-systems might use that.")
(defcustom py-indent-comments t
"When t, comment lines are indented."
:type 'boolean
:tag "py-indent-comments"
:group 'python-mode)
(defcustom py-uncomment-indents-p nil
"When non-nil, after uncomment indent lines."
:type 'boolean
:tag "py-uncomment-indents-p"
:group 'python-mode)
(defcustom py-separator-char 47
"The character, which separates the system file-path components.
Precedes guessing when not empty, returned by function `py-separator-char'."
:type 'character
:tag "py-separator-char"
:group 'python-mode)
;; used as a string finally
;; kept a character not to break existing customizations
(characterp py-separator-char)(setq py-separator-char (char-to-string py-separator-char)))
(defcustom py-custom-temp-directory ""
"If set, will take precedence over guessed values from `py-temp-directory'. Default is the empty string."
:type 'string
:tag "py-custom-temp-directory"
:group 'python-mode)
(defcustom py-beep-if-tab-change t
"Ring the bell if `tab-width' is changed.
If a comment of the form
\t# vi:set tabsize=<number>:
is found before the first code line when the file is entered, and the
current value of (the general Emacs variable) `tab-width' does not
equal <number>, `tab-width' is set to <number>, a message saying so is
displayed in the echo area, and if `py-beep-if-tab-change' is non-nil
the Emacs bell is also rung as a warning."
:type 'boolean
:tag "py-beep-if-tab-change"
:group 'python-mode)
(defcustom py-jump-on-exception t
"Jump to innermost exception frame in Python output buffer.
When this variable is non-nil and an exception occurs when running
Python code synchronously in a subprocess, jump immediately to the
source code of the innermost traceback frame."
:type 'boolean
:tag "py-jump-on-exception"
:group 'python-mode)
(defcustom py-ask-about-save t
"If not nil, ask about which buffers to save before executing some code.
Otherwise, all modified buffers are saved without asking."
:type 'boolean
:tag "py-ask-about-save"
:group 'python-mode)
(defcustom py-delete-function 'delete-char
"Function called by `py-electric-delete' when deleting forwards."
:type 'function
:tag "py-delete-function"
:group 'python-mode)
(defcustom py-pdbtrack-do-tracking-p t
"Controls whether the pdbtrack feature is enabled or not.
When non-nil, pdbtrack is enabled in all comint-based buffers,
e.g. shell buffers and the *Python* buffer. When using pdb to debug a
Python program, pdbtrack notices the pdb prompt and displays the
source file and line that the program is stopped at, much the same way
as ‘gud-mode’ does for debugging C programs with gdb."
:type 'boolean
:tag "py-pdbtrack-do-tracking-p"
:group 'python-mode)
(make-variable-buffer-local 'py-pdbtrack-do-tracking-p)
(defcustom py-pdbtrack-filename-mapping nil
"Supports mapping file paths when opening file buffers in pdbtrack.
When non-nil this is an alist mapping paths in the Python interpreter
to paths in Emacs."
:type 'alist
:tag "py-pdbtrack-filename-mapping"
:group 'python-mode)
(defcustom py-pdbtrack-minor-mode-string " PDB"
"String to use in the minor mode list when pdbtrack is enabled."
:type 'string
:tag "py-pdbtrack-minor-mode-string"
:group 'python-mode)
(defcustom py-import-check-point-max
"Max number of characters to search Java-ish import statement.
When `python-mode' tries to calculate the shell
-- either a CPython or a Jython shell --
it looks at the so-called `shebang'.
If that's not available, it looks at some of the
file heading imports to see if they look Java-like."
:type 'integer
:tag "py-import-check-point-max
:group 'python-mode)
(defcustom py-jython-packages
'("java" "javax")
"Imported packages that imply `jython-mode'."
:type '(repeat string)
:tag "py-jython-packages
:group 'python-mode)
(defcustom py-current-defun-show t
"If `py-current-defun' should jump to the definition.
Highlights it while waiting PY-WHICH-FUNC-DELAY seconds.
Afterwards returning to previous position.
Default is t."
:type 'boolean
:tag "py-current-defun-show"
:group 'python-mode)
(defcustom py-current-defun-delay 2
"When called interactively, `py-current-defun' should wait PY-WHICH-FUNC-DELAY seconds at the definition name found, before returning to previous position."
:type 'number
:tag "py-current-defun-delay"
:group 'python-mode)
(defcustom py--delete-temp-file-delay 1
"Used by `py--delete-temp-file'."
:type 'number
:tag "py--delete-temp-file-delay"
:group 'python-mode)
(defcustom py-python-send-delay 5
"Seconds to wait for output, used by `py--send-...' functions.
See also ‘py-ipython-send-delay’"
:type 'number
:tag "py-python-send-delay"
:group 'python-mode)
(defcustom py-ipython-send-delay 9
"Seconds to wait for output, used by `py--send-...' functions.
See also ‘py-python-send-delay’"
:type 'number
:tag "py-ipython-send-delay"
:group 'python-mode)
(defcustom py-master-file nil
"Execute the named master file instead of the buffer's file.
Default is nil.
With relative path variable `default-directory' is prepended.
Beside you may set this variable in the file's local
variable section, e.g.:
# Local Variables:
# py-master-file: \"\"
# End:"
:type 'string
:tag "py-master-file"
:group 'python-mode)
(make-variable-buffer-local 'py-master-file)
(defcustom py-pychecker-command "pychecker"
"Shell command used to run Pychecker."
:type 'string
:tag "py-pychecker-command"
:group 'python-mode)
(defcustom py-pychecker-command-args "--stdlib"
"String arguments to be passed to pychecker."
:type 'string
:tag "py-pychecker-command-args"
:group 'python-mode)
(defcustom py-pyflakes-command "pyflakes"
"Shell command used to run Pyflakes."
:type 'string
:tag "py-pyflakes-command"
:group 'python-mode)
(defcustom py-pyflakes-command-args ""
"String arguments to be passed to pyflakes.
Default is \"\""
:type 'string
:tag "py-pyflakes-command-args"
:group 'python-mode)
(defcustom py-pep8-command "pep8"
"Shell command used to run pep8."
:type 'string
:tag "py-pep8-command"
:group 'python-mode)
(defcustom py-pep8-command-args ""
"String arguments to be passed to pylint.
Default is \"\""
:type 'string
:tag "py-pep8-command-args"
:group 'python-mode)
(defcustom py-pyflakespep8-command (concat py-install-directory "/")
"Shell command used to run `pyflakespep8'."
:type 'string
:tag "py-pyflakespep8-command"
:group 'python-mode)
(defcustom py-pyflakespep8-command-args ""
"String arguments to be passed to pyflakespep8.
Default is \"\""
:type 'string
:tag "py-pyflakespep8-command-args"
:group 'python-mode)
(defcustom py-pylint-command "pylint"
"Shell command used to run Pylint."
:type 'string
:tag "py-pylint-command"
:group 'python-mode)
(defcustom py-pylint-command-args '("--errors-only")
"String arguments to be passed to pylint.
Default is \"--errors-only\""
:type '(repeat string)
:tag "py-pylint-command-args"
:group 'python-mode)
(defcustom py-shell-input-prompt-1-regexp ">>> "
"A regular expression to match the input prompt of the shell."
:type 'regexp
:tag "py-shell-input-prompt-1-regexp"
:group 'python-mode)
(defcustom py-shell-input-prompt-2-regexp "[.][.][.] "
"A regular expression to match the input prompt.
Applies to the shell after the first line of input."
:type 'string
:tag "py-shell-input-prompt-2-regexp"
:group 'python-mode)
(defcustom py-shell-prompt-read-only t
"If non-nil, the python prompt is read only.
Setting this variable will only effect new shells."
:type 'boolean
:tag "py-shell-prompt-read-only"
:group 'python-mode)
(defcustom py-honor-IPYTHONDIR-p nil
"When non-nil ipython-history file is constructed by $IPYTHONDIR.
Default is nil.
Otherwise value of ‘py-ipython-history’ is used."
:type 'boolean
:tag "py-honor-IPYTHONDIR-p"
:group 'python-mode)
(defcustom py-ipython-history "~/.ipython/history"
"Ipython-history default file.
Used when ‘py-honor-IPYTHONDIR-p’ is nil - th default"
:type 'string
:tag "py-ipython-history"
:group 'python-mode)
(defcustom py-honor-PYTHONHISTORY-p nil
"When non-nil python-history file is set by $PYTHONHISTORY.
Default is nil.
Otherwise value of ‘py-python-history’ is used."
:type 'boolean
:tag "py-honor-PYTHONHISTORY-p"
:group 'python-mode)
(defcustom py-python-history "~/.python_history"
"Python-history default file. Used when ‘py-honor-PYTHONHISTORY-p’ is nil (default)."
:type 'string
:tag "py-python-history"
:group 'python-mode)
(defcustom py-switch-buffers-on-execute-p nil
"When non-nil switch to the Python output buffer.
If `py-keep-windows-configuration' is t, this will take precedence over setting here."
:type 'boolean
:tag "py-switch-buffers-on-execute-p"
:group 'python-mode)
(defcustom py-split-window-on-execute 'just-two
"When non-nil split windows.
Default is just-two - when code is send to interpreter.
Splits screen into source-code buffer and current ‘py-shell’ result.
Other buffer will be hidden that way.
When set to t, ‘python-mode’ tries to reuse existing windows
and will split only if needed.
With 'always, results will displayed in a new window.
Both t and `always' is experimental still.
For the moment: If a multitude of python-shells/buffers should be
visible, open them manually and set `py-keep-windows-configuration' to t.
See also `py-keep-windows-configuration'"
:type '(choice
(const :tag "default" just-two)
(const :tag "reuse" t)
(const :tag "no split" nil)
(const :tag "just-two" just-two)
(const :tag "always" always))
:tag "py-split-window-on-execute"
:group 'python-mode)
(defcustom py-split-window-on-execute-threshold 3
"Maximal number of displayed windows.
Honored, when `py-split-window-on-execute' is t, i.e. \"reuse\".
Don't split when max number of displayed windows is reached."
:type 'number
:tag "py-split-window-on-execute-threshold"
:group 'python-mode)
(defcustom py-split-windows-on-execute-function 'split-window-vertically
"How window should get splitted to display results of py-execute-... functions."
:type '(choice (const :tag "split-window-vertically" split-window-vertically)
(const :tag "split-window-horizontally" split-window-horizontally)
:tag "py-split-windows-on-execute-function"
:group 'python-mode)
(defcustom py-shell-fontify-style nil
"Fontify current input resp. output in Python shell. Default is nil.
INPUT will leave output unfontified.
ALL keeps output fontified.
At any case only current input gets fontified."
:type '(choice (const :tag "Default" all)
(const :tag "Input" input)
(const :tag "Nil" nil)
:tag "py-shell-fontify-style"
:group 'python-mode)
(defcustom py-hide-show-keywords
'("class" "def" "elif" "else" "except"
"for" "if" "while" "finally" "try"
"Keywords composing visible heads."
:type '(repeat string)
:tag "py-hide-show-keywords
:group 'python-mode)
(defcustom py-hide-show-hide-docstrings t
"Controls if doc strings can be hidden by hide-show."
:type 'boolean
:tag "py-hide-show-hide-docstrings"
:group 'python-mode)
(defcustom py-hide-comments-when-hiding-all t
"Hide the comments too when you do an `hs-hide-all'."
:type 'boolean
:tag "py-hide-comments-when-hiding-all"
:group 'python-mode)
(defcustom py-outline-mode-keywords
'("class" "def" "elif" "else" "except"
"for" "if" "while" "finally" "try"
"Keywords composing visible heads."
:type '(repeat string)
:tag "py-outline-mode-keywords
:group 'python-mode)
(defcustom python-mode-hook nil
"Hook run when entering Python mode."
:type 'hook
:tag "python-mode-hook"
:group 'python-mode
(defcustom py-shell-name
(if (eq system-type 'windows-nt)
;; "python"
"A PATH/TO/EXECUTABLE or default value `py-shell' may look for.
If no shell is specified by command.
On Windows default is C:/Python27/python
--there is no garantee it exists, please check your system--
Else python"
:type 'string
:tag "py-shell-name
:group 'python-mode)
(defvar py-default-interpreter py-shell-name)
(defvar py-tempfile nil
"Internally used.")
(defvar py-named-shells (list 'ipython 'ipython-dedicated 'ipython-no-switch 'ipython-switch 'ipython-switch-dedicated 'ipython2.7 'ipython2.7-dedicated 'ipython2.7-no-switch 'ipython2.7-switch 'ipython2.7-switch-dedicated 'ipython3 'ipython3-dedicated 'ipython3-no-switch 'ipython3-switch 'ipython3-switch-dedicated 'jython 'jython-dedicated 'jython-no-switch 'jython-switch 'jython-switch-dedicated 'python 'python-dedicated 'python-no-switch 'python-switch 'python-switch-dedicated 'python2 'python2-dedicated 'python2-no-switch 'python2-switch 'python2-switch-dedicated 'python3 'python3-dedicated 'python3-no-switch 'python3-switch 'python3-switch-dedicated))
(defcustom py-python-command
(if (eq system-type 'windows-nt)
;; "C:\\Python27\\python.exe"
;; "C:/Python33/Lib/site-packages/IPython"
"Make sure directory in in the PATH-variable.
Windows: edit in \"Advanced System Settings/Environment Variables\"
Commonly \"C:\\\\Python27\\\\python.exe\"
With Anaconda for example the following works here:
Else /usr/bin/python"
:type 'string
:tag "py-python-command
:group 'python-mode)
(defcustom py-python-command-args '("-i")
"String arguments to be used when starting a Python shell."
:type 'string
:tag "py-python-command-args"
:group 'python-mode)
(defcustom py-python2-command
(if (eq system-type 'windows-nt)
;; "python2"
"Make sure, the directory where python.exe resides in in the PATH-variable.
Windows: If needed, edit in
\"Advanced System Settings/Environment Variables\"
With Anaconda for example the following works here:
Else /usr/bin/python"
:type 'string
:tag "py-python2-command
:group 'python-mode)
(defcustom py-python2-command-args '("-i")
"String arguments to be used when starting a Python shell."
:type '(repeat string)
:tag "py-python2-command-args"
:group 'python-mode)
;; "/usr/bin/python3"
(defcustom py-python3-command
(if (eq system-type 'windows-nt)
"A PATH/TO/EXECUTABLE or default value `py-shell' may look for.
Unless shell is specified by command.
On Windows see C:/Python3/python.exe
--there is no garantee it exists, please check your system--
At GNU systems see /usr/bin/python3"
:type 'string
:tag "py-python3-command
:group 'python-mode)
(defcustom py-python3-command-args '("-i")
"String arguments to be used when starting a Python3 shell."
:type '(repeat string)
:tag "py-python3-command-args"
:group 'python-mode)
(defcustom py-ipython-command
(if (eq system-type 'windows-nt)
;; "ipython"
;; "C:/Python33/Lib/site-packages/IPython"
;; "/usr/bin/ipython"
"A PATH/TO/EXECUTABLE or default value.
`M-x IPython RET' may look for,
Unless IPython-shell is specified by command.
On Windows default is \"C:\\\\Python27\\\\python.exe\"
While with Anaconda for example the following works here:
Else /usr/bin/ipython"
:type 'string
:tag "py-ipython-command
:group 'python-mode)
(defcustom py-ipython-command-args
(if (eq system-type 'windows-nt)
"-i C:\\Python27\\Scripts\\"
"--pylab --automagic")
"String arguments to be used when starting a Python shell.
At Windows make sure is PATH.
Also setting PATH/TO/SCRIPT here should work, for example;
With Anaconda the following is known to work:
:type 'string
:tag "py-ipython-command-args
:group 'python-mode)
(defcustom py-jython-command
(if (eq system-type 'windows-nt)
"A PATH/TO/EXECUTABLE or default value.
`M-x Jython RET' may look for, if no Jython-shell is specified by command.
Not known to work at windows
Default /usr/bin/jython"
:type 'string
:tag "py-jython-command
:group 'python-mode)
(defcustom py-jython-command-args ""
"String arguments to be used when starting a Python shell."
:type 'string
:tag "py-jython-command-args"
:group 'python-mode)
(defcustom py-shell-toggle-1 py-python2-command
"A PATH/TO/EXECUTABLE or default value used by `py-toggle-shell'."
:type 'string
:tag "py-shell-toggle-1"
:group 'python-mode)
(defcustom py-shell-toggle-2 py-python3-command
"A PATH/TO/EXECUTABLE or default value used by `py-toggle-shell'."
:type 'string
:tag "py-shell-toggle-2"
:group 'python-mode)
(defcustom py--imenu-create-index-p nil
"Non-nil means Python mode creates and displays an index menu of functions and global variables."
:type 'boolean
:tag "py--imenu-create-index-p"
:group 'python-mode)
(defvar py-history-filter-regexp "\\`\\s-*\\S-?\\S-?\\s-*\\'\\|'''/tmp/"
"Input matching this regexp is not saved on the history list.
Default ignores all inputs of 0, 1, or 2 non-blank characters.")
(defcustom py-match-paren-mode nil
"Non-nil means, cursor will jump to beginning or end of a block.
This vice versa, to beginning first.
Sets `py-match-paren-key' in ‘python-mode-map’.
Customize `py-match-paren-key' which key to use."
:type 'boolean
:tag "py-match-paren-mode"
:group 'python-mode)
(defcustom py-match-paren-key "%"
"String used by \\[comment-region] to comment out a block of code.
This should follow the convention for non-indenting comment lines so
that the indentation commands won't get confused (i.e., the string
should be of the form `#x...' where `x' is not a blank or a tab, and
`...' is arbitrary). However, this string should not end in whitespace."
:type 'string
:tag "py-match-paren-key"
:group 'python-mode)
(defcustom py-kill-empty-line t
"If t, ‘py-indent-forward-line’ kills empty lines."
:type 'boolean
:tag "py-kill-empty-line"
:group 'python-mode)
(defcustom py-imenu-show-method-args-p nil
"Controls echoing of arguments of functions & methods in the Imenu buffer.
When non-nil, arguments are printed."
:type 'boolean
:tag "py-imenu-show-method-args-p"
:group 'python-mode)
(defcustom py-use-local-default nil
"If t, ‘py-shell’ will use `py-shell-local-path'.
Alternative to default Python.
Making switch between several virtualenv's easier,
`python-mode' should deliver an installer, so named-shells pointing to virtualenv's will be available."
:type 'boolean
:tag "py-use-local-default"
:group 'python-mode)
(defcustom py-edit-only-p nil
"Don't check for installed Python executables.
Default is nil.
See bug report at launchpad, lp:944093."
:type 'boolean
:tag "py-edit-only-p"
:group 'python-mode)
(defcustom py-force-py-shell-name-p nil
"When t, execution with kind of Python specified in `py-shell-name' is enforced, possibly shebang doesn't take precedence."
:type 'boolean
:tag "py-force-py-shell-name-p"
:group 'python-mode)
(defcustom python-mode-v5-behavior-p nil
"Execute region through `shell-command-on-region'.
As v5 did it - lp:990079. This might fail with certain chars - see UnicodeEncodeError lp:550661"
:type 'boolean
:tag "python-mode-v5-behavior-p"
:group 'python-mode)
(defcustom py-trailing-whitespace-smart-delete-p nil
"Default is nil.
When t, ‘python-mode’ calls
\(add-hook 'before-save-hook 'delete-trailing-whitespace nil 'local)
Also commands may delete trailing whitespace by the way.
When editing other peoples code, this may produce a larger diff than expected"
:type 'boolean
:tag "py-trailing-whitespace-smart-delete-p"
:group 'python-mode)
(defcustom py-newline-delete-trailing-whitespace-p t
"Delete trailing whitespace maybe left by `py-newline-and-indent'.
Default is t. See lp:1100892"
:type 'boolean
:tag "py-newline-delete-trailing-whitespace-p"
:group 'python-mode)
(defcustom py--warn-tmp-files-left-p nil
"Messages a warning, when `py-temp-directory' contains files susceptible being left by previous Python-mode sessions. See also lp:987534."
:type 'boolean
:tag "py--warn-tmp-files-left-p"
:group 'python-mode)
(defcustom py-complete-ac-sources '(ac-source-pycomplete)
"List of ‘auto-complete’ sources assigned to `ac-sources'.
In `py-complete-initialize'.
Default is known to work an Ubuntu 14.10 - having python-
mode, pymacs and auto-complete-el, with the following minimal
Emacs initialization:
\(require 'pymacs)
\(require 'auto-complete-config)
:type 'hook
:tag "py-complete-ac-sources"
:options '(ac-source-pycomplete ac-source-abbrev ac-source-dictionary ac-source-words-in-same-mode-buffers)
:group 'python-mode)
(defcustom py-remove-cwd-from-path t
"Whether to allow loading of Python modules from the current directory.
If this is non-nil, Emacs removes '' from sys.path when starting
a Python process. This is the default, for security
reasons, as it is easy for the Python process to be started
without the user's realization (e.g. to perform completion)."
:type 'boolean
:tag "py-remove-cwd-from-path"
:group 'python-mode)
(defcustom py-shell-local-path ""
"If `py-use-local-default' is non-nil, `py-shell' will use EXECUTABLE indicated here incl. path."
:type 'string
:tag "py-shell-local-path"
:group 'python-mode)
(defcustom py-python-edit-version ""
"When not empty, fontify according to Python version specified.
Default is the empty string, a useful value \"python3\" maybe.
When empty, version is guessed via `py-choose-shell'."
:type 'string
:tag "py-python-edit-version"
:group 'python-mode)
(defcustom py-ipython-execute-delay 0.3
"Delay needed by execute functions when no IPython shell is running."
:type 'float
:tag "py-ipython-execute-delay"
:group 'python-mode)
(defvar py-shell-completion-setup-code
import readline
except ImportError:
def __COMPLETER_all_completions(text): []
import rlcompleter
def __COMPLETER_all_completions(text):
import sys
completions = []
i = 0
while True:
res = readline.get_completer()(text, i)
if not res: break
i += 1
except NameError:
return completions"
"Code used to setup completion in Python processes.")
(defvar py-shell-module-completion-code "';'.join(__COMPLETER_all_completions('''%s'''))"
"Python code used to get completions separated by semicolons for imports.")
(defvar py-ipython-module-completion-code
"import IPython
version = IPython.__version__
if \'0.10\' < version:
from IPython.core.completerlib import module_completion
"For IPython v0.11 or greater.
Use the following as the value of this variable:
(defvar py-ipython-module-completion-string
"See also `py-ipython-module-completion-code'.")
(defcustom py--imenu-create-index-function 'py--imenu-index
"Switch between `py--imenu-create-index-new', which also lists modules variables, and series 5. index-machine."
:type '(choice
(const :tag "'py--imenu-create-index-new, also lists modules variables " py--imenu-create-index-new)
(const :tag "py--imenu-create-index, series 5. index-machine" py--imenu-create-index)
(const :tag "py--imenu-index, honor type annotations" py--imenu-index)
:tag "py--imenu-create-index-function"
:group 'python-mode)
(defvar py-line-re "^"
"Used by generated functions." )
(defvar py-input-filter-re "\\`\\s-*\\S-?\\S-?\\s-*\\'"
"Input matching this regexp is not saved on the history list.
Default ignores all inputs of 0, 1, or 2 non-blank characters.")
(defvaralias 'inferior-python-filter-regexp 'py-input-filter-re)
(defvar strip-chars-before "\\`[ \t\r\n]*"
"Regexp indicating which chars shall be stripped before STRING - which is defined by `string-chars-preserve'.")
(defvar strip-chars-after "[ \t\r\n]*\\'"
"Regexp indicating which chars shall be stripped after STRING - which is defined by `string-chars-preserve'.")
(defcustom py-docstring-style 'pep-257-nn
"Implemented styles:
A value of NIL won't care about quotes
position and will treat docstrings a normal string, any other
value may result in one of the following docstring styles:
Process foo, return bar.
Process foo, return bar.
If processing fails throw ProcessingError.
\"\"\"Process foo, return bar.\"\"\"
Process foo, return bar.
If processing fails throw ProcessingError.
\"\"\"Process foo, return bar.\"\"\"
\"\"\"Process foo, return bar.
If processing fails throw ProcessingError.
\"\"\"Process foo, return bar.\"\"\"
\"\"\"Process foo, return bar.
If processing fails throw ProcessingError.
\"\"\"Process foo, return bar.\"\"\"
Process foo, return bar.
If processing fails throw ProcessingError.
:type '(choice
(const :tag "Don't format docstrings" nil)
(const :tag "Django's coding standards style." django)
(const :tag "One newline and start and Two at end style." onetwo)
(const :tag "PEP-257 with 2 newlines at end of string." pep-257)
(const :tag "PEP-257 with 1 newline at end of string." pep-257-nn)
(const :tag "Symmetric style." symmetric))
:tag "py-docstring-style"
:group 'python-mode)
(defcustom py-execute-directory nil
"Stores the file's default directory-name py-execute-... functions act upon.
Used by Python-shell for output of `py-execute-buffer' and related commands.
See also `py-use-current-dir-when-execute-p'"
:type 'string
:tag "py-execute-directory"
:group 'python-mode)
(defcustom py-use-current-dir-when-execute-p t
"Current directory used for output.
See also `py-execute-directory'"
:type 'boolean
:tag "py-use-current-dir-when-execute-p"
:group 'python-mode)
(defcustom py-keep-shell-dir-when-execute-p nil
"Don't change Python shell's current working directory when sending code.
See also `py-execute-directory'"
:type 'boolean
:tag "py-keep-shell-dir-when-execute-p"
:group 'python-mode)
(defcustom py-fileless-buffer-use-default-directory-p t
"When `py-use-current-dir-when-execute-p' is non-nil and no buffer-file exists, value of `default-directory' sets current working directory of Python output shell."
:type 'boolean
:tag "py-fileless-buffer-use-default-directory-p"
:group 'python-mode)
(defcustom py-check-command "pychecker --stdlib"
"Command used to check a Python file."
:type 'string
:tag "py-check-command"
:group 'python-mode)
(defvar py-this-abbrevs-changed nil
"Internally used by ‘python-mode-hook’.")
(defvar py-ffap-p nil)
(defvar py-ffap nil)
(defvar ffap-alist nil)
(defvar py-buffer-name nil
"Internal use.
The buffer last output was sent to.")
(defvar py-orig-buffer-or-file nil
"Internal use.")
(defun py--set-ffap-form ()
(cond ((and py-ffap-p py-ffap)
(eval-after-load "ffap"
'(push '(python-mode . py-module-path) ffap-alist))
(setq ffap-alist (remove '(python-mode . py-ffap-module-path) ffap-alist))
(setq ffap-alist (remove '(py-shell-mode . py-ffap-module-path)
(t (setq ffap-alist (remove '(python-mode . py-ffap-module-path) ffap-alist))
(setq ffap-alist (remove '(py-shell-mode . py-ffap-module-path)
(setq ffap-alist (remove '(python-mode . py-module-path) ffap-alist)))))
(defcustom py-ffap-p nil
"Select python-modes way to find file at point.
Default is nil"
:type '(choice
(const :tag "default" nil)
(const :tag "use py-ffap" py-ffap))
:tag "py-ffap-p"
:set (lambda (symbol value)
(set-default symbol value)
:group 'python-mode)
(defcustom py-keep-windows-configuration nil
"Takes precedence over:
`py-split-window-on-execute' and `py-switch-buffers-on-execute-p'.
See lp:1239498
To suppres window-changes due to error-signaling also.
Set `py-keep-windows-configuration' onto 'force
Default is nil"
:type '(choice
(const :tag "nil" nil)
(const :tag "t" t)
(const :tag "force" 'force))
:tag "py-keep-windows-configuration"
:group 'python-mode)
(defvar py-output-buffer "*Python Output*"
"Currently unused.
Output buffer is created dynamically according to Python version and kind of process-handling")
(make-variable-buffer-local 'py-output-buffer)
(defcustom py-force-default-output-buffer-p nil
"Enforce sending output to the default output ‘buffer-name’.
Set by defvar ‘py-output-buffer’
Bug #31 - wrong fontification caused by string-delimiters in output"
:type 'boolean
:tag "py-force-default-output-buffer-p"
:group 'python-mode)
(defvar py-ffap-string-code
"Python code used to get a string with the path of a module.")
(defcustom py-shell-prompt-regexp ">>> "
"Regular Expression matching top\-level input prompt of python shell.
It should not contain a caret (^) at the beginning."
:type 'string
:tag "py-shell-prompt-regexp"
:group 'python-mode)
(defvar py-ffap-setup-code
"def __FFAP_get_module_path(module):
import os
path = __import__(module).__file__
if path[-4:] == '.pyc' and os.path.exists(path[0:-1]):
path = path[:-1]
return path
return ''
"Python code to get a module path.")
(defvar py-eldoc-window-configuration nil
"Keeps window-configuration when function ‘eldoc-mode’ is called.")
(defvar py-eldoc-setup-code
"def __PYDOC_get_help(obj):
import inspect
if hasattr(obj, 'startswith'):
obj = eval(obj, globals())
doc = inspect.getdoc(obj)
if not doc and callable(obj):
target = None
if inspect.isclass(obj) and hasattr(obj, '__init__'):
target = obj.__init__
objtype = 'class'
target = obj
objtype = 'def'
if target:
args = inspect.formatargspec(
name = obj.__name__
doc = '{objtype} {name}{args}'.format(
objtype=objtype, name=name, args=args)
doc = doc.splitlines()[0]
doc = ''
exec('print doc')
except SyntaxError:
"Python code to setup documentation retrieval.")
(defcustom py-shell-prompt-output-regexp ""
"Regular Expression matching output prompt of python shell.
It should not contain a caret (^) at the beginning."
:type 'string
:tag "py-shell-prompt-output-regexp"
:group 'python-mode)
(defvar py-underscore-word-syntax-p t
"This is set later by defcustom, only initial value here.
If underscore chars should be of ‘syntax-class’ `word', not of `symbol'.
Underscores in word-class makes `forward-word'.
Travels the indentifiers. Default is t.
See also command `toggle-py-underscore-word-syntax-p'")
(defvar py-autofill-timer nil)
(defvar py-fill-column-orig fill-column)
;; defvared value isn't updated maybe
(defvar python-mode-message-string
(if (or (string= "python-mode.el" (buffer-name))
(ignore-errors (string-match "python-mode.el" (py--buffer-filename-remote-maybe))))
"Internally used. Reports the ‘python-mode’ branch.")
;; defvared value isn't updated maybe
(setq python-mode-message-string
(if (or (string= "python-mode.el" (buffer-name))
(ignore-errors (string-match "python-mode.el" (py--buffer-filename-remote-maybe))))
(unless (fboundp 'string-to-syntax)
;; Skip's XE workaround
(defun string-to-syntax (s)
((equal s "|") '(15))
((equal s "_") '(3))
(t (error "Unhandled string: %s" s)))))
(defvar python-mode-syntax-table nil
"Give punctuation syntax to ASCII that normally has symbol.
Syntax or has word syntax and isn't a letter.")
(setq python-mode-syntax-table
(let ((table (make-syntax-table)))
;; Give punctuation syntax to ASCII that normally has symbol
;; syntax or has word syntax and isn't a letter.
(let ((symbol (string-to-syntax "_"))
(sst (standard-syntax-table)))
(dotimes (i 128)
(unless (= i ?_)
(if (equal symbol (aref sst i))
(modify-syntax-entry i "." table)))))
(modify-syntax-entry ?$ "." table)
(modify-syntax-entry ?% "." table)
;; exceptions
(modify-syntax-entry ?# "<" table)
(modify-syntax-entry ?\n ">" table)
(modify-syntax-entry ?' "\"" table)
(modify-syntax-entry ?` "$" table)
(if py-underscore-word-syntax-p
(modify-syntax-entry ?\_ "w" table)
(modify-syntax-entry ?\_ "_" table))
(defvar py-local-command nil
"Returns locally used executable-name.")
(make-variable-buffer-local 'py-local-command)
(defvar py-local-versioned-command nil
"Returns locally used executable-name including its version.")
(make-variable-buffer-local 'py-local-versioned-command)
(defvar py-ipython-completion-command-string nil
"Select command according to IPython version.
Either ‘py-ipython0.10-completion-command-string’
or ‘py-ipython0.11-completion-command-string’.
‘py-ipython0.11-completion-command-string’ also covers version 0.12")
(defvar py-ipython0.10-completion-command-string
"print(';'.join(__IP.Completer.all_completions('%s'))) #PYTHON-MODE SILENT\n"
"The string send to ipython to query for all possible completions.")
(defvar py-ipython0.11-completion-command-string
"print(';'.join(get_ipython().Completer.all_completions('%s'))) #PYTHON-MODE SILENT\n"
"The string send to ipython to query for all possible completions.")
(defvar py-encoding-string-re "^[ \t]*#[ \t]*-\\*-[ \t]*coding:.+-\\*-"
"Matches encoding string of a Python file.")
(defvar py-shebang-regexp "#![ \t]?\\([^ \t\n]+\\)[ \t]*\\([biptj]+ython[^ \t\n]*\\)"
"Detecting the shell in head of file.")
;; (setq py-shebang-regexp "#![ \t]?\\([^ \t\n]+\\)[ \t]*\\([biptj]+ython[^ \t\n]*\\)")
(defvar py-separator-char "/"
"Values set by defcustom only will not be seen in batch-mode.")
(defvar py-temp-directory
(let ((ok '(lambda (x)
(and x
(setq x (expand-file-name x)) ; always true
(file-directory-p x)
(file-writable-p x)
(and (not (string= "" py-custom-temp-directory))
(if (funcall ok py-custom-temp-directory)
(setq erg (expand-file-name py-custom-temp-directory))
(if (file-directory-p (expand-file-name py-custom-temp-directory))
(error "Py-custom-temp-directory set but not writable")
(error "Py-custom-temp-directory not an existing directory"))))
(and (funcall ok (getenv "TMPDIR"))
(setq erg (getenv "TMPDIR")))
(and (funcall ok (getenv "TEMP/TMP"))
(setq erg (getenv "TEMP/TMP")))
(and (funcall ok "/usr/tmp")
(setq erg "/usr/tmp"))
(and (funcall ok "/tmp")
(setq erg "/tmp"))
(and (funcall ok "/var/tmp")
(setq erg "/var/tmp"))
(and (eq system-type 'darwin)
(funcall ok "/var/folders")
(setq erg "/var/folders"))
(and (or (eq system-type 'ms-dos)(eq system-type 'windows-nt))
(funcall ok (concat "c:" py-separator-char "Users"))
(setq erg (concat "c:" py-separator-char "Users")))
;; (funcall ok ".")
"Couldn't find a usable temp directory -- set `py-temp-directory'"))
(when erg (setq py-temp-directory erg)))
"Directory used for temporary files created by a *Python* process.
By default, guesses the first directory from this list that exists and that you
can write into: the value (if any) of the environment variable TMPDIR,
/usr/tmp, /tmp, /var/tmp, or the current directory.
`py-custom-temp-directory' will take precedence when setq")
(defvar py-pdbtrack-input-prompt "^[(<]*[Ii]?[Pp]y?db[>)]+ *"
"Recognize the prompt.")
(defvar py-pydbtrack-input-prompt "^[(]*ipydb[>)]+ "
"Recognize the pydb-prompt.")
(defvar py-ipython-input-prompt-re "In \\[[0-9]+\\]:\\|^[ ]\\{3\\}[.]\\{3,\\}:"
"A regular expression to match the IPython input prompt.")
;; prevent ipython.el's setting
(setq py-ipython-input-prompt-re "[IO][un]t? \\[[0-9]+\\]:\\|^[ ]\\{3\\}[.]\\{3,\\}:" )
(defvar py-exec-command nil
"Internally used.")
(defvar py-which-bufname "Python")
(defvar py-pychecker-history nil)
(defvar py-pyflakes-history nil)
(defvar py-pep8-history nil)
(defvar py-pyflakespep8-history nil)
(defvar py-pylint-history nil)
(defvar py-ipython-output-prompt-re "^Out\\[[0-9]+\\]: "
"A regular expression to match the output prompt of IPython.")
(defvar py-mode-output-map nil
"Keymap used in *Python Output* buffers.")
(defvar hs-hide-comments-when-hiding-all t
"Defined in hideshow.el, silence compiler warnings here.")
(defvar py-force-local-shell-p nil
"Used internally, see `toggle-force-local-shell'.")
(defvar py-shell-complete-debug nil
"For interal use when debugging, stores completions." )
(defcustom py-debug-p nil
"When non-nil, keep resp. store information useful for debugging.
Temporary files are not deleted. Other functions might implement
some logging etc."
:type 'boolean
:tag "py-debug-p"
:group 'python-mode)
(defcustom py-section-start "# {{"
"Delimit arbitrary chunks of code."
:type 'string
:tag "py-section-start"
:group 'python-mode)
(defcustom py-section-end "# }}"
"Delimit arbitrary chunks of code."
:type 'string
:tag "py-section-end"
:group 'python-mode)
(defvar py-section-re py-section-start)
(defvar py-last-window-configuration nil
"Internal use: restore ‘py-restore-window-configuration’ when completion is done resp. abandoned.")
(defvar py-exception-buffer nil
"Will be set internally, let-bound, remember source buffer where error might occur.")
(defvar py-string-delim-re "\\(\"\"\"\\|'''\\|\"\\|'\\)"
"When looking at beginning of string.")
(defvar py-labelled-re "[ \\t]*:[[:graph:]]+"
"When looking at label.")
;; (setq py-labelled-re "[ \\t]*:[[:graph:]]+")
(defvar py-expression-skip-regexp "[^ (=:#\t\r\n\f]"
"Py-expression assumes chars indicated possible composing a ‘py-expression’, skip it.")
(defvar py-expression-skip-chars "^ (=#\t\r\n\f"
"Py-expression assumes chars indicated possible composing a ‘py-expression’, skip it.")
(setq py-expression-skip-chars "^ [{(=#\t\r\n\f")
(defvar py-expression-re "[^ =#\t\r\n\f]+"
"Py-expression assumes chars indicated possible composing a ‘py-expression’, when ‘looking-at’ or -back.")
(defcustom py-paragraph-re paragraph-start
"Allow Python specific ‘paragraph-start’ var."
:type 'string
:tag "py-paragraph-re"
:group 'python-mode)
(defvar py-not-expression-regexp "[ .=#\t\r\n\f)]+"
"Py-expression assumes chars indicated probably will not compose a ‘py-expression’.")
(defvar py-not-expression-chars " #\t\r\n\f"
"Py-expression assumes chars indicated probably will not compose a ‘py-expression’.")
(defvar py-partial-expression-backward-chars "^] .=,\"'()[{}:#\t\r\n\f"
"Py-partial-expression assumes chars indicated possible composing a ‘py-partial-expression’, skip it.")
;; (setq py-partial-expression-backward-chars "^] .=,\"'()[{}:#\t\r\n\f")
(defvar py-partial-expression-forward-chars "^ .\"')}]:#\t\r\n\f")
;; (setq py-partial-expression-forward-chars "^ .\"')}]:#\t\r\n\f")
(defvar py-partial-expression-re (concat "[" py-partial-expression-backward-chars (substring py-partial-expression-forward-chars 1) "]+"))
(setq py-partial-expression-re (concat "[" py-partial-expression-backward-chars "]+"))
(defvar py-statement-re py-partial-expression-re)
(defvar py-indent-re ".+"
"This var is introduced for regularity only.")
(setq py-indent-re ".+")
(defvar py-operator-re "[ \t]*\\(\\.\\|+\\|-\\|*\\|//\\|//\\|&\\|%\\||\\|\\^\\|>>\\|<<\\|<\\|<=\\|>\\|>=\\|==\\|!=\\|=\\)[ \t]*"
"Matches most of Python syntactical meaningful characters.
See also `py-assignment-re'")
;; (setq py-operator-re "[ \t]*\\(\\.\\|+\\|-\\|*\\|//\\|//\\|&\\|%\\||\\|\\^\\|>>\\|<<\\|<\\|<=\\|>\\|>=\\|==\\|!=\\|=\\)[ \t]*")
(defvar py-assignment-re "[ \t]*=[^=]"
"Matches assignment operator inclusive whitespaces around.
See also `py-operator-re'")
(defvar py-delimiter-re "\\(\\.[[:alnum:]]\\|,\\|;\\|:\\)[ \t\n]"
"Delimiting elements of lists or other programming constructs.")
(defvar py-line-number-offset 0
"When an exception occurs as a result of ‘py-execute-region’.
A subsequent ‘py-up-exception’ needs the line number where the region
started, in order to jump to the correct file line.
This variable is set in ‘py-execute-region’ and used in ‘py--jump-to-exception’.")
(defvar py-match-paren-no-use-syntax-pps nil)
(defvar py-traceback-line-re
"[ \t]+File \"\\([^\"]+\\)\", line \\([0-9]+\\)"
"Regular expression that describes tracebacks.")
(defvar py-XXX-tag-face 'py-XXX-tag-face)
(defvar py-pseudo-keyword-face 'py-pseudo-keyword-face)
(defvar py-variable-name-face 'py-variable-name-face)
(defvar py-number-face 'py-number-face)
(defvar py-decorators-face 'py-decorators-face)
(defvar py-object-reference-face 'py-object-reference-face)
(defvar py-builtins-face 'py-builtins-face)
(defvar py-class-name-face 'py-class-name-face)
(defvar py-exception-name-face 'py-exception-name-face)
(defvar py-import-from-face 'py-import-from-face)
(defvar py-def-class-face 'py-def-class-face)
(defvar py-try-if-face 'py-try-if-face)
(defvar py-file-queue nil
"Queue of Python temp files awaiting execution.
Currently-active file is at the head of the list.")
(defvar jython-mode-hook nil
"Hook called by `jython-mode'.
`jython-mode' also calls `python-mode-hook'.")
(defvar py-shell-hook nil
"Hook called by `py-shell'.")
(defvar python-font-lock-keywords nil)
(defvar py-dotted-expression-syntax-table
(let ((table (make-syntax-table python-mode-syntax-table)))
(modify-syntax-entry ?_ "_" table)
(modify-syntax-entry ?."_" table)
"Syntax table used to identify Python dotted expressions.")
(defvar python-default-template "if"
"Default template to expand by `python-expand-template'.
Updated on each expansion.")
(defvar py-already-guessed-indent-offset nil
"Internal use by ‘py-indent-line’.
When `this-command' is `eq' to `last-command', use the guess already computed.")
(make-variable-buffer-local 'py-already-guessed-indent-offset)
(defvar py-shell-template "
\(defun NAME (&optional argprompt)
\"Start an DOCNAME interpreter in another window.
With optional \\\\[universal-argument] user is prompted
for options to pass to the DOCNAME interpreter. \"
(interactive \"P\")
(let\* ((py-shell-name \"FULLNAME\"))
(py-shell argprompt)
(when (called-interactively-p 'any) (switch-to-buffer (current-buffer))
(goto-char (point-max)))))
(defvar py-fast-filter-re (concat "\\("
(mapconcat 'identity
(delq nil (list py-shell-input-prompt-1-regexp py-shell-input-prompt-2-regexp py-ipython-input-prompt-re py-ipython-output-prompt-re py-pdbtrack-input-prompt py-pydbtrack-input-prompt "[.]\\{3,\\}:? *"))
"Internally used by `py-fast-filter'.
‘ansi-color-filter-apply’ might return
Result: \"\\nIn [10]: ....: ....: ....: 1\\n\\nIn [11]: \"")
;; Constants
(defconst py-block-closing-keywords-re
"[ \t]*\\_<\\(return\\|raise\\|break\\|continue\\|pass\\)\\_>[ \n\t]"
"Matches the beginning of a class, method or compound statement.")
(setq py-block-closing-keywords-re
"[ \t]*\\_<\\(return\\|raise\\|break\\|continue\\|pass\\)\\_>[ \n\t]")
(defconst py-finally-re
"[ \t]*\\_<finally\\_>[: \n\t]"
"Regular expression matching keyword which closes a try-block.")
(defconst py-except-re
"[ \t]*\\_<except\\_>[:( \n\t]*"
"Regular expression matching keyword which composes a try-block.")
(defconst py-return-re
".*:?[ \t]*\\_<\\(return\\)\\_>[ \n\t]*"
"Regular expression matching keyword which typically closes a function.")
(defconst py-decorator-re
"[ \t]*@[^ ]+\\_>[ \n\t]*"
"Regular expression matching keyword which typically closes a function.")
(defcustom py-outdent-re-raw
"async def"
"async for"
"async with"
"Used by ‘py-outdent-re’."
:type '(repeat string)
:tag "py-outdent-re-raw"
:group 'python-mode
(defconst py-outdent-re
"[ \t]*\\_<"
(regexp-opt py-outdent-re-raw)
"Regular expression matching lines not to augment indent after.
See ‘py-no-outdent-re-raw’ for better readable content")
(defcustom py-no-outdent-re-raw
"Uused by o‘py-no-outdent-re’."
:type '(repeat string)
:tag "py-no-outdent-re-raw"
:group 'python-mode)
(defconst py-no-outdent-re
"[ \t]*\\_<"
(regexp-opt py-no-outdent-re-raw)
"Regular expression matching lines not to augment indent after.
See ‘py-no-outdent-re-raw’ for better readable content")
(defconst py-assignment-re "\\_<\\w+\\_>[ \t]*\\(=\\|+=\\|*=\\|%=\\|&=\\|^=\\|<<=\\|-=\\|/=\\|**=\\||=\\|>>=\\|//=\\)"
"If looking at the beginning of an assignment.")
(defconst py-block-re "[ \t]*\\_<\\(class\\|def\\|async def\\|async for\\|for\\|if\\|try\\|while\\|with\\|async with\\)\\_>[:( \n\t]*"
"Matches the beginning of a compound statement.")
(defconst py-minor-block-re "[ \t]*\\_<\\(for\\|async for\\|if\\|try\\|with\\|async with\\|except\\)\\_>[:( \n\t]*"
"Matches the beginning of an `for', `if', `try', `except' or `with' block.")
(defconst py-try-block-re "[ \t]*\\_<try\\_>[: \n\t]"
"Matches the beginning of a `try' block.")
(defconst py-except-block-re "[ \t]*\\_<except\\_> *a?s? *[[:print:]]*[: \n\t]"
"Matches the beginning of a `except' block.")
(defconst py-for-block-re "[ \t]*\\_<\\(for\\|async for\\)\\_> +[[:alpha:]_][[:alnum:]_]* +in +[[:alpha:]_][[:alnum:]_()]* *[: \n\t]"
"Matches the beginning of a `try' block.")
(defconst py-if-block-re "[ \t]*\\_<if\\_> +[[:alpha:]_][[:alnum:]_]* *[: \n\t]"
"Matches the beginning of an `if' block.")
(defconst py-else-block-re "[ \t]*\\_<else:?[ \n\t]*"
"Matches the beginning of an `else' block.")
(defconst py-elif-block-re "[ \t]*\\_<elif\\_> +[[:alpha:]_][[:alnum:]_]* *[: \n\t]"
"Matches the beginning of an `elif' block.")
(defconst py-class-re "[ \t]*\\_<\\(class\\)\\_>[ \n\t]"
"Matches the beginning of a class definition.")
(defconst py-def-or-class-re "[ \t]*\\_<\\(async def\\|class\\|def\\)\\_>[ \n\t]+\\([[:alnum:]_]*\\)"
"Matches the beginning of a class- or functions definition.
Second group grabs the name")
;; (setq py-def-or-class-re "[ \t]*\\_<\\(async def\\|class\\|def\\)\\_>[ \n\t]")
;; (defconst py-def-re "[ \t]*\\_<\\(async def\\|def\\)\\_>[ \n\t]"
(defconst py-def-re "[ \t]*\\_<\\(def\\|async def\\)\\_>[ \n\t]"
"Matches the beginning of a functions definition.")
(defcustom py-block-or-clause-re-raw
"async for"
"async with"
"async def"
"async class"
"Matches the beginning of a compound statement or it's clause."
:type '(repeat string)
:tag "py-block-or-clause-re-raw"
:group 'python-mode)
(defvar py-block-or-clause-re
"[ \t]*\\_<\\("
(regexp-opt py-block-or-clause-re-raw)
"\\)\\_>[( \t]*.*:?")
"See ‘py-block-or-clause-re-raw’, which it reads.")
;; (setq py-block-or-clause-re
;; (concat
;; "[ \t]*\\_<\\("
;; (regexp-opt py-block-or-clause-re-raw)
;; "\\)\\_>[( \t]*.*:?"))
(defcustom py-block-re-raw
"Matches the beginning of a compound statement but not it's clause."
:type '(repeat string)
:tag "py-block-re-raw"
:group 'python-mode)
(defvar py-block-re
"[ \t]*\\_<\\("
(regexp-opt py-block-re-raw)
"\\)\\_>[( \t]*.*:?")
"See ‘py-block-or-clause-re-raw’, which it reads.")
(defconst py-clause-re
"[ \t]*\\_<\\("
(mapconcat 'identity
"\\)\\_>[( \t]*.*:?")
"Regular expression matching lines not to augment indent after.")
(defcustom py-extended-block-or-clause-re-raw
"async def"
"async for"
"async with"
"Matches the beginning of a compound statement or it's clause."
:type '(repeat string)
:tag "py-extended-block-or-clause-re-raw"
:group 'python-mode)
(defconst py-extended-block-or-clause-re
"[ \t]*\\_<\\("
(regexp-opt py-extended-block-or-clause-re-raw)
"\\)\\_>[( \t]*.*:?")
"See ‘py-block-or-clause-re-raw’, which it reads.")
(defcustom py-top-level-re
(regexp-opt py-extended-block-or-clause-re-raw)
"\\)\\_>[( \t]*.*:?")
"A form which starts at zero indent level, but is not a comment."
:type '(regexp)
:tag "py-top-level-re"
:group 'python-mode
(defvar py-comment-re comment-start
"Needed for normalized processing.")
(defconst py-block-keywords
(regexp-opt py-block-or-clause-re-raw)
"Matches known keywords opening a block.
Customizing `py-block-or-clause-re-raw' will change values here")
(defcustom py-clause-re-raw
"Matches the beginning of a clause."
:type '(repeat string)
:tag "py-clause-re-raw"
:group 'python-mode)
(defconst py-clause-re
"[ \t]*\\_<\\("
(regexp-opt py-clause-re-raw)
"\\)\\_>[( \t]*.*:?")
"See ‘py-clause-re-raw’, which it reads.")
(defconst py-elif-re "[ \t]*\\_<\\elif\\_>[:( \n\t]*"
"Matches the beginning of a compound if-statement's clause exclusively.")
(defconst py-try-clause-re
"[ \t]*\\_<\\("
(mapconcat 'identity
"\\)\\_>[( \t]*.*:")
"Matches the beginning of a compound try-statement's clause.")
(defconst py-if-re "[ \t]*\\_<if\\_>[( \n\t]*"
"Matches the beginning of a compound statement saying `if'.")
(defconst py-try-re "[ \t]*\\_<try\\_>[:( \n\t]*"
"Matches the beginning of a compound statement saying `try'." )
(defcustom py-compilation-regexp-alist
`((,(rx line-start (1+ (any " \t")) "File \""
(group (1+ (not (any "\"<")))) ; avoid `<stdin>' &c
"\", line " (group (1+ digit)))
1 2)
(,(rx " in file " (group (1+ not-newline)) " on line "
(group (1+ digit)))
1 2)
(,(rx line-start "> " (group (1+ (not (any "(\"<"))))
"(" (group (1+ digit)) ")" (1+ (not (any "("))) "()")
1 2))
"Fetch errors from Py-shell.
hooked into `compilation-error-regexp-alist'"
:type '(alist string)
:tag "py-compilation-regexp-alist"
:group 'python-mode)
(defun py--quote-syntax (n)
"Put `syntax-table' property correctly on triple quote.
Used for syntactic keywords. N is the match number (1, 2 or 3)."
;; Given a triple quote, we have to check the context to know
;; whether this is an opening or closing triple or whether it's
;; quoted anyhow, and should be ignored. (For that we need to do
;; the same job as `syntax-ppss' to be correct and it seems to be OK
;; to use it here despite initial worries.) We also have to sort
;; out a possible prefix -- well, we don't _have_ to, but I think it
;; should be treated as part of the string.
;; Test cases:
;; ur"""ar""" x='"' # """
;; x = ''' """ ' a
;; '''
;; x '"""' x """ \"""" x
(goto-char (match-beginning 0))
;; Consider property for the last char if in a fenced string.
((= n 3)
(let* ((font-lock-syntactic-keywords nil)
(syntax (parse-partial-sexp (point-min) (point))))
(when (eq t (nth 3 syntax)) ; after unclosed fence
(goto-char (nth 8 syntax)) ; fence position
;; (skip-chars-forward "uUrR") ; skip any prefix
;; Is it a matching sequence?
(if (eq (char-after) (char-after (match-beginning 2)))
(eval-when-compile (string-to-syntax "|"))))))
;; Consider property for initial char, accounting for prefixes.
((or (and (= n 2) ; leading quote (not prefix)
(not (match-end 1))) ; prefix is null
(and (= n 1) ; prefix
(match-end 1))) ; non-empty
(let ((font-lock-syntactic-keywords nil))
(unless (eq 'string (syntax-ppss-context (parse-partial-sexp (point-min) (point))))
(eval-when-compile (string-to-syntax "|")))))
;; Otherwise (we're in a non-matching string) the property is
;; nil, which is OK.
(defconst py-font-lock-syntactic-keywords
;; Make outer chars of matching triple-quote sequences into generic
;; string delimiters. Fixme: Is there a better way?
;; First avoid a sequence preceded by an odd number of backslashes.
`((,(concat "\\(?:^\\|[^\\]\\(?:\\\\.\\)*\\)" ;Prefix.
(1 (py--quote-syntax 1) t t)
(2 (py--quote-syntax 2) t t)
(3 (py--quote-syntax 3) t t)
(6 (py--quote-syntax 1) t t))))
(defconst py-windows-config-register 313465889
"Internal used.")
(defvar py-windows-config nil
"Completion stores ‘py-windows-config-register’ here.")
(put 'py-indent-offset 'safe-local-variable 'integerp)
;; testing
(defvar py-ert-test-default-executables
(list "python" "python3" "ipython")
"Serialize tests employing dolist.")
(defvar py--shell-unfontify nil
"Internally used by `py--run-unfontify-timer'.")
(make-variable-buffer-local 'py--shell-unfontify)
(defvar py--timer nil
"Used by `py--run-unfontify-timer'.")
(make-variable-buffer-local 'py--timer)
(defvar py--timer-delay nil
"Used by `py--run-unfontify-timer'.")
(make-variable-buffer-local 'py--timer-delay)
(defcustom py-shell-unfontify-p t
"Run `py--run-unfontify-timer' unfontifying the shell banner-text.
Default is nil"
:type 'boolean
:tag "py-shell-unfontify-p"
:group 'python-mode)
(defun py--unfontify-banner-intern (buffer)
"Internal use, unfontify BUFFER."
(goto-char (point-min))
(let ((erg (or (ignore-errors (car-safe comint-last-prompt))
(re-search-forward py-fast-filter-re nil t 1)
(match-beginning 0))
;; (sit-for 1 t)
(if erg
(font-lock-unfontify-region (point-min) erg)
(goto-char (point-max)))
(progn (and py-debug-p (message "%s" (concat "py--unfontify-banner: Don't see a prompt in buffer " (buffer-name buffer)))))))))
(defun py--unfontify-banner (&optional buffer)
"Unfontify the shell banner-text.
Cancels `py--timer'
Expects being called by `py--run-unfontify-timer'
Optional argument BUFFER which select."
(let ((buffer (or buffer (current-buffer))))
(if (ignore-errors (buffer-live-p (get-buffer buffer)))
(with-current-buffer buffer
(py--unfontify-banner-intern buffer)
(and (timerp py--timer)(cancel-timer py--timer)))
(and (timerp py--timer)(cancel-timer py--timer)))))
(defun py--run-unfontify-timer (&optional buffer)
"Unfontify the shell banner-text.
Optional argument BUFFER select buffer."
(when py--shell-unfontify
(let ((buffer (or buffer (current-buffer))))
(if (and
(buffer-live-p buffer)
(eq major-mode 'py-python-shell-mode)
(eq major-mode 'py-ipython-shell-mode)))
(unless py--timer
(setq py--timer
(if py--timer-delay (setq py--timer-delay 3)
(setq py--timer-delay 0.1))
#'py--unfontify-banner buffer)))
(cancel-timer py--timer)))))
(defsubst py-keep-region-active ()
"Keep the region active in XEmacs."
(and (boundp 'zmacs-region-stays)
(setq zmacs-region-stays t)))
;; GNU's syntax-ppss-context
(unless (functionp 'syntax-ppss-context)
(defsubst syntax-ppss-context (ppss)
((nth 3 ppss) 'string)
((nth 4 ppss) 'comment)
(t nil))))
(defface py-XXX-tag-face
'((t (:inherit font-lock-string-face)))
:tag "py-XXX-tag-face"
:group 'python-mode)
(defface py-pseudo-keyword-face
'((t (:inherit font-lock-keyword-face)))
"Face for pseudo keywords in Python mode, like self, True, False,
See also `py-object-reference-face'"
:tag "py-pseudo-keyword-face"
:group 'python-mode)
(defface py-object-reference-face
'((t (:inherit py-pseudo-keyword-face)))
"Face when referencing object members from its class resp. method., commonly \"cls\" and \"self\""
:tag "py-object-reference-face"
:group 'python-mode)
(defface py-variable-name-face
'((t (:inherit default)))
"Face method decorators."
:tag "py-variable-name-face"
:group 'python-mode)
(defface py-number-face
'((t (:inherit default)))
"Highlight numbers."
:tag "py-number-face"
:group 'python-mode)
(defface py-try-if-face
'((t (:inherit font-lock-keyword-face)))
"Highlight keywords."
:tag "py-try-if-face"
:group 'python-mode)
(defface py-import-from-face
'((t (:inherit font-lock-keyword-face)))
"Highlight keywords."
:tag "py-import-from-face"
:group 'python-mode)
(defface py-def-class-face
'((t (:inherit font-lock-keyword-face)))
"Highlight keywords."
:tag "py-def-class-face"
:group 'python-mode)
;; PEP 318 decorators
(defface py-decorators-face
'((t (:inherit font-lock-keyword-face)))
"Face method decorators."
:tag "py-decorators-face"
:group 'python-mode)
(defface py-builtins-face
'((t (:inherit font-lock-builtin-face)))
"Face for builtins like TypeError, object, open, and exec."
:tag "py-builtins-face"
:group 'python-mode)
(defface py-class-name-face
'((t (:inherit font-lock-type-face)))
"Face for classes."
:tag "py-class-name-face"
:group 'python-mode)
(defface py-exception-name-face
'((t (:inherit font-lock-builtin-face)))
:tag "py-exception-name-face"
:group 'python-mode)
(defun py--python-send-setup-code-intern (name &optional msg)
(let ((setup-file (concat (py--normalize-directory py-temp-directory) "py-" name ""))
(buf (current-buffer))
py-return-result-p py-store-result-p)
(unless (file-readable-p setup-file)
(insert (eval (car (read-from-string (concat "py-" name "-setup-code")))))
(write-file setup-file)))
(py--execute-file-base nil setup-file nil buf)
(when msg (message "%s" (concat name " setup-code sent to " (process-name (get-buffer-process buf)))))))
(defun py--python-send-completion-setup-code ()
"For Python see py--python-send-setup-code."
(py--python-send-setup-code-intern "shell-completion" py-verbose-p))
(defun py--python-send-ffap-setup-code ()
"For Python see py--python-send-setup-code."
(py--python-send-setup-code-intern "ffap" py-verbose-p))
(defun py--python-send-eldoc-setup-code ()
"For Python see py--python-send-setup-code."
(py--python-send-setup-code-intern "eldoc" py-verbose-p))
(defun py--ipython-import-module-completion ()
"Setup IPython v0.11 or greater.
Used by `py-ipython-module-completion-string'"
(let ((setup-file (concat (py--normalize-directory py-temp-directory) "")))
(unless (file-readable-p setup-file)
(insert py-ipython-module-completion-code)
(write-file setup-file)))
(py--execute-file-base nil setup-file nil (current-buffer))))
(defun py--at-raw-string ()
"If at beginning of a raw-string."
(and (looking-at "\"\"\"\\|'''") (member (char-before) (list ?u ?U ?r ?R))))
(defun py--docstring-p (pos)
"Check to see if there is a docstring at POS."
(goto-char pos)
(when (py--at-raw-string)
(forward-char -1)
(setq pos (point)))
(when (py-backward-statement)
(when (looking-at py-def-or-class-re)
(defun py--font-lock-syntactic-face-function (state)
"STATE expected as result von (parse-partial-sexp (point-min) (point)."
(if (nth 3 state)
(if (py--docstring-p (nth 8 state))
(and (fboundp 'make-obsolete-variable)
(make-obsolete-variable 'py-mode-hook 'python-mode-hook nil))
(defun py-choose-shell-by-shebang (&optional shebang)
"Choose shell by looking at #! on the first line.
If SHEBANG is non-nil, returns the shebang as string,
otherwise the Python resp. Jython shell command name."
;; look for an interpreter specified in the first line
(let* (erg res)
(goto-char (point-min))
(when (looking-at py-shebang-regexp)
(if shebang
(setq erg (match-string-no-properties 0))
(setq erg (split-string (match-string-no-properties 0) "[#! \t]"))
(dolist (ele erg)
(when (string-match "[bijp]+ython" ele)
(setq res ele))))))
(when (and py-verbose-p (called-interactively-p 'any)) (message "%s" res))
(defun py--choose-shell-by-import ()
"Choose CPython or Jython mode based imports.
If a file imports any packages in `py-jython-packages', within
`py-import-check-point-max' characters from the start of the file,
return `jython', otherwise return nil."
(let (mode)
(goto-char (point-min))
(while (and (not mode)
"^\\(\\(from\\)\\|\\(import\\)\\) \\([^ \t\n.]+\\)"
py-import-check-point-max t))
(setq mode (and (member (match-string 4) py-jython-packages)
(defun py-choose-shell-by-path (&optional separator-char)
"SEPARATOR-CHAR according to system ‘path-separator’.
Select Python executable according to version desplayed in path.
Returns versioned string, nil if nothing appropriate found"
(let ((path (py--buffer-filename-remote-maybe))
(separator-char (or separator-char py-separator-char))
(when (and path separator-char
(string-match (concat separator-char "[iI]?[pP]ython[0-9.]+" separator-char) path))
(setq erg (substring path
(1+ (string-match (concat separator-char "[iI]?[pP]ython[0-9.]+" separator-char) path)) (1- (match-end 0)))))
(when (called-interactively-p 'any) (message "%s" erg))
(defun py-which-python (&optional shell)
"Return version of Python of current environment, a number.
Optional argument SHELL selected shell."
(let* ((cmd (or shell (py-choose-shell)))
(treffer (string-match "\\([23]*\\.?[0-9\\.]*\\)$" cmd))
version erg)
(if treffer
;; if a number if part of python name, assume it's the version
(setq version (substring-no-properties cmd treffer))
(setq erg (shell-command-to-string (concat cmd " --version")))
(setq version (cond ((string-match (concat "\\(on top of Python \\)" "\\([0-9]\\.[0-9]+\\)") erg)
(match-string-no-properties 2 erg))
((string-match "\\([0-9]\\.[0-9]+\\)" erg)
(substring erg 7 (1- (length erg)))))))
(when (called-interactively-p 'any)
(if version
(when py-verbose-p (message "%s" version))
(message "%s" "Could not detect Python on your system")))
(string-to-number version)))
(defun py-python-current-environment ()
"Return path of current Python installation."
(let* ((cmd (py-choose-shell))
(denv (shell-command-to-string (concat "type " cmd)))
(erg (substring denv (string-match "/" denv))))
(when (called-interactively-p 'any)
(if erg
(message "%s" erg)
(message "%s" "Could not detect Python on your system")))
;; requested by org-mode still
(defalias 'py-toggle-shells 'py-choose-shell)
(defun py--cleanup-process-name (res)
"Make res ready for use by `executable-find'.
Returns RES or substring of RES"
(if (string-match "<" res)
(substring res 0 (match-beginning 0))
(defalias 'py-which-shell 'py-choose-shell)
(defun py-choose-shell (&optional arg fast)
"Return an appropriate executable as a string.
Returns nil, if no executable found.
This does the following:
- look for an interpreter with `py-choose-shell-by-shebang'
- examine imports using `py--choose-shell-by-import'
- look if Path/To/File indicates a Python version
- if not successful, return default value of `py-shell-name'
When interactivly called, messages the shell name.
Optional argument FAST use fast-process."
(interactive "P")
(let* (res
(erg (cond (py-force-py-shell-name-p
(default-value 'py-shell-name))
(if (not (string= "" py-shell-local-path))
(expand-file-name py-shell-local-path)
(message "Abort: `py-use-local-default' is set to `t' but `py-shell-local-path' is empty. Maybe call `py-toggle-local-default-use'")))
((and (or fast py-fast-process-p)
(comint-check-proc (current-buffer))
(string-match "ython" (process-name (get-buffer-process (current-buffer)))))
(setq res (process-name (get-buffer-process (current-buffer))))
(py--cleanup-process-name res)))
((and (not py-fast-process-p)
(comint-check-proc (current-buffer))
(setq done t)
(string-match "ython" (process-name (get-buffer-process (current-buffer)))))
(setq res (process-name (get-buffer-process (current-buffer))))
(py--cleanup-process-name res))
(t (or
(default-value 'py-shell-name)
(cmd (if (or
;; comint-check-proc was succesful
py-edit-only-p) erg
(executable-find erg))))
(if cmd
(when (called-interactively-p 'any)
(message "%s" cmd))
(when (called-interactively-p 'any) (message "%s" "Could not detect Python on your system. Maybe set `py-edit-only-p'?")))
(defun py--normalize-directory (directory)
"Make sure DIRECTORY ends with a file-path separator char.
(let ((erg (cond ((string-match (concat py-separator-char "$") directory)
((not (string= "" directory))
(concat directory py-separator-char)))))
(unless erg (when py-verbose-p (message "Warning: directory is empty")))
(defun py--normalize-pythonpath (pythonpath)
"Make sure PYTHONPATH ends with a colon.
(let ((erg (cond ((string-match (concat path-separator "$") pythonpath)
((not (string= "" pythonpath))
(concat pythonpath path-separator))
(t pythonpath))))
(defun py-install-directory-check ()
"Do some sanity check for `py-install-directory'.
Returns t if successful."
(let ((erg (and (boundp 'py-install-directory) (stringp py-install-directory) (< 1 (length py-install-directory)))))
(when (called-interactively-p 'any) (message "py-install-directory-check: %s" erg))
(defun py-guess-py-install-directory ()
"Takes value of user directory aka $HOME.
If `(locate-library \"python-mode\")' is not succesful.
Used only, if `py-install-directory' is empty."
(let ((erg (cond ((locate-library "python-mode")
(file-name-directory (locate-library "python-mode")))
((ignore-errors (string-match "python-mode" (py--buffer-filename-remote-maybe)))
(file-name-directory (py--buffer-filename-remote-maybe)))
((string-match "python-mode" (buffer-name))
(cond ((and (or (not py-install-directory) (string= "" py-install-directory)) erg)
(setq py-install-directory erg))
(t (setq py-install-directory (expand-file-name "~/")))))
(when (and py-verbose-p (called-interactively-p 'any)) (message "Setting py-install-directory to: %s" py-install-directory))
(defun py--fetch-pythonpath ()
"Consider settings of ‘py-pythonpath’."
(if (string= "" py-pythonpath)
(getenv "PYTHONPATH")
(concat (py--normalize-pythonpath (getenv "PYTHONPATH")) py-pythonpath)))
(defun py-load-pymacs ()
"Load Pymacs as delivered.
Pymacs has been written by François Pinard and many others.
See original source:"
(let ((pyshell (py-choose-shell))
(path (py--fetch-pythonpath))
(py-install-directory (cond ((string= "" py-install-directory)
(t (py--normalize-directory py-install-directory)))))
(if (py-install-directory-check)
;; If Pymacs has not been loaded before, prepend py-install-directory to
;; PYTHONPATH, so that the Pymacs delivered with python-mode is used.
(unless (featurep 'pymacs)
(setenv "PYTHONPATH" (concat
(expand-file-name py-install-directory)
(if path (concat path-separator path)))))
(setenv "PYMACS_PYTHON" (if (string-match "IP" pyshell)
(require 'pymacs))
(error "`py-install-directory' not set, see INSTALL"))))
(when py-load-pymacs-p (py-load-pymacs))
(when (and py-load-pymacs-p (featurep 'pymacs))
(defun py-load-pycomplete ()
"Load Pymacs based pycomplete."
(let* ((path (py--fetch-pythonpath))
(py-install-directory (cond ((string= "" py-install-directory)
(t (py--normalize-directory py-install-directory))))
(pycomplete-directory (concat (expand-file-name py-install-directory) "completion")))
(if (py-install-directory-check)
;; If the Pymacs process is already running, augment its path.
(when (and (get-process "pymacs") (fboundp 'pymacs-exec))
(pymacs-exec (concat "sys.path.insert(0, '" pycomplete-directory "')")))
(require 'pymacs)
(setenv "PYTHONPATH" (concat
(if path (concat path-separator path))))
(push pycomplete-directory load-path)
(require 'pycomplete)
(add-hook 'python-mode-hook 'py-complete-initialize))
(error "`py-install-directory' not set, see INSTALL")))))
(when (functionp 'py-load-pycomplete)
(defun py-set-load-path ()
"Include needed subdirs of ‘python-mode’ directory."
(let ((py-install-directory (py--normalize-directory py-install-directory)))
(cond ((and (not (string= "" py-install-directory))(stringp py-install-directory))
(push (expand-file-name py-install-directory) load-path)
(push (concat (expand-file-name py-install-directory) "completion") load-path)
(push (concat (expand-file-name py-install-directory) "extensions") load-path)
(push (concat (expand-file-name py-install-directory) "test") load-path)
(push (concat (expand-file-name py-install-directory) "tools") load-path)
(push (concat (expand-file-name py-install-directory) "autopair") load-path))
(let ((guessed-py-install-directory (py-guess-py-install-directory)))
(when guessed-py-install-directory
(push guessed-py-install-directory load-path))))
(t (error "Please set `py-install-directory', see INSTALL"))
(when (called-interactively-p 'any) (message "%s" load-path)))))
(unless py-install-directory
(push default-directory load-path)
(push (concat default-directory "extensions") load-path))
(defun py-count-lines (&optional beg end)
"Count lines in accessible part until current line.
Optional argument BEG specify beginning.
Optional argument END specify end."
(let ((count 0)
(beg (or beg (point-min)))
(end (or end (point))))
(if (or (eq major-mode 'comint-mode)
(eq major-mode 'py-shell-mode))
(re-search-backward py-fast-filter-re nil t 1)
(goto-char (match-end 0))
;; (when py-debug-p (message "%s" "py-count-lines: Don't see a prompt here"))
(goto-char beg))
(goto-char beg)))
(while (and (< (point) end)(not (eobp)) (skip-chars-forward "^\n" end))
(setq count (1+ count))
(unless (or (not (< (point) end)) (eobp)) (forward-char 1)
(setq count (+ count (abs (skip-chars-forward "\n" end))))))
(when (bolp) (setq count (1+ count)))
(when (and py-debug-p (called-interactively-p 'any)) (message "%s" count))
(defmacro py-escaped ()
"Return t if char is preceded by an odd number of backslashes."
(< 0 (% (abs (skip-chars-backward "\\\\")) 2))))
(defmacro py-current-line-backslashed-p ()
"Return t if current line is a backslashed continuation line."
(skip-chars-backward " \t\r\n\f")
(and (eq (char-before (point)) ?\\ )
(defmacro py-preceding-line-backslashed-p ()
"Return t if preceding line is a backslashed continuation line."
(skip-chars-backward " \t\r\n\f")
(and (eq (char-before (point)) ?\\ )
(defun py--escape-doublequotes (start end)
"Escape doublequotes in region by START END."
(let ((end (copy-marker end)))
(goto-char start)
(while (and (not (eobp)) (< 0 (abs (skip-chars-forward "^\"" end))))
(when (eq (char-after) ?\")
(unless (py-escaped)
(insert "\\")
(forward-char 1)))))))
(defun py--escape-open-paren-col1 (start end)
"Start from position START until position END."
(goto-char start)
;; (switch-to-buffer (current-buffer))
(while (re-search-forward "^(" end t 1)
(insert "\\")
(and py-company-pycomplete-p (require 'company-pycomplete))
;; Macros
(defmacro empty-line-p ()
"Return t if cursor is at an line with nothing but whitespace-characters, nil otherwise."
(looking-at "\\s-*$"))))
(require 'ansi-color)
(require 'cc-cmds)
(require 'cl)
(require 'comint)
(require 'compile)
(require 'custom)
(require 'flymake)
(require 'hippie-exp)
(require 'shell)
(require 'thingatpt)
(require 'which-func)
(defun py-define-menu (map)
(easy-menu-define py-menu map "Py"
["Ipython" ipython
:help " `ipython'
Start an IPython interpreter."]
["Ipython2\.7" ipython2\.7
:help " `ipython2\.7'"]
["Ipython3" ipython3
:help " `ipython3'
Start an IPython3 interpreter."]
["Jython" jython
:help " `jython'
Start an Jython interpreter."]
["Python" python
:help " `python'
Start an Python interpreter."]
["Python2" python2
:help " `python2'
Start an Python2 interpreter."]
["Python3" python3
:help " `python3'
Start an Python3 interpreter."])
("Shift right"
["Shift block right" py-shift-block-right
:help " `py-shift-block-right'
Indent block by COUNT spaces."]
["Shift block or clause right" py-shift-block-or-clause-right
:help " `py-shift-block-or-clause-right'
Indent block-or-clause by COUNT spaces."]
["Shift class right" py-shift-class-right
:help " `py-shift-class-right'
Indent class by COUNT spaces."]
["Shift clause right" py-shift-clause-right
:help " `py-shift-clause-right'
Indent clause by COUNT spaces."]
["Shift comment right" py-shift-comment-right
:help " `py-shift-comment-right'
Indent comment by COUNT spaces."]
["Shift def right" py-shift-def-right
:help " `py-shift-def-right'
Indent def by COUNT spaces."]
["Shift def or class right" py-shift-def-or-class-right
:help " `py-shift-def-or-class-right'
Indent def-or-class by COUNT spaces."]
["Shift indent right" py-shift-indent-right
:help " `py-shift-indent-right'
Indent indent by COUNT spaces."]
["Shift minor block right" py-shift-minor-block-right
:help " `py-shift-minor-block-right'
Indent minor-block by COUNT spaces."]
["Shift paragraph right" py-shift-paragraph-right
:help " `py-shift-paragraph-right'
Indent paragraph by COUNT spaces."]
["Shift region right" py-shift-region-right
:help " `py-shift-region-right'
Indent region by COUNT spaces."]
["Shift statement right" py-shift-statement-right
:help " `py-shift-statement-right'
Indent statement by COUNT spaces."]
["Shift top level right" py-shift-top-level-right
:help " `py-shift-top-level-right'
Indent top-level by COUNT spaces."])
("Shift left"
["Shift block left" py-shift-block-left
:help " `py-shift-block-left'
Dedent block by COUNT spaces."]
["Shift block or clause left" py-shift-block-or-clause-left
:help " `py-shift-block-or-clause-left'
Dedent block-or-clause by COUNT spaces."]
["Shift class left" py-shift-class-left
:help " `py-shift-class-left'
Dedent class by COUNT spaces."]
["Shift clause left" py-shift-clause-left
:help " `py-shift-clause-left'
Dedent clause by COUNT spaces."]
["Shift comment left" py-shift-comment-left
:help " `py-shift-comment-left'
Dedent comment by COUNT spaces."]
["Shift def left" py-shift-def-left
:help " `py-shift-def-left'
Dedent def by COUNT spaces."]
["Shift def or class left" py-shift-def-or-class-left
:help " `py-shift-def-or-class-left'
Dedent def-or-class by COUNT spaces."]
["Shift indent left" py-shift-indent-left
:help " `py-shift-indent-left'
Dedent indent by COUNT spaces."]
["Shift minor block left" py-shift-minor-block-left
:help " `py-shift-minor-block-left'
Dedent minor-block by COUNT spaces."]
["Shift paragraph left" py-shift-paragraph-left
:help " `py-shift-paragraph-left'
Dedent paragraph by COUNT spaces."]
["Shift region left" py-shift-region-left
:help " `py-shift-region-left'
Dedent region by COUNT spaces."]
["Shift statement left" py-shift-statement-left
:help " `py-shift-statement-left'
Dedent statement by COUNT spaces."]))
["Mark block" py-mark-block
:help " `py-mark-block'
Mark block, take beginning of line positions."]
["Mark block or clause" py-mark-block-or-clause
:help " `py-mark-block-or-clause'
Mark block-or-clause, take beginning of line positions."]
["Mark class" py-mark-class
:help " `py-mark-class'
Mark class, take beginning of line positions."]
["Mark clause" py-mark-clause
:help " `py-mark-clause'
Mark clause, take beginning of line positions."]
["Mark comment" py-mark-comment
:help " `py-mark-comment'
Mark comment at point."]
["Mark def" py-mark-def
:help " `py-mark-def'
Mark def, take beginning of line positions."]
["Mark def or class" py-mark-def-or-class
:help " `py-mark-def-or-class'
Mark def-or-class, take beginning of line positions."]
["Mark expression" py-mark-expression
:help " `py-mark-expression'
Mark expression at point."]
["Mark except block" py-mark-except-block
:help " `py-mark-except-block'
Mark except-block, take beginning of line positions."]
["Mark if block" py-mark-if-block
:help " `py-mark-if-block'
Mark if-block, take beginning of line positions."]
["Mark indent" py-mark-indent
:help " `py-mark-indent'
Mark indent, take beginning of line positions."]
["Mark line" py-mark-line
:help " `py-mark-line'
Mark line at point."]
["Mark minor block" py-mark-minor-block
:help " `py-mark-minor-block'
Mark minor-block, take beginning of line positions."]
["Mark partial expression" py-mark-partial-expression
:help " `py-mark-partial-expression'
Mark partial-expression at point."]
["Mark paragraph" py-mark-paragraph
:help " `py-mark-paragraph'
Mark paragraph at point."]
["Mark section" py-mark-section
:help " `py-mark-section'
Mark section at point."]
["Mark statement" py-mark-statement
:help " `py-mark-statement'
Mark statement, take beginning of line positions."]
["Mark top level" py-mark-top-level
:help " `py-mark-top-level'
Mark top-level, take beginning of line positions."]
["Mark try block" py-mark-try-block
:help " `py-mark-try-block'
Mark try-block, take beginning of line positions."])
["Copy block" py-copy-block
:help " `py-copy-block'
Copy block at point."]
["Copy block or clause" py-copy-block-or-clause
:help " `py-copy-block-or-clause'
Copy block-or-clause at point."]
["Copy class" py-copy-class
:help " `py-copy-class'
Copy class at point."]
["Copy clause" py-copy-clause
:help " `py-copy-clause'
Copy clause at point."]
["Copy comment" py-copy-comment
:help " `py-copy-comment'"]
["Copy def" py-copy-def
:help " `py-copy-def'
Copy def at point."]
["Copy def or class" py-copy-def-or-class
:help " `py-copy-def-or-class'
Copy def-or-class at point."]
["Copy expression" py-copy-expression
:help " `py-copy-expression'
Copy expression at point."]
["Copy except block" py-copy-except-block