   "*Controls echoing of arguments of functions & methods in the imenu buffer.
 When non-nil, arguments are printed.")
 
-
--
-;; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-;; NO USER DEFINABLE VARIABLES BEYOND THIS POINT
-
 (make-variable-buffer-local 'py-indent-offset)
-
-;; Differentiate between Emacs 18, Lucid Emacs, and Emacs 19.  This
-;; seems to be the standard way of checking this.
-;; BAW - This is *not* the right solution.  When at all possible,
-;; instead of testing for the version of Emacs, use feature tests.
-
-(setq py-this-is-lucid-emacs-p (string-match "Lucid\\|XEmacs" emacs-version))
-(setq py-this-is-emacs-19-p
-      (and
-       (not py-this-is-lucid-emacs-p)
-       (string-match "^19\\." emacs-version)))
 
 ;; 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-delete-function 'backward-delete-char-untabify
+  "*Function called by `py-delete-char' when deleting characters.")
+
+(defvar py-backspace-function 'backward-delete-char-untabify
+  "*Function called by `py-backspace-command' when deleting characters.")
+
++
+;; Constants
+
+;; Regexp matching a Python string literal
+(defconst py-stringlit-re
+  (concat
+   "'\\([^'\n\\]\\|\\\\.\\)*'"		; single-quoted
+   "\\|"				; or
+   "\"\\([^\"\n\\]\\|\\\\.\\)*\""))	; double-quoted
+
+;; Regexp matching Python lines that are continued via backslash.
+;; This is tricky because a trailing backslash does not mean
+;; continuation if it's in a comment
+(defconst py-continued-re
+  (concat
+   "\\(" "[^#'\"\n\\]" "\\|" py-stringlit-re "\\)*"
+   "\\\\$"))
+  
+;; Regexp matching blank or comment lines.
+(defconst py-blank-or-comment-re "[ \t]*\\($\\|#\\)")
+
+;; Regexp matching clauses to be outdented one level.
+(defconst py-outdent-re
+  (concat "\\(" (mapconcat 'identity
+			   '("else:"
+			     "except\\(\\s +.*\\)?:"
+			     "finally:"
+			     "elif\\s +.*:")
+			   "\\|")
+	  "\\)"))
+  
+
+;; Regexp matching lines to not outdent after.
+(defconst py-no-outdent-re
+  (concat "\\(" (mapconcat 'identity
+			   '("try:"
+			     "except\\(\\s +.*\\)?:"
+			     "while\\s +.*:"
+			     "for\\s +.*:"
+			     "if\\s +.*:"
+			     "elif\\s +.*:"
+			     "\\(return\\|break\\|raise\\|continue\\)[ \t\n]"
+			     )
+			   "\\|")
+	  "\\)"))
+
+;; Regexp matching a function, method or variable assignment.  If you
+;; change this, you probably have to change `py-current-defun' as
+;; well.  This is only used by `py-current-defun' to find the name for
+;; add-log.el.
+(defvar py-defun-start-re
+  "^\\([ \t]*\\)def[ \t]+\\([a-zA-Z_0-9]+\\)\\|\\(^[a-zA-Z_0-9]+\\)[ \t]*=")
+
+;; Regexp for finding a class name.  If you change this, you probably
+;; have to change `py-current-defun' as well.  This is only used by
+;; `py-current-defun' to find the name for add-log.el.
+(defvar py-class-start-re "^class[ \t]*\\([a-zA-Z_0-9]+\\)")
+
+
++
+;; Utilities
+
+(defmacro py-safe (&rest body)
+  ;; safely execute BODY, return nil if an error occurred
+  (` (condition-case nil
+	 (progn (,@ body))
+       (error nil))))
+
+(defsubst py-keep-region-active ()
+  ;; Do whatever is necessary to keep the region active in XEmacs.
+  ;; Ignore byte-compiler warnings you might see.  Also note that
+  ;; FSF's Emacs 19 does it differently; its policy doesn't require us
+  ;; to take explicit action.
+  (and (boundp 'zmacs-region-stays)
+       (setq zmacs-region-stays t)))
+
++
+;; 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.")


;;; Code:


;; user definable variables
;; vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv

(defvar py-python-command "python"
  "*Shell command used to start Python interpreter.")

(defvar py-indent-offset 4
  "*Indentation increment.
Note that `\\[py-guess-indent-offset]' can usually guess a good value
when you're editing someone else's Python code.")

(defvar py-align-multiline-strings-p t
  "*Flag describing how multiline 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.")

(defvar 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).")

(defvar py-honor-comment-indentation t
  "*Controls how comment lines influence subsequent indentation.

When nil, all comment lines are skipped for indentation purposes, and
in Emacs 19, a faster algorithm is used.

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

;; (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.")

(and (py-safe (require 'easymenu) t)
     (easy-menu-define
      py-menu py-mode-map "Python Mode menu"
      '("Python"
	["Comment Out Region"   py-comment-region  (mark)]
	["Uncomment Region"     (py-comment-region (point) (mark) '(4)) (mark)]
	"-"
	["Mark current block"   py-mark-block t]
	["Mark current def"     mark-python-def-or-class t]
	["Mark current class"   (mark-python-def-or-class t) t]
	"-"
	["Shift region left"    py-shift-region-left (mark)]
	["Shift region right"   py-shift-region-right (mark)]
	"-"
	["Execute buffer"       py-execute-buffer t]
	["Execute region"       py-execute-region (mark)]
	["Start interpreter..." py-shell t]
	"-"
	["Go to start of block" py-goto-block-up t]
	["Go to start of class" (beginning-of-python-def-or-class t) t]
	["Move to end of class" (end-of-python-def-or-class t) t]
	["Move to start of def" beginning-of-python-def-or-class t]
	["Move to end of def"   end-of-python-def-or-class t]
	"-"
	["Describe mode"        py-describe-mode t]
	)))


