Alain Leufroy avatar Alain Leufroy committed 1dd7cce

[emacs] rename python-mode + fancier colors

Comments (0)

Files changed (3)

   (require 'color-theme);;)
   (color-theme-initialize)
 
+;; color names see: http://en.wikipedia.org/wiki/X11_color_names
 (defun color-theme-dark-alain-laptop ()
   "My personal color theme based on `color-theme-dark-laptop' :D"
   (interactive)
     (color-theme-install
      '(color-theme-dark-alain-laptop
        ;; ((foreground-color . "color-194"))
-       ((foreground-color . "color-230"))
+       ((foreground-color . "lightyellow"))
 ;;       nil
        nil
-       (font-lock-string-face ((t (:foreground "color-246"))))
-       (font-lock-comment-face ((t (:foreground "color-238"))))
-       (font-lock-builtin-face ((t (:foreground "blue"))))
-       (font-lock-comment-face ((t (:foreground "blue"))))
-       (font-lock-doc-face ((t (:foreground "blue"))))
-       (font-lock-doc-string-face ((t (:foreground "blue"))))
-       (font-lock-emphasized-face ((t (:foreground ""))))
-       (font-lock-exit-face ((t (:foreground "blue"))))
-       (font-lock-function-name-face ((t (:foreground "color-76"))))
-       (font-lock-keyword-face ((t (:foreground "color-227"))))
-       (font-lock-other-emphasized-face ((t (:foreground ""))))
-       (font-lock-other-type-face ((t (:foreground ""))))
-       (font-lock-preprocessor-face ((t (:foreground ""))))
-       (font-lock-reference-facey ((t (:foreground ""))))
-       (font-lock-special-comment-face ((t (:foreground ""))))
-       (font-lock-special-keyword-face ((t (:foreground ""))))
-       (font-lock-type-face ((t (:foreground ""))))
-       (font-lock-variable-name-face ((t (:foreground ""))))
-       (font-lock-warning-face ((t (:foreground ""))))
-       (py-pseudo-keyword-face ((t (:foreground "color-87"))))
+       (font-lock-string-face ((t (:foreground "khaki"))))
+       (font-lock-comment-face ((t (:foreground "dimgray"))))
+       (font-lock-builtin-face ((t (:foreground "dodgerblue"))))
+;;       (font-lock-doc-face ((t (:foreground "blue"))))
+;;       (font-lock-doc-string-face ((t (:foreground "blue"))))
+       (font-lock-emphasized-face ((t (:foreground "red"))))
+;;       (font-lock-exit-face ((t (:foreground "blue"))))
+       (font-lock-function-name-face ((t (:foreground "lawngreen"))))
+       (font-lock-keyword-face ((t (:foreground "darkorange"))))
+;;       (font-lock-other-emphasized-face ((t (:foreground "red"))))
+;;       (font-lock-other-type-face ((t (:foreground "red"))))
+       (font-lock-preprocessor-face ((t (:foreground "tan"))))
+;;       (font-lock-reference-facey ((t (:foreground "red"))))
+       (font-lock-special-comment-face ((t (:foreground "wheat"))))
+       (font-lock-special-keyword-face ((t (:foreground "deepskyblue"))))
+;;       (font-lock-type-face ((t (:foreground "red"))))
+;;       (font-lock-variable-name-face ((t (:foreground "red"))))
+       (font-lock-warning-face ((t (:foreground "red"))))
+       (py-pseudo-keyword-face ((t (:foreground "steelblue"))))
        (py-XXX-tag-face ((t (:foreground "red" :background "yellow"))))
-       (py-decorators-face ((t (:foreground "color-171"))))
-       (py-builtins-face ((t (:foreground "color-154"))))
+       (py-decorators-face ((t (:foreground "deeppink"))))
+       (py-builtins-face ((t (:foreground "color-31"))))
        (py-class-name-face ((t (:foreground "color-82"))))
-       (py-exception-name-face ((t (:foreground "color-34"))))
-       (py-end-bloc-keyword-face ((t (:foreground "color-197"))))
+       (py-exception-name-face ((t (:foreground "color-28"))))
+       (py-end-bloc-keyword-face ((t (:foreground "color-48"))))
 ;;       (py-constant-face ((t (:foreground "white"))))
        (py-warning-face ((t (:background "red"))))
        ))))
 ;; Emacs will not automatically add new lines at the end of the buffer
 (setq-default next-line-add-newlines nil) 
 ;; change tab by spaces
+
 (setq indent-line-function 'insert-tab)
 (setq-default indent-tabs-mode nil)
 (setq-default c-basic-offset 4)
 (setq scroll-step 1)
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; MODES
-(autoload 'python-mode "python-mode.el" "Python mode." t)
+(autoload 'python-mode "my-python-mode.el" "Python mode." t)
 (setq auto-mode-alist (append '(("/*.\.py$" . python-mode)) auto-mode-alist))
 (when (load "flymake" t)
   (defun flymake-pylint-init ()

emacs.d/site-lisp/my-python-mode.el

+;; python-mode.el --- Major mode for editing Python programs
+
+;; Copyright (C) 1992,1993,1994  Tim Peters
+
+;; Author: 2003-2011 https://launchpad.net/python-mode
+;;         1995-2002 Barry A. Warsaw
+;;         1992-1994 Tim Peters
+;; Maintainer: python-mode@python.org
+;; Created:    Feb 1992
+;; Keywords:   python languages oop
+
+(defconst py-version "6.0.3"
+  "`python-mode' version number.")
+
+;; This file is part of python-mode.el.
+;;
+;; python-mode.el 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.
+;;
+;; python-mode.el is distributed in the hope that it will be useful, but
+;; WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+;; for more details.
+;;
+;; You should have received a copy of the GNU General Public License along
+;; with python-mode.el.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This is a major mode for editing Python programs.  It was developed by Tim
+;; Peters after an original idea by Michael A. Guravage.  Tim subsequently
+;; left the net and in 1995, Barry Warsaw inherited the mode.  Tim came back
+;; but disavowed all responsibility for the mode.  In fact, we suspect he
+;; doesn't even use Emacs any more <wink>.  In 2003, python-mode.el was moved
+;; to its own SourceForge project apart from the Python project, and in 2008
+;; it was moved to Launchpad for all project administration.  python-mode.el
+;; is maintained by the volunteers at the python-mode@python.org mailing
+;; list.
+
+;; python-mode.el is different than, and pre-dates by many years, the
+;; python.el that comes with FSF Emacs.  We'd like to merge the two modes but
+;; have few cycles to do so.  Volunteers are welcome.
+
+;; pdbtrack support contributed by Ken Manheimer, April 2001.  Skip Montanaro
+;; has also contributed significantly to python-mode's development.
+
+;; Author of ipython.el's stuff integrated here is Alexander Schmolck.
+
+;; Please use Launchpad to submit bugs or patches:
+;;
+;;     https://launchpad.net/python-mode
+
+;; INSTALLATION:
+
+;; To install, just drop this file into a directory on your load-path and
+;; byte-compile it.  To set up Emacs to automatically edit files ending in
+;; ".py" using python-mode, add to your emacs init file
+;;
+;; GNU Emacs: ~/.emacs, ~/.emacs.el, or ~/.emacs.d/init.el
+;;
+;; XEmacs: ~/.xemacs/init.el
+;;
+;; the following code:
+;;
+;;    (setq auto-mode-alist (cons '("\\.py$" . python-mode) auto-mode-alist))
+;;    (setq interpreter-mode-alist (cons '("python" . python-mode)
+;;                                       interpreter-mode-alist))
+;;    (autoload 'python-mode "python-mode" "Python editing mode." t)
+;;
+;; In XEmacs syntax highlighting should be enabled automatically.  In GNU
+;; Emacs you may have to add these lines to your init file:
+;;
+;;    (global-font-lock-mode t)
+;;    (setq font-lock-maximum-decoration t)
+
+;; BUG REPORTING:
+
+;; As mentioned above, please use the Launchpad python-mode project for
+;; submitting bug reports or patches.  The old recommendation, to use C-c C-b
+;; will still work, but those reports have a higher chance of getting buried
+;; in our inboxes.  Please include a complete, but concise code sample and a
+;; recipe for reproducing the bug.  Send suggestions and other comments to
+;; python-mode@python.org.
+
+;; When in a Python mode buffer, do a C-h m for more help.  It's doubtful that
+;; a texinfo manual would be very useful, but if you want to contribute one,
+;; we'll certainly accept it!
+
+;;; ToDo
+;; Question calls of `py-guess-indent-offset', as
+;; required indent may change throughout the buffer.
+;; Rather may it be called by argument
+
+;;; Code:
+
+(require 'comint)
+(require 'custom)
+(require 'compile)
+(require 'ansi-color)
+(require 'cc-cmds)
+(when (featurep 'xemacs)
+  (require 'highlight-indentation))
+
+(eval-when-compile (require 'cl))
+
+;; user definable variables
+;; vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
+
+(defgroup python nil
+  "Support for the Python programming language, <http://www.python.org/>"
+  :group 'languages
+  :prefix "py-")
+
+(defcustom py-install-directory nil
+  "Directory where python-mode.el and it's subdirectories should be installed. Needed for completion and other environment stuff only. "
+  :type 'string
+  :group 'python)
+
+(defcustom py-tab-always-indent t
+  "*Non-nil means TAB in Python mode should always reindent the current line,
+regardless of where in the line point is when the TAB command is used."
+  :type 'boolean
+  :group 'python)
+
+(defcustom py-close-provides-newline t
+  "If a newline is inserted, when line after block isn't empty. Default is non-nil. "
+  :type 'boolean
+  :group 'python)
+
+(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
+  :group 'python)
+
+(defcustom py-electric-comment-p t
+  "If \"#\" should call `py-electric-comment'. Default is `t'. "
+  :type 'boolean
+  :group 'python)
+
+(defcustom py-electric-comment-add-space-p t
+  "If py-electric-comment should add a space.  Default is `nil'. "
+  :type 'boolean
+  :group 'python)
+
+(defcustom py-electric-colon-active-p nil
+  "`py-electric-colon' feature.  Default is `nil'. See lp:837065 for discussions. "
+  :type 'boolean
+  :group 'python)
+
+(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
+  :group 'python)
+
+(defcustom py-closing-list-dedents-bos t
+  "If non-nil, closing parentesis dedents onto column of statement, otherwise keeps additional `py-indent-offset', default is nil "
+  :type 'boolean
+  :group 'python)
+
+;; Execute stuff start
+
+;; backward compatibility
+(defalias 'py-python-command 'py-shell-name)
+(defalias 'py-jpython-command 'py-shell-name)
+(defalias 'py-jython-command 'py-shell-name)
+(defalias 'py-default-interpreter 'py-shell-name)
+(defalias 'python-command 'py-shell-name)
+
+(defcustom py-encoding-string " # -*- coding: utf-8 -*-"
+  "Default string specifying encoding in the heading of file. "
+  :type 'string
+  :group 'python)
+
+(defcustom py-shebang-startstring "#! /bin/env"
+  "Detecting the shell in head of file. "
+  :type 'string
+  :group 'python)
+
+(defcustom py-shebang-regexp "#![ \t]?\\([^ \t\n]*[ \t]\\)?[^ \t\n]*\\([pj]ython[^ \t\n]*\\)"
+  "Detecting the shell in head of file. "
+  :type 'regexp
+  :group 'python)
+
+
+
+(defcustom py-python-command-args '("-i")
+  "*List of string arguments to be used when starting a Python shell."
+  :type '(repeat string)
+  :group 'python)
+(make-variable-buffer-local 'py-python-command-args)
+
+(set-default 'py-python-command-args  '("-i"))
+
+(make-obsolete-variable 'py-jpython-command-args 'py-jython-command-args nil)
+(defcustom py-jython-command-args '("-i")
+  "*List of string arguments to be used when starting a Jython shell."
+  :type '(repeat string)
+  :group 'python
+  :tag "Jython Command Args")
+
+(defcustom py-cleanup-temporary  nil
+ "If temporary buffers and files used by functions executing region  should be deleted afterwards. "
+
+:type 'boolean
+:group 'python
+)
+
+;; Execute stuff end
+;; Output stuff start
+(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
+  :group 'python)
+
+(defvar py-shell-alist
+  '(("jython" . 'jython)
+    ("python" . 'cpython))
+  "*Alist of interpreters and python shells. Used by `py-choose-shell'
+to select the appropriate python interpreter mode for a file.")
+
+(defcustom py-shell-input-prompt-1-regexp "^>>> "
+  "*A regular expression to match the input prompt of the shell."
+  :type 'string
+  :group 'python)
+
+(defcustom py-shell-input-prompt-2-regexp "^[.][.][.] "
+  "*A regular expression to match the input prompt of the shell after the
+  first line of input."
+  :type 'string
+  :group 'python)
+
+(defcustom py-shell-switch-buffers-on-execute t
+  "*Controls switching to the Python buffer where commands are
+  executed.  When non-nil the buffer switches to the Python buffer, if
+  not no switching occurs."
+  :type 'boolean
+  :group 'python)
+
+(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
+  :group 'python)
+(make-variable-buffer-local 'py-indent-offset)
+
+(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
+  :group 'python)
+(make-variable-buffer-local 'py-lhs-inbound-indent)
+
+(defcustom py-rhs-inbound-indent 1
+  "When inside a multiline-assignment: How many colums indent should be more than opening bracket, brace or parenthesis. "
+  :type 'integer
+  :group 'python)
+(make-variable-buffer-local 'py-rhs-inbound-indent)
+
+(defcustom py-continuation-offset 4
+  "*Additional amount of offset to give for some continuation lines.
+Continuation lines are those that immediately follow a backslash
+terminated line. "
+  :type 'integer
+  :group 'python)
+
+(defcustom py-kill-empty-line t
+  "If t, py-indent-forward-line kills empty lines. "
+  :type 'boolean
+  :group 'python)
+
+(defcustom py-smart-indentation t
+  "*Should `python-mode' try to automagically set some indentation variables?
+When this variable is non-nil, two things happen when a buffer is set
+to `python-mode':
+
+    1. `py-indent-offset' is guessed from existing code in the buffer.
+       Only guessed values between 2 and 8 are considered.  If a valid
+       guess can't be made (perhaps because you are visiting a new
+       file), then the value in `py-indent-offset' is used.
+
+    2. `indent-tabs-mode' is turned off if `py-indent-offset' does not
+       equal `tab-width' (`indent-tabs-mode' is never turned on by
+       Python mode).  This means that for newly written code, tabs are
+       only inserted in indentation if one tab is one indentation
+       level, otherwise only spaces are used.
+
+Note that both these settings occur *after* `python-mode-hook' is run,
+so if you want to defeat the automagic configuration, you must also
+set `py-smart-indentation' to nil in your `python-mode-hook'."
+  :type 'boolean
+  :group 'python)
+
+(defcustom py-align-multiline-strings-p t
+  "*Flag describing how multi-line triple quoted strings are aligned.
+When this flag is non-nil, continuation lines are lined up under the
+preceding line's indentation.  When this flag is nil, continuation
+lines are aligned to column zero."
+  :type '(choice (const :tag "Align under preceding line" t)
+                 (const :tag "Align to column zero" nil))
+  :group 'python)
+
+(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
+  :group 'python)
+
+(defcustom py-honor-comment-indentation t
+  "*Controls how comment lines influence subsequent indentation.
+
+When nil, all comment lines are skipped for indentation purposes, and
+if possible, a faster algorithm is used (i.e. X/Emacs 19 and beyond).
+
+When t, lines that begin with a single `#' are a hint to subsequent
+line indentation.  If the previous line is such a comment line (as
+opposed to one that starts with `py-block-comment-prefix'), then its
+indentation is used as a hint for this line's indentation.  Lines that
+begin with `py-block-comment-prefix' are ignored for indentation
+purposes.
+
+When not nil or t, comment lines that begin with a single `#' are used
+as indentation hints, unless the comment character is in column zero."
+  :type '(choice
+          (const :tag "Skip all comment lines (fast)" nil)
+          (const :tag "Single # `sets' indentation for next line" t)
+          (const :tag "Single # `sets' indentation except at column zero"
+                 other)
+          )
+  :group 'python)
+
+(defcustom 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)
+                    x))))
+    (or (funcall ok (getenv "TMPDIR"))
+        (funcall ok "/usr/tmp")
+        (funcall ok "/tmp")
+        (funcall ok "/var/tmp")
+        (funcall ok  ".")
+        (error
+         "Couldn't find a usable temp directory -- set `py-temp-directory'")))
+  "*Directory used for temporary files created by a *Python* process.
+By default, 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."
+  :type 'string
+  :group 'python)
+
+(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
+  :group 'python)
+
+(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
+  :group 'python)
+
+(defcustom py-backspace-function 'backward-delete-char-untabify
+  "*Function called by `py-electric-backspace' when deleting backwards."
+  :type 'function
+  :group 'python)
+
+(defcustom py-delete-function 'delete-char
+  "*Function called by `py-electric-delete' when deleting forwards."
+  :type 'function
+  :group 'python)
+
+(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
+  :group 'python)
+(make-variable-buffer-local 'py-pdbtrack-do-tracking-p)
+
+(defcustom py-pdbtrack-minor-mode-string " PDB"
+  "*String to use in the minor mode list when pdbtrack is enabled."
+  :type 'string
+  :group 'python)
+
+(defcustom py-import-check-point-max
+  20000
+  "Maximum number of characters to search for a Java-ish import statement.
+When `python-mode' tries to calculate the shell to use (either a
+CPython or a Jython shell), it looks at the so-called `shebang' line
+-- i.e. #! line.  If that's not available, it looks at some of the
+file heading imports to see if they look Java-like."
+  :type 'integer
+  :group 'python
+  )
+
+(make-obsolete-variable 'py-jpython-packages 'py-jython-packages nil)
+(defcustom py-jython-packages
+  '("java" "javax")
+  "Imported packages that imply `jython-mode'."
+  :type '(repeat string)
+  :group 'python)
+
+(defcustom py-current-defun-show  t
+ "If `py-current-defun' should jump to the definition, highlight it while waiting PY-WHICH-FUNC-DELAY seconds, before returning to previous position.
+
+Default is `t'."
+
+:type 'boolean
+:group 'python)
+
+(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
+:group 'python)
+
+(defcustom py-send-receive-delay  5
+ "Seconds to wait for output, used by `python-send-receive'. "
+
+:type 'number
+:group 'python)
+
+;; Not customizable
+(defvar py-exec-command nil
+  "Mode commands will set this. ")
+(make-variable-buffer-local 'py-exec-command)
+
+(defcustom py-master-file nil
+  "If non-nil, \\[py-execute-buffer] executes the named
+master file instead of the buffer's file.  If the file name has a
+relative path, the value of variable `default-directory' for the
+buffer is prepended to come up with a file name.
+
+Beside you may set this variable in the file's local
+variable section, e.g.:
+
+    # Local Variables:
+    # py-master-file: \"master.py\"
+    # End:
+
+"
+  :type 'string
+  :group 'python)
+(make-variable-buffer-local 'py-master-file)
+
+(defcustom py-pychecker-command "pychecker"
+  "*Shell command used to run Pychecker."
+  :type 'string
+  :group 'python
+  :tag "Pychecker Command")
+
+(defcustom py-pychecker-command-args '("--stdlib")
+  "*List of string arguments to be passed to pychecker."
+  :type '(repeat string)
+  :group 'python
+  :tag "Pychecker Command Args")
+
+(defcustom py-hide-show-keywords
+  '(
+    "class"    "def"    "elif"    "else"    "except"
+    "for"      "if"     "while"   "finally" "try"
+    "with"
+    )
+  "*Keywords that can be hidden by hide-show"
+  :type '(repeat string)
+  :group 'python)
+
+(defcustom py-hide-show-hide-docstrings t
+  "*Controls if doc strings can be hidden by hide-show"
+  :type 'boolean
+  :group 'python)
+
+(defcustom py-mark-decorators nil
+  "If py-mark-def-or-class functions should mark decorators too. Default is `nil'. "
+  :type 'boolean
+  :group 'python)
+
+
+;; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+;; NO USER DEFINABLE VARIABLES BEYOND THIS POINT
+(defvar py-expression-skip-regexp "^ =:#\t\r\n\f"
+  "py-expression assumes chars indicated possible composing a py-expression, skip it. ")
+;; (setq py-expression-skip-regexp "^ =:#\t\r\n\f")
+
+(defvar py-expression-looking-regexp "[^ =:#\t\r\n\f)]"
+  "py-expression assumes chars indicated possible composing a py-expression, when looking-at or -back. ")
+;; (setq py-expression-looking-regexp "[^ =:#\t\r\n\f)]")
+
+(defvar py-not-expression-regexp "[ .=:#\t\r\n\f)]"
+  "py-expression assumes chars indicated probably will not compose a py-expression. ")
+;; (setq py-not-expression-regexp "[ .=:#\t\r\n\f)]")
+
+(defvar py-minor-expression-skip-regexp "^ .()[]{}=:#\t\r\n\f"
+  "py-minor-expression assumes chars indicated possible composing a py-minor-expression, skip it. ")
+;; (setq py-minor-expression-skip-regexp "^ .(){}=:#\t\r\n\f")
+
+(defvar py-minor-expression-forward-regexp "^ .)}=:#\t\r\n\f"
+  "py-minor-expression assumes chars indicated possible composing a py-minor-expression, skip it. ")
+
+(defvar py-minor-expression-backward-regexp "^ .({=:#\t\r\n\f"
+  "py-minor-expression assumes chars indicated possible composing a py-minor-expression, skip it. ")
+
+(defvar py-not-minor-expression-skip-regexp " \\.=:#\t\r\n\f"
+  "py-minor-expression assumes chars indicated may not compose a py-minor-expression, skip it. ")
+
+(defvar py-minor-expression-looking-regexp "[^ .=:#\t\r\n\f)]"
+  "py-minor-expression assumes chars indicated possible composing a py-minor-expression, when looking-at or -back. ")
+;; (setq py-minor-expression-looking-regexp "[^ .=:#\t\r\n\f)]")
+
+(defvar py-not-minor-expression-regexp "[ .=:#\t\r\n\f)]"
+  "py-minor-expression assumes chars indicated probably will not compose a py-minor-expression. ")
+;; (setq py-not-minor-expression-regexp "[ .=:#\t\r\n\f)]")
+
+(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.")
+
+;; Skip's XE workaround
+(unless (functionp 'string-to-syntax)
+    (defun string-to-syntax (s)
+      (cond
+       ((equal s "|") '(15))
+       ((equal s "_") '(3))
+       (t (error "Unhandled string: %s" s))))
+  )
+
+;; GNU's syntax-ppss-context
+(unless (functionp 'syntax-ppss-context)
+ (defsubst syntax-ppss-context (ppss)
+  (cond
+   ((nth 3 ppss) 'string)
+   ((nth 4 ppss) 'comment)
+   (t nil))))
+
+(defvar empty-line-p-chars "^[ \t\r\f]*$"
+  "Empty-line-p-chars.")
+
+(defun empty-line-p (&optional iact)
+  "Returns t if cursor is at an empty line, nil otherwise."
+  (interactive "p")
+  (save-excursion
+    (let ((erg (progn
+                 (beginning-of-line)
+                 (looking-at empty-line-p-chars))))
+      (when iact
+        (message "%s" erg))
+      erg)))
+
+(defconst py-font-lock-syntactic-keywords
+  '(("[^\\]\\\\\\(?:\\\\\\\\\\)*\\(\\s\"\\)\\1\\(\\1\\)"
+     (2
+      (7)))
+    ("\\([RUBrub]?\\)[Rr]?\\(\\s\"\\)\\2\\(\\2\\)"
+     (1
+      (python-quote-syntax 1))
+     (2
+      (python-quote-syntax 2))
+     (3
+      (python-quote-syntax 3)))))
+
+(defun python-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
+  (save-excursion
+    (goto-char (match-beginning 0))
+    (cond
+     ;; Consider property for the last char if in a fenced string.
+     ((= n 3)
+      (let* ((font-lock-syntactic-keywords nil)
+             (syntax (if (featurep 'xemacs)
+                         (parse-partial-sexp (point-min) (point))
+                       (syntax-ppss))))
+        (when (eq t (nth 3 syntax))     ; after unclosed fence
+          (goto-char (nth 8 syntax))    ; fence position
+          (skip-chars-forward "uUrRbB") ; 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)
+               (= (match-beginning 1) (match-end 1))) ; prefix is null
+          (and (= n 1)                  ; prefix
+               (/= (match-beginning 1) (match-end 1)))) ; non-empty
+      (let ((font-lock-syntactic-keywords nil))
+        (unless (eq 'string (syntax-ppss-context (if (featurep 'xemacs)
+                                                     (parse-partial-sexp (point-min) (point))
+                                                   (syntax-ppss))))
+          ;; (eval-when-compile (string-to-syntax "|"))
+          (eval-when-compile (string-to-syntax "|")))))
+     ;; Otherwise (we're in a non-matching string) the property is
+     ;; nil, which is OK.
+     )))
+(defvar py-mode-syntax-table nil)
+(setq py-mode-syntax-table
+      (let ((table (make-syntax-table))
+            (tablelookup (if (featurep 'xemacs)
+                             'get-char-table
+                           'aref)))
+        ;; Give punctuation syntax to ASCII that normally has symbol
+        ;; syntax or has word syntax and isn't a letter.
+        (if (featurep 'xemacs)
+            (setq table (standard-syntax-table))
+          (let ((symbol (string-to-syntax "_"))
+                ;; (symbol (string-to-syntax "_"))
+                (sst (standard-syntax-table)))
+            (dotimes (i 128)
+              (unless (= i ?_)
+                (if (equal symbol (funcall tablelookup 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)
+        (modify-syntax-entry ?\_ "w" table)
+        table))
+
+(defconst python-space-backslash-table
+  (let ((table (copy-syntax-table py-mode-syntax-table)))
+    (modify-syntax-entry ?\\ " " table)
+    table)
+  "`python-mode-syntax-table' with backslash given whitespace syntax.")
+
+(defface py-variable-name-face
+  '((t (:inherit default)))
+  ;; '((t (:inherit 'font-lock-variable-name-face)))
+  "Face method decorators."
+  :group 'python)
+(defvar py-variable-name-face 'py-variable-name-face)
+
+;; ;; Face for None, True, False, self, and Ellipsis
+(defface py-pseudo-keyword-face
+  '((t (:inherit font-lock-keyword-face)))
+  "Face for pseudo keywords in Python mode, like self, True, False, Ellipsis."
+  :group 'python)
+(defvar py-pseudo-keyword-face 'py-pseudo-keyword-face)
+
+(defface py-XXX-tag-face
+  '((t (:inherit font-lock-string-face)))
+  "XXX\\|TODO\\|FIXME "
+  :group 'python)
+(defvar py-XXX-tag-face 'py-XXX-tag-face)
+
+;; PEP 318 decorators
+(defface py-decorators-face
+  '((t (:inherit font-lock-keyword-face)))
+  "Face method decorators."
+  :group 'python)
+(defvar py-decorators-face 'py-decorators-face)
+
+;; Face for builtins
+(defface py-builtins-face
+  '((t (:inherit font-lock-builtin-face)))
+  "Face for builtins like TypeError, object, open, and exec."
+  :group 'python)
+(defvar py-builtins-face 'py-builtins-face)
+
+(defface py-class-name-face
+  '((t (:inherit font-lock-type-face)))
+  "Face for builtins like TypeError, object, open, and exec."
+  :group 'python)
+(defvar py-class-name-face 'py-class-name-face)
+
+;; XXX, TODO, and FIXME comments and such
+(defface py-exception-name-face
+  '((t (:inherit font-lock-builtin-face)))
+  "."
+  :group 'python)
+(defvar py-exception-name-face 'py-exception-name-face)
+
+(defface py-end-bloc-keyword-face
+  '((t (:inherit font-lock-keyword-face)))
+  "."
+  :group 'python)
+(defvar py-end-bloc-keyword-face 'py-end-bloc-keyword-face)
+
+(defface py-constant-face
+  '((t (:inherit font-lock-constant-face)))
+  "."
+  :group 'python)
+(defvar py-constant-face 'py-constant-face)
+
+(defface py-warning-face
+  '((t (:inherit font-lock-warning-face)))
+  "."
+  :group 'python)
+(defvar py-warning-face 'py-warning-face)
+
+(defvar py-font-lock-keywords
+  (let ((kw1 (mapconcat 'identity
+                        '("and"      "assert"               "class"
+                                     "def"      "del"       "elif"
+                          "else"     "except"   "for"       "from"
+                          "global"   "if"       "import"    "in"
+                          "is"       "lambda"   "not"       "or"
+                                                "as"
+                          "while"    "with"
+                          )
+                        "\\|"))
+        (kw2 (mapconcat 'identity
+                        '("else:" "except:" "finally:" "try:" "lambda:")
+                        "\\|"))
+        (kw3 (mapconcat 'identity
+                        ;; Don't include Ellipsis in this list, since it is already defined as a pseudo keyword.
+                        '("_" "__debug__" "__doc__" "__import__" "__name__" "__package__"
+                          "abs" "all" "any" "apply"
+                          "basestring" "bin" "bool" "buffer" "bytearray"
+                          "callable" "chr" "classmethod" "cmp" "coerce"
+                          "compile" "complex" "copyright" "credits"
+                          "delattr" "dict" "dir" "divmod" "enumerate" "eval"
+                          "exec" "execfile" "exit" "file" "filter" "float"
+                          "format" "getattr" "globals" "hasattr" "hash" "help"
+                          "hex" "id" "input" "int" "intern" "isinstance"
+                          "issubclass" "iter" "len" "license" "list" "locals"
+                          "long" "map" "max" "memoryview" "min" "next"
+                          "object" "oct" "open" "ord" "pow" "property"
+                          "quit" "range" "raw_input" "reduce" "reload" "repr"
+                          "round" "set" "setattr" "slice" "sorted"
+                          "staticmethod" "str" "sum" "super" "tuple" "type"
+                          "unichr" "unicode" "vars" "xrange" "zip"
+
+                          "bin" "bytearray" "bytes" "format"
+
+                          "memoryview" "next")
+                        "\\|"))
+        (kw4 (mapconcat 'identity
+                        ;; Exceptions and warnings
+                        '("ArithmeticError" "AssertionError"
+                          "AttributeError" "BaseException" "BufferError"
+                          "BytesWarning" "DeprecationWarning" "EOFError"
+                          "EnvironmentError" "Exception"
+                          "FloatingPointError" "FutureWarning" "GeneratorExit"
+                          "IOError" "ImportError" "ImportWarning"
+                          "IndentationError" "IndexError"
+                          "KeyError" "KeyboardInterrupt" "LookupError"
+                          "MemoryError" "NameError" "NotImplemented"
+                          "NotImplementedError" "OSError" "OverflowError"
+                          "PendingDeprecationWarning" "ReferenceError"
+                          "RuntimeError" "RuntimeWarning" "StandardError"
+                          "StopIteration" "SyntaxError" "SyntaxWarning"
+                          "SystemError" "SystemExit" "TabError" "TypeError"
+                          "UnboundLocalError" "UnicodeDecodeError"
+                          "UnicodeEncodeError" "UnicodeError"
+                          "UnicodeTranslateError" "UnicodeWarning"
+                          "UserWarning" "ValueError" "Warning"
+                          "ZeroDivisionError" "WindowsError")
+                        "\\|"))
+        )
+    (list
+     ;; decorators
+     '("^[ \t]*\\(@[a-zA-Z_][a-zA-Z_0-9.]+\\)\\((.+)\\)?" 1 'py-decorators-face)
+     ;; keywords
+     (cons (concat "\\<\\(" kw1 "\\)\\>[ \n\t(]") 1)
+     ;; builtins when they don't appear as object attributes
+     (list (concat "\\([^. \t]\\|^\\)[ \t]*\\<\\(" kw3 "\\)\\>[ \n\t(]") 2
+           'py-builtins-face)
+     ;; block introducing keywords with immediately following colons.
+     ;; Yes "except" is in both lists.
+     (cons (concat "\\<\\(" kw2 "\\)[ \n\t(]") 1)
+     ;; Exceptions
+     (list (concat "\\<\\(" kw4 "\\)[ \n\t:,()]") 1 'py-exception-name-face)
+     ;; raise stmts
+     '("\\<raise[ \t]+\\([a-zA-Z_]+[a-zA-Z0-9_.]*\\)" 1 py-exception-name-face)
+     ;; except clauses
+     '("\\<except[ \t]+\\([a-zA-Z_]+[a-zA-Z0-9_.]*\\)" 1 py-exception-name-face)
+     ;; classes
+     '("\\<class[ \t]+\\([a-zA-Z_]+[a-zA-Z0-9_]*\\)" 1 py-class-name-face)
+     ;; functions
+     '("\\<def[ \t]+\\([a-zA-Z_]+[a-zA-Z0-9_]*\\)"
+       1 font-lock-function-name-face)
+     ;; pseudo-keywords
+     '("\\<\\(self\\|cls\\|Ellipsis\\|True\\|False\\|None\\)\\>"
+       1 py-pseudo-keyword-face)
+     '("[ \t]*\\(_\\{0,2\\}[a-zA-Z][a-zA-Z_0-9.]+_\\{0,2\\}\\) *\\(+\\|-\\|*\\|**\\|/\\|//\\|&\\|%\\||\\|^\\|>>\\|<<\\)? ?=[^=\n]"
+       1 py-variable-name-face)
+     ;; XXX, TODO, and FIXME tags
+     '("XXX\\|TODO\\|FIXME" 0 py-XXX-tag-face t)
+     '("\\(return\\|raise\\|break\\|continue\\|pass\\|yield\\)" 0 py-end-bloc-keyword-face)
+     '("[\n \\(]\\([A-Z_]*\\)[, \n]" 1 py-constant-face)
+     '("[\n ]\\(print\\)[\n \t]" 1 py-warning-face)
+     ;; special marking for string escapes and percent substitutes;
+     ;; loops adapted from lisp-mode in font-lock.el
+     ;; '((lambda (bound)
+     ;;     (catch 'found
+     ;;       (while (re-search-forward
+     ;;               (concat
+     ;;                "\\(\\\\\\\\\\|\\\\x..\\|\\\\u....\\|\\\\U........\\|"
+     ;;                "\\\\[0-9][0-9]*\\|\\\\[abfnrtv\"']\\)") bound t)
+     ;;         (let ((face (get-text-property (1- (point)) 'face)))
+     ;;           (when (or (and (listp face) (memq 'font-lock-string-face face))
+     ;;                     (eq 'font-lock-string-face face))
+     ;;             (throw 'found t))))))
+     ;;   (1 'font-lock-regexp-grouping-backslash prepend))
+     ;; '((lambda (bound)
+     ;;     (catch 'found
+     ;;       (while (re-search-forward "\\(%[^(]\\|%([^)]*).\\)" bound t)
+     ;;         (let ((face (get-text-property (1- (point)) 'face)))
+     ;;           (when (or (and (listp face) (memq 'font-lock-string-face face))
+     ;;                     (eq 'font-lock-string-face face))
+     ;;             (throw 'found t))))))
+     ;;   (1 'font-lock-regexp-grouping-construct prepend))
+     ))
+  "Additional expressions to highlight in Python mode.")
+
+;; have to bind py-file-queue before installing the kill-emacs-hook
+(defvar py-file-queue nil
+  "Queue of Python temp files awaiting execution.
+Currently-active file is at the head of the list.")
+
+(defvar py-pdbtrack-is-tracking-p nil)
+
+(defvar py-pychecker-history nil)
+
+
+;; Constants
+(defconst py-assignment-re "\\<\\w+\\>[ \t]*\\(=\\|+=\\|*=\\|%=\\|&=\\|^=\\|<<=\\|-=\\|/=\\|**=\\||=\\|>>=\\|//=\\)"
+  "If looking at the beginning of an assignment. ")
+
+(defconst py-block-re "[ \t]*\\<\\(class\\|def\\|for\\|if\\|try\\|while\\|with\\)\\>"
+  "Matches the beginning of a class, method or compound statement. ")
+
+(defconst py-return-re
+  ".*:?[ \t]*\\<\\(return\\)\\>"
+  "Regular expression matching keyword which typically closes a function. ")
+
+(defconst py-closing-re
+  "[ \t]*\\_<)\\_>"
+  "Regular expression matching keyword which typically closes a function. ")
+
+(defconst py-class-re "[ \t]*\\<\\(class\\)\\>"
+  "Matches the beginning of a class definition. ")
+
+(defconst py-def-or-class-re "[ \t]*\\<\\(def\\|class\\)\\>"
+  "Matches the beginning of a class- or functions definition. ")
+
+(defconst py-def-re "[ \t]*\\<\\(def\\)\\>"
+  "Matches the beginning of a functions definition. ")
+
+(defconst py-if-clause-re "[ \t]*\\<\\elif\\>"
+  "Matches the beginning of a compound statement's clause. ")
+
+(defconst py-try-clause-re
+  (concat "\\(" (mapconcat 'identity
+                           '("except\\(\\s +.*\\)?:"
+                             "finally:")
+                           "\\|")
+          "\\)")
+  "Matches the beginning of a try-statement's clause. ")
+
+(defconst py-if-block-re "[ \t]*\\<if\\>"
+  "Matches the beginning of a compound statement saying `if'. ")
+
+(defconst py-try-block-re "[ \t]*\\<try\\>"
+  "Matches the beginning of a compound statement saying `try'. " )
+
+(defconst py-stringlit-re
+  (concat
+   ;; These fail if backslash-quote ends the string (not worth
+   ;; fixing?).  They precede the short versions so that the first two
+   ;; quotes don't look like an empty short string.
+   ;;
+   ;; (maybe raw), long single quoted triple quoted strings (SQTQ),
+   ;; with potential embedded single quotes
+   "[rRuUbB]?'''[^']*\\(\\('[^']\\|''[^']\\)[^']*\\)*'''"
+   "\\|"
+   ;; (maybe raw), long double quoted triple quoted strings (DQTQ),
+   ;; with potential embedded double quotes
+   "[rRuUbB]?\"\"\"[^\"]*\\(\\(\"[^\"]\\|\"\"[^\"]\\)[^\"]*\\)*\"\"\""
+   "\\|"
+   "[rRuUbB]?'\\([^'\n\\]\\|\\\\.\\)*'"     ; single-quoted
+   "\\|"                                    ; or
+   "[rRuUbB]?\"\\([^\"\n\\]\\|\\\\.\\)*\""  ; double-quoted
+   )
+  "Regular expression matching a Python string literal.")
+
+(defconst py-continued-re
+  ;; This is tricky because a trailing backslash does not mean
+  ;; continuation if it's in a comment
+  (concat
+   "\\(" "[^#'\"\n\\]" "\\|" py-stringlit-re "\\)*"
+   "\\\\$")
+  "Regular expression matching Python backslash continuation lines.")
+
+(defconst py-blank-or-comment-re "[ \t]*\\($\\|#\\)"
+  "Regular expression matching a blank or comment line.")
+
+(defconst py-block-or-clause-re "[ \t]*\\<\\(if\\|else\\|elif\\|while\\|for\\|def\\|class\\|try\\|except\\|finally\\|with\\)\\>"
+  "Matches the beginning of a compound statement or it's clause. ")
+
+(defconst py-clause-re "[ \t]*\\<\\(else\\|except\\|finally\\|elif\\)\\>"
+  "Matches the beginning of a compound statement's clause. ")
+
+(defconst py-block-closing-keywords-re
+  "\\(return\\|raise\\|break\\|continue\\|pass\\)"
+  "Regular expression matching keywords which typically close a block.")
+
+(defconst py-no-outdent-re "\\(try:\\|except\\(\\s +.*\\)?:\\|while\\s +.*:\\|for\\s +.*:\\|if\\s +.*:\\|elif\\s +.*:\\)\\([ 	]*\\<\\(return\\|raise\\|break\\|continue\\|pass\\)\\>[ 	\n]\\)")
+
+;; (defconst py-no-outdent-re
+;;   (concat
+;;    "\\("
+;;    (mapconcat 'identity
+;;               (list "try:"
+;;                     "except\\(\\s +.*\\)?:"
+;;                     "while\\s +.*:"
+;;                     "for\\s +.*:"
+;;                     "if\\s +.*:"
+;;                     "elif\\s +.*:"
+;;                     (concat py-block-closing-keywords-re "[ \t\n]")
+;;                     )
+;;               "\\|")
+;;           "\\)")
+;;   "Regular expression matching lines not to dedent after.")
+
+(defconst py-traceback-line-re
+  "[ \t]+File \"\\([^\"]+\\)\", line \\([0-9]+\\)"
+  "Regular expression that describes tracebacks.")
+
+;; pdbtrack constants
+(defconst py-pdbtrack-stack-entry-regexp
+;  "^> \\([^(]+\\)(\\([0-9]+\\))\\([?a-zA-Z0-9_]+\\)()"
+  "^> \\(.*\\)(\\([0-9]+\\))\\([?a-zA-Z0-9_<>]+\\)()"
+  "Regular expression pdbtrack uses to find a stack trace entry.")
+
+;; pydb-328837.diff
+;; (defconst py-pdbtrack-stack-entry-regexp
+;;   "^(\\([-a-zA-Z0-9_/.]*\\):\\([0-9]+\\)):[ \t]?\\(.*\n\\)"
+;;   "Regular expression pdbtrack uses to find a stack trace entry for pydb.
+;;
+;; The debugger outputs program-location lines that look like this:
+;;    (/usr/bin/zonetab2pot.py:15): makePOT")
+
+(defconst py-pdbtrack-marker-regexp-file-group 1
+  "Group position in gud-pydb-marker-regexp that matches the file name.")
+
+(defconst py-pdbtrack-marker-regexp-line-group 2
+  "Group position in gud-pydb-marker-regexp that matches the line number.")
+
+(defconst py-pdbtrack-marker-regexp-funcname-group 3
+  "Group position in gud-pydb-marker-regexp that matches the function name.")
+
+(defconst py-pdbtrack-input-prompt "\n[(<]*[Pp]y?db[>)]+ "
+  "Regular expression pdbtrack uses to recognize a pdb prompt.")
+
+(defconst py-pydbtrack-stack-entry-regexp
+  "^(\\([-a-zA-Z0-9_/.]*\\):\\([0-9]+\\)):[ \t]?\\(.*\n\\)"
+  "Regular expression pdbtrack uses to find a stack trace entry for pydb.
+
+The debugger outputs program-location lines that look like this:
+   (/usr/bin/zonetab2pot.py:15): makePOT")
+
+(defconst py-pdbtrack-track-range 10000
+  "Max number of characters from end of buffer to search for stack entry.")
+
+
+;; Major mode boilerplate
+
+;; define a mode-specific abbrev table for those who use such things
+(defvar python-mode-abbrev-table nil
+  "Abbrev table in use in `python-mode' buffers.")
+(define-abbrev-table 'python-mode-abbrev-table nil)
+
+(defvar py-mode-abbrev-table nil
+  "Abbrev table in use in `python-mode' buffers.")
+(define-abbrev-table 'py-mode-abbrev-table nil)
+
+(defvar inferior-python-mode-abbrev-table nil
+  "Abbrev table in use in `python-mode' buffers.")
+(define-abbrev-table 'inferior-python-mode-abbrev-table nil)
+
+(defvar jython-mode-abbrev-table nil
+  "Abbrev table in use in `python-mode' buffers.")
+(define-abbrev-table 'jython-mode-abbrev-table nil)
+
+(defcustom python-mode-hook nil
+  "Hook run when entering Python mode."
+  :group 'python
+  :type 'hook)
+
+(custom-add-option 'python-mode-hook 'py-imenu-create-index-new)
+(custom-add-option 'python-mode-hook
+		   (lambda ()
+		     "Turn off Indent Tabs mode."
+		     (setq indent-tabs-mode nil)))
+(custom-add-option 'python-mode-hook 'turn-on-eldoc-mode)
+(custom-add-option 'python-mode-hook 'abbrev-mode)
+;; (custom-add-option 'python-mode-hook 'python-setup-brm)
+
+(make-obsolete-variable 'jpython-mode-hook 'jython-mode-hook nil)
+(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'.")
+
+;; In previous version of python-mode.el, the hook was incorrectly
+;; called py-mode-hook, and was not defvar'd.  Deprecate its use.
+(and (fboundp 'make-obsolete-variable)
+     (make-obsolete-variable 'py-mode-hook 'python-mode-hook nil))
+
+;; Menu definitions, only relevent if you have the easymenu.el package
+;; (standard in the latest Emacs 19 and XEmacs 19 distributions).
+(defvar py-menu nil
+  "Menu for Python Mode.
+This menu will get created automatically if you have the `easymenu'
+package.  Note that the latest X/Emacs releases contain this package.")
+
+(defvar py-mode-map
+  (let ((map (make-sparse-keymap)))
+    ;; electric keys
+    (define-key map [(:)] 'py-electric-colon)
+    (define-key map [(\#)] 'py-electric-comment)
+    (define-key map [(delete)] 'py-electric-delete)
+    (define-key map [(backspace)] 'py-electric-backspace)
+    (define-key map [(control backspace)] 'py-hungry-delete-backwards)
+    ;; moving point
+    (define-key map [(control c)(control n)] 'py-end-of-statement)
+    (define-key map [(control c)(control a)] 'py-mark-statement)
+    (define-key map [(control c)(control p)] 'py-beginning-of-statement)
+    (define-key map [(control c)(control u)] 'py-beginning-of-block)
+    (define-key map [(control c)(control q)] 'py-end-of-block)
+    (define-key map [(control c) (delete)] 'py-hungry-delete-forward)
+    (define-key map [(control meta e)] 'py-end-of-def-or-class)
+    (define-key map [(control j)] 'py-newline-and-indent)
+    (define-key map (kbd "RET") 'py-newline-and-indent)
+    (define-key map [(super backspace)] 'py-dedent-forward-line)
+    ;; (define-key map [(control return)] 'py-newline-and-dedent)
+    ;; indentation level modifiers
+    (define-key map [(control c)(\/)] 'py-indent-line-outmost)
+    (define-key map [(control c)(control l)] 'py-shift-left)
+    (define-key map [(control c)(control r)] 'py-shift-right)
+    (define-key map [(control c)(<)] 'py-shift-left)
+    (define-key map [(control c)(>)] 'py-shift-right)
+    (define-key map [(control c)(tab)] 'py-indent-region)
+    (define-key map [(control c)(:)] 'py-guess-indent-offset)
+    ;; subprocess commands
+    (define-key map [(control c)(control c)] 'py-execute-buffer)
+    (define-key map [(control c)(control m)] 'py-execute-import-or-reload)
+    (define-key map [(control c)(control s)] 'py-execute-string)
+    (define-key map [(control c)(|)] 'py-execute-region)
+    (define-key map [(control meta x)] 'py-execute-def-or-class)
+    (define-key map [(control c)(!)] 'py-shell)
+    (define-key map [(control c)(control t)] 'py-toggle-shells)
+    (define-key map [(control meta h)] 'py-mark-def-or-class)
+    (define-key map [(control c)(control k)] 'py-mark-block-or-clause)
+    ;; Miscellaneous
+    (define-key map [(control c)(control d)] 'py-pdbtrack-toggle-stack-tracking)
+    (define-key map [(control c)(control f)] 'py-sort-imports)
+    (define-key map [(control c)(\#)] 'py-comment-region)
+    (define-key map [(control c)(\?)] 'py-describe-mode)
+    (define-key map [(control c)(control e)] 'py-describe-symbol)
+    (define-key map [(control meta a)] 'py-beginning-of-def-or-class)
+    (define-key map [(control c)(-)] 'py-up-exception)
+    (define-key map [(control c)(=)] 'py-down-exception)
+    (define-key map [(control x) (n) (d)] 'py-narrow-to-defun)
+    ;; information
+    (define-key map [(control c)(control b)] 'py-submit-bug-report)
+    (define-key map [(control c)(control v)] 'py-version)
+    (define-key map [(control c)(control w)] 'py-pychecker-run)
+    (define-key map [(control c)(c)] 'py-compute-indentation)
+    ;; shadow global bindings for newline-and-indent
+    (mapc #'(lambda (key)
+              (define-key map key 'py-newline-and-indent))
+          (where-is-internal 'newline-and-indent))
+    (easy-menu-define py-menu map "Python Mode menu"
+      '("Python"
+        :help "Python-specific features"
+        ["Execute statement" py-execute-statement
+         :help "Send statement at point to Python interpreter. "]
+        ["Execute block" py-execute-block
+         :help "Send compound statement at point to Python interpreter. "]
+        ["Execute def" py-execute-def
+         :help "Send function at point to Python interpreter. "]
+        ["Execute region" py-execute-region
+         :help "Send region to Python interpreter. "]
+        ["Execute buffer" py-execute-buffer
+         :help "Send buffer to Python interpreter. "]
+        "-"
+        ["Copy block" py-copy-block
+         :help "Copy innermost compound statement at point"]
+        ["Copy def-or-class" py-copy-def-or-class
+         :help "Copy innermost definition at point"]
+        ["Copy statement" py-copy-statement
+         :help "Copy statement at point"]
+        ["Copy expression" py-copy-expression
+         :help "Copy expression at point"]
+        ["Copy partial-expression" py-copy-partial-expression
+         :help "\".\" operators delimit a partial-expression expression on it's level"]
+        "-"
+        ["Beginning of block" py-beginning-of-block
+         :help "Go to start of innermost compound statement at point"]
+        ["End of block" py-end-of-block
+         :help "Go to end of innermost compound statement at point"]
+        ["Beginning of Def-or-Class" py-beginning-of-def-or-class
+         :help "Go to start of innermost definition at point"]
+        ["End of Def-or-Class" py-end-of-def-or-class
+         :help "Go to end of innermost function definition at point"]
+        ["Beginning of-class" beginning-of-class
+         :help "Go to start of class definition "]
+        ["End of Class" py-end-of-class
+         :help "Go to end of class definition "]
+        "-"
+        ("Templates..."
+         :help "Expand templates for compound statements"
+         :filter (lambda (&rest junk)
+                   (abbrev-table-menu python-mode-abbrev-table)))
+        "-"
+        ["Switch to interpreter" py-shell
+         :help "Switch to `inferior' Python in separate buffer"]
+        ["Import/reload file" py-execute-import-or-reload
+         :help "Load into inferior Python session"]
+        ["Set default process" py-set-proc
+         :help "Make buffer's inferior process the default"
+         :active (buffer-live-p py-buffer)]
+        ["pychecker-run" py-pychecker-run :help "Run pychecker"]
+        ["Debugger" pdb :help "Run pdb under GUD"]
+        "-"
+        ["Help on symbol" py-describe-symbol
+         :help "Use pydoc on symbol at point"]
+        ["Complete symbol" completion-at-point
+         :help "Complete (qualified) symbol before point"]
+        ["Find function" py-find-function
+         :help "Try to find source definition of function at point"]
+        ["Update imports" py-find-imports
+         :help "Update list of top-level imports for completion"]))
+    map))
+
+(defvar py-mode-output-map nil
+  "Keymap used in *Python Output* buffers.")
+(if py-mode-output-map
+    nil
+  (setq py-mode-output-map (make-sparse-keymap))
+  (define-key py-mode-output-map [button2]  'py-mouseto-exception)
+  (define-key py-mode-output-map "\C-c\C-c" 'py-goto-exception)
+  ;; TBD: Disable all self-inserting keys.  This is bogus, we should
+  ;; really implement this as *Python Output* buffer being read-only
+  (mapc #' (lambda (key)
+             (define-key py-mode-output-map key
+               #'(lambda () (interactive) (beep))))
+           (where-is-internal 'self-insert-command))
+  )
+
+(defvar py-shell-map nil
+  "Keymap used in *Python* shell buffers.")
+(if py-shell-map
+    nil
+  (setq py-shell-map (copy-keymap comint-mode-map))
+  (define-key py-shell-map [tab]   'tab-to-tab-stop)
+  (define-key py-shell-map "\C-c-" 'py-up-exception)
+  (define-key py-shell-map "\C-c=" 'py-down-exception)
+  )
+
+;; An auxiliary syntax table which places underscore and dot in the
+;; symbol class for simplicity
+(defvar py-dotted-expression-syntax-table nil
+  "Syntax table used to identify Python dotted expressions.")
+(when (not py-dotted-expression-syntax-table)
+  (setq py-dotted-expression-syntax-table
+        (copy-syntax-table py-mode-syntax-table))
+  (modify-syntax-entry ?_ "_" py-dotted-expression-syntax-table)
+  (modify-syntax-entry ?. "_" py-dotted-expression-syntax-table))
+
+(defvar py-help-mode-syntax-table
+  (let ((st (make-syntax-table py-mode-syntax-table)))
+    ;; Don't get confused by apostrophes in the process's output (e.g. if
+    ;; you execute "help(os)").
+    (modify-syntax-entry ?\' "." st)
+    ;; Maybe we should do the same for double quotes?
+    (modify-syntax-entry ?\" "." st)
+    st))
+
+;; credits to python.el
+(defun py-beg-of-defun-function ()
+  (set (make-local-variable 'beginning-of-defun-function)
+       'py-beginning-of-def-or-class))
+
+(defun py-end-of-defun-function ()
+  (set (make-local-variable 'end-of-defun-function) 'py-end-of-def-or-class))
+
+
+;; Utilities
+(defsubst py-keep-region-active ()
+  "Keep the region active in XEmacs."
+  ;; Ignore byte-compiler warnings you might see.  Also note that
+  ;; FSF's Emacs does it differently; its policy doesn't require us
+  ;; to take explicit action.
+  (and (boundp 'zmacs-region-stays)
+       (setq zmacs-region-stays t)))
+
+(defsubst py-point (position)
+  "Returns the value of point at certain commonly referenced POSITIONs.
+POSITION can be one of the following symbols:
+
+  bol  -- beginning of line
+  eol  -- end of line
+  bod  -- beginning of def or class
+  eod  -- end of def or class
+  bob  -- beginning of buffer
+  eob  -- end of buffer
+  boi  -- back to indentation
+  bos  -- beginning of statement
+
+This function does not modify point or mark."
+  (let ((orig (point)))
+    (cond
+     ((eq position 'bol) (beginning-of-line))
+     ((eq position 'eol) (end-of-line))
+     ((eq position 'bod) (py-beginning-of-def-or-class 'either))
+     ((eq position 'eod) (py-end-of-def-or-class 'either))
+     ;; Kind of funny, I know, but useful for py-up-exception.
+     ((eq position 'bob) (goto-char (point-min)))
+     ((eq position 'eob) (goto-char (point-max)))
+     ((eq position 'boi) (back-to-indentation))
+     ((eq position 'bos) (py-goto-initial-line))
+     (t (error "Unknown buffer position requested: %s" position))
+     )
+    (prog1
+        (point)
+      (goto-char orig))))
+
+(defun py-in-literal (&optional lim)
+  "Return non-nil if point is in a Python literal (a comment or string).
+Optional argument LIM indicates the beginning of the containing form,
+i.e. the limit on how far back to scan."
+  (let* ((lim (or lim (point-min)))
+         (state (if (featurep 'xemacs)
+                    (parse-partial-sexp lim (point))
+                  (syntax-ppss))))
+    (cond
+     ((nth 3 state) 'string)
+     ((nth 4 state) 'comment))))
+
+(defsubst py-in-string-or-comment-p ()
+  "Return beginning position if point is in a Python literal (a comment or string)."
+  (nth 8 (if (featurep 'xemacs)
+             (parse-partial-sexp (point-min) (point))
+           (syntax-ppss))))
+
+(defcustom py-shell-name "python"
+  "A default value `py-shell' may look for, if no shell is specified by command. "
+  :type 'string
+  :group 'python)
+(make-variable-buffer-local 'py-shell-name)
+
+
+;;;; Imenu.
+(defvar py-imenu-class-regexp
+  (concat                               ; <<classes>>
+   "\\("                                ;
+   "^[ \t]*"                            ; newline and maybe whitespace
+   "\\(class[ \t]+[a-zA-Z0-9_]+\\)"     ; class name
+                                        ; possibly multiple superclasses
+   "\\([ \t]*\\((\\([a-zA-Z0-9_,. \t\n]\\)*)\\)?\\)"
+   "[ \t]*:"                            ; and the final :
+   "\\)"                                ; >>classes<<
+   )
+  "Regexp for Python classes for use with the Imenu package."
+  )
+
+(defvar py-imenu-method-regexp
+  (concat                               ; <<methods and functions>>
+   "\\("                                ;
+   "^[ \t]*"                            ; new line and maybe whitespace
+   "\\(def[ \t]+"                       ; function definitions start with def
+   "\\([a-zA-Z0-9_]+\\)"                ;   name is here
+                                        ;   function arguments...
+   ;;   "[ \t]*(\\([-+/a-zA-Z0-9_=,\* \t\n.()\"'#]*\\))"
+   "[ \t]*(\\([^:#]*\\))"
+   "\\)"                                ; end of def
+   "[ \t]*:"                            ; and then the :
+   "\\)"                                ; >>methods and functions<<
+   )
+  "Regexp for Python methods/functions for use with the Imenu package."
+  )
+
+(defvar py-imenu-method-no-arg-parens '(2 8)
+  "Indices into groups of the Python regexp for use with Imenu.
+
+Using these values will result in smaller Imenu lists, as arguments to
+functions are not listed.
+
+See the variable `py-imenu-show-method-args-p' for more
+information.")
+
+(defvar py-imenu-method-arg-parens '(2 7)
+  "Indices into groups of the Python regexp for use with imenu.
+Using these values will result in large Imenu lists, as arguments to
+functions are listed.
+
+See the variable `py-imenu-show-method-args-p' for more
+information.")
+
+;; Note that in this format, this variable can still be used with the
+;; imenu--generic-function. Otherwise, there is no real reason to have
+;; it.
+(defvar py-imenu-generic-expression
+  (cons
+   (concat
+    py-imenu-class-regexp
+    "\\|"                               ; or...
+    py-imenu-method-regexp
+    )
+   py-imenu-method-no-arg-parens)
+  "Generic Python expression which may be used directly with Imenu.
+Used by setting the variable `imenu-generic-expression' to this value.
+Also, see the function \\[py-imenu-create-index-new] for a better
+alternative for finding the index.")
+
+;; These next two variables are used when searching for the Python
+;; class/definitions. Just saving some time in accessing the
+;; generic-python-expression, really.
+(defvar py-imenu-generic-regexp nil)
+(defvar py-imenu-generic-parens nil)
+
+(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
+  :group 'python)
+
+(defun py-switch-imenu-index-function ()
+  "For development only. Good old renamed `py-imenu-create-index'-function hangs with medium size files already. Working `py-imenu-create-index-new' is active by default.
+
+Switch between classic index machine `py-imenu-create-index' and new `py-imenu-create-index-new'.
+
+The former may provide a more detailed report, thus maintaining two different index-machines is considered. "
+  (interactive)
+  (if (eq major-mode 'python-mode)
+      (progn
+        (if (eq imenu-create-index-function 'py-imenu-create-index-new)
+            (setq imenu-create-index-function #'py-imenu-create-index)
+          (setq imenu-create-index-function #'py-imenu-create-index-new))
+        (when (interactive-p) (message "imenu-create-index-function: %s" (prin1-to-string imenu-create-index-function))))
+    (error "%s" "Only available in buffers set to python-mode")))
+
+(defun py-imenu-create-index ()
+  "Python interface function for the Imenu package.
+Finds all Python classes and functions/methods. Calls function
+\\[py-imenu-create-index-engine].  See that function for the details
+of how this works."
+  (setq py-imenu-generic-regexp (car py-imenu-generic-expression)
+        py-imenu-generic-parens (if py-imenu-show-method-args-p
+                                    py-imenu-method-arg-parens
+                                  py-imenu-method-no-arg-parens))
+  (goto-char (point-min))
+  ;; Warning: When the buffer has no classes or functions, this will
+  ;; return nil, which seems proper according to the Imenu API, but
+  ;; causes an error in the XEmacs port of Imenu.  Sigh.
+  (py-imenu-create-index-engine nil))
+
+(defun py-imenu-create-index-engine (&optional start-indent)
+  "Function for finding Imenu definitions in Python.
+
+Finds all definitions (classes, methods, or functions) in a Python
+file for the Imenu package.
+
+Returns a possibly nested alist of the form
+
+        (INDEX-NAME . INDEX-POSITION)
+
+The second element of the alist may be an alist, producing a nested
+list as in
+
+        (INDEX-NAME . INDEX-ALIST)
+
+This function should not be called directly, as it calls itself
+recursively and requires some setup.  Rather this is the engine for
+the function \\[py-imenu-create-index-function].
+
+It works recursively by looking for all definitions at the current
+indention level.  When it finds one, it adds it to the alist.  If it
+finds a definition at a greater indentation level, it removes the
+previous definition from the alist. In its place it adds all
+definitions found at the next indentation level.  When it finds a
+definition that is less indented then the current level, it returns
+the alist it has created thus far.
+
+The optional argument START-INDENT indicates the starting indentation
+at which to continue looking for Python classes, methods, or
+functions.  If this is not supplied, the function uses the indentation
+of the first definition found."
+  (let (index-alist
+        sub-method-alist
+        looking-p
+        def-name prev-name
+        cur-indent def-pos
+        (class-paren (first py-imenu-generic-parens))
+        (def-paren (second py-imenu-generic-parens)))
+    (setq looking-p
+          (re-search-forward py-imenu-generic-regexp (point-max) t))
+    (while looking-p
+      (save-excursion
+        ;; used to set def-name to this value but generic-extract-name
+        ;; is new to imenu-1.14. this way it still works with
+        ;; imenu-1.11
+        ;;(imenu--generic-extract-name py-imenu-generic-parens))
+        (let ((cur-paren (if (match-beginning class-paren)
+                             class-paren def-paren)))
+          (setq def-name
+                (buffer-substring-no-properties (match-beginning cur-paren)
+                                                (match-end cur-paren))))
+        (save-match-data
+          (py-beginning-of-def-or-class))
+        (beginning-of-line)
+        (setq cur-indent (current-indentation)))
+      ;; HACK: want to go to the next correct definition location.  We
+      ;; explicitly list them here but it would be better to have them
+      ;; in a list.
+      (setq def-pos
+            (or (match-beginning class-paren)
+                (match-beginning def-paren)))
+      ;; if we don't have a starting indent level, take this one
+      (or start-indent
+          (setq start-indent cur-indent))
+      ;; if we don't have class name yet, take this one
+      (or prev-name
+          (setq prev-name def-name))
+      ;; what level is the next definition on?  must be same, deeper
+      ;; or shallower indentation
+      (cond
+       ;; Skip code in comments and strings
+       ((py-in-literal))
+       ;; at the same indent level, add it to the list...
+       ((= start-indent cur-indent)
+        (push (cons def-name def-pos) index-alist))
+       ;; deeper indented expression, recurse
+       ((< start-indent cur-indent)
+        ;; the point is currently on the expression we're supposed to
+        ;; start on, so go back to the last expression. The recursive
+        ;; call will find this place again and add it to the correct
+        ;; list
+        (re-search-backward py-imenu-generic-regexp (point-min) 'move)
+        (setq sub-method-alist (py-imenu-create-index-engine cur-indent))
+        (if sub-method-alist
+            ;; we put the last element on the index-alist on the start
+            ;; of the submethod alist so the user can still get to it.
+            (let ((save-elmt (pop index-alist)))
+              (push (cons prev-name
+                          (cons save-elmt sub-method-alist))
+                    index-alist))))
+       ;; found less indented expression, we're done.
+       (t
+        (setq looking-p nil)
+        (re-search-backward py-imenu-generic-regexp (point-min) t)))
+      ;; end-cond
+      (setq prev-name def-name)
+      (and looking-p
+           (setq looking-p
+                 (re-search-forward py-imenu-generic-regexp
+                                    (point-max) 'move))))
+    (nreverse index-alist)))
+
+(defun py-imenu-create-index-new (&optional beg end)
+  "`imenu-create-index-function' for Python. "
+  (let ((orig (point))
+        (beg (cond (beg)
+                   ((region-active-p)
+                    (region-beginning))
+                   (t (point-min))))
+        (end (cond (end)
+                   ((region-active-p)
+                    (region-end))
+                   (t (point-max))))
+        (first t)
+        inside-class index-alist sublist vars)
+    (goto-char beg)
+    (while (re-search-forward "^[ \t]*\\(?:\\(def\\|class\\)\\)[ \t]+\\(?:\\(\\sw+\\)\\)" end 'move 1)
+      (unless (py-in-string-or-comment-p)
+        (let ((pos (match-beginning 0))
+              (name (match-string-no-properties 2)))
+          (when (string= "class" (match-string-no-properties 1))
+            (setq name (concat "class " name)
+                  inside-class t))
+          (cond ((and first inside-class)
+                 (push (cons name pos) index-alist)
+                 (setq first nil))
+                (inside-class
+                 (progn (push (cons (concat " " name) pos) sublist)
+                        (push (cons name sublist) index-alist)))
+                (t (push (cons name pos) index-alist))))))
+    ;;    (message "Funktionen und Klassen: %s" index-alist)
+    ;; Look for module variables.
+    (goto-char (point-min))
+    (while (re-search-forward "^\\(?:\\sw+\\)[ \t]*=" end t)
+      (unless (py-in-string-or-comment-p)
+        (push (cons (match-string 1) (match-beginning 1))
+              vars)))
+    (setq index-alist (nreverse index-alist))
+    (when vars
+      (push (cons "Module variables"
+                  (nreverse vars))
+            index-alist))
+    (goto-char orig)
+    index-alist))
+
+
+(defun py-choose-shell-by-shebang ()
+  "Choose shell by looking at #! on the first line.
+Returns the specified Python resp. Jython shell command name. "
+  (interactive)
+  ;; look for an interpreter specified in the first line
+  ;; similar to set-auto-mode (files.el)
+  (let ((interpreter (save-excursion
+                       (goto-char (point-min))
+                       (when (looking-at py-shebang-regexp)
+                            (setq erg (match-string-no-properties 0))
+                            (substring erg (string-match "[ijp]+ython" erg))))))
+    (when (interactive-p) (message "%s" interpreter))
+    interpreter))
+
+(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)
+    (save-excursion
+      (goto-char (point-min))
+      (while (and (not mode)
+                  (search-forward-regexp
+                   "^\\(\\(from\\)\\|\\(import\\)\\) \\([^ \t\n.]+\\)"
+                   py-import-check-point-max t))
+        (setq mode (and (member (match-string 4) py-jython-packages)
+                        'jython
+                        ))))
+    mode))
+
+(defalias 'py-which-shell 'py-choose-shell)
+(defun py-choose-shell (&optional arg)
+  "Looks for an appropriate mode function.
+This does the following:
+ - reads py-shell-name
+ - look for an interpreter with `py-choose-shell-by-shebang'
+ - examine imports using `py-choose-shell-by-import'
+ - default to the variable `py-shell-name'
+
+With \\[universal-argument]) user is prompted to specify a reachable Python version."
+  (interactive "P")
+  (let ((erg (cond ((eq 4 (prefix-numeric-value arg))
+                    (read-from-minibuffer "Python Shell: " py-shell-name))
+                   ((py-choose-shell-by-shebang))
+                   ((py-choose-shell-by-import))
+                   (t py-shell-name))))
+    (when (interactive-p) (message "%s" erg))
+    (setq py-shell-name erg)
+    erg))
+
+(defun py-python-default-environment ()
+  "Returns path of Python default installation. "
+  (interactive)
+  (let* ((cmd (py-choose-shell))
+         (denv (shell-command-to-string (concat "type " cmd)))
+         (erg (substring denv (string-match "/" denv))))
+    (when (interactive-p)
+      (if erg
+          (message "%s" erg)
+        (message "%s" "Could not detect Python on your system")))
+    erg))
+
+(defun py-insert-default-shebang ()
+  "Insert in buffer shebang of installed default Python. "
+  (interactive "*")
+  (let* ((erg (py-python-default-environment))
+         (sheb (concat "#! " erg)))
+    (insert sheb)))
+
+(defun py-set-load-path ()
+  "Include the python-mode directory inclusiv needed subdirs.
+
+If `py-install-directory' isn't set, guess from buffer-file-name. "
+  (interactive)
+  (cond ((ignore-errors py-install-directory)
+         (add-to-list 'load-path (expand-file-name py-install-directory))
+         (add-to-list 'load-path (concat (expand-file-name py-install-directory) "/completion"))
+         (add-to-list 'load-path (concat py-install-directory "/pymacs"))
+         (add-to-list 'load-path (concat (expand-file-name py-install-directory) "/test"))
+         (add-to-list 'load-path (concat (expand-file-name py-install-directory) "/tools")))
+        ((string-match "/test$" default-directory)
+         (add-to-list 'load-path (concat (expand-file-name "../") "completion"))
+         (add-to-list 'load-path (concat (expand-file-name "../") "pymacs"))
+         (add-to-list 'load-path (concat (expand-file-name "../") "test"))
+         (add-to-list 'load-path (concat (expand-file-name "../") "tools")))
+        (t
+         (add-to-list 'load-path (file-name-directory buffer-file-name))
+         (add-to-list 'load-path (concat (file-name-directory buffer-file-name) "completion"))
+         (add-to-list 'load-path (concat (file-name-directory buffer-file-name) "pymacs"))
+         (add-to-list 'load-path (concat (file-name-directory buffer-file-name) "test"))
+         (add-to-list 'load-path (concat (file-name-directory buffer-file-name) "tools"))))
+  (when (interactive-p) (message "%s" load-path)))
+
+(define-derived-mode python2-mode python-mode "Python2"
+  "Edit and run code used by Python version 2 series. "
+  :group 'Python
+  :abbrev nil
+  (set (make-local-variable 'py-exec-command) '(format "execfile(r'%s') # PYTHON-MODE\n" filename))
+  (py-toggle-shells "python2"))
+
+(define-derived-mode python3-mode python-mode "Python3"
+  "Edit and run code used by Python version 3 series. "
+  :group 'Python
+  :abbrev nil
+  (set (make-local-variable 'py-exec-command) '(format "exec(compile(open('%s').read(), '%s', 'exec')) # PYTHON-MODE\n" file file))
+  (py-toggle-shells "python3"))
+
+(defun python-mode ()
+  "Major mode for editing Python files.
+To submit a problem report, enter `\\[py-submit-bug-report]' from a
+`python-mode' buffer.  Do `\\[py-describe-mode]' for detailed
+documentation.  To see what version of `python-mode' you are running,
+enter `\\[py-version]'.
+
+This mode knows about Python indentation, tokens, comments and
+continuation lines.  Paragraphs are separated by blank lines only.
+
+COMMANDS
+\\{py-mode-map}
+VARIABLES
+
+py-indent-offset\t\tindentation increment
+py-block-comment-prefix\t\tcomment string used by `comment-region'
+py-shell-name\t\tshell command to invoke Python interpreter
+py-temp-directory\t\tdirectory used for temp files (if needed)
+py-beep-if-tab-change\t\tring the bell if `tab-width' is changed"
+  (interactive)
+  ;; (unload-python-el)
+  ;; set up local variables
+  (kill-all-local-variables)
+  (make-local-variable 'paragraph-separate)
+  (make-local-variable 'paragraph-start)
+  (make-local-variable 'require-final-newline)
+  (make-local-variable 'comment-start)
+  (make-local-variable 'comment-end)
+  (make-local-variable 'comment-start-skip)
+  (make-local-variable 'comment-column)
+  (make-local-variable 'comment-indent-function)
+  (make-local-variable 'indent-region-function)
+  (make-local-variable 'indent-line-function)
+  (make-local-variable 'add-log-current-defun-function)
+  (make-local-variable 'fill-paragraph-function)
+  ;;
+  (set-syntax-table py-mode-syntax-table)
+  ;; from python.el, version "22.1"
+  (set (make-local-variable 'font-lock-defaults)
+       '(py-font-lock-keywords nil nil nil nil
+                               (font-lock-syntactic-keywords
+                                . py-font-lock-syntactic-keywords)))
+  (setq major-mode 'python-mode
+        mode-name "Python"
+        local-abbrev-table python-mode-abbrev-table
+        paragraph-separate "^[ \t]*$"
+        paragraph-start "^[ \t]*$"
+        require-final-newline t
+        comment-start "#"
+        comment-end ""
+        comment-start-skip "^[ \t]*#+ *"
+        comment-column 40
+        comment-indent-function 'py-comment-indent-function
+        indent-region-function 'py-indent-region
+        indent-line-function 'py-indent-line
+        ;; tell add-log.el how to find the current function/method/variable
+        add-log-current-defun-function 'py-current-defun
+
+        fill-paragraph-function 'py-fill-paragraph)
+  (use-local-map py-mode-map)
+  ;; add the menu
+  (if py-menu
+      (easy-menu-add py-menu))
+  ;; Emacs 19 requires this
+  (if (boundp 'comment-multi-line)
+      (setq comment-multi-line nil))
+  ;; Install Imenu if available
+  (when (ignore-errors (require 'imenu))
+    (setq imenu-create-index-function #'py-imenu-create-index-new)
+    ;;    (setq imenu-create-index-function #'py-imenu-create-index)
+    (setq imenu-generic-expression py-imenu-generic-expression)
+    (when (fboundp 'imenu-add-to-menubar)
+      (imenu-add-to-menubar (format "%s-%s" "IM" mode-name))
+      (remove-hook 'imenu-add-menubar-index 'python-mode-hook)))
+  ;; Add support for HideShow
+  (add-to-list 'hs-special-modes-alist
+               (list
+                'python-mode
+                ;; start regex
+                (concat (if py-hide-show-hide-docstrings
+                            "^\\s-*\"\"\"\\|" "")
+                        (mapconcat 'identity
+                                   (mapcar #'(lambda (x) (concat "^\\s-*" x "\\>"))
+                                           py-hide-show-keywords)
+                                   "\\|"))
+                ;; end regex
+                nil
+                ;; comment-start regex
+                "#"
+                ;; forward-sexp function
+                (lambda (arg)
+                  (py-goto-beyond-block)
+                  (skip-chars-backward " \t\n"))
+                nil))
+  (add-hook 'python-mode-hook 'py-beg-of-defun-function)
+  (add-hook 'python-mode-hook 'py-end-of-defun-function)
+  ;;  (add-hook 'python-mode-hook 'py-versions-mode)
+  ;; Run the mode hook.  Note that py-mode-hook is deprecated.
+  (if python-mode-hook
+      (run-hooks 'python-mode-hook)
+    (run-hooks 'py-mode-hook))
+  ;; Now do the automagical guessing
+  (if py-smart-indentation
+      (let ((offset py-indent-offset))
+        ;; Nil if this fails to guess a good value
+        (if (and (ignore-errors (py-guess-indent-offset))
+                 (<= py-indent-offset 8)
+                 (>= py-indent-offset 2))
+            (setq offset py-indent-offset))
+        (setq py-indent-offset offset)
+        ;; Only turn indent-tabs-mode off if tab-width !=
+        ;; py-indent-offset.  Never turn it on, because the user must
+        ;; have explicitly turned it off.
+        (if (/= tab-width py-indent-offset)
+            (setq indent-tabs-mode nil))))
+  ;; Set the default shell if not already set
+  (when (null py-shell-name)
+    (py-toggle-shells (py-choose-shell)))
+  (when (interactive-p) (message "python-mode loaded from: %s" "python-mode.el")))
+
+(make-obsolete 'jpython-mode 'jython-mode nil)
+(defun jython-mode ()
+  "Major mode for editing Jython/Jython files.
+This is a simple wrapper around `python-mode'.
+It runs `jython-mode-hook' then calls `python-mode.'
+It is added to `interpreter-mode-alist' and `py-choose-shell'.
+"
+  (interactive)
+  (python-mode)
+  (py-toggle-shells "jython")
+  (when jython-mode-hook
+      (run-hooks 'jython-mode-hook)))
+
+;; It's handy to add recognition of Python files to the
+;; interpreter-mode-alist and to auto-mode-alist.  With the former, we
+;; can specify different `derived-modes' based on the #! line, but
+;; with the latter, we can't.  So we just won't add them if they're
+;; already added.
+
+(let ((modes '(("jython" . jython-mode)
+               ("python" . python-mode)
+               ("python3" . python-mode)
+               )))
+  (while modes
+    (when (not (assoc (car modes) interpreter-mode-alist))
+      (push (car modes) interpreter-mode-alist))
+    (setq modes (cdr modes))))
+
+(when (not (or (rassq 'python-mode auto-mode-alist)
+               (rassq 'jython-mode auto-mode-alist)))
+  (push '("\\.py$" . python-mode) auto-mode-alist))
+
+;; electric characters
+(defun py-outdent-p ()
+  "Returns non-nil if the current line should dedent one level."
+  (save-excursion
+    (and (progn (back-to-indentation)
+                (looking-at py-clause-re))
+         ;; short circuit infloop on illegal construct
+         (not (bobp))
+         (progn (forward-line -1)
+                (py-goto-initial-line)
+                (back-to-indentation)
+                (when (looking-at py-blank-or-comment-re)
+                  (backward-to-indentation 1))
+                (not (looking-at py-no-outdent-re))))))
+
+(defun py-electric-comment (arg)
+  "Insert a comment. If starting a comment, indent accordingly.
+If a numeric
+argument ARG is provided, that many colons are inserted
+non-electrically.
+With universal-prefix-key C-u a \"#\"
+Electric behavior is inhibited inside a string or
+comment."
+  (interactive "*P")
+  (if py-electric-comment-p
+      (if (ignore-errors (eq 4 (car-safe arg)))
+          (insert "#")
+        (when (and (eq last-command 'py-electric-comment) (looking-back " "))
+          (forward-char -1))
+        (if (interactive-p) (self-insert-command (prefix-numeric-value arg))
+          (insert "#"))
+        (let ((orig (copy-marker (point)))
+                    (indent (py-compute-indentation)))
+          (unless (or (eq (current-indentation) indent)(looking-back "#[ \t]*"))
+                (goto-char orig)
+                  (beginning-of-line)
+                  (delete-horizontal-space)
+            (indent-to indent)
+            (goto-char orig))
+                  (when py-electric-comment-add-space-p
+            (unless (looking-at "[ \t]")
+              (insert " "))))
+        (setq last-command this-command))
+    (self-insert-command (prefix-numeric-value arg))))
+
+(defun py-electric-colon (arg)
+  "If `py-electric-colon-active-p' is non-nil only:
+Insert a colon and indent accordingly.
+If a numeric argument ARG is provided, that many colons are inserted
+non-electrically.
+
+Electric behavior is inhibited inside a string or
+comment or by universal prefix C-u."
+  (interactive "*P")
+  (cond ((not py-electric-colon-active-p)
+         (self-insert-command (prefix-numeric-value arg)))
+        ((eq 4 (prefix-numeric-value arg))
+         (self-insert-command 1))
+        (t (self-insert-command (prefix-numeric-value arg))
+           (unless (py-in-string-or-comment-p)
+             (let ((orig (copy-marker (point)))
+                   (indent (py-compute-indentation)))
+               (unless (eq (current-indentation) indent)
+                 (beginning-of-line)
+                 (delete-horizontal-space)
+                 (indent-to indent))
+               (goto-char orig))))))
+
+(defun py-insert-super ()
+  "Insert a function \"super()\" from current environment.
+As example given in Python v3.1 documentation » The Python Standard Library »
+
+class C(B):
+    def method(self, arg):
+        super().method(arg) # This does the same thing as:
+                               # super(C, self).method(arg)"
+  (interactive "*")
+  (let* ((orig (point))
+         (funcname (progn
+                 (py-beginning-of-def)
+                 (when (looking-at (concat py-def-re " *\\([^(]+\\) *(\\(?:[^),]*\\),? *\\([^)]*\\))"))
+                   (match-string-no-properties 2))))
+         (args (match-string-no-properties 3))
+         (erg (py-which-python))
+         classname)
+    (if (< erg 3)
+        (progn
+          (py-beginning-of-class)
+          (when (looking-at (concat py-class-re " *\\([^( ]+\\)"))
+            (setq classname (match-string-no-properties 2)))
+          (goto-char orig)
+          ;; super(C, self).method(arg)"
+          (insert (concat "super(" classname ", self)." funcname "(" args ")")))
+      (goto-char orig)
+      (insert (concat "super()." funcname "(" args ")")))))
+
+(defun py-execute-file (proc filename &optional cmd)
+  "Send to Python interpreter process PROC, in Python version 2.. \"execfile('FILENAME')\".
+Make that process's buffer visible and force display.  Also make
+comint believe the user typed this string so that
+`kill-output-from-shell' does The Right Thing."
+  (let ((curbuf (current-buffer))
+        (procbuf (process-buffer proc))
+                                        ;       (comint-scroll-to-bottom-on-output t)
+        (msg (format "## executing temporary file %s...\n" filename))
+        (cmd (cond (cmd)
+                   (py-exec-command)
+                   (t (py-which-execute-file-command filename)))))
+    (unwind-protect
+        (save-excursion
+          (set-buffer procbuf)
+          (goto-char (point-max))
+          (move-marker (process-mark proc) (point))
+          (funcall (process-filter proc) proc msg))
+      (set-buffer curbuf))
+    (process-send-string proc cmd)))
+
+
+;; Python subprocess utilities and filters
+(defvar py-exception-buffer nil)
+
+(defun py-comint-output-filter-function (string)
+  "Watch output for Python prompt and exec next file waiting in queue.
+This function is appropriate for `comint-output-filter-functions'."
+  ;;remove ansi terminal escape sequences from string, not sure why they are
+  ;;still around...
+  (setq string (ansi-color-filter-apply string))
+  (when (and (string-match py-shell-input-prompt-1-regexp string)
+                   py-file-queue)
+    (if py-shell-switch-buffers-on-execute
+      (pop-to-buffer (current-buffer)))
+    (ignore-errors (delete-file (car py-file-queue)))
+    (setq py-file-queue (cdr py-file-queue))
+    (if py-file-queue
+        (let ((pyproc (get-buffer-process (current-buffer))))
+          (py-execute-file pyproc (car py-file-queue))))
+    ))
+
+(defun py-pdbtrack-overlay-arrow (activation)
+  "Activate or de arrow at beginning-of-line in current buffer."
+  ;; This was derived/simplified from edebug-overlay-arrow
+  (cond (activation
+         (setq overlay-arrow-position (make-marker))
+         (setq overlay-arrow-string "=>")
+         (set-marker overlay-arrow-position (py-point 'bol) (current-buffer))
+         (setq py-pdbtrack-is-tracking-p t))
+        (overlay-arrow-position
+         (setq overlay-arrow-position nil)
+         (setq py-pdbtrack-is-tracking-p nil))
+        ))
+
+(defun py-pdbtrack-track-stack-file (text)
+  "Show the file indicated by the pdb stack entry line, in a separate window.
+
+Activity is disabled if the buffer-local variable
+`py-pdbtrack-do-tracking-p' is nil.
+
+We depend on the pdb input prompt matching `py-pdbtrack-input-prompt'
+at the beginning of the line.
+
+If the traceback target file path is invalid, we look for the most
+recently visited python-mode buffer which either has the name of the
+current function \(or class) or which defines the function \(or
+class).  This is to provide for remote scripts, eg, Zope's 'Script
+\(Python)' - put a _copy_ of the script in a buffer named for the
+script, and set to python-mode, and pdbtrack will find it.)"
+  ;; Instead of trying to piece things together from partial text
+  ;; (which can be almost useless depending on Emacs version), we
+  ;; monitor to the point where we have the next pdb prompt, and then
+  ;; check all text from comint-last-input-end to process-mark.
+  ;;
+  ;; Also, we're very conservative about clearing the overlay arrow,
+  ;; to minimize residue.  This means, for instance, that executing
+  ;; other pdb commands wipe out the highlight.  You can always do a
+  ;; 'where' (aka 'w') command to reveal the overlay arrow.
+  (let* ((origbuf (current-buffer))
+         (currproc (get-buffer-process origbuf)))
+
+    (if (not (and currproc py-pdbtrack-do-tracking-p))
+        (py-pdbtrack-overlay-arrow nil)
+
+      (let* ((procmark (process-mark currproc))
+             (block (buffer-substring (max comint-last-input-end
+                                           (- procmark
+                                              py-pdbtrack-track-range))
+                                      procmark))
+             target target_fname target_lineno target_buffer)
+
+        (if (not (string-match (concat py-pdbtrack-input-prompt "$") block))
+            (py-pdbtrack-overlay-arrow nil)
+
+          (setq target (py-pdbtrack-get-source-buffer block))
+
+          (if (stringp target)
+              (message "pdbtrack: %s" target)
+
+            (setq target_lineno (car target))
+            (setq target_buffer (cadr target))
+            (setq target_fname (buffer-file-name target_buffer))
+            (switch-to-buffer-other-window target_buffer)
+            (goto-char (point-min))
+            (forward-line target_lineno)
+            (message "pdbtrack: line %s, file %s" target_lineno target_fname)
+            (py-pdbtrack-overlay-arrow t)
+            (pop-to-buffer origbuf t)
+
+            )))))
+  )
+
+(defun py-pdbtrack-get-source-buffer (block)
+  "Return line number and buffer of code indicated by block's traceback text.
+
+We look first to visit the file indicated in the trace.
+
+Failing that, we look for the most recently visited python-mode buffer
+with the same name or having the named function.
+
+If we're unable find the source code we return a string describing the
+problem as best as we can determine."
+
+  (if (and (not (string-match py-pdbtrack-stack-entry-regexp block))
+	   (not (string-match py-pydbtrack-stack-entry-regexp block)))
+      "Traceback cue not found"
+    (let* ((filename (match-string
+		      py-pdbtrack-marker-regexp-file-group block))
+           (lineno (string-to-number (match-string
+				   py-pdbtrack-marker-regexp-line-group
+				   block)))
+           (funcname (match-string py-pdbtrack-marker-regexp-funcname-group
+				   block))
+           funcbuffer)