cinap_lenrekadd hg and python4bb9e2215 years agoHistory
3768 lines · 138.6 KB · Emacs Lisp
RawDownload
  ;; as well.  This is only used by py-current-defun to find the name  ;; for add-log.el.  "Regular expression matching a function, method, or variable assignment.") (defconst py-class-start-re "^class[ \t]*\\([a-zA-Z_0-9]+\\)"  ;; 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.  "Regular expression for finding a class name.") (defconst py-traceback-line-re  "[ \t]+File \"\\([^\"]+\\)\", line \\([0-9]+\\)"  "Regular expression that describes tracebacks.") ;; pdbtrack contants(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.") (defconst py-pdbtrack-input-prompt "\n[(<]*pdb[>)]+ "  "Regular expression pdbtrack uses to recognize a pdb prompt.") (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 python-mode-hook nil  "*Hook called by `python-mode'.") (defvar jpython-mode-hook nil  "*Hook called by `jpython-mode'. `jpython-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)) (defvar py-mode-map ()  "Keymap used in `python-mode' buffers.")(if py-mode-map    nil  (setq py-mode-map (make-sparse-keymap))  ;; electric keys  (define-key py-mode-map ":" 'py-electric-colon)  ;; indentation level modifiers  (define-key py-mode-map "\C-c\C-l"  'py-shift-region-left)  (define-key py-mode-map "\C-c\C-r"  'py-shift-region-right)  (define-key py-mode-map "\C-c<"     'py-shift-region-left)  (define-key py-mode-map "\C-c>"     'py-shift-region-right)  ;; paragraph and string filling  (define-key py-mode-map "\eq"       'py-fill-paragraph)  ;; subprocess commands  (define-key py-mode-map "\C-c\C-c"  'py-execute-buffer)  (define-key py-mode-map "\C-c\C-m"  'py-execute-import-or-reload)  (define-key py-mode-map "\C-c\C-s"  'py-execute-string)  (define-key py-mode-map "\C-c|"     'py-execute-region)  (define-key py-mode-map "\e\C-x"    'py-execute-def-or-class)  (define-key py-mode-map "\C-c!"     'py-shell)  (define-key py-mode-map "\C-c\C-t"  'py-toggle-shells)  ;; Caution!  Enter here at your own risk.  We are trying to support  ;; several behaviors and it gets disgusting. :-( This logic ripped  ;; largely from CC Mode.  ;;  ;; In XEmacs 19, Emacs 19, and Emacs 20, we use this to bind  ;; backwards deletion behavior to DEL, which both Delete and  ;; Backspace get translated to.  There's no way to separate this  ;; behavior in a clean way, so deal with it!  Besides, it's been  ;; this way since the dawn of time.  (if (not (boundp 'delete-key-deletes-forward))      (define-key py-mode-map "\177" 'py-electric-backspace)    ;; However, XEmacs 20 actually achieved enlightenment.  It is    ;; possible to sanely define both backward and forward deletion    ;; behavior under X separately (TTYs are forever beyond hope, but    ;; who cares?  XEmacs 20 does the right thing with these too).    (define-key py-mode-map [delete]    'py-electric-delete)    (define-key py-mode-map [backspace] 'py-electric-backspace))  ;; Separate M-BS from C-M-h.  The former should remain  ;; backward-kill-word.  (define-key py-mode-map [(control meta h)] 'py-mark-def-or-class)  (define-key py-mode-map "\C-c\C-k"  'py-mark-block)  ;; Miscellaneous  (define-key py-mode-map "\C-c:"     'py-guess-indent-offset)  (define-key py-mode-map "\C-c\t"    'py-indent-region)  (define-key py-mode-map "\C-c\C-d"  'py-pdbtrack-toggle-stack-tracking)  (define-key py-mode-map "\C-c\C-n"  'py-next-statement)  (define-key py-mode-map "\C-c\C-p"  'py-previous-statement)  (define-key py-mode-map "\C-c\C-u"  'py-goto-block-up)  (define-key py-mode-map "\C-c#"     'py-comment-region)  (define-key py-mode-map "\C-c?"     'py-describe-mode)  (define-key py-mode-map "\C-c\C-h"  'py-help-at-point)  (define-key py-mode-map "\e\C-a"    'py-beginning-of-def-or-class)  (define-key py-mode-map "\e\C-e"    'py-end-of-def-or-class)  (define-key py-mode-map "\C-c-"     'py-up-exception)  (define-key py-mode-map "\C-c="     'py-down-exception)  ;; stuff that is `standard' but doesn't interface well with  ;; python-mode, which forces us to rebind to special commands  (define-key py-mode-map "\C-xnd"    'py-narrow-to-defun)  ;; information  (define-key py-mode-map "\C-c\C-b" 'py-submit-bug-report)  (define-key py-mode-map "\C-c\C-v" 'py-version)  (define-key py-mode-map "\C-c\C-w" 'py-pychecker-run)  ;; shadow global bindings for newline-and-indent w/ the py- version.  ;; BAW - this is extremely bad form, but I'm not going to change it  ;; for now.  (mapcar #'(lambda (key)	      (define-key py-mode-map key 'py-newline-and-indent))	  (where-is-internal 'newline-and-indent))  ;; Force RET to be py-newline-and-indent even if it didn't get  ;; mapped by the above code.  motivation: Emacs' default binding for  ;; RET is `newline' and C-j is `newline-and-indent'.  Most Pythoneers  ;; expect RET to do a `py-newline-and-indent' and any Emacsers who  ;; dislike this are probably knowledgeable enough to do a rebind.  ;; However, we do *not* change C-j since many Emacsers have already  ;; swapped RET and C-j and they don't want C-j bound to `newline' to   ;; change.  (define-key py-mode-map "\C-m" 'py-newline-and-indent)  ) (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  (mapcar #' (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)  ) (defvar py-mode-syntax-table nil  "Syntax table used in `python-mode' buffers.")(when (not py-mode-syntax-table)  (setq py-mode-syntax-table (make-syntax-table))  (modify-syntax-entry ?\( "()" py-mode-syntax-table)  (modify-syntax-entry ?\) ")(" py-mode-syntax-table)  (modify-syntax-entry ?\[ "(]" py-mode-syntax-table)  (modify-syntax-entry ?\] ")[" py-mode-syntax-table)  (modify-syntax-entry ?\{ "(}" py-mode-syntax-table)  (modify-syntax-entry ?\} "){" py-mode-syntax-table)  ;; Add operator symbols misassigned in the std table  (modify-syntax-entry ?\$ "."  py-mode-syntax-table)  (modify-syntax-entry ?\% "."  py-mode-syntax-table)  (modify-syntax-entry ?\& "."  py-mode-syntax-table)  (modify-syntax-entry ?\* "."  py-mode-syntax-table)  (modify-syntax-entry ?\+ "."  py-mode-syntax-table)  (modify-syntax-entry ?\- "."  py-mode-syntax-table)  (modify-syntax-entry ?\/ "."  py-mode-syntax-table)  (modify-syntax-entry ?\< "."  py-mode-syntax-table)  (modify-syntax-entry ?\= "."  py-mode-syntax-table)  (modify-syntax-entry ?\> "."  py-mode-syntax-table)  (modify-syntax-entry ?\| "."  py-mode-syntax-table)  ;; For historical reasons, underscore is word class instead of  ;; symbol class.  GNU conventions say it should be symbol class, but  ;; there's a natural conflict between what major mode authors want  ;; and what users expect from `forward-word' and `backward-word'.  ;; Guido and I have hashed this out and have decided to keep  ;; underscore in word class.  If you're tempted to change it, try  ;; binding M-f and M-b to py-forward-into-nomenclature and  ;; py-backward-into-nomenclature instead.  This doesn't help in all  ;; situations where you'd want the different behavior  ;; (e.g. backward-kill-word).  (modify-syntax-entry ?\_ "w"  py-mode-syntax-table)  ;; Both single quote and double quote are string delimiters  (modify-syntax-entry ?\' "\"" py-mode-syntax-table)  (modify-syntax-entry ?\" "\"" py-mode-syntax-table)  ;; backquote is open and close paren  (modify-syntax-entry ?\` "$"  py-mode-syntax-table)  ;; comment delimiters  (modify-syntax-entry ?\# "<"  py-mode-syntax-table)  (modify-syntax-entry ?\n ">"  py-mode-syntax-table)  ) ;; 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))  ;; 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 ()  "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))) (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 ((here (point)))    (cond     ((eq position 'bol) (beginning-of-line))     ((eq position 'eol) (end-of-line))     ((eq position 'bod) (py-beginning-of-def-or-class))     ((eq position 'eod) (py-end-of-def-or-class))     ;; Kind of funny, I know, but useful for py-up-exception.     ((eq position 'bob) (beginning-of-buffer))     ((eq position 'eob) (end-of-buffer))     ((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 here)))) (defsubst py-highlight-line (from to file line)  (cond   ((fboundp 'make-extent)    ;; XEmacs    (let ((e (make-extent from to)))      (set-extent-property e 'mouse-face 'highlight)      (set-extent-property e 'py-exc-info (cons file line))      (set-extent-property e 'keymap py-mode-output-map)))   (t    ;; Emacs -- Please port this!    )   )) (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."  ;; This is the version used for non-XEmacs, which has a nicer  ;; interface.  ;;  ;; WARNING: Watch out for infinite recursion.  (let* ((lim (or lim (py-point 'bod)))	 (state (parse-partial-sexp lim (point))))    (cond     ((nth 3 state) 'string)     ((nth 4 state) 'comment)     (t nil)))) ;; XEmacs has a built-in function that should make this much quicker.;; In this case, lim is ignored(defun py-fast-in-literal (&optional lim)  "Fast version of `py-in-literal', used only by XEmacs.Optional LIM is ignored."  ;; don't have to worry about context == 'block-comment  (buffer-syntactic-context)) (if (fboundp 'buffer-syntactic-context)    (defalias 'py-in-literal 'py-fast-in-literal))  ;; 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.") (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"     py-mark-def-or-class t]	["Mark current class"   (py-mark-def-or-class t) t]	"-"	["Shift region left"    py-shift-region-left (mark)]	["Shift region right"   py-shift-region-right (mark)]	"-"	["Import/reload file"   py-execute-import-or-reload t]	["Execute buffer"       py-execute-buffer t]	["Execute region"       py-execute-region (mark)]	["Execute def or class" py-execute-def-or-class (mark)]	["Execute string"       py-execute-string t]	["Start interpreter..." py-shell t]	"-"	["Go to start of block" py-goto-block-up t]	["Go to start of class" (py-beginning-of-def-or-class t) t]	["Move to end of class" (py-end-of-def-or-class t) t]	["Move to start of def" py-beginning-of-def-or-class t]	["Move to end of def"   py-end-of-def-or-class t]	"-"	["Describe mode"        py-describe-mode t]	)))  ;; Imenu definitions(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 tofunctions are not listed. See the variable `py-imenu-show-method-args-p' for moreinformation.") (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 tofunctions are listed. See the variable `py-imenu-show-method-args-p' for moreinformation.") ;; 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] for a betteralternative 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)  (defun py-imenu-create-index-function ()  "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 detailsof 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 Pythonfile 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 nestedlist as in 	(INDEX-NAME . INDEX-ALIST) This function should not be called directly, as it calls itselfrecursively and requires some setup.  Rather this is the engine forthe function \\[py-imenu-create-index-function]. It works recursively by looking for all definitions at the currentindention level.  When it finds one, it adds it to the alist.  If itfinds a definition at a greater indentation level, it removes theprevious definition from the alist. In its place it adds alldefinitions found at the next indentation level.  When it finds adefinition that is less indented then the current level, it returnsthe alist it has created thus far. The optional argument START-INDENT indicates the starting indentationat which to continue looking for Python classes, methods, orfunctions.  If this is not supplied, the function uses the indentationof 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 'either))	(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

Lines 501–1000 of 3768. Previous lines