History

add hg and python

cinap_lenrek committed 15 years ago

Commit 4bb9e221 parent 987265c3706 files · +1228772 −-233Browse files

Showing the changes to sys/src/cmd/python/Misc/python-mode.el (1 of 3706 files). Show all

Unified · Split

sys/src/cmd/python/Misc/python-mode.el+3768−0
@@ -0,0 +1,3768 @@
1+;;; python-mode.el --- Major mode for editing Python programs
2+
3+;; Copyright (C) 1992,1993,1994 Tim Peters
4+
5+;; Author: 1995-2002 Barry A. Warsaw
6+;; 1992-1994 Tim Peters
7+;; Maintainer: python-mode@python.org
8+;; Created: Feb 1992
9+;; Keywords: python languages oop
10+
11+(defconst py-version "$Revision: 34960 $"
12+ "`python-mode' version number.")
13+
14+;; This software is provided as-is, without express or implied
15+;; warranty. Permission to use, copy, modify, distribute or sell this
16+;; software, without fee, for any purpose and by any individual or
17+;; organization, is hereby granted, provided that the above copyright
18+;; notice and this paragraph appear in all copies.
19+
20+;;; Commentary:
21+
22+;; This is a major mode for editing Python programs. It was developed
23+;; by Tim Peters after an original idea by Michael A. Guravage. Tim
24+;; subsequently left the net; in 1995, Barry Warsaw inherited the mode
25+;; and is the current maintainer. Tim's now back but disavows all
26+;; responsibility for the mode. Smart Tim :-)
27+
28+;; pdbtrack support contributed by Ken Manheimer, April 2001.
29+
30+;; Please use the SourceForge Python project to submit bugs or
31+;; patches:
32+;;
33+;; http://sourceforge.net/projects/python
34+
35+;; FOR MORE INFORMATION:
36+
37+;; There is some information on python-mode.el at
38+
39+;; http://www.python.org/emacs/python-mode/
40+;;
41+;; It does contain links to other packages that you might find useful,
42+;; such as pdb interfaces, OO-Browser links, etc.
43+
44+;; BUG REPORTING:
45+
46+;; As mentioned above, please use the SourceForge Python project for
47+;; submitting bug reports or patches. The old recommendation, to use
48+;; C-c C-b will still work, but those reports have a higher chance of
49+;; getting buried in my mailbox. Please include a complete, but
50+;; concise code sample and a recipe for reproducing the bug. Send
51+;; suggestions and other comments to python-mode@python.org.
52+
53+;; When in a Python mode buffer, do a C-h m for more help. It's
54+;; doubtful that a texinfo manual would be very useful, but if you
55+;; want to contribute one, I'll certainly accept it!
56+
57+;;; Code:
58+
59+(require 'comint)
60+(require 'custom)
61+(require 'cl)
62+(require 'compile)
63+
64+
65+;; user definable variables
66+;; vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
67+
68+(defgroup python nil
69+ "Support for the Python programming language, <http://www.python.org/>"
70+ :group 'languages
71+ :prefix "py-")
72+
73+(defcustom py-python-command "python"
74+ "*Shell command used to start Python interpreter."
75+ :type 'string
76+ :group 'python)
77+
78+(defcustom py-jpython-command "jpython"
79+ "*Shell command used to start the JPython interpreter."
80+ :type 'string
81+ :group 'python
82+ :tag "JPython Command")
83+
84+(defcustom py-default-interpreter 'cpython
85+ "*Which Python interpreter is used by default.
86+The value for this variable can be either `cpython' or `jpython'.
87+
88+When the value is `cpython', the variables `py-python-command' and
89+`py-python-command-args' are consulted to determine the interpreter
90+and arguments to use.
91+
92+When the value is `jpython', the variables `py-jpython-command' and
93+`py-jpython-command-args' are consulted to determine the interpreter
94+and arguments to use.
95+
96+Note that this variable is consulted only the first time that a Python
97+mode buffer is visited during an Emacs session. After that, use
98+\\[py-toggle-shells] to change the interpreter shell."
99+ :type '(choice (const :tag "Python (a.k.a. CPython)" cpython)
100+ (const :tag "JPython" jpython))
101+ :group 'python)
102+
103+(defcustom py-python-command-args '("-i")
104+ "*List of string arguments to be used when starting a Python shell."
105+ :type '(repeat string)
106+ :group 'python)
107+
108+(defcustom py-jpython-command-args '("-i")
109+ "*List of string arguments to be used when starting a JPython shell."
110+ :type '(repeat string)
111+ :group 'python
112+ :tag "JPython Command Args")
113+
114+(defcustom py-indent-offset 4
115+ "*Amount of offset per level of indentation.
116+`\\[py-guess-indent-offset]' can usually guess a good value when
117+you're editing someone else's Python code."
118+ :type 'integer
119+ :group 'python)
120+
121+(defcustom py-continuation-offset 4
122+ "*Additional amount of offset to give for some continuation lines.
123+Continuation lines are those that immediately follow a backslash
124+terminated line. Only those continuation lines for a block opening
125+statement are given this extra offset."
126+ :type 'integer
127+ :group 'python)
128+
129+(defcustom py-smart-indentation t
130+ "*Should `python-mode' try to automagically set some indentation variables?
131+When this variable is non-nil, two things happen when a buffer is set
132+to `python-mode':
133+
134+ 1. `py-indent-offset' is guessed from existing code in the buffer.
135+ Only guessed values between 2 and 8 are considered. If a valid
136+ guess can't be made (perhaps because you are visiting a new
137+ file), then the value in `py-indent-offset' is used.
138+
139+ 2. `indent-tabs-mode' is turned off if `py-indent-offset' does not
140+ equal `tab-width' (`indent-tabs-mode' is never turned on by
141+ Python mode). This means that for newly written code, tabs are
142+ only inserted in indentation if one tab is one indentation
143+ level, otherwise only spaces are used.
144+
145+Note that both these settings occur *after* `python-mode-hook' is run,
146+so if you want to defeat the automagic configuration, you must also
147+set `py-smart-indentation' to nil in your `python-mode-hook'."
148+ :type 'boolean
149+ :group 'python)
150+
151+(defcustom py-align-multiline-strings-p t
152+ "*Flag describing how multi-line triple quoted strings are aligned.
153+When this flag is non-nil, continuation lines are lined up under the
154+preceding line's indentation. When this flag is nil, continuation
155+lines are aligned to column zero."
156+ :type '(choice (const :tag "Align under preceding line" t)
157+ (const :tag "Align to column zero" nil))
158+ :group 'python)
159+
160+(defcustom py-block-comment-prefix "##"
161+ "*String used by \\[comment-region] to comment out a block of code.
162+This should follow the convention for non-indenting comment lines so
163+that the indentation commands won't get confused (i.e., the string
164+should be of the form `#x...' where `x' is not a blank or a tab, and
165+`...' is arbitrary). However, this string should not end in whitespace."
166+ :type 'string
167+ :group 'python)
168+
169+(defcustom py-honor-comment-indentation t
170+ "*Controls how comment lines influence subsequent indentation.
171+
172+When nil, all comment lines are skipped for indentation purposes, and
173+if possible, a faster algorithm is used (i.e. X/Emacs 19 and beyond).
174+
175+When t, lines that begin with a single `#' are a hint to subsequent
176+line indentation. If the previous line is such a comment line (as
177+opposed to one that starts with `py-block-comment-prefix'), then its
178+indentation is used as a hint for this line's indentation. Lines that
179+begin with `py-block-comment-prefix' are ignored for indentation
180+purposes.
181+
182+When not nil or t, comment lines that begin with a single `#' are used
183+as indentation hints, unless the comment character is in column zero."
184+ :type '(choice
185+ (const :tag "Skip all comment lines (fast)" nil)
186+ (const :tag "Single # `sets' indentation for next line" t)
187+ (const :tag "Single # `sets' indentation except at column zero"
188+ other)
189+ )
190+ :group 'python)
191+
192+(defcustom py-temp-directory
193+ (let ((ok '(lambda (x)
194+ (and x
195+ (setq x (expand-file-name x)) ; always true
196+ (file-directory-p x)
197+ (file-writable-p x)
198+ x))))
199+ (or (funcall ok (getenv "TMPDIR"))
200+ (funcall ok "/usr/tmp")
201+ (funcall ok "/tmp")
202+ (funcall ok "/var/tmp")
203+ (funcall ok ".")
204+ (error
205+ "Couldn't find a usable temp directory -- set `py-temp-directory'")))
206+ "*Directory used for temporary files created by a *Python* process.
207+By default, the first directory from this list that exists and that you
208+can write into: the value (if any) of the environment variable TMPDIR,
209+/usr/tmp, /tmp, /var/tmp, or the current directory."
210+ :type 'string
211+ :group 'python)
212+
213+(defcustom py-beep-if-tab-change t
214+ "*Ring the bell if `tab-width' is changed.
215+If a comment of the form
216+
217+ \t# vi:set tabsize=<number>:
218+
219+is found before the first code line when the file is entered, and the
220+current value of (the general Emacs variable) `tab-width' does not
221+equal <number>, `tab-width' is set to <number>, a message saying so is
222+displayed in the echo area, and if `py-beep-if-tab-change' is non-nil
223+the Emacs bell is also rung as a warning."
224+ :type 'boolean
225+ :group 'python)
226+
227+(defcustom py-jump-on-exception t
228+ "*Jump to innermost exception frame in *Python Output* buffer.
229+When this variable is non-nil and an exception occurs when running
230+Python code synchronously in a subprocess, jump immediately to the
231+source code of the innermost traceback frame."
232+ :type 'boolean
233+ :group 'python)
234+
235+(defcustom py-ask-about-save t
236+ "If not nil, ask about which buffers to save before executing some code.
237+Otherwise, all modified buffers are saved without asking."
238+ :type 'boolean
239+ :group 'python)
240+
241+(defcustom py-backspace-function 'backward-delete-char-untabify
242+ "*Function called by `py-electric-backspace' when deleting backwards."
243+ :type 'function
244+ :group 'python)
245+
246+(defcustom py-delete-function 'delete-char
247+ "*Function called by `py-electric-delete' when deleting forwards."
248+ :type 'function
249+ :group 'python)
250+
251+(defcustom py-imenu-show-method-args-p nil
252+ "*Controls echoing of arguments of functions & methods in the Imenu buffer.
253+When non-nil, arguments are printed."
254+ :type 'boolean
255+ :group 'python)
256+(make-variable-buffer-local 'py-indent-offset)
257+
258+(defcustom py-pdbtrack-do-tracking-p t
259+ "*Controls whether the pdbtrack feature is enabled or not.
260+When non-nil, pdbtrack is enabled in all comint-based buffers,
261+e.g. shell buffers and the *Python* buffer. When using pdb to debug a
262+Python program, pdbtrack notices the pdb prompt and displays the
263+source file and line that the program is stopped at, much the same way
264+as gud-mode does for debugging C programs with gdb."
265+ :type 'boolean
266+ :group 'python)
267+(make-variable-buffer-local 'py-pdbtrack-do-tracking-p)
268+
269+(defcustom py-pdbtrack-minor-mode-string " PDB"
270+ "*String to use in the minor mode list when pdbtrack is enabled."
271+ :type 'string
272+ :group 'python)
273+
274+(defcustom py-import-check-point-max
275+ 20000
276+ "Maximum number of characters to search for a Java-ish import statement.
277+When `python-mode' tries to calculate the shell to use (either a
278+CPython or a JPython shell), it looks at the so-called `shebang' line
279+-- i.e. #! line. If that's not available, it looks at some of the
280+file heading imports to see if they look Java-like."
281+ :type 'integer
282+ :group 'python
283+ )
284+
285+(defcustom py-jpython-packages
286+ '("java" "javax" "org" "com")
287+ "Imported packages that imply `jpython-mode'."
288+ :type '(repeat string)
289+ :group 'python)
290+
291+;; Not customizable
292+(defvar py-master-file nil
293+ "If non-nil, execute the named file instead of the buffer's file.
294+The intent is to allow you to set this variable in the file's local
295+variable section, e.g.:
296+
297+ # Local Variables:
298+ # py-master-file: \"master.py\"
299+ # End:
300+
301+so that typing \\[py-execute-buffer] in that buffer executes the named
302+master file instead of the buffer's file. If the file name has a
303+relative path, the value of variable `default-directory' for the
304+buffer is prepended to come up with a file name.")
305+(make-variable-buffer-local 'py-master-file)
306+
307+(defcustom py-pychecker-command "pychecker"
308+ "*Shell command used to run Pychecker."
309+ :type 'string
310+ :group 'python
311+ :tag "Pychecker Command")
312+
313+(defcustom py-pychecker-command-args '("--stdlib")
314+ "*List of string arguments to be passed to pychecker."
315+ :type '(repeat string)
316+ :group 'python
317+ :tag "Pychecker Command Args")
318+
319+(defvar py-shell-alist
320+ '(("jpython" . 'jpython)
321+ ("jython" . 'jpython)
322+ ("python" . 'cpython))
323+ "*Alist of interpreters and python shells. Used by `py-choose-shell'
324+to select the appropriate python interpreter mode for a file.")
325+
326+
327+;; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
328+;; NO USER DEFINABLE VARIABLES BEYOND THIS POINT
329+
330+(defconst py-emacs-features
331+ (let (features)
332+ features)
333+ "A list of features extant in the Emacs you are using.
334+There are many flavors of Emacs out there, with different levels of
335+support for features needed by `python-mode'.")
336+
337+;; Face for None, True, False, self, and Ellipsis
338+(defvar py-pseudo-keyword-face 'py-pseudo-keyword-face
339+ "Face for pseudo keywords in Python mode, like self, True, False, Ellipsis.")
340+(make-face 'py-pseudo-keyword-face)
341+
342+(defun py-font-lock-mode-hook ()
343+ (or (face-differs-from-default-p 'py-pseudo-keyword-face)
344+ (copy-face 'font-lock-keyword-face 'py-pseudo-keyword-face)))
345+(add-hook 'font-lock-mode-hook 'py-font-lock-mode-hook)
346+
347+(defvar python-font-lock-keywords
348+ (let ((kw1 (mapconcat 'identity
349+ '("and" "assert" "break" "class"
350+ "continue" "def" "del" "elif"
351+ "else" "except" "exec" "for"
352+ "from" "global" "if" "import"
353+ "in" "is" "lambda" "not"
354+ "or" "pass" "print" "raise"
355+ "return" "while" "yield"
356+ )
357+ "\\|"))
358+ (kw2 (mapconcat 'identity
359+ '("else:" "except:" "finally:" "try:")
360+ "\\|"))
361+ (kw3 (mapconcat 'identity
362+ '("ArithmeticError" "AssertionError"
363+ "AttributeError" "DeprecationWarning" "EOFError"
364+ "Ellipsis" "EnvironmentError" "Exception" "False"
365+ "FloatingPointError" "FutureWarning" "IOError"
366+ "ImportError" "IndentationError" "IndexError"
367+ "KeyError" "KeyboardInterrupt" "LookupError"
368+ "MemoryError" "NameError" "None" "NotImplemented"
369+ "NotImplementedError" "OSError" "OverflowError"
370+ "OverflowWarning" "PendingDeprecationWarning"
371+ "ReferenceError" "RuntimeError" "RuntimeWarning"
372+ "StandardError" "StopIteration" "SyntaxError"
373+ "SyntaxWarning" "SystemError" "SystemExit"
374+ "TabError" "True" "TypeError" "UnboundLocalError"
375+ "UnicodeDecodeError" "UnicodeEncodeError"
376+ "UnicodeError" "UnicodeTranslateError"
377+ "UserWarning" "ValueError" "Warning"
378+ "ZeroDivisionError" "__debug__"
379+ "__import__" "__name__" "abs" "apply" "basestring"
380+ "bool" "buffer" "callable" "chr" "classmethod"
381+ "cmp" "coerce" "compile" "complex" "copyright"
382+ "delattr" "dict" "dir" "divmod"
383+ "enumerate" "eval" "execfile" "exit" "file"
384+ "filter" "float" "getattr" "globals" "hasattr"
385+ "hash" "hex" "id" "input" "int" "intern"
386+ "isinstance" "issubclass" "iter" "len" "license"
387+ "list" "locals" "long" "map" "max" "min" "object"
388+ "oct" "open" "ord" "pow" "property" "range"
389+ "raw_input" "reduce" "reload" "repr" "round"
390+ "setattr" "slice" "staticmethod" "str" "sum"
391+ "super" "tuple" "type" "unichr" "unicode" "vars"
392+ "xrange" "zip")
393+ "\\|"))
394+ )
395+ (list
396+ ;; keywords
397+ (cons (concat "\\b\\(" kw1 "\\)\\b[ \n\t(]") 1)
398+ ;; builtins when they don't appear as object attributes
399+ (cons (concat "\\(\\b\\|[.]\\)\\(" kw3 "\\)\\b[ \n\t(]") 2)
400+ ;; block introducing keywords with immediately following colons.
401+ ;; Yes "except" is in both lists.
402+ (cons (concat "\\b\\(" kw2 "\\)[ \n\t(]") 1)
403+ ;; `as' but only in "import foo as bar"
404+ '("[ \t]*\\(\\bfrom\\b.*\\)?\\bimport\\b.*\\b\\(as\\)\\b" . 2)
405+ ;; classes
406+ '("\\bclass[ \t]+\\([a-zA-Z_]+[a-zA-Z0-9_]*\\)"
407+ 1 font-lock-type-face)
408+ ;; functions
409+ '("\\bdef[ \t]+\\([a-zA-Z_]+[a-zA-Z0-9_]*\\)"
410+ 1 font-lock-function-name-face)
411+ ;; pseudo-keywords
412+ '("\\b\\(self\\|None\\|True\\|False\\|Ellipsis\\)\\b"
413+ 1 py-pseudo-keyword-face)
414+ ))
415+ "Additional expressions to highlight in Python mode.")
416+(put 'python-mode 'font-lock-defaults '(python-font-lock-keywords))
417+
418+;; have to bind py-file-queue before installing the kill-emacs-hook
419+(defvar py-file-queue nil
420+ "Queue of Python temp files awaiting execution.
421+Currently-active file is at the head of the list.")
422+
423+(defvar py-pdbtrack-is-tracking-p nil)
424+(defvar py-pdbtrack-last-grubbed-buffer nil
425+ "Record of the last buffer used when the source path was invalid.
426+
427+This buffer is consulted before the buffer-list history for satisfying
428+`py-pdbtrack-grub-for-buffer', since it's the most often the likely
429+prospect as debugging continues.")
430+(make-variable-buffer-local 'py-pdbtrack-last-grubbed-buffer)
431+(defvar py-pychecker-history nil)
432+
433+
434+
435+;; Constants
436+
437+(defconst py-stringlit-re
438+ (concat
439+ ;; These fail if backslash-quote ends the string (not worth
440+ ;; fixing?). They precede the short versions so that the first two
441+ ;; quotes don't look like an empty short string.
442+ ;;
443+ ;; (maybe raw), long single quoted triple quoted strings (SQTQ),
444+ ;; with potential embedded single quotes
445+ "[rR]?'''[^']*\\(\\('[^']\\|''[^']\\)[^']*\\)*'''"
446+ "\\|"
447+ ;; (maybe raw), long double quoted triple quoted strings (DQTQ),
448+ ;; with potential embedded double quotes
449+ "[rR]?\"\"\"[^\"]*\\(\\(\"[^\"]\\|\"\"[^\"]\\)[^\"]*\\)*\"\"\""
450+ "\\|"
451+ "[rR]?'\\([^'\n\\]\\|\\\\.\\)*'" ; single-quoted
452+ "\\|" ; or
453+ "[rR]?\"\\([^\"\n\\]\\|\\\\.\\)*\"" ; double-quoted
454+ )
455+ "Regular expression matching a Python string literal.")
456+
457+(defconst py-continued-re
458+ ;; This is tricky because a trailing backslash does not mean
459+ ;; continuation if it's in a comment
460+ (concat
461+ "\\(" "[^#'\"\n\\]" "\\|" py-stringlit-re "\\)*"
462+ "\\\\$")
463+ "Regular expression matching Python backslash continuation lines.")
464+
465+(defconst py-blank-or-comment-re "[ \t]*\\($\\|#\\)"
466+ "Regular expression matching a blank or comment line.")
467+
468+(defconst py-outdent-re
469+ (concat "\\(" (mapconcat 'identity
470+ '("else:"
471+ "except\\(\\s +.*\\)?:"
472+ "finally:"
473+ "elif\\s +.*:")
474+ "\\|")
475+ "\\)")
476+ "Regular expression matching statements to be dedented one level.")
477+
478+(defconst py-block-closing-keywords-re
479+ "\\(return\\|raise\\|break\\|continue\\|pass\\)"
480+ "Regular expression matching keywords which typically close a block.")
481+
482+(defconst py-no-outdent-re
483+ (concat
484+ "\\("
485+ (mapconcat 'identity
486+ (list "try:"
487+ "except\\(\\s +.*\\)?:"
488+ "while\\s +.*:"
489+ "for\\s +.*:"
490+ "if\\s +.*:"
491+ "elif\\s +.*:"
492+ (concat py-block-closing-keywords-re "[ \t\n]")
493+ )
494+ "\\|")
495+ "\\)")
496+ "Regular expression matching lines not to dedent after.")
497+
498+(defconst py-defun-start-re
499+ "^\\([ \t]*\\)def[ \t]+\\([a-zA-Z_0-9]+\\)\\|\\(^[a-zA-Z_0-9]+\\)[ \t]*="
500+ ;; If you change this, you probably have to change py-current-defun
501+ ;; as well. This is only used by py-current-defun to find the name
502+ ;; for add-log.el.
503+ "Regular expression matching a function, method, or variable assignment.")
504+
505+(defconst py-class-start-re "^class[ \t]*\\([a-zA-Z_0-9]+\\)"
506+ ;; If you change this, you probably have to change py-current-defun
507+ ;; as well. This is only used by py-current-defun to find the name
508+ ;; for add-log.el.
509+ "Regular expression for finding a class name.")
510+
511+(defconst py-traceback-line-re
512+ "[ \t]+File \"\\([^\"]+\\)\", line \\([0-9]+\\)"
513+ "Regular expression that describes tracebacks.")
514+
515+;; pdbtrack contants
516+(defconst py-pdbtrack-stack-entry-regexp
517+; "^> \\([^(]+\\)(\\([0-9]+\\))\\([?a-zA-Z0-9_]+\\)()"
518+ "^> \\(.*\\)(\\([0-9]+\\))\\([?a-zA-Z0-9_]+\\)()"
519+ "Regular expression pdbtrack uses to find a stack trace entry.")
520+
521+(defconst py-pdbtrack-input-prompt "\n[(<]*pdb[>)]+ "
522+ "Regular expression pdbtrack uses to recognize a pdb prompt.")
523+
524+(defconst py-pdbtrack-track-range 10000
525+ "Max number of characters from end of buffer to search for stack entry.")
526+
527+
528+
529+;; Major mode boilerplate
530+
531+;; define a mode-specific abbrev table for those who use such things
532+(defvar python-mode-abbrev-table nil
533+ "Abbrev table in use in `python-mode' buffers.")
534+(define-abbrev-table 'python-mode-abbrev-table nil)
535+
536+(defvar python-mode-hook nil
537+ "*Hook called by `python-mode'.")
538+
539+(defvar jpython-mode-hook nil
540+ "*Hook called by `jpython-mode'. `jpython-mode' also calls
541+`python-mode-hook'.")
542+
543+(defvar py-shell-hook nil
544+ "*Hook called by `py-shell'.")
545+
546+;; In previous version of python-mode.el, the hook was incorrectly
547+;; called py-mode-hook, and was not defvar'd. Deprecate its use.
548+(and (fboundp 'make-obsolete-variable)
549+ (make-obsolete-variable 'py-mode-hook 'python-mode-hook))
550+
551+(defvar py-mode-map ()
552+ "Keymap used in `python-mode' buffers.")
553+(if py-mode-map
554+ nil
555+ (setq py-mode-map (make-sparse-keymap))
556+ ;; electric keys
557+ (define-key py-mode-map ":" 'py-electric-colon)
558+ ;; indentation level modifiers
559+ (define-key py-mode-map "\C-c\C-l" 'py-shift-region-left)
560+ (define-key py-mode-map "\C-c\C-r" 'py-shift-region-right)
561+ (define-key py-mode-map "\C-c<" 'py-shift-region-left)
562+ (define-key py-mode-map "\C-c>" 'py-shift-region-right)
563+ ;; paragraph and string filling
564+ (define-key py-mode-map "\eq" 'py-fill-paragraph)
565+ ;; subprocess commands
566+ (define-key py-mode-map "\C-c\C-c" 'py-execute-buffer)
567+ (define-key py-mode-map "\C-c\C-m" 'py-execute-import-or-reload)
568+ (define-key py-mode-map "\C-c\C-s" 'py-execute-string)
569+ (define-key py-mode-map "\C-c|" 'py-execute-region)
570+ (define-key py-mode-map "\e\C-x" 'py-execute-def-or-class)
571+ (define-key py-mode-map "\C-c!" 'py-shell)
572+ (define-key py-mode-map "\C-c\C-t" 'py-toggle-shells)
573+ ;; Caution! Enter here at your own risk. We are trying to support
574+ ;; several behaviors and it gets disgusting. :-( This logic ripped
575+ ;; largely from CC Mode.
576+ ;;
577+ ;; In XEmacs 19, Emacs 19, and Emacs 20, we use this to bind
578+ ;; backwards deletion behavior to DEL, which both Delete and
579+ ;; Backspace get translated to. There's no way to separate this
580+ ;; behavior in a clean way, so deal with it! Besides, it's been
581+ ;; this way since the dawn of time.
582+ (if (not (boundp 'delete-key-deletes-forward))
583+ (define-key py-mode-map "\177" 'py-electric-backspace)
584+ ;; However, XEmacs 20 actually achieved enlightenment. It is
585+ ;; possible to sanely define both backward and forward deletion
586+ ;; behavior under X separately (TTYs are forever beyond hope, but
587+ ;; who cares? XEmacs 20 does the right thing with these too).
588+ (define-key py-mode-map [delete] 'py-electric-delete)
589+ (define-key py-mode-map [backspace] 'py-electric-backspace))
590+ ;; Separate M-BS from C-M-h. The former should remain
591+ ;; backward-kill-word.
592+ (define-key py-mode-map [(control meta h)] 'py-mark-def-or-class)
593+ (define-key py-mode-map "\C-c\C-k" 'py-mark-block)
594+ ;; Miscellaneous
595+ (define-key py-mode-map "\C-c:" 'py-guess-indent-offset)
596+ (define-key py-mode-map "\C-c\t" 'py-indent-region)
597+ (define-key py-mode-map "\C-c\C-d" 'py-pdbtrack-toggle-stack-tracking)
598+ (define-key py-mode-map "\C-c\C-n" 'py-next-statement)
599+ (define-key py-mode-map "\C-c\C-p" 'py-previous-statement)
600+ (define-key py-mode-map "\C-c\C-u" 'py-goto-block-up)
601+ (define-key py-mode-map "\C-c#" 'py-comment-region)
602+ (define-key py-mode-map "\C-c?" 'py-describe-mode)
603+ (define-key py-mode-map "\C-c\C-h" 'py-help-at-point)
604+ (define-key py-mode-map "\e\C-a" 'py-beginning-of-def-or-class)
605+ (define-key py-mode-map "\e\C-e" 'py-end-of-def-or-class)
606+ (define-key py-mode-map "\C-c-" 'py-up-exception)
607+ (define-key py-mode-map "\C-c=" 'py-down-exception)
608+ ;; stuff that is `standard' but doesn't interface well with
609+ ;; python-mode, which forces us to rebind to special commands
610+ (define-key py-mode-map "\C-xnd" 'py-narrow-to-defun)
611+ ;; information
612+ (define-key py-mode-map "\C-c\C-b" 'py-submit-bug-report)
613+ (define-key py-mode-map "\C-c\C-v" 'py-version)
614+ (define-key py-mode-map "\C-c\C-w" 'py-pychecker-run)
615+ ;; shadow global bindings for newline-and-indent w/ the py- version.
616+ ;; BAW - this is extremely bad form, but I'm not going to change it
617+ ;; for now.
618+ (mapcar #'(lambda (key)
619+ (define-key py-mode-map key 'py-newline-and-indent))
620+ (where-is-internal 'newline-and-indent))
621+ ;; Force RET to be py-newline-and-indent even if it didn't get
622+ ;; mapped by the above code. motivation: Emacs' default binding for
623+ ;; RET is `newline' and C-j is `newline-and-indent'. Most Pythoneers
624+ ;; expect RET to do a `py-newline-and-indent' and any Emacsers who
625+ ;; dislike this are probably knowledgeable enough to do a rebind.
626+ ;; However, we do *not* change C-j since many Emacsers have already
627+ ;; swapped RET and C-j and they don't want C-j bound to `newline' to
628+ ;; change.
629+ (define-key py-mode-map "\C-m" 'py-newline-and-indent)
630+ )
631+
632+(defvar py-mode-output-map nil
633+ "Keymap used in *Python Output* buffers.")
634+(if py-mode-output-map
635+ nil
636+ (setq py-mode-output-map (make-sparse-keymap))
637+ (define-key py-mode-output-map [button2] 'py-mouseto-exception)
638+ (define-key py-mode-output-map "\C-c\C-c" 'py-goto-exception)
639+ ;; TBD: Disable all self-inserting keys. This is bogus, we should
640+ ;; really implement this as *Python Output* buffer being read-only
641+ (mapcar #' (lambda (key)
642+ (define-key py-mode-output-map key
643+ #'(lambda () (interactive) (beep))))
644+ (where-is-internal 'self-insert-command))
645+ )
646+
647+(defvar py-shell-map nil
648+ "Keymap used in *Python* shell buffers.")
649+(if py-shell-map
650+ nil
651+ (setq py-shell-map (copy-keymap comint-mode-map))
652+ (define-key py-shell-map [tab] 'tab-to-tab-stop)
653+ (define-key py-shell-map "\C-c-" 'py-up-exception)
654+ (define-key py-shell-map "\C-c=" 'py-down-exception)
655+ )
656+
657+(defvar py-mode-syntax-table nil
658+ "Syntax table used in `python-mode' buffers.")
659+(when (not py-mode-syntax-table)
660+ (setq py-mode-syntax-table (make-syntax-table))
661+ (modify-syntax-entry ?\( "()" py-mode-syntax-table)
662+ (modify-syntax-entry ?\) ")(" py-mode-syntax-table)
663+ (modify-syntax-entry ?\[ "(]" py-mode-syntax-table)
664+ (modify-syntax-entry ?\] ")[" py-mode-syntax-table)
665+ (modify-syntax-entry ?\{ "(}" py-mode-syntax-table)
666+ (modify-syntax-entry ?\} "){" py-mode-syntax-table)
667+ ;; Add operator symbols misassigned in the std table
668+ (modify-syntax-entry ?\$ "." py-mode-syntax-table)
669+ (modify-syntax-entry ?\% "." py-mode-syntax-table)
670+ (modify-syntax-entry ?\& "." py-mode-syntax-table)
671+ (modify-syntax-entry ?\* "." py-mode-syntax-table)
672+ (modify-syntax-entry ?\+ "." py-mode-syntax-table)
673+ (modify-syntax-entry ?\- "." py-mode-syntax-table)
674+ (modify-syntax-entry ?\/ "." py-mode-syntax-table)
675+ (modify-syntax-entry ?\< "." py-mode-syntax-table)
676+ (modify-syntax-entry ?\= "." py-mode-syntax-table)
677+ (modify-syntax-entry ?\> "." py-mode-syntax-table)
678+ (modify-syntax-entry ?\| "." py-mode-syntax-table)
679+ ;; For historical reasons, underscore is word class instead of
680+ ;; symbol class. GNU conventions say it should be symbol class, but
681+ ;; there's a natural conflict between what major mode authors want
682+ ;; and what users expect from `forward-word' and `backward-word'.
683+ ;; Guido and I have hashed this out and have decided to keep
684+ ;; underscore in word class. If you're tempted to change it, try
685+ ;; binding M-f and M-b to py-forward-into-nomenclature and
686+ ;; py-backward-into-nomenclature instead. This doesn't help in all
687+ ;; situations where you'd want the different behavior
688+ ;; (e.g. backward-kill-word).
689+ (modify-syntax-entry ?\_ "w" py-mode-syntax-table)
690+ ;; Both single quote and double quote are string delimiters
691+ (modify-syntax-entry ?\' "\"" py-mode-syntax-table)
692+ (modify-syntax-entry ?\" "\"" py-mode-syntax-table)
693+ ;; backquote is open and close paren
694+ (modify-syntax-entry ?\` "$" py-mode-syntax-table)
695+ ;; comment delimiters
696+ (modify-syntax-entry ?\# "<" py-mode-syntax-table)
697+ (modify-syntax-entry ?\n ">" py-mode-syntax-table)
698+ )
699+
700+;; An auxiliary syntax table which places underscore and dot in the
701+;; symbol class for simplicity
702+(defvar py-dotted-expression-syntax-table nil
703+ "Syntax table used to identify Python dotted expressions.")
704+(when (not py-dotted-expression-syntax-table)
705+ (setq py-dotted-expression-syntax-table
706+ (copy-syntax-table py-mode-syntax-table))
707+ (modify-syntax-entry ?_ "_" py-dotted-expression-syntax-table)
708+ (modify-syntax-entry ?. "_" py-dotted-expression-syntax-table))
709+
710+
711+
712+;; Utilities
713+(defmacro py-safe (&rest body)
714+ "Safely execute BODY, return nil if an error occurred."
715+ (` (condition-case nil
716+ (progn (,@ body))
717+ (error nil))))
718+
719+(defsubst py-keep-region-active ()
720+ "Keep the region active in XEmacs."
721+ ;; Ignore byte-compiler warnings you might see. Also note that
722+ ;; FSF's Emacs 19 does it differently; its policy doesn't require us
723+ ;; to take explicit action.
724+ (and (boundp 'zmacs-region-stays)
725+ (setq zmacs-region-stays t)))
726+
727+(defsubst py-point (position)
728+ "Returns the value of point at certain commonly referenced POSITIONs.
729+POSITION can be one of the following symbols:
730+
731+ bol -- beginning of line
732+ eol -- end of line
733+ bod -- beginning of def or class
734+ eod -- end of def or class
735+ bob -- beginning of buffer
736+ eob -- end of buffer
737+ boi -- back to indentation
738+ bos -- beginning of statement
739+
740+This function does not modify point or mark."
741+ (let ((here (point)))
742+ (cond
743+ ((eq position 'bol) (beginning-of-line))
744+ ((eq position 'eol) (end-of-line))
745+ ((eq position 'bod) (py-beginning-of-def-or-class))
746+ ((eq position 'eod) (py-end-of-def-or-class))
747+ ;; Kind of funny, I know, but useful for py-up-exception.
748+ ((eq position 'bob) (beginning-of-buffer))
749+ ((eq position 'eob) (end-of-buffer))
750+ ((eq position 'boi) (back-to-indentation))
751+ ((eq position 'bos) (py-goto-initial-line))
752+ (t (error "Unknown buffer position requested: %s" position))
753+ )
754+ (prog1
755+ (point)
756+ (goto-char here))))
757+
758+(defsubst py-highlight-line (from to file line)
759+ (cond
760+ ((fboundp 'make-extent)
761+ ;; XEmacs
762+ (let ((e (make-extent from to)))
763+ (set-extent-property e 'mouse-face 'highlight)
764+ (set-extent-property e 'py-exc-info (cons file line))
765+ (set-extent-property e 'keymap py-mode-output-map)))
766+ (t
767+ ;; Emacs -- Please port this!
768+ )
769+ ))
770+
771+(defun py-in-literal (&optional lim)
772+ "Return non-nil if point is in a Python literal (a comment or string).
773+Optional argument LIM indicates the beginning of the containing form,
774+i.e. the limit on how far back to scan."
775+ ;; This is the version used for non-XEmacs, which has a nicer
776+ ;; interface.
777+ ;;
778+ ;; WARNING: Watch out for infinite recursion.
779+ (let* ((lim (or lim (py-point 'bod)))
780+ (state (parse-partial-sexp lim (point))))
781+ (cond
782+ ((nth 3 state) 'string)
783+ ((nth 4 state) 'comment)
784+ (t nil))))
785+
786+;; XEmacs has a built-in function that should make this much quicker.
787+;; In this case, lim is ignored
788+(defun py-fast-in-literal (&optional lim)
789+ "Fast version of `py-in-literal', used only by XEmacs.
790+Optional LIM is ignored."
791+ ;; don't have to worry about context == 'block-comment
792+ (buffer-syntactic-context))
793+
794+(if (fboundp 'buffer-syntactic-context)
795+ (defalias 'py-in-literal 'py-fast-in-literal))
796+
797+
798+
799+;; Menu definitions, only relevent if you have the easymenu.el package
800+;; (standard in the latest Emacs 19 and XEmacs 19 distributions).
801+(defvar py-menu nil
802+ "Menu for Python Mode.
803+This menu will get created automatically if you have the `easymenu'
804+package. Note that the latest X/Emacs releases contain this package.")
805+
806+(and (py-safe (require 'easymenu) t)
807+ (easy-menu-define
808+ py-menu py-mode-map "Python Mode menu"
809+ '("Python"
810+ ["Comment Out Region" py-comment-region (mark)]
811+ ["Uncomment Region" (py-comment-region (point) (mark) '(4)) (mark)]
812+ "-"
813+ ["Mark current block" py-mark-block t]
814+ ["Mark current def" py-mark-def-or-class t]
815+ ["Mark current class" (py-mark-def-or-class t) t]
816+ "-"
817+ ["Shift region left" py-shift-region-left (mark)]
818+ ["Shift region right" py-shift-region-right (mark)]
819+ "-"
820+ ["Import/reload file" py-execute-import-or-reload t]
821+ ["Execute buffer" py-execute-buffer t]
822+ ["Execute region" py-execute-region (mark)]
823+ ["Execute def or class" py-execute-def-or-class (mark)]
824+ ["Execute string" py-execute-string t]
825+ ["Start interpreter..." py-shell t]
826+ "-"
827+ ["Go to start of block" py-goto-block-up t]
828+ ["Go to start of class" (py-beginning-of-def-or-class t) t]
829+ ["Move to end of class" (py-end-of-def-or-class t) t]
830+ ["Move to start of def" py-beginning-of-def-or-class t]
831+ ["Move to end of def" py-end-of-def-or-class t]
832+ "-"
833+ ["Describe mode" py-describe-mode t]
834+ )))
835+
836+
837+
838+;; Imenu definitions
839+(defvar py-imenu-class-regexp
840+ (concat ; <<classes>>
841+ "\\(" ;
842+ "^[ \t]*" ; newline and maybe whitespace
843+ "\\(class[ \t]+[a-zA-Z0-9_]+\\)" ; class name
844+ ; possibly multiple superclasses
845+ "\\([ \t]*\\((\\([a-zA-Z0-9_,. \t\n]\\)*)\\)?\\)"
846+ "[ \t]*:" ; and the final :
847+ "\\)" ; >>classes<<
848+ )
849+ "Regexp for Python classes for use with the Imenu package."
850+ )
851+
852+(defvar py-imenu-method-regexp
853+ (concat ; <<methods and functions>>
854+ "\\(" ;
855+ "^[ \t]*" ; new line and maybe whitespace
856+ "\\(def[ \t]+" ; function definitions start with def
857+ "\\([a-zA-Z0-9_]+\\)" ; name is here
858+ ; function arguments...
859+;; "[ \t]*(\\([-+/a-zA-Z0-9_=,\* \t\n.()\"'#]*\\))"
860+ "[ \t]*(\\([^:#]*\\))"
861+ "\\)" ; end of def
862+ "[ \t]*:" ; and then the :
863+ "\\)" ; >>methods and functions<<
864+ )
865+ "Regexp for Python methods/functions for use with the Imenu package."
866+ )
867+
868+(defvar py-imenu-method-no-arg-parens '(2 8)
869+ "Indices into groups of the Python regexp for use with Imenu.
870+
871+Using these values will result in smaller Imenu lists, as arguments to
872+functions are not listed.
873+
874+See the variable `py-imenu-show-method-args-p' for more
875+information.")
876+
877+(defvar py-imenu-method-arg-parens '(2 7)
878+ "Indices into groups of the Python regexp for use with imenu.
879+Using these values will result in large Imenu lists, as arguments to
880+functions are listed.
881+
882+See the variable `py-imenu-show-method-args-p' for more
883+information.")
884+
885+;; Note that in this format, this variable can still be used with the
886+;; imenu--generic-function. Otherwise, there is no real reason to have
887+;; it.
888+(defvar py-imenu-generic-expression
889+ (cons
890+ (concat
891+ py-imenu-class-regexp
892+ "\\|" ; or...
893+ py-imenu-method-regexp
894+ )
895+ py-imenu-method-no-arg-parens)
896+ "Generic Python expression which may be used directly with Imenu.
897+Used by setting the variable `imenu-generic-expression' to this value.
898+Also, see the function \\[py-imenu-create-index] for a better
899+alternative for finding the index.")
900+
901+;; These next two variables are used when searching for the Python
902+;; class/definitions. Just saving some time in accessing the
903+;; generic-python-expression, really.
904+(defvar py-imenu-generic-regexp nil)
905+(defvar py-imenu-generic-parens nil)
906+
907+
908+(defun py-imenu-create-index-function ()
909+ "Python interface function for the Imenu package.
910+Finds all Python classes and functions/methods. Calls function
911+\\[py-imenu-create-index-engine]. See that function for the details
912+of how this works."
913+ (setq py-imenu-generic-regexp (car py-imenu-generic-expression)
914+ py-imenu-generic-parens (if py-imenu-show-method-args-p
915+ py-imenu-method-arg-parens
916+ py-imenu-method-no-arg-parens))
917+ (goto-char (point-min))
918+ ;; Warning: When the buffer has no classes or functions, this will
919+ ;; return nil, which seems proper according to the Imenu API, but
920+ ;; causes an error in the XEmacs port of Imenu. Sigh.
921+ (py-imenu-create-index-engine nil))
922+
923+(defun py-imenu-create-index-engine (&optional start-indent)
924+ "Function for finding Imenu definitions in Python.
925+
926+Finds all definitions (classes, methods, or functions) in a Python
927+file for the Imenu package.
928+
929+Returns a possibly nested alist of the form
930+
931+ (INDEX-NAME . INDEX-POSITION)
932+
933+The second element of the alist may be an alist, producing a nested
934+list as in
935+
936+ (INDEX-NAME . INDEX-ALIST)
937+
938+This function should not be called directly, as it calls itself
939+recursively and requires some setup. Rather this is the engine for
940+the function \\[py-imenu-create-index-function].
941+
942+It works recursively by looking for all definitions at the current
943+indention level. When it finds one, it adds it to the alist. If it
944+finds a definition at a greater indentation level, it removes the
945+previous definition from the alist. In its place it adds all
946+definitions found at the next indentation level. When it finds a
947+definition that is less indented then the current level, it returns
948+the alist it has created thus far.
949+
950+The optional argument START-INDENT indicates the starting indentation
951+at which to continue looking for Python classes, methods, or
952+functions. If this is not supplied, the function uses the indentation
953+of the first definition found."
954+ (let (index-alist
955+ sub-method-alist
956+ looking-p
957+ def-name prev-name
958+ cur-indent def-pos
959+ (class-paren (first py-imenu-generic-parens))
960+ (def-paren (second py-imenu-generic-parens)))
961+ (setq looking-p
962+ (re-search-forward py-imenu-generic-regexp (point-max) t))
963+ (while looking-p
964+ (save-excursion
965+ ;; used to set def-name to this value but generic-extract-name
966+ ;; is new to imenu-1.14. this way it still works with
967+ ;; imenu-1.11
968+ ;;(imenu--generic-extract-name py-imenu-generic-parens))
969+ (let ((cur-paren (if (match-beginning class-paren)
970+ class-paren def-paren)))
971+ (setq def-name
972+ (buffer-substring-no-properties (match-beginning cur-paren)
973+ (match-end cur-paren))))
974+ (save-match-data
975+ (py-beginning-of-def-or-class 'either))
976+ (beginning-of-line)
977+ (setq cur-indent (current-indentation)))
978+ ;; HACK: want to go to the next correct definition location. We
979+ ;; explicitly list them here but it would be better to have them
980+ ;; in a list.
981+ (setq def-pos
982+ (or (match-beginning class-paren)
983+ (match-beginning def-paren)))
984+ ;; if we don't have a starting indent level, take this one
985+ (or start-indent
986+ (setq start-indent cur-indent))
987+ ;; if we don't have class name yet, take this one
988+ (or prev-name
989+ (setq prev-name def-name))
990+ ;; what level is the next definition on? must be same, deeper
991+ ;; or shallower indentation
992+ (cond
993+ ;; Skip code in comments and strings
994+ ((py-in-literal))
995+ ;; at the same indent level, add it to the list...
996+ ((= start-indent cur-indent)
997+ (push (cons def-name def-pos) index-alist))
998+ ;; deeper indented expression, recurse
999+ ((< start-indent cur-indent)
1000+ ;; the point is currently on the expression we're supposed to
1001+ ;; start on, so go back to the last expression. The recursive
1002+ ;; call will find this place again and add it to the correct
1003+ ;; list
1004+ (re-search-backward py-imenu-generic-regexp (point-min) 'move)
1005+ (setq sub-method-alist (py-imenu-create-index-engine cur-indent))
1006+ (if sub-method-alist
1007+ ;; we put the last element on the index-alist on the start
1008+ ;; of the submethod alist so the user can still get to it.
1009+ (let ((save-elmt (pop index-alist)))
1010+ (push (cons prev-name
1011+ (cons save-elmt sub-method-alist))
1012+ index-alist))))
1013+ ;; found less indented expression, we're done.
1014+ (t
1015+ (setq looking-p nil)
1016+ (re-search-backward py-imenu-generic-regexp (point-min) t)))
1017+ ;; end-cond
1018+ (setq prev-name def-name)
1019+ (and looking-p
1020+ (setq looking-p
1021+ (re-search-forward py-imenu-generic-regexp
1022+ (point-max) 'move))))
1023+ (nreverse index-alist)))
1024+
1025+
1026+
1027+(defun py-choose-shell-by-shebang ()
1028+ "Choose CPython or JPython mode by looking at #! on the first line.
1029+Returns the appropriate mode function.
1030+Used by `py-choose-shell', and similar to but distinct from
1031+`set-auto-mode', though it uses `auto-mode-interpreter-regexp' (if available)."
1032+ ;; look for an interpreter specified in the first line
1033+ ;; similar to set-auto-mode (files.el)
1034+ (let* ((re (if (boundp 'auto-mode-interpreter-regexp)
1035+ auto-mode-interpreter-regexp
1036+ ;; stolen from Emacs 21.2
1037+ "#![ \t]?\\([^ \t\n]*/bin/env[ \t]\\)?\\([^ \t\n]+\\)"))
1038+ (interpreter (save-excursion
1039+ (goto-char (point-min))
1040+ (if (looking-at re)
1041+ (match-string 2)
1042+ "")))
1043+ elt)
1044+ ;; Map interpreter name to a mode.
1045+ (setq elt (assoc (file-name-nondirectory interpreter)
1046+ py-shell-alist))
1047+ (and elt (caddr elt))))
1048+
1049+
1050+
1051+(defun py-choose-shell-by-import ()
1052+ "Choose CPython or JPython mode based imports.
1053+If a file imports any packages in `py-jpython-packages', within
1054+`py-import-check-point-max' characters from the start of the file,
1055+return `jpython', otherwise return nil."
1056+ (let (mode)
1057+ (save-excursion
1058+ (goto-char (point-min))
1059+ (while (and (not mode)
1060+ (search-forward-regexp
1061+ "^\\(\\(from\\)\\|\\(import\\)\\) \\([^ \t\n.]+\\)"
1062+ py-import-check-point-max t))
1063+ (setq mode (and (member (match-string 4) py-jpython-packages)
1064+ 'jpython
1065+ ))))
1066+ mode))
1067+
1068+
1069+(defun py-choose-shell ()
1070+ "Choose CPython or JPython mode. Returns the appropriate mode function.
1071+This does the following:
1072+ - look for an interpreter with `py-choose-shell-by-shebang'
1073+ - examine imports using `py-choose-shell-by-import'
1074+ - default to the variable `py-default-interpreter'"
1075+ (interactive)
1076+ (or (py-choose-shell-by-shebang)
1077+ (py-choose-shell-by-import)
1078+ py-default-interpreter
1079+; 'cpython ;; don't use to py-default-interpreter, because default
1080+; ;; is only way to choose CPython
1081+ ))
1082+
1083+
1084+;;;###autoload
1085+(defun python-mode ()
1086+ "Major mode for editing Python files.
1087+To submit a problem report, enter `\\[py-submit-bug-report]' from a
1088+`python-mode' buffer. Do `\\[py-describe-mode]' for detailed
1089+documentation. To see what version of `python-mode' you are running,
1090+enter `\\[py-version]'.
1091+
1092+This mode knows about Python indentation, tokens, comments and
1093+continuation lines. Paragraphs are separated by blank lines only.
1094+
1095+COMMANDS
1096+\\{py-mode-map}
1097+VARIABLES
1098+
1099+py-indent-offset\t\tindentation increment
1100+py-block-comment-prefix\t\tcomment string used by `comment-region'
1101+py-python-command\t\tshell command to invoke Python interpreter
1102+py-temp-directory\t\tdirectory used for temp files (if needed)
1103+py-beep-if-tab-change\t\tring the bell if `tab-width' is changed"
1104+ (interactive)
1105+ ;; set up local variables
1106+ (kill-all-local-variables)
1107+ (make-local-variable 'font-lock-defaults)
1108+ (make-local-variable 'paragraph-separate)
1109+ (make-local-variable 'paragraph-start)
1110+ (make-local-variable 'require-final-newline)
1111+ (make-local-variable 'comment-start)
1112+ (make-local-variable 'comment-end)
1113+ (make-local-variable 'comment-start-skip)
1114+ (make-local-variable 'comment-column)
1115+ (make-local-variable 'comment-indent-function)
1116+ (make-local-variable 'indent-region-function)
1117+ (make-local-variable 'indent-line-function)
1118+ (make-local-variable 'add-log-current-defun-function)
1119+ ;;
1120+ (set-syntax-table py-mode-syntax-table)
1121+ (setq major-mode 'python-mode
1122+ mode-name "Python"
1123+ local-abbrev-table python-mode-abbrev-table
1124+ font-lock-defaults '(python-font-lock-keywords)
1125+ paragraph-separate "^[ \t]*$"
1126+ paragraph-start "^[ \t]*$"
1127+ require-final-newline t
1128+ comment-start "# "
1129+ comment-end ""
1130+ comment-start-skip "# *"
1131+ comment-column 40
1132+ comment-indent-function 'py-comment-indent-function
1133+ indent-region-function 'py-indent-region
1134+ indent-line-function 'py-indent-line
1135+ ;; tell add-log.el how to find the current function/method/variable
1136+ add-log-current-defun-function 'py-current-defun
1137+ )
1138+ (use-local-map py-mode-map)
1139+ ;; add the menu
1140+ (if py-menu
1141+ (easy-menu-add py-menu))
1142+ ;; Emacs 19 requires this
1143+ (if (boundp 'comment-multi-line)
1144+ (setq comment-multi-line nil))
1145+ ;; Install Imenu if available
1146+ (when (py-safe (require 'imenu))
1147+ (setq imenu-create-index-function #'py-imenu-create-index-function)
1148+ (setq imenu-generic-expression py-imenu-generic-expression)
1149+ (if (fboundp 'imenu-add-to-menubar)
1150+ (imenu-add-to-menubar (format "%s-%s" "IM" mode-name)))
1151+ )
1152+ ;; Run the mode hook. Note that py-mode-hook is deprecated.
1153+ (if python-mode-hook
1154+ (run-hooks 'python-mode-hook)
1155+ (run-hooks 'py-mode-hook))
1156+ ;; Now do the automagical guessing
1157+ (if py-smart-indentation
1158+ (let ((offset py-indent-offset))
1159+ ;; It's okay if this fails to guess a good value
1160+ (if (and (py-safe (py-guess-indent-offset))
1161+ (<= py-indent-offset 8)
1162+ (>= py-indent-offset 2))
1163+ (setq offset py-indent-offset))
1164+ (setq py-indent-offset offset)
1165+ ;; Only turn indent-tabs-mode off if tab-width !=
1166+ ;; py-indent-offset. Never turn it on, because the user must
1167+ ;; have explicitly turned it off.
1168+ (if (/= tab-width py-indent-offset)
1169+ (setq indent-tabs-mode nil))
1170+ ))
1171+ ;; Set the default shell if not already set
1172+ (when (null py-which-shell)
1173+ (py-toggle-shells (py-choose-shell))))
1174+
1175+
1176+(defun jpython-mode ()
1177+ "Major mode for editing JPython/Jython files.
1178+This is a simple wrapper around `python-mode'.
1179+It runs `jpython-mode-hook' then calls `python-mode.'
1180+It is added to `interpreter-mode-alist' and `py-choose-shell'.
1181+"
1182+ (interactive)
1183+ (python-mode)
1184+ (py-toggle-shells 'jpython)
1185+ (when jpython-mode-hook
1186+ (run-hooks 'jpython-mode-hook)))
1187+
1188+
1189+;; It's handy to add recognition of Python files to the
1190+;; interpreter-mode-alist and to auto-mode-alist. With the former, we
1191+;; can specify different `derived-modes' based on the #! line, but
1192+;; with the latter, we can't. So we just won't add them if they're
1193+;; already added.
1194+(let ((modes '(("jpython" . jpython-mode)
1195+ ("jython" . jpython-mode)
1196+ ("python" . python-mode))))
1197+ (while modes
1198+ (when (not (assoc (car modes) interpreter-mode-alist))
1199+ (push (car modes) interpreter-mode-alist))
1200+ (setq modes (cdr modes))))
1201+
1202+(when (not (or (rassq 'python-mode auto-mode-alist)
1203+ (rassq 'jpython-mode auto-mode-alist)))
1204+ (push '("\\.py$" . python-mode) auto-mode-alist))
1205+
1206+
1207+
1208+;; electric characters
1209+(defun py-outdent-p ()
1210+ "Returns non-nil if the current line should dedent one level."
1211+ (save-excursion
1212+ (and (progn (back-to-indentation)
1213+ (looking-at py-outdent-re))
1214+ ;; short circuit infloop on illegal construct
1215+ (not (bobp))
1216+ (progn (forward-line -1)
1217+ (py-goto-initial-line)
1218+ (back-to-indentation)
1219+ (while (or (looking-at py-blank-or-comment-re)
1220+ (bobp))
1221+ (backward-to-indentation 1))
1222+ (not (looking-at py-no-outdent-re)))
1223+ )))
1224+
1225+(defun py-electric-colon (arg)
1226+ "Insert a colon.
1227+In certain cases the line is dedented appropriately. If a numeric
1228+argument ARG is provided, that many colons are inserted
1229+non-electrically. Electric behavior is inhibited inside a string or
1230+comment."
1231+ (interactive "*P")
1232+ (self-insert-command (prefix-numeric-value arg))
1233+ ;; are we in a string or comment?
1234+ (if (save-excursion
1235+ (let ((pps (parse-partial-sexp (save-excursion
1236+ (py-beginning-of-def-or-class)
1237+ (point))
1238+ (point))))
1239+ (not (or (nth 3 pps) (nth 4 pps)))))
1240+ (save-excursion
1241+ (let ((here (point))
1242+ (outdent 0)
1243+ (indent (py-compute-indentation t)))
1244+ (if (and (not arg)
1245+ (py-outdent-p)
1246+ (= indent (save-excursion
1247+ (py-next-statement -1)
1248+ (py-compute-indentation t)))
1249+ )
1250+ (setq outdent py-indent-offset))
1251+ ;; Don't indent, only dedent. This assumes that any lines
1252+ ;; that are already dedented relative to
1253+ ;; py-compute-indentation were put there on purpose. It's
1254+ ;; highly annoying to have `:' indent for you. Use TAB, C-c
1255+ ;; C-l or C-c C-r to adjust. TBD: Is there a better way to
1256+ ;; determine this???
1257+ (if (< (current-indentation) indent) nil
1258+ (goto-char here)
1259+ (beginning-of-line)
1260+ (delete-horizontal-space)
1261+ (indent-to (- indent outdent))
1262+ )))))
1263+
1264+
1265+;; Python subprocess utilities and filters
1266+(defun py-execute-file (proc filename)
1267+ "Send to Python interpreter process PROC \"execfile('FILENAME')\".
1268+Make that process's buffer visible and force display. Also make
1269+comint believe the user typed this string so that
1270+`kill-output-from-shell' does The Right Thing."
1271+ (let ((curbuf (current-buffer))
1272+ (procbuf (process-buffer proc))
1273+; (comint-scroll-to-bottom-on-output t)
1274+ (msg (format "## working on region in file %s...\n" filename))
1275+ (cmd (format "execfile(r'%s')\n" filename)))
1276+ (unwind-protect
1277+ (save-excursion
1278+ (set-buffer procbuf)
1279+ (goto-char (point-max))
1280+ (move-marker (process-mark proc) (point))
1281+ (funcall (process-filter proc) proc msg))
1282+ (set-buffer curbuf))
1283+ (process-send-string proc cmd)))
1284+
1285+(defun py-comint-output-filter-function (string)
1286+ "Watch output for Python prompt and exec next file waiting in queue.
1287+This function is appropriate for `comint-output-filter-functions'."
1288+ ;; TBD: this should probably use split-string
1289+ (when (and (or (string-equal string ">>> ")
1290+ (and (>= (length string) 5)
1291+ (string-equal (substring string -5) "\n>>> ")))
1292+ py-file-queue)
1293+ (pop-to-buffer (current-buffer))
1294+ (py-safe (delete-file (car py-file-queue)))
1295+ (setq py-file-queue (cdr py-file-queue))
1296+ (if py-file-queue
1297+ (let ((pyproc (get-buffer-process (current-buffer))))
1298+ (py-execute-file pyproc (car py-file-queue))))
1299+ ))
1300+
1301+(defun py-pdbtrack-overlay-arrow (activation)
1302+ "Activate or de arrow at beginning-of-line in current buffer."
1303+ ;; This was derived/simplified from edebug-overlay-arrow
1304+ (cond (activation
1305+ (setq overlay-arrow-position (make-marker))
1306+ (setq overlay-arrow-string "=>")
1307+ (set-marker overlay-arrow-position (py-point 'bol) (current-buffer))
1308+ (setq py-pdbtrack-is-tracking-p t))
1309+ (overlay-arrow-position
1310+ (setq overlay-arrow-position nil)
1311+ (setq py-pdbtrack-is-tracking-p nil))
1312+ ))
1313+
1314+(defun py-pdbtrack-track-stack-file (text)
1315+ "Show the file indicated by the pdb stack entry line, in a separate window.
1316+
1317+Activity is disabled if the buffer-local variable
1318+`py-pdbtrack-do-tracking-p' is nil.
1319+
1320+We depend on the pdb input prompt matching `py-pdbtrack-input-prompt'
1321+at the beginning of the line.
1322+
1323+If the traceback target file path is invalid, we look for the most
1324+recently visited python-mode buffer which either has the name of the
1325+current function \(or class) or which defines the function \(or
1326+class). This is to provide for remote scripts, eg, Zope's 'Script
1327+(Python)' - put a _copy_ of the script in a buffer named for the
1328+script, and set to python-mode, and pdbtrack will find it.)"
1329+ ;; Instead of trying to piece things together from partial text
1330+ ;; (which can be almost useless depending on Emacs version), we
1331+ ;; monitor to the point where we have the next pdb prompt, and then
1332+ ;; check all text from comint-last-input-end to process-mark.
1333+ ;;
1334+ ;; Also, we're very conservative about clearing the overlay arrow,
1335+ ;; to minimize residue. This means, for instance, that executing
1336+ ;; other pdb commands wipe out the highlight. You can always do a
1337+ ;; 'where' (aka 'w') command to reveal the overlay arrow.
1338+ (let* ((origbuf (current-buffer))
1339+ (currproc (get-buffer-process origbuf)))
1340+
1341+ (if (not (and currproc py-pdbtrack-do-tracking-p))
1342+ (py-pdbtrack-overlay-arrow nil)
1343+
1344+ (let* ((procmark (process-mark currproc))
1345+ (block (buffer-substring (max comint-last-input-end
1346+ (- procmark
1347+ py-pdbtrack-track-range))
1348+ procmark))
1349+ target target_fname target_lineno)
1350+
1351+ (if (not (string-match (concat py-pdbtrack-input-prompt "$") block))
1352+ (py-pdbtrack-overlay-arrow nil)
1353+
1354+ (setq target (py-pdbtrack-get-source-buffer block))
1355+
1356+ (if (stringp target)
1357+ (message "pdbtrack: %s" target)
1358+
1359+ (setq target_lineno (car target))
1360+ (setq target_buffer (cadr target))
1361+ (setq target_fname (buffer-file-name target_buffer))
1362+ (switch-to-buffer-other-window target_buffer)
1363+ (goto-line target_lineno)
1364+ (message "pdbtrack: line %s, file %s" target_lineno target_fname)
1365+ (py-pdbtrack-overlay-arrow t)
1366+ (pop-to-buffer origbuf t)
1367+
1368+ )))))
1369+ )
1370+
1371+(defun py-pdbtrack-get-source-buffer (block)
1372+ "Return line number and buffer of code indicated by block's traceback text.
1373+
1374+We look first to visit the file indicated in the trace.
1375+
1376+Failing that, we look for the most recently visited python-mode buffer
1377+with the same name or having
1378+having the named function.
1379+
1380+If we're unable find the source code we return a string describing the
1381+problem as best as we can determine."
1382+
1383+ (if (not (string-match py-pdbtrack-stack-entry-regexp block))
1384+
1385+ "Traceback cue not found"
1386+
1387+ (let* ((filename (match-string 1 block))
1388+ (lineno (string-to-int (match-string 2 block)))
1389+ (funcname (match-string 3 block))
1390+ funcbuffer)
1391+
1392+ (cond ((file-exists-p filename)
1393+ (list lineno (find-file-noselect filename)))
1394+
1395+ ((setq funcbuffer (py-pdbtrack-grub-for-buffer funcname lineno))
1396+ (if (string-match "/Script (Python)$" filename)
1397+ ;; Add in number of lines for leading '##' comments:
1398+ (setq lineno
1399+ (+ lineno
1400+ (save-excursion
1401+ (set-buffer funcbuffer)
1402+ (count-lines
1403+ (point-min)
1404+ (max (point-min)
1405+ (string-match "^\\([^#]\\|#[^#]\\|#$\\)"
1406+ (buffer-substring (point-min)
1407+ (point-max)))
1408+ ))))))
1409+ (list lineno funcbuffer))
1410+
1411+ ((= (elt filename 0) ?\<)
1412+ (format "(Non-file source: '%s')" filename))
1413+
1414+ (t (format "Not found: %s(), %s" funcname filename)))
1415+ )
1416+ )
1417+ )
1418+
1419+(defun py-pdbtrack-grub-for-buffer (funcname lineno)
1420+ "Find most recent buffer itself named or having function funcname.
1421+
1422+We first check the last buffer this function found, if any, then walk
1423+throught the buffer-list history for python-mode buffers that are
1424+named for funcname or define a function funcname."
1425+ (let ((buffers (buffer-list))
1426+ curbuf
1427+ got)
1428+ (while (and buffers (not got))
1429+ (setq buf (car buffers)
1430+ buffers (cdr buffers))
1431+ (if (and (save-excursion (set-buffer buf)
1432+ (string= major-mode "python-mode"))
1433+ (or (string-match funcname (buffer-name buf))
1434+ (string-match (concat "^\\s-*\\(def\\|class\\)\\s-+"
1435+ funcname "\\s-*(")
1436+ (save-excursion
1437+ (set-buffer buf)
1438+ (buffer-substring (point-min)
1439+ (point-max))))))
1440+ (setq got buf)))
1441+ (setq py-pdbtrack-last-grubbed-buffer got)))
1442+
1443+(defun py-postprocess-output-buffer (buf)
1444+ "Highlight exceptions found in BUF.
1445+If an exception occurred return t, otherwise return nil. BUF must exist."
1446+ (let (line file bol err-p)
1447+ (save-excursion
1448+ (set-buffer buf)
1449+ (beginning-of-buffer)
1450+ (while (re-search-forward py-traceback-line-re nil t)
1451+ (setq file (match-string 1)
1452+ line (string-to-int (match-string 2))
1453+ bol (py-point 'bol))
1454+ (py-highlight-line bol (py-point 'eol) file line)))
1455+ (when (and py-jump-on-exception line)
1456+ (beep)
1457+ (py-jump-to-exception file line)
1458+ (setq err-p t))
1459+ err-p))
1460+
1461+
1462+
1463+;;; Subprocess commands
1464+
1465+;; only used when (memq 'broken-temp-names py-emacs-features)
1466+(defvar py-serial-number 0)
1467+(defvar py-exception-buffer nil)
1468+(defconst py-output-buffer "*Python Output*")
1469+(make-variable-buffer-local 'py-output-buffer)
1470+
1471+;; for toggling between CPython and JPython
1472+(defvar py-which-shell nil)
1473+(defvar py-which-args py-python-command-args)
1474+(defvar py-which-bufname "Python")
1475+(make-variable-buffer-local 'py-which-shell)
1476+(make-variable-buffer-local 'py-which-args)
1477+(make-variable-buffer-local 'py-which-bufname)
1478+
1479+(defun py-toggle-shells (arg)
1480+ "Toggles between the CPython and JPython shells.
1481+
1482+With positive argument ARG (interactively \\[universal-argument]),
1483+uses the CPython shell, with negative ARG uses the JPython shell, and
1484+with a zero argument, toggles the shell.
1485+
1486+Programmatically, ARG can also be one of the symbols `cpython' or
1487+`jpython', equivalent to positive arg and negative arg respectively."
1488+ (interactive "P")
1489+ ;; default is to toggle
1490+ (if (null arg)
1491+ (setq arg 0))
1492+ ;; preprocess arg
1493+ (cond
1494+ ((equal arg 0)
1495+ ;; toggle
1496+ (if (string-equal py-which-bufname "Python")
1497+ (setq arg -1)
1498+ (setq arg 1)))
1499+ ((equal arg 'cpython) (setq arg 1))
1500+ ((equal arg 'jpython) (setq arg -1)))
1501+ (let (msg)
1502+ (cond
1503+ ((< 0 arg)
1504+ ;; set to CPython
1505+ (setq py-which-shell py-python-command
1506+ py-which-args py-python-command-args
1507+ py-which-bufname "Python"
1508+ msg "CPython"
1509+ mode-name "Python"))
1510+ ((> 0 arg)
1511+ (setq py-which-shell py-jpython-command
1512+ py-which-args py-jpython-command-args
1513+ py-which-bufname "JPython"
1514+ msg "JPython"
1515+ mode-name "JPython"))
1516+ )
1517+ (message "Using the %s shell" msg)
1518+ (setq py-output-buffer (format "*%s Output*" py-which-bufname))))
1519+
1520+;;;###autoload
1521+(defun py-shell (&optional argprompt)
1522+ "Start an interactive Python interpreter in another window.
1523+This is like Shell mode, except that Python is running in the window
1524+instead of a shell. See the `Interactive Shell' and `Shell Mode'
1525+sections of the Emacs manual for details, especially for the key
1526+bindings active in the `*Python*' buffer.
1527+
1528+With optional \\[universal-argument], the user is prompted for the
1529+flags to pass to the Python interpreter. This has no effect when this
1530+command is used to switch to an existing process, only when a new
1531+process is started. If you use this, you will probably want to ensure
1532+that the current arguments are retained (they will be included in the
1533+prompt). This argument is ignored when this function is called
1534+programmatically, or when running in Emacs 19.34 or older.
1535+
1536+Note: You can toggle between using the CPython interpreter and the
1537+JPython interpreter by hitting \\[py-toggle-shells]. This toggles
1538+buffer local variables which control whether all your subshell
1539+interactions happen to the `*JPython*' or `*Python*' buffers (the
1540+latter is the name used for the CPython buffer).
1541+
1542+Warning: Don't use an interactive Python if you change sys.ps1 or
1543+sys.ps2 from their default values, or if you're running code that
1544+prints `>>> ' or `... ' at the start of a line. `python-mode' can't
1545+distinguish your output from Python's output, and assumes that `>>> '
1546+at the start of a line is a prompt from Python. Similarly, the Emacs
1547+Shell mode code assumes that both `>>> ' and `... ' at the start of a
1548+line are Python prompts. Bad things can happen if you fool either
1549+mode.
1550+
1551+Warning: If you do any editing *in* the process buffer *while* the
1552+buffer is accepting output from Python, do NOT attempt to `undo' the
1553+changes. Some of the output (nowhere near the parts you changed!) may
1554+be lost if you do. This appears to be an Emacs bug, an unfortunate
1555+interaction between undo and process filters; the same problem exists in
1556+non-Python process buffers using the default (Emacs-supplied) process
1557+filter."
1558+ (interactive "P")
1559+ ;; Set the default shell if not already set
1560+ (when (null py-which-shell)
1561+ (py-toggle-shells py-default-interpreter))
1562+ (let ((args py-which-args))
1563+ (when (and argprompt
1564+ (interactive-p)
1565+ (fboundp 'split-string))
1566+ ;; TBD: Perhaps force "-i" in the final list?
1567+ (setq args (split-string
1568+ (read-string (concat py-which-bufname
1569+ " arguments: ")
1570+ (concat
1571+ (mapconcat 'identity py-which-args " ") " ")
1572+ ))))
1573+ (switch-to-buffer-other-window
1574+ (apply 'make-comint py-which-bufname py-which-shell nil args))
1575+ (make-local-variable 'comint-prompt-regexp)
1576+ (setq comint-prompt-regexp "^>>> \\|^[.][.][.] \\|^(pdb) ")
1577+ (add-hook 'comint-output-filter-functions
1578+ 'py-comint-output-filter-function)
1579+ ;; pdbtrack
1580+ (add-hook 'comint-output-filter-functions 'py-pdbtrack-track-stack-file)
1581+ (setq py-pdbtrack-do-tracking-p t)
1582+ (set-syntax-table py-mode-syntax-table)
1583+ (use-local-map py-shell-map)
1584+ (run-hooks 'py-shell-hook)
1585+ ))
1586+
1587+(defun py-clear-queue ()
1588+ "Clear the queue of temporary files waiting to execute."
1589+ (interactive)
1590+ (let ((n (length py-file-queue)))
1591+ (mapcar 'delete-file py-file-queue)
1592+ (setq py-file-queue nil)
1593+ (message "%d pending files de-queued." n)))
1594+
1595+
1596+(defun py-execute-region (start end &optional async)
1597+ "Execute the region in a Python interpreter.
1598+
1599+The region is first copied into a temporary file (in the directory
1600+`py-temp-directory'). If there is no Python interpreter shell
1601+running, this file is executed synchronously using
1602+`shell-command-on-region'. If the program is long running, use
1603+\\[universal-argument] to run the command asynchronously in its own
1604+buffer.
1605+
1606+When this function is used programmatically, arguments START and END
1607+specify the region to execute, and optional third argument ASYNC, if
1608+non-nil, specifies to run the command asynchronously in its own
1609+buffer.
1610+
1611+If the Python interpreter shell is running, the region is execfile()'d
1612+in that shell. If you try to execute regions too quickly,
1613+`python-mode' will queue them up and execute them one at a time when
1614+it sees a `>>> ' prompt from Python. Each time this happens, the
1615+process buffer is popped into a window (if it's not already in some
1616+window) so you can see it, and a comment of the form
1617+
1618+ \t## working on region in file <name>...
1619+
1620+is inserted at the end. See also the command `py-clear-queue'."
1621+ (interactive "r\nP")
1622+ ;; Skip ahead to the first non-blank line
1623+ (let* ((proc (get-process py-which-bufname))
1624+ (temp (if (memq 'broken-temp-names py-emacs-features)
1625+ (let
1626+ ((sn py-serial-number)
1627+ (pid (and (fboundp 'emacs-pid) (emacs-pid))))
1628+ (setq py-serial-number (1+ py-serial-number))
1629+ (if pid
1630+ (format "python-%d-%d" sn pid)
1631+ (format "python-%d" sn)))
1632+ (make-temp-name "python-")))
1633+ (file (concat (expand-file-name temp py-temp-directory) ".py"))
1634+ (cur (current-buffer))
1635+ (buf (get-buffer-create file))
1636+ shell)
1637+ ;; Write the contents of the buffer, watching out for indented regions.
1638+ (save-excursion
1639+ (goto-char start)
1640+ (beginning-of-line)
1641+ (while (and (looking-at "\\s *$")
1642+ (< (point) end))
1643+ (forward-line 1))
1644+ (setq start (point))
1645+ (or (< start end)
1646+ (error "Region is empty"))
1647+ (let ((needs-if (/= (py-point 'bol) (py-point 'boi))))
1648+ (set-buffer buf)
1649+ (python-mode)
1650+ (when needs-if
1651+ (insert "if 1:\n"))
1652+ (insert-buffer-substring cur start end)
1653+ ;; Set the shell either to the #! line command, or to the
1654+ ;; py-which-shell buffer local variable.
1655+ (setq shell (or (py-choose-shell-by-shebang)
1656+ (py-choose-shell-by-import)
1657+ py-which-shell))))
1658+ (cond
1659+ ;; always run the code in its own asynchronous subprocess
1660+ (async
1661+ ;; User explicitly wants this to run in its own async subprocess
1662+ (save-excursion
1663+ (set-buffer buf)
1664+ (write-region (point-min) (point-max) file nil 'nomsg))
1665+ (let* ((buf (generate-new-buffer-name py-output-buffer))
1666+ ;; TBD: a horrible hack, but why create new Custom variables?
1667+ (arg (if (string-equal py-which-bufname "Python")
1668+ "-u" "")))
1669+ (start-process py-which-bufname buf shell arg file)
1670+ (pop-to-buffer buf)
1671+ (py-postprocess-output-buffer buf)
1672+ ;; TBD: clean up the temporary file!
1673+ ))
1674+ ;; if the Python interpreter shell is running, queue it up for
1675+ ;; execution there.
1676+ (proc
1677+ ;; use the existing python shell
1678+ (save-excursion
1679+ (set-buffer buf)
1680+ (write-region (point-min) (point-max) file nil 'nomsg))
1681+ (if (not py-file-queue)
1682+ (py-execute-file proc file)
1683+ (message "File %s queued for execution" file))
1684+ (setq py-file-queue (append py-file-queue (list file)))
1685+ (setq py-exception-buffer (cons file (current-buffer))))
1686+ (t
1687+ ;; TBD: a horrible hack, but why create new Custom variables?
1688+ (let ((cmd (concat shell (if (string-equal py-which-bufname "JPython")
1689+ " -" ""))))
1690+ ;; otherwise either run it synchronously in a subprocess
1691+ (save-excursion
1692+ (set-buffer buf)
1693+ (shell-command-on-region (point-min) (point-max)
1694+ cmd py-output-buffer))
1695+ ;; shell-command-on-region kills the output buffer if it never
1696+ ;; existed and there's no output from the command
1697+ (if (not (get-buffer py-output-buffer))
1698+ (message "No output.")
1699+ (setq py-exception-buffer (current-buffer))
1700+ (let ((err-p (py-postprocess-output-buffer py-output-buffer)))
1701+ (pop-to-buffer py-output-buffer)
1702+ (if err-p
1703+ (pop-to-buffer py-exception-buffer)))
1704+ ))
1705+ ))
1706+ ;; Clean up after ourselves.
1707+ (kill-buffer buf)))
1708+
1709+
1710+;; Code execution commands
1711+(defun py-execute-buffer (&optional async)
1712+ "Send the contents of the buffer to a Python interpreter.
1713+If the file local variable `py-master-file' is non-nil, execute the
1714+named file instead of the buffer's file.
1715+
1716+If there is a *Python* process buffer it is used. If a clipping
1717+restriction is in effect, only the accessible portion of the buffer is
1718+sent. A trailing newline will be supplied if needed.
1719+
1720+See the `\\[py-execute-region]' docs for an account of some
1721+subtleties, including the use of the optional ASYNC argument."
1722+ (interactive "P")
1723+ (if py-master-file
1724+ (let* ((filename (expand-file-name py-master-file))
1725+ (buffer (or (get-file-buffer filename)
1726+ (find-file-noselect filename))))
1727+ (set-buffer buffer)))
1728+ (py-execute-region (point-min) (point-max) async))
1729+
1730+(defun py-execute-import-or-reload (&optional async)
1731+ "Import the current buffer's file in a Python interpreter.
1732+
1733+If the file has already been imported, then do reload instead to get
1734+the latest version.
1735+
1736+If the file's name does not end in \".py\", then do execfile instead.
1737+
1738+If the current buffer is not visiting a file, do `py-execute-buffer'
1739+instead.
1740+
1741+If the file local variable `py-master-file' is non-nil, import or
1742+reload the named file instead of the buffer's file. The file may be
1743+saved based on the value of `py-execute-import-or-reload-save-p'.
1744+
1745+See the `\\[py-execute-region]' docs for an account of some
1746+subtleties, including the use of the optional ASYNC argument.
1747+
1748+This may be preferable to `\\[py-execute-buffer]' because:
1749+
1750+ - Definitions stay in their module rather than appearing at top
1751+ level, where they would clutter the global namespace and not affect
1752+ uses of qualified names (MODULE.NAME).
1753+
1754+ - The Python debugger gets line number information about the functions."
1755+ (interactive "P")
1756+ ;; Check file local variable py-master-file
1757+ (if py-master-file
1758+ (let* ((filename (expand-file-name py-master-file))
1759+ (buffer (or (get-file-buffer filename)
1760+ (find-file-noselect filename))))
1761+ (set-buffer buffer)))
1762+ (let ((file (buffer-file-name (current-buffer))))
1763+ (if file
1764+ (progn
1765+ ;; Maybe save some buffers
1766+ (save-some-buffers (not py-ask-about-save) nil)
1767+ (py-execute-string
1768+ (if (string-match "\\.py$" file)
1769+ (let ((f (file-name-sans-extension
1770+ (file-name-nondirectory file))))
1771+ (format "if globals().has_key('%s'):\n reload(%s)\nelse:\n import %s\n"
1772+ f f f))
1773+ (format "execfile(r'%s')\n" file))
1774+ async))
1775+ ;; else
1776+ (py-execute-buffer async))))
1777+
1778+
1779+(defun py-execute-def-or-class (&optional async)
1780+ "Send the current function or class definition to a Python interpreter.
1781+
1782+If there is a *Python* process buffer it is used.
1783+
1784+See the `\\[py-execute-region]' docs for an account of some
1785+subtleties, including the use of the optional ASYNC argument."
1786+ (interactive "P")
1787+ (save-excursion
1788+ (py-mark-def-or-class)
1789+ ;; mark is before point
1790+ (py-execute-region (mark) (point) async)))
1791+
1792+
1793+(defun py-execute-string (string &optional async)
1794+ "Send the argument STRING to a Python interpreter.
1795+
1796+If there is a *Python* process buffer it is used.
1797+
1798+See the `\\[py-execute-region]' docs for an account of some
1799+subtleties, including the use of the optional ASYNC argument."
1800+ (interactive "sExecute Python command: ")
1801+ (save-excursion
1802+ (set-buffer (get-buffer-create
1803+ (generate-new-buffer-name " *Python Command*")))
1804+ (insert string)
1805+ (py-execute-region (point-min) (point-max) async)))
1806+
1807+
1808+
1809+(defun py-jump-to-exception (file line)
1810+ "Jump to the Python code in FILE at LINE."
1811+ (let ((buffer (cond ((string-equal file "<stdin>")
1812+ (if (consp py-exception-buffer)
1813+ (cdr py-exception-buffer)
1814+ py-exception-buffer))
1815+ ((and (consp py-exception-buffer)
1816+ (string-equal file (car py-exception-buffer)))
1817+ (cdr py-exception-buffer))
1818+ ((py-safe (find-file-noselect file)))
1819+ ;; could not figure out what file the exception
1820+ ;; is pointing to, so prompt for it
1821+ (t (find-file (read-file-name "Exception file: "
1822+ nil
1823+ file t))))))
1824+ (pop-to-buffer buffer)
1825+ ;; Force Python mode
1826+ (if (not (eq major-mode 'python-mode))
1827+ (python-mode))
1828+ (goto-line line)
1829+ (message "Jumping to exception in file %s on line %d" file line)))
1830+
1831+(defun py-mouseto-exception (event)
1832+ "Jump to the code which caused the Python exception at EVENT.
1833+EVENT is usually a mouse click."
1834+ (interactive "e")
1835+ (cond
1836+ ((fboundp 'event-point)
1837+ ;; XEmacs
1838+ (let* ((point (event-point event))
1839+ (buffer (event-buffer event))
1840+ (e (and point buffer (extent-at point buffer 'py-exc-info)))
1841+ (info (and e (extent-property e 'py-exc-info))))
1842+ (message "Event point: %d, info: %s" point info)
1843+ (and info
1844+ (py-jump-to-exception (car info) (cdr info)))
1845+ ))
1846+ ;; Emacs -- Please port this!
1847+ ))
1848+
1849+(defun py-goto-exception ()
1850+ "Go to the line indicated by the traceback."
1851+ (interactive)
1852+ (let (file line)
1853+ (save-excursion
1854+ (beginning-of-line)
1855+ (if (looking-at py-traceback-line-re)
1856+ (setq file (match-string 1)
1857+ line (string-to-int (match-string 2)))))
1858+ (if (not file)
1859+ (error "Not on a traceback line"))
1860+ (py-jump-to-exception file line)))
1861+
1862+(defun py-find-next-exception (start buffer searchdir errwhere)
1863+ "Find the next Python exception and jump to the code that caused it.
1864+START is the buffer position in BUFFER from which to begin searching
1865+for an exception. SEARCHDIR is a function, either
1866+`re-search-backward' or `re-search-forward' indicating the direction
1867+to search. ERRWHERE is used in an error message if the limit (top or
1868+bottom) of the trackback stack is encountered."
1869+ (let (file line)
1870+ (save-excursion
1871+ (set-buffer buffer)
1872+ (goto-char (py-point start))
1873+ (if (funcall searchdir py-traceback-line-re nil t)
1874+ (setq file (match-string 1)
1875+ line (string-to-int (match-string 2)))))
1876+ (if (and file line)
1877+ (py-jump-to-exception file line)
1878+ (error "%s of traceback" errwhere))))
1879+
1880+(defun py-down-exception (&optional bottom)
1881+ "Go to the next line down in the traceback.
1882+With \\[univeral-argument] (programmatically, optional argument
1883+BOTTOM), jump to the bottom (innermost) exception in the exception
1884+stack."
1885+ (interactive "P")
1886+ (let* ((proc (get-process "Python"))
1887+ (buffer (if proc "*Python*" py-output-buffer)))
1888+ (if bottom
1889+ (py-find-next-exception 'eob buffer 're-search-backward "Bottom")
1890+ (py-find-next-exception 'eol buffer 're-search-forward "Bottom"))))
1891+
1892+(defun py-up-exception (&optional top)
1893+ "Go to the previous line up in the traceback.
1894+With \\[universal-argument] (programmatically, optional argument TOP)
1895+jump to the top (outermost) exception in the exception stack."
1896+ (interactive "P")
1897+ (let* ((proc (get-process "Python"))
1898+ (buffer (if proc "*Python*" py-output-buffer)))
1899+ (if top
1900+ (py-find-next-exception 'bob buffer 're-search-forward "Top")
1901+ (py-find-next-exception 'bol buffer 're-search-backward "Top"))))
1902+
1903+
1904+;; Electric deletion
1905+(defun py-electric-backspace (arg)
1906+ "Delete preceding character or levels of indentation.
1907+Deletion is performed by calling the function in `py-backspace-function'
1908+with a single argument (the number of characters to delete).
1909+
1910+If point is at the leftmost column, delete the preceding newline.
1911+
1912+Otherwise, if point is at the leftmost non-whitespace character of a
1913+line that is neither a continuation line nor a non-indenting comment
1914+line, or if point is at the end of a blank line, this command reduces
1915+the indentation to match that of the line that opened the current
1916+block of code. The line that opened the block is displayed in the
1917+echo area to help you keep track of where you are. With
1918+\\[universal-argument] dedents that many blocks (but not past column
1919+zero).
1920+
1921+Otherwise the preceding character is deleted, converting a tab to
1922+spaces if needed so that only a single column position is deleted.
1923+\\[universal-argument] specifies how many characters to delete;
1924+default is 1.
1925+
1926+When used programmatically, argument ARG specifies the number of
1927+blocks to dedent, or the number of characters to delete, as indicated
1928+above."
1929+ (interactive "*p")
1930+ (if (or (/= (current-indentation) (current-column))
1931+ (bolp)
1932+ (py-continuation-line-p)
1933+; (not py-honor-comment-indentation)
1934+; (looking-at "#[^ \t\n]") ; non-indenting #
1935+ )
1936+ (funcall py-backspace-function arg)
1937+ ;; else indent the same as the colon line that opened the block
1938+ ;; force non-blank so py-goto-block-up doesn't ignore it
1939+ (insert-char ?* 1)
1940+ (backward-char)
1941+ (let ((base-indent 0) ; indentation of base line
1942+ (base-text "") ; and text of base line
1943+ (base-found-p nil))
1944+ (save-excursion
1945+ (while (< 0 arg)
1946+ (condition-case nil ; in case no enclosing block
1947+ (progn
1948+ (py-goto-block-up 'no-mark)
1949+ (setq base-indent (current-indentation)
1950+ base-text (py-suck-up-leading-text)
1951+ base-found-p t))
1952+ (error nil))
1953+ (setq arg (1- arg))))
1954+ (delete-char 1) ; toss the dummy character
1955+ (delete-horizontal-space)
1956+ (indent-to base-indent)
1957+ (if base-found-p
1958+ (message "Closes block: %s" base-text)))))
1959+
1960+
1961+(defun py-electric-delete (arg)
1962+ "Delete preceding or following character or levels of whitespace.
1963+
1964+The behavior of this function depends on the variable
1965+`delete-key-deletes-forward'. If this variable is nil (or does not
1966+exist, as in older Emacsen and non-XEmacs versions), then this
1967+function behaves identically to \\[c-electric-backspace].
1968+
1969+If `delete-key-deletes-forward' is non-nil and is supported in your
1970+Emacs, then deletion occurs in the forward direction, by calling the
1971+function in `py-delete-function'.
1972+
1973+\\[universal-argument] (programmatically, argument ARG) specifies the
1974+number of characters to delete (default is 1)."
1975+ (interactive "*p")
1976+ (if (or (and (fboundp 'delete-forward-p) ;XEmacs 21
1977+ (delete-forward-p))
1978+ (and (boundp 'delete-key-deletes-forward) ;XEmacs 20
1979+ delete-key-deletes-forward))
1980+ (funcall py-delete-function arg)
1981+ (py-electric-backspace arg)))
1982+
1983+;; required for pending-del and delsel modes
1984+(put 'py-electric-colon 'delete-selection t) ;delsel
1985+(put 'py-electric-colon 'pending-delete t) ;pending-del
1986+(put 'py-electric-backspace 'delete-selection 'supersede) ;delsel
1987+(put 'py-electric-backspace 'pending-delete 'supersede) ;pending-del
1988+(put 'py-electric-delete 'delete-selection 'supersede) ;delsel
1989+(put 'py-electric-delete 'pending-delete 'supersede) ;pending-del
1990+
1991+
1992+
1993+(defun py-indent-line (&optional arg)
1994+ "Fix the indentation of the current line according to Python rules.
1995+With \\[universal-argument] (programmatically, the optional argument
1996+ARG non-nil), ignore dedenting rules for block closing statements
1997+(e.g. return, raise, break, continue, pass)
1998+
1999+This function is normally bound to `indent-line-function' so
2000+\\[indent-for-tab-command] will call it."
2001+ (interactive "P")
2002+ (let* ((ci (current-indentation))
2003+ (move-to-indentation-p (<= (current-column) ci))
2004+ (need (py-compute-indentation (not arg))))
2005+ ;; see if we need to dedent
2006+ (if (py-outdent-p)
2007+ (setq need (- need py-indent-offset)))
2008+ (if (/= ci need)
2009+ (save-excursion
2010+ (beginning-of-line)
2011+ (delete-horizontal-space)
2012+ (indent-to need)))
2013+ (if move-to-indentation-p (back-to-indentation))))
2014+
2015+(defun py-newline-and-indent ()
2016+ "Strives to act like the Emacs `newline-and-indent'.
2017+This is just `strives to' because correct indentation can't be computed
2018+from scratch for Python code. In general, deletes the whitespace before
2019+point, inserts a newline, and takes an educated guess as to how you want
2020+the new line indented."
2021+ (interactive)
2022+ (let ((ci (current-indentation)))
2023+ (if (< ci (current-column)) ; if point beyond indentation
2024+ (newline-and-indent)
2025+ ;; else try to act like newline-and-indent "normally" acts
2026+ (beginning-of-line)
2027+ (insert-char ?\n 1)
2028+ (move-to-column ci))))
2029+
2030+(defun py-compute-indentation (honor-block-close-p)
2031+ "Compute Python indentation.
2032+When HONOR-BLOCK-CLOSE-P is non-nil, statements such as `return',
2033+`raise', `break', `continue', and `pass' force one level of
2034+dedenting."
2035+ (save-excursion
2036+ (beginning-of-line)
2037+ (let* ((bod (py-point 'bod))
2038+ (pps (parse-partial-sexp bod (point)))
2039+ (boipps (parse-partial-sexp bod (py-point 'boi)))
2040+ placeholder)
2041+ (cond
2042+ ;; are we inside a multi-line string or comment?
2043+ ((or (and (nth 3 pps) (nth 3 boipps))
2044+ (and (nth 4 pps) (nth 4 boipps)))
2045+ (save-excursion
2046+ (if (not py-align-multiline-strings-p) 0
2047+ ;; skip back over blank & non-indenting comment lines
2048+ ;; note: will skip a blank or non-indenting comment line
2049+ ;; that happens to be a continuation line too
2050+ (re-search-backward "^[ \t]*\\([^ \t\n#]\\|#[ \t\n]\\)" nil 'move)
2051+ (back-to-indentation)
2052+ (current-column))))
2053+ ;; are we on a continuation line?
2054+ ((py-continuation-line-p)
2055+ (let ((startpos (point))
2056+ (open-bracket-pos (py-nesting-level))
2057+ endpos searching found state)
2058+ (if open-bracket-pos
2059+ (progn
2060+ ;; align with first item in list; else a normal
2061+ ;; indent beyond the line with the open bracket
2062+ (goto-char (1+ open-bracket-pos)) ; just beyond bracket
2063+ ;; is the first list item on the same line?
2064+ (skip-chars-forward " \t")
2065+ (if (null (memq (following-char) '(?\n ?# ?\\)))
2066+ ; yes, so line up with it
2067+ (current-column)
2068+ ;; first list item on another line, or doesn't exist yet
2069+ (forward-line 1)
2070+ (while (and (< (point) startpos)
2071+ (looking-at "[ \t]*[#\n\\\\]")) ; skip noise
2072+ (forward-line 1))
2073+ (if (and (< (point) startpos)
2074+ (/= startpos
2075+ (save-excursion
2076+ (goto-char (1+ open-bracket-pos))
2077+ (forward-comment (point-max))
2078+ (point))))
2079+ ;; again mimic the first list item
2080+ (current-indentation)
2081+ ;; else they're about to enter the first item
2082+ (goto-char open-bracket-pos)
2083+ (setq placeholder (point))
2084+ (py-goto-initial-line)
2085+ (py-goto-beginning-of-tqs
2086+ (save-excursion (nth 3 (parse-partial-sexp
2087+ placeholder (point)))))
2088+ (+ (current-indentation) py-indent-offset))))
2089+
2090+ ;; else on backslash continuation line
2091+ (forward-line -1)
2092+ (if (py-continuation-line-p) ; on at least 3rd line in block
2093+ (current-indentation) ; so just continue the pattern
2094+ ;; else started on 2nd line in block, so indent more.
2095+ ;; if base line is an assignment with a start on a RHS,
2096+ ;; indent to 2 beyond the leftmost "="; else skip first
2097+ ;; chunk of non-whitespace characters on base line, + 1 more
2098+ ;; column
2099+ (end-of-line)
2100+ (setq endpos (point)
2101+ searching t)
2102+ (back-to-indentation)
2103+ (setq startpos (point))
2104+ ;; look at all "=" from left to right, stopping at first
2105+ ;; one not nested in a list or string
2106+ (while searching
2107+ (skip-chars-forward "^=" endpos)
2108+ (if (= (point) endpos)
2109+ (setq searching nil)
2110+ (forward-char 1)
2111+ (setq state (parse-partial-sexp startpos (point)))
2112+ (if (and (zerop (car state)) ; not in a bracket
2113+ (null (nth 3 state))) ; & not in a string
2114+ (progn
2115+ (setq searching nil) ; done searching in any case
2116+ (setq found
2117+ (not (or
2118+ (eq (following-char) ?=)
2119+ (memq (char-after (- (point) 2))
2120+ '(?< ?> ?!)))))))))
2121+ (if (or (not found) ; not an assignment
2122+ (looking-at "[ \t]*\\\\")) ; <=><spaces><backslash>
2123+ (progn
2124+ (goto-char startpos)
2125+ (skip-chars-forward "^ \t\n")))
2126+ ;; if this is a continuation for a block opening
2127+ ;; statement, add some extra offset.
2128+ (+ (current-column) (if (py-statement-opens-block-p)
2129+ py-continuation-offset 0)
2130+ 1)
2131+ ))))
2132+
2133+ ;; not on a continuation line
2134+ ((bobp) (current-indentation))
2135+
2136+ ;; Dfn: "Indenting comment line". A line containing only a
2137+ ;; comment, but which is treated like a statement for
2138+ ;; indentation calculation purposes. Such lines are only
2139+ ;; treated specially by the mode; they are not treated
2140+ ;; specially by the Python interpreter.
2141+
2142+ ;; The rules for indenting comment lines are a line where:
2143+ ;; - the first non-whitespace character is `#', and
2144+ ;; - the character following the `#' is whitespace, and
2145+ ;; - the line is dedented with respect to (i.e. to the left
2146+ ;; of) the indentation of the preceding non-blank line.
2147+
2148+ ;; The first non-blank line following an indenting comment
2149+ ;; line is given the same amount of indentation as the
2150+ ;; indenting comment line.
2151+
2152+ ;; All other comment-only lines are ignored for indentation
2153+ ;; purposes.
2154+
2155+ ;; Are we looking at a comment-only line which is *not* an
2156+ ;; indenting comment line? If so, we assume that it's been
2157+ ;; placed at the desired indentation, so leave it alone.
2158+ ;; Indenting comment lines are aligned as statements down
2159+ ;; below.
2160+ ((and (looking-at "[ \t]*#[^ \t\n]")
2161+ ;; NOTE: this test will not be performed in older Emacsen
2162+ (fboundp 'forward-comment)
2163+ (<= (current-indentation)
2164+ (save-excursion
2165+ (forward-comment (- (point-max)))
2166+ (current-indentation))))
2167+ (current-indentation))
2168+
2169+ ;; else indentation based on that of the statement that
2170+ ;; precedes us; use the first line of that statement to
2171+ ;; establish the base, in case the user forced a non-std
2172+ ;; indentation for the continuation lines (if any)
2173+ (t
2174+ ;; skip back over blank & non-indenting comment lines note:
2175+ ;; will skip a blank or non-indenting comment line that
2176+ ;; happens to be a continuation line too. use fast Emacs 19
2177+ ;; function if it's there.
2178+ (if (and (eq py-honor-comment-indentation nil)
2179+ (fboundp 'forward-comment))
2180+ (forward-comment (- (point-max)))
2181+ (let ((prefix-re (concat py-block-comment-prefix "[ \t]*"))
2182+ done)
2183+ (while (not done)
2184+ (re-search-backward "^[ \t]*\\([^ \t\n#]\\|#\\)" nil 'move)
2185+ (setq done (or (bobp)
2186+ (and (eq py-honor-comment-indentation t)
2187+ (save-excursion
2188+ (back-to-indentation)
2189+ (not (looking-at prefix-re))
2190+ ))
2191+ (and (not (eq py-honor-comment-indentation t))
2192+ (save-excursion
2193+ (back-to-indentation)
2194+ (and (not (looking-at prefix-re))
2195+ (or (looking-at "[^#]")
2196+ (not (zerop (current-column)))
2197+ ))
2198+ ))
2199+ ))
2200+ )))
2201+ ;; if we landed inside a string, go to the beginning of that
2202+ ;; string. this handles triple quoted, multi-line spanning
2203+ ;; strings.
2204+ (py-goto-beginning-of-tqs (nth 3 (parse-partial-sexp bod (point))))
2205+ ;; now skip backward over continued lines
2206+ (setq placeholder (point))
2207+ (py-goto-initial-line)
2208+ ;; we may *now* have landed in a TQS, so find the beginning of
2209+ ;; this string.
2210+ (py-goto-beginning-of-tqs
2211+ (save-excursion (nth 3 (parse-partial-sexp
2212+ placeholder (point)))))
2213+ (+ (current-indentation)
2214+ (if (py-statement-opens-block-p)
2215+ py-indent-offset
2216+ (if (and honor-block-close-p (py-statement-closes-block-p))
2217+ (- py-indent-offset)
2218+ 0)))
2219+ )))))
2220+
2221+(defun py-guess-indent-offset (&optional global)
2222+ "Guess a good value for, and change, `py-indent-offset'.
2223+
2224+By default, make a buffer-local copy of `py-indent-offset' with the
2225+new value, so that other Python buffers are not affected. With
2226+\\[universal-argument] (programmatically, optional argument GLOBAL),
2227+change the global value of `py-indent-offset'. This affects all
2228+Python buffers (that don't have their own buffer-local copy), both
2229+those currently existing and those created later in the Emacs session.
2230+
2231+Some people use a different value for `py-indent-offset' than you use.
2232+There's no excuse for such foolishness, but sometimes you have to deal
2233+with their ugly code anyway. This function examines the file and sets
2234+`py-indent-offset' to what it thinks it was when they created the
2235+mess.
2236+
2237+Specifically, it searches forward from the statement containing point,
2238+looking for a line that opens a block of code. `py-indent-offset' is
2239+set to the difference in indentation between that line and the Python
2240+statement following it. If the search doesn't succeed going forward,
2241+it's tried again going backward."
2242+ (interactive "P") ; raw prefix arg
2243+ (let (new-value
2244+ (start (point))
2245+ (restart (point))
2246+ (found nil)
2247+ colon-indent)
2248+ (py-goto-initial-line)
2249+ (while (not (or found (eobp)))
2250+ (when (and (re-search-forward ":[ \t]*\\($\\|[#\\]\\)" nil 'move)
2251+ (not (py-in-literal restart)))
2252+ (setq restart (point))
2253+ (py-goto-initial-line)
2254+ (if (py-statement-opens-block-p)
2255+ (setq found t)
2256+ (goto-char restart))))
2257+ (unless found
2258+ (goto-char start)
2259+ (py-goto-initial-line)
2260+ (while (not (or found (bobp)))
2261+ (setq found (and
2262+ (re-search-backward ":[ \t]*\\($\\|[#\\]\\)" nil 'move)
2263+ (or (py-goto-initial-line) t) ; always true -- side effect
2264+ (py-statement-opens-block-p)))))
2265+ (setq colon-indent (current-indentation)
2266+ found (and found (zerop (py-next-statement 1)))
2267+ new-value (- (current-indentation) colon-indent))
2268+ (goto-char start)
2269+ (if (not found)
2270+ (error "Sorry, couldn't guess a value for py-indent-offset")
2271+ (funcall (if global 'kill-local-variable 'make-local-variable)
2272+ 'py-indent-offset)
2273+ (setq py-indent-offset new-value)
2274+ (or noninteractive
2275+ (message "%s value of py-indent-offset set to %d"
2276+ (if global "Global" "Local")
2277+ py-indent-offset)))
2278+ ))
2279+
2280+(defun py-comment-indent-function ()
2281+ "Python version of `comment-indent-function'."
2282+ ;; This is required when filladapt is turned off. Without it, when
2283+ ;; filladapt is not used, comments which start in column zero
2284+ ;; cascade one character to the right
2285+ (save-excursion
2286+ (beginning-of-line)
2287+ (let ((eol (py-point 'eol)))
2288+ (and comment-start-skip
2289+ (re-search-forward comment-start-skip eol t)
2290+ (setq eol (match-beginning 0)))
2291+ (goto-char eol)
2292+ (skip-chars-backward " \t")
2293+ (max comment-column (+ (current-column) (if (bolp) 0 1)))
2294+ )))
2295+
2296+(defun py-narrow-to-defun (&optional class)
2297+ "Make text outside current defun invisible.
2298+The defun visible is the one that contains point or follows point.
2299+Optional CLASS is passed directly to `py-beginning-of-def-or-class'."
2300+ (interactive "P")
2301+ (save-excursion
2302+ (widen)
2303+ (py-end-of-def-or-class class)
2304+ (let ((end (point)))
2305+ (py-beginning-of-def-or-class class)
2306+ (narrow-to-region (point) end))))
2307+
2308+
2309+(defun py-shift-region (start end count)
2310+ "Indent lines from START to END by COUNT spaces."
2311+ (save-excursion
2312+ (goto-char end)
2313+ (beginning-of-line)
2314+ (setq end (point))
2315+ (goto-char start)
2316+ (beginning-of-line)
2317+ (setq start (point))
2318+ (indent-rigidly start end count)))
2319+
2320+(defun py-shift-region-left (start end &optional count)
2321+ "Shift region of Python code to the left.
2322+The lines from the line containing the start of the current region up
2323+to (but not including) the line containing the end of the region are
2324+shifted to the left, by `py-indent-offset' columns.
2325+
2326+If a prefix argument is given, the region is instead shifted by that
2327+many columns. With no active region, dedent only the current line.
2328+You cannot dedent the region if any line is already at column zero."
2329+ (interactive
2330+ (let ((p (point))
2331+ (m (mark))
2332+ (arg current-prefix-arg))
2333+ (if m
2334+ (list (min p m) (max p m) arg)
2335+ (list p (save-excursion (forward-line 1) (point)) arg))))
2336+ ;; if any line is at column zero, don't shift the region
2337+ (save-excursion
2338+ (goto-char start)
2339+ (while (< (point) end)
2340+ (back-to-indentation)
2341+ (if (and (zerop (current-column))
2342+ (not (looking-at "\\s *$")))
2343+ (error "Region is at left edge"))
2344+ (forward-line 1)))
2345+ (py-shift-region start end (- (prefix-numeric-value
2346+ (or count py-indent-offset))))
2347+ (py-keep-region-active))
2348+
2349+(defun py-shift-region-right (start end &optional count)
2350+ "Shift region of Python code to the right.
2351+The lines from the line containing the start of the current region up
2352+to (but not including) the line containing the end of the region are
2353+shifted to the right, by `py-indent-offset' columns.
2354+
2355+If a prefix argument is given, the region is instead shifted by that
2356+many columns. With no active region, indent only the current line."
2357+ (interactive
2358+ (let ((p (point))
2359+ (m (mark))
2360+ (arg current-prefix-arg))
2361+ (if m
2362+ (list (min p m) (max p m) arg)
2363+ (list p (save-excursion (forward-line 1) (point)) arg))))
2364+ (py-shift-region start end (prefix-numeric-value
2365+ (or count py-indent-offset)))
2366+ (py-keep-region-active))
2367+
2368+(defun py-indent-region (start end &optional indent-offset)
2369+ "Reindent a region of Python code.
2370+
2371+The lines from the line containing the start of the current region up
2372+to (but not including) the line containing the end of the region are
2373+reindented. If the first line of the region has a non-whitespace
2374+character in the first column, the first line is left alone and the
2375+rest of the region is reindented with respect to it. Else the entire
2376+region is reindented with respect to the (closest code or indenting
2377+comment) statement immediately preceding the region.
2378+
2379+This is useful when code blocks are moved or yanked, when enclosing
2380+control structures are introduced or removed, or to reformat code
2381+using a new value for the indentation offset.
2382+
2383+If a numeric prefix argument is given, it will be used as the value of
2384+the indentation offset. Else the value of `py-indent-offset' will be
2385+used.
2386+
2387+Warning: The region must be consistently indented before this function
2388+is called! This function does not compute proper indentation from
2389+scratch (that's impossible in Python), it merely adjusts the existing
2390+indentation to be correct in context.
2391+
2392+Warning: This function really has no idea what to do with
2393+non-indenting comment lines, and shifts them as if they were indenting
2394+comment lines. Fixing this appears to require telepathy.
2395+
2396+Special cases: whitespace is deleted from blank lines; continuation
2397+lines are shifted by the same amount their initial line was shifted,
2398+in order to preserve their relative indentation with respect to their
2399+initial line; and comment lines beginning in column 1 are ignored."
2400+ (interactive "*r\nP") ; region; raw prefix arg
2401+ (save-excursion
2402+ (goto-char end) (beginning-of-line) (setq end (point-marker))
2403+ (goto-char start) (beginning-of-line)
2404+ (let ((py-indent-offset (prefix-numeric-value
2405+ (or indent-offset py-indent-offset)))
2406+ (indents '(-1)) ; stack of active indent levels
2407+ (target-column 0) ; column to which to indent
2408+ (base-shifted-by 0) ; amount last base line was shifted
2409+ (indent-base (if (looking-at "[ \t\n]")
2410+ (py-compute-indentation t)
2411+ 0))
2412+ ci)
2413+ (while (< (point) end)
2414+ (setq ci (current-indentation))
2415+ ;; figure out appropriate target column
2416+ (cond
2417+ ((or (eq (following-char) ?#) ; comment in column 1
2418+ (looking-at "[ \t]*$")) ; entirely blank
2419+ (setq target-column 0))
2420+ ((py-continuation-line-p) ; shift relative to base line
2421+ (setq target-column (+ ci base-shifted-by)))
2422+ (t ; new base line
2423+ (if (> ci (car indents)) ; going deeper; push it
2424+ (setq indents (cons ci indents))
2425+ ;; else we should have seen this indent before
2426+ (setq indents (memq ci indents)) ; pop deeper indents
2427+ (if (null indents)
2428+ (error "Bad indentation in region, at line %d"
2429+ (save-restriction
2430+ (widen)
2431+ (1+ (count-lines 1 (point)))))))
2432+ (setq target-column (+ indent-base
2433+ (* py-indent-offset
2434+ (- (length indents) 2))))
2435+ (setq base-shifted-by (- target-column ci))))
2436+ ;; shift as needed
2437+ (if (/= ci target-column)
2438+ (progn
2439+ (delete-horizontal-space)
2440+ (indent-to target-column)))
2441+ (forward-line 1))))
2442+ (set-marker end nil))
2443+
2444+(defun py-comment-region (beg end &optional arg)
2445+ "Like `comment-region' but uses double hash (`#') comment starter."
2446+ (interactive "r\nP")
2447+ (let ((comment-start py-block-comment-prefix))
2448+ (comment-region beg end arg)))
2449+
2450+
2451+;; Functions for moving point
2452+(defun py-previous-statement (count)
2453+ "Go to the start of the COUNTth preceding Python statement.
2454+By default, goes to the previous statement. If there is no such
2455+statement, goes to the first statement. Return count of statements
2456+left to move. `Statements' do not include blank, comment, or
2457+continuation lines."
2458+ (interactive "p") ; numeric prefix arg
2459+ (if (< count 0) (py-next-statement (- count))
2460+ (py-goto-initial-line)
2461+ (let (start)
2462+ (while (and
2463+ (setq start (point)) ; always true -- side effect
2464+ (> count 0)
2465+ (zerop (forward-line -1))
2466+ (py-goto-statement-at-or-above))
2467+ (setq count (1- count)))
2468+ (if (> count 0) (goto-char start)))
2469+ count))
2470+
2471+(defun py-next-statement (count)
2472+ "Go to the start of next Python statement.
2473+If the statement at point is the i'th Python statement, goes to the
2474+start of statement i+COUNT. If there is no such statement, goes to the
2475+last statement. Returns count of statements left to move. `Statements'
2476+do not include blank, comment, or continuation lines."
2477+ (interactive "p") ; numeric prefix arg
2478+ (if (< count 0) (py-previous-statement (- count))
2479+ (beginning-of-line)
2480+ (let (start)
2481+ (while (and
2482+ (setq start (point)) ; always true -- side effect
2483+ (> count 0)
2484+ (py-goto-statement-below))
2485+ (setq count (1- count)))
2486+ (if (> count 0) (goto-char start)))
2487+ count))
2488+
2489+(defun py-goto-block-up (&optional nomark)
2490+ "Move up to start of current block.
2491+Go to the statement that starts the smallest enclosing block; roughly
2492+speaking, this will be the closest preceding statement that ends with a
2493+colon and is indented less than the statement you started on. If
2494+successful, also sets the mark to the starting point.
2495+
2496+`\\[py-mark-block]' can be used afterward to mark the whole code
2497+block, if desired.
2498+
2499+If called from a program, the mark will not be set if optional argument
2500+NOMARK is not nil."
2501+ (interactive)
2502+ (let ((start (point))
2503+ (found nil)
2504+ initial-indent)
2505+ (py-goto-initial-line)
2506+ ;; if on blank or non-indenting comment line, use the preceding stmt
2507+ (if (looking-at "[ \t]*\\($\\|#[^ \t\n]\\)")
2508+ (progn
2509+ (py-goto-statement-at-or-above)
2510+ (setq found (py-statement-opens-block-p))))
2511+ ;; search back for colon line indented less
2512+ (setq initial-indent (current-indentation))
2513+ (if (zerop initial-indent)
2514+ ;; force fast exit
2515+ (goto-char (point-min)))
2516+ (while (not (or found (bobp)))
2517+ (setq found
2518+ (and
2519+ (re-search-backward ":[ \t]*\\($\\|[#\\]\\)" nil 'move)
2520+ (or (py-goto-initial-line) t) ; always true -- side effect
2521+ (< (current-indentation) initial-indent)
2522+ (py-statement-opens-block-p))))
2523+ (if found
2524+ (progn
2525+ (or nomark (push-mark start))
2526+ (back-to-indentation))
2527+ (goto-char start)
2528+ (error "Enclosing block not found"))))
2529+
2530+(defun py-beginning-of-def-or-class (&optional class count)
2531+ "Move point to start of `def' or `class'.
2532+
2533+Searches back for the closest preceding `def'. If you supply a prefix
2534+arg, looks for a `class' instead. The docs below assume the `def'
2535+case; just substitute `class' for `def' for the other case.
2536+Programmatically, if CLASS is `either', then moves to either `class'
2537+or `def'.
2538+
2539+When second optional argument is given programmatically, move to the
2540+COUNTth start of `def'.
2541+
2542+If point is in a `def' statement already, and after the `d', simply
2543+moves point to the start of the statement.
2544+
2545+Otherwise (i.e. when point is not in a `def' statement, or at or
2546+before the `d' of a `def' statement), searches for the closest
2547+preceding `def' statement, and leaves point at its start. If no such
2548+statement can be found, leaves point at the start of the buffer.
2549+
2550+Returns t iff a `def' statement is found by these rules.
2551+
2552+Note that doing this command repeatedly will take you closer to the
2553+start of the buffer each time.
2554+
2555+To mark the current `def', see `\\[py-mark-def-or-class]'."
2556+ (interactive "P") ; raw prefix arg
2557+ (setq count (or count 1))
2558+ (let ((at-or-before-p (<= (current-column) (current-indentation)))
2559+ (start-of-line (goto-char (py-point 'bol)))
2560+ (start-of-stmt (goto-char (py-point 'bos)))
2561+ (start-re (cond ((eq class 'either) "^[ \t]*\\(class\\|def\\)\\>")
2562+ (class "^[ \t]*class\\>")
2563+ (t "^[ \t]*def\\>")))
2564+ )
2565+ ;; searching backward
2566+ (if (and (< 0 count)
2567+ (or (/= start-of-stmt start-of-line)
2568+ (not at-or-before-p)))
2569+ (end-of-line))
2570+ ;; search forward
2571+ (if (and (> 0 count)
2572+ (zerop (current-column))
2573+ (looking-at start-re))
2574+ (end-of-line))
2575+ (if (re-search-backward start-re nil 'move count)
2576+ (goto-char (match-beginning 0)))))
2577+
2578+;; Backwards compatibility
2579+(defalias 'beginning-of-python-def-or-class 'py-beginning-of-def-or-class)
2580+
2581+(defun py-end-of-def-or-class (&optional class count)
2582+ "Move point beyond end of `def' or `class' body.
2583+
2584+By default, looks for an appropriate `def'. If you supply a prefix
2585+arg, looks for a `class' instead. The docs below assume the `def'
2586+case; just substitute `class' for `def' for the other case.
2587+Programmatically, if CLASS is `either', then moves to either `class'
2588+or `def'.
2589+
2590+When second optional argument is given programmatically, move to the
2591+COUNTth end of `def'.
2592+
2593+If point is in a `def' statement already, this is the `def' we use.
2594+
2595+Else, if the `def' found by `\\[py-beginning-of-def-or-class]'
2596+contains the statement you started on, that's the `def' we use.
2597+
2598+Otherwise, we search forward for the closest following `def', and use that.
2599+
2600+If a `def' can be found by these rules, point is moved to the start of
2601+the line immediately following the `def' block, and the position of the
2602+start of the `def' is returned.
2603+
2604+Else point is moved to the end of the buffer, and nil is returned.
2605+
2606+Note that doing this command repeatedly will take you closer to the
2607+end of the buffer each time.
2608+
2609+To mark the current `def', see `\\[py-mark-def-or-class]'."
2610+ (interactive "P") ; raw prefix arg
2611+ (if (and count (/= count 1))
2612+ (py-beginning-of-def-or-class (- 1 count)))
2613+ (let ((start (progn (py-goto-initial-line) (point)))
2614+ (which (cond ((eq class 'either) "\\(class\\|def\\)")
2615+ (class "class")
2616+ (t "def")))
2617+ (state 'not-found))
2618+ ;; move point to start of appropriate def/class
2619+ (if (looking-at (concat "[ \t]*" which "\\>")) ; already on one
2620+ (setq state 'at-beginning)
2621+ ;; else see if py-beginning-of-def-or-class hits container
2622+ (if (and (py-beginning-of-def-or-class class)
2623+ (progn (py-goto-beyond-block)
2624+ (> (point) start)))
2625+ (setq state 'at-end)
2626+ ;; else search forward
2627+ (goto-char start)
2628+ (if (re-search-forward (concat "^[ \t]*" which "\\>") nil 'move)
2629+ (progn (setq state 'at-beginning)
2630+ (beginning-of-line)))))
2631+ (cond
2632+ ((eq state 'at-beginning) (py-goto-beyond-block) t)
2633+ ((eq state 'at-end) t)
2634+ ((eq state 'not-found) nil)
2635+ (t (error "Internal error in `py-end-of-def-or-class'")))))
2636+
2637+;; Backwards compabitility
2638+(defalias 'end-of-python-def-or-class 'py-end-of-def-or-class)
2639+
2640+
2641+;; Functions for marking regions
2642+(defun py-mark-block (&optional extend just-move)
2643+ "Mark following block of lines. With prefix arg, mark structure.
2644+Easier to use than explain. It sets the region to an `interesting'
2645+block of succeeding lines. If point is on a blank line, it goes down to
2646+the next non-blank line. That will be the start of the region. The end
2647+of the region depends on the kind of line at the start:
2648+
2649+ - If a comment, the region will include all succeeding comment lines up
2650+ to (but not including) the next non-comment line (if any).
2651+
2652+ - Else if a prefix arg is given, and the line begins one of these
2653+ structures:
2654+
2655+ if elif else try except finally for while def class
2656+
2657+ the region will be set to the body of the structure, including
2658+ following blocks that `belong' to it, but excluding trailing blank
2659+ and comment lines. E.g., if on a `try' statement, the `try' block
2660+ and all (if any) of the following `except' and `finally' blocks
2661+ that belong to the `try' structure will be in the region. Ditto
2662+ for if/elif/else, for/else and while/else structures, and (a bit
2663+ degenerate, since they're always one-block structures) def and
2664+ class blocks.
2665+
2666+ - Else if no prefix argument is given, and the line begins a Python
2667+ block (see list above), and the block is not a `one-liner' (i.e.,
2668+ the statement ends with a colon, not with code), the region will
2669+ include all succeeding lines up to (but not including) the next
2670+ code statement (if any) that's indented no more than the starting
2671+ line, except that trailing blank and comment lines are excluded.
2672+ E.g., if the starting line begins a multi-statement `def'
2673+ structure, the region will be set to the full function definition,
2674+ but without any trailing `noise' lines.
2675+
2676+ - Else the region will include all succeeding lines up to (but not
2677+ including) the next blank line, or code or indenting-comment line
2678+ indented strictly less than the starting line. Trailing indenting
2679+ comment lines are included in this case, but not trailing blank
2680+ lines.
2681+
2682+A msg identifying the location of the mark is displayed in the echo
2683+area; or do `\\[exchange-point-and-mark]' to flip down to the end.
2684+
2685+If called from a program, optional argument EXTEND plays the role of
2686+the prefix arg, and if optional argument JUST-MOVE is not nil, just
2687+moves to the end of the block (& does not set mark or display a msg)."
2688+ (interactive "P") ; raw prefix arg
2689+ (py-goto-initial-line)
2690+ ;; skip over blank lines
2691+ (while (and
2692+ (looking-at "[ \t]*$") ; while blank line
2693+ (not (eobp))) ; & somewhere to go
2694+ (forward-line 1))
2695+ (if (eobp)
2696+ (error "Hit end of buffer without finding a non-blank stmt"))
2697+ (let ((initial-pos (point))
2698+ (initial-indent (current-indentation))
2699+ last-pos ; position of last stmt in region
2700+ (followers
2701+ '((if elif else) (elif elif else) (else)
2702+ (try except finally) (except except) (finally)
2703+ (for else) (while else)
2704+ (def) (class) ) )
2705+ first-symbol next-symbol)
2706+
2707+ (cond
2708+ ;; if comment line, suck up the following comment lines
2709+ ((looking-at "[ \t]*#")
2710+ (re-search-forward "^[ \t]*[^ \t#]" nil 'move) ; look for non-comment
2711+ (re-search-backward "^[ \t]*#") ; and back to last comment in block
2712+ (setq last-pos (point)))
2713+
2714+ ;; else if line is a block line and EXTEND given, suck up
2715+ ;; the whole structure
2716+ ((and extend
2717+ (setq first-symbol (py-suck-up-first-keyword) )
2718+ (assq first-symbol followers))
2719+ (while (and
2720+ (or (py-goto-beyond-block) t) ; side effect
2721+ (forward-line -1) ; side effect
2722+ (setq last-pos (point)) ; side effect
2723+ (py-goto-statement-below)
2724+ (= (current-indentation) initial-indent)
2725+ (setq next-symbol (py-suck-up-first-keyword))
2726+ (memq next-symbol (cdr (assq first-symbol followers))))
2727+ (setq first-symbol next-symbol)))
2728+
2729+ ;; else if line *opens* a block, search for next stmt indented <=
2730+ ((py-statement-opens-block-p)
2731+ (while (and
2732+ (setq last-pos (point)) ; always true -- side effect
2733+ (py-goto-statement-below)
2734+ (> (current-indentation) initial-indent)
2735+ )))
2736+
2737+ ;; else plain code line; stop at next blank line, or stmt or
2738+ ;; indenting comment line indented <
2739+ (t
2740+ (while (and
2741+ (setq last-pos (point)) ; always true -- side effect
2742+ (or (py-goto-beyond-final-line) t)
2743+ (not (looking-at "[ \t]*$")) ; stop at blank line
2744+ (or
2745+ (>= (current-indentation) initial-indent)
2746+ (looking-at "[ \t]*#[^ \t\n]"))) ; ignore non-indenting #
2747+ nil)))
2748+
2749+ ;; skip to end of last stmt
2750+ (goto-char last-pos)
2751+ (py-goto-beyond-final-line)
2752+
2753+ ;; set mark & display
2754+ (if just-move
2755+ () ; just return
2756+ (push-mark (point) 'no-msg)
2757+ (forward-line -1)
2758+ (message "Mark set after: %s" (py-suck-up-leading-text))
2759+ (goto-char initial-pos))))
2760+
2761+(defun py-mark-def-or-class (&optional class)
2762+ "Set region to body of def (or class, with prefix arg) enclosing point.
2763+Pushes the current mark, then point, on the mark ring (all language
2764+modes do this, but although it's handy it's never documented ...).
2765+
2766+In most Emacs language modes, this function bears at least a
2767+hallucinogenic resemblance to `\\[py-end-of-def-or-class]' and
2768+`\\[py-beginning-of-def-or-class]'.
2769+
2770+And in earlier versions of Python mode, all 3 were tightly connected.
2771+Turned out that was more confusing than useful: the `goto start' and
2772+`goto end' commands are usually used to search through a file, and
2773+people expect them to act a lot like `search backward' and `search
2774+forward' string-search commands. But because Python `def' and `class'
2775+can nest to arbitrary levels, finding the smallest def containing
2776+point cannot be done via a simple backward search: the def containing
2777+point may not be the closest preceding def, or even the closest
2778+preceding def that's indented less. The fancy algorithm required is
2779+appropriate for the usual uses of this `mark' command, but not for the
2780+`goto' variations.
2781+
2782+So the def marked by this command may not be the one either of the
2783+`goto' commands find: If point is on a blank or non-indenting comment
2784+line, moves back to start of the closest preceding code statement or
2785+indenting comment line. If this is a `def' statement, that's the def
2786+we use. Else searches for the smallest enclosing `def' block and uses
2787+that. Else signals an error.
2788+
2789+When an enclosing def is found: The mark is left immediately beyond
2790+the last line of the def block. Point is left at the start of the
2791+def, except that: if the def is preceded by a number of comment lines
2792+followed by (at most) one optional blank line, point is left at the
2793+start of the comments; else if the def is preceded by a blank line,
2794+point is left at its start.
2795+
2796+The intent is to mark the containing def/class and its associated
2797+documentation, to make moving and duplicating functions and classes
2798+pleasant."
2799+ (interactive "P") ; raw prefix arg
2800+ (let ((start (point))
2801+ (which (cond ((eq class 'either) "\\(class\\|def\\)")
2802+ (class "class")
2803+ (t "def"))))
2804+ (push-mark start)
2805+ (if (not (py-go-up-tree-to-keyword which))
2806+ (progn (goto-char start)
2807+ (error "Enclosing %s not found"
2808+ (if (eq class 'either)
2809+ "def or class"
2810+ which)))
2811+ ;; else enclosing def/class found
2812+ (setq start (point))
2813+ (py-goto-beyond-block)
2814+ (push-mark (point))
2815+ (goto-char start)
2816+ (if (zerop (forward-line -1)) ; if there is a preceding line
2817+ (progn
2818+ (if (looking-at "[ \t]*$") ; it's blank
2819+ (setq start (point)) ; so reset start point
2820+ (goto-char start)) ; else try again
2821+ (if (zerop (forward-line -1))
2822+ (if (looking-at "[ \t]*#") ; a comment
2823+ ;; look back for non-comment line
2824+ ;; tricky: note that the regexp matches a blank
2825+ ;; line, cuz \n is in the 2nd character class
2826+ (and
2827+ (re-search-backward "^[ \t]*[^ \t#]" nil 'move)
2828+ (forward-line 1))
2829+ ;; no comment, so go back
2830+ (goto-char start)))))))
2831+ (exchange-point-and-mark)
2832+ (py-keep-region-active))
2833+
2834+;; ripped from cc-mode
2835+(defun py-forward-into-nomenclature (&optional arg)
2836+ "Move forward to end of a nomenclature section or word.
2837+With \\[universal-argument] (programmatically, optional argument ARG),
2838+do it that many times.
2839+
2840+A `nomenclature' is a fancy way of saying AWordWithMixedCaseNotUnderscores."
2841+ (interactive "p")
2842+ (let ((case-fold-search nil))
2843+ (if (> arg 0)
2844+ (re-search-forward
2845+ "\\(\\W\\|[_]\\)*\\([A-Z]*[a-z0-9]*\\)"
2846+ (point-max) t arg)
2847+ (while (and (< arg 0)
2848+ (re-search-backward
2849+ "\\(\\W\\|[a-z0-9]\\)[A-Z]+\\|\\(\\W\\|[_]\\)\\w+"
2850+ (point-min) 0))
2851+ (forward-char 1)
2852+ (setq arg (1+ arg)))))
2853+ (py-keep-region-active))
2854+
2855+(defun py-backward-into-nomenclature (&optional arg)
2856+ "Move backward to beginning of a nomenclature section or word.
2857+With optional ARG, move that many times. If ARG is negative, move
2858+forward.
2859+
2860+A `nomenclature' is a fancy way of saying AWordWithMixedCaseNotUnderscores."
2861+ (interactive "p")
2862+ (py-forward-into-nomenclature (- arg))
2863+ (py-keep-region-active))
2864+
2865+
2866+
2867+;; pdbtrack functions
2868+(defun py-pdbtrack-toggle-stack-tracking (arg)
2869+ (interactive "P")
2870+ (if (not (get-buffer-process (current-buffer)))
2871+ (error "No process associated with buffer '%s'" (current-buffer)))
2872+ ;; missing or 0 is toggle, >0 turn on, <0 turn off
2873+ (if (or (not arg)
2874+ (zerop (setq arg (prefix-numeric-value arg))))
2875+ (setq py-pdbtrack-do-tracking-p (not py-pdbtrack-do-tracking-p))
2876+ (setq py-pdbtrack-do-tracking-p (> arg 0)))
2877+ (message "%sabled Python's pdbtrack"
2878+ (if py-pdbtrack-do-tracking-p "En" "Dis")))
2879+
2880+(defun turn-on-pdbtrack ()
2881+ (interactive)
2882+ (py-pdbtrack-toggle-stack-tracking 1))
2883+
2884+(defun turn-off-pdbtrack ()
2885+ (interactive)
2886+ (py-pdbtrack-toggle-stack-tracking 0))
2887+
2888+
2889+
2890+;; Pychecker
2891+(defun py-pychecker-run (command)
2892+ "*Run pychecker (default on the file currently visited)."
2893+ (interactive
2894+ (let ((default
2895+ (format "%s %s %s" py-pychecker-command
2896+ (mapconcat 'identity py-pychecker-command-args " ")
2897+ (buffer-file-name)))
2898+ (last (when py-pychecker-history
2899+ (let* ((lastcmd (car py-pychecker-history))
2900+ (cmd (cdr (reverse (split-string lastcmd))))
2901+ (newcmd (reverse (cons (buffer-file-name) cmd))))
2902+ (mapconcat 'identity newcmd " ")))))
2903+
2904+ (list
2905+ (if (fboundp 'read-shell-command)
2906+ (read-shell-command "Run pychecker like this: "
2907+ (if last
2908+ last
2909+ default)
2910+ 'py-pychecker-history)
2911+ (read-string "Run pychecker like this: "
2912+ (if last
2913+ last
2914+ default)
2915+ 'py-pychecker-history))
2916+ )))
2917+ (save-some-buffers (not py-ask-about-save) nil)
2918+ (compile-internal command "No more errors"))
2919+
2920+
2921+
2922+;; pydoc commands. The guts of this function is stolen from XEmacs's
2923+;; symbol-near-point, but without the useless regexp-quote call on the
2924+;; results, nor the interactive bit. Also, we've added the temporary
2925+;; syntax table setting, which Skip originally had broken out into a
2926+;; separate function. Note that Emacs doesn't have the original
2927+;; function.
2928+(defun py-symbol-near-point ()
2929+ "Return the first textual item to the nearest point."
2930+ ;; alg stolen from etag.el
2931+ (save-excursion
2932+ (with-syntax-table py-dotted-expression-syntax-table
2933+ (if (or (bobp) (not (memq (char-syntax (char-before)) '(?w ?_))))
2934+ (while (not (looking-at "\\sw\\|\\s_\\|\\'"))
2935+ (forward-char 1)))
2936+ (while (looking-at "\\sw\\|\\s_")
2937+ (forward-char 1))
2938+ (if (re-search-backward "\\sw\\|\\s_" nil t)
2939+ (progn (forward-char 1)
2940+ (buffer-substring (point)
2941+ (progn (forward-sexp -1)
2942+ (while (looking-at "\\s'")
2943+ (forward-char 1))
2944+ (point))))
2945+ nil))))
2946+
2947+(defun py-help-at-point ()
2948+ "Get help from Python based on the symbol nearest point."
2949+ (interactive)
2950+ (let* ((sym (py-symbol-near-point))
2951+ (base (substring sym 0 (or (search "." sym :from-end t) 0)))
2952+ cmd)
2953+ (if (not (equal base ""))
2954+ (setq cmd (concat "import " base "\n")))
2955+ (setq cmd (concat "import pydoc\n"
2956+ cmd
2957+ "try: pydoc.help('" sym "')\n"
2958+ "except: print 'No help available on:', \"" sym "\""))
2959+ (message cmd)
2960+ (py-execute-string cmd)
2961+ (set-buffer "*Python Output*")
2962+ ;; BAW: Should we really be leaving the output buffer in help-mode?
2963+ (help-mode)))
2964+
2965+
2966+
2967+;; Documentation functions
2968+
2969+;; dump the long form of the mode blurb; does the usual doc escapes,
2970+;; plus lines of the form ^[vc]:name$ to suck variable & command docs
2971+;; out of the right places, along with the keys they're on & current
2972+;; values
2973+(defun py-dump-help-string (str)
2974+ (with-output-to-temp-buffer "*Help*"
2975+ (let ((locals (buffer-local-variables))
2976+ funckind funcname func funcdoc
2977+ (start 0) mstart end
2978+ keys )
2979+ (while (string-match "^%\\([vc]\\):\\(.+\\)\n" str start)
2980+ (setq mstart (match-beginning 0) end (match-end 0)
2981+ funckind (substring str (match-beginning 1) (match-end 1))
2982+ funcname (substring str (match-beginning 2) (match-end 2))
2983+ func (intern funcname))
2984+ (princ (substitute-command-keys (substring str start mstart)))
2985+ (cond
2986+ ((equal funckind "c") ; command
2987+ (setq funcdoc (documentation func)
2988+ keys (concat
2989+ "Key(s): "
2990+ (mapconcat 'key-description
2991+ (where-is-internal func py-mode-map)
2992+ ", "))))
2993+ ((equal funckind "v") ; variable
2994+ (setq funcdoc (documentation-property func 'variable-documentation)
2995+ keys (if (assq func locals)
2996+ (concat
2997+ "Local/Global values: "
2998+ (prin1-to-string (symbol-value func))
2999+ " / "
3000+ (prin1-to-string (default-value func)))
3001+ (concat
3002+ "Value: "
3003+ (prin1-to-string (symbol-value func))))))
3004+ (t ; unexpected
3005+ (error "Error in py-dump-help-string, tag `%s'" funckind)))
3006+ (princ (format "\n-> %s:\t%s\t%s\n\n"
3007+ (if (equal funckind "c") "Command" "Variable")
3008+ funcname keys))
3009+ (princ funcdoc)
3010+ (terpri)
3011+ (setq start end))
3012+ (princ (substitute-command-keys (substring str start))))
3013+ (print-help-return-message)))
3014+
3015+(defun py-describe-mode ()
3016+ "Dump long form of Python-mode docs."
3017+ (interactive)
3018+ (py-dump-help-string "Major mode for editing Python files.
3019+Knows about Python indentation, tokens, comments and continuation lines.
3020+Paragraphs are separated by blank lines only.
3021+
3022+Major sections below begin with the string `@'; specific function and
3023+variable docs begin with `->'.
3024+
3025+@EXECUTING PYTHON CODE
3026+
3027+\\[py-execute-import-or-reload]\timports or reloads the file in the Python interpreter
3028+\\[py-execute-buffer]\tsends the entire buffer to the Python interpreter
3029+\\[py-execute-region]\tsends the current region
3030+\\[py-execute-def-or-class]\tsends the current function or class definition
3031+\\[py-execute-string]\tsends an arbitrary string
3032+\\[py-shell]\tstarts a Python interpreter window; this will be used by
3033+\tsubsequent Python execution commands
3034+%c:py-execute-import-or-reload
3035+%c:py-execute-buffer
3036+%c:py-execute-region
3037+%c:py-execute-def-or-class
3038+%c:py-execute-string
3039+%c:py-shell
3040+
3041+@VARIABLES
3042+
3043+py-indent-offset\tindentation increment
3044+py-block-comment-prefix\tcomment string used by comment-region
3045+
3046+py-python-command\tshell command to invoke Python interpreter
3047+py-temp-directory\tdirectory used for temp files (if needed)
3048+
3049+py-beep-if-tab-change\tring the bell if tab-width is changed
3050+%v:py-indent-offset
3051+%v:py-block-comment-prefix
3052+%v:py-python-command
3053+%v:py-temp-directory
3054+%v:py-beep-if-tab-change
3055+
3056+@KINDS OF LINES
3057+
3058+Each physical line in the file is either a `continuation line' (the
3059+preceding line ends with a backslash that's not part of a comment, or
3060+the paren/bracket/brace nesting level at the start of the line is
3061+non-zero, or both) or an `initial line' (everything else).
3062+
3063+An initial line is in turn a `blank line' (contains nothing except
3064+possibly blanks or tabs), a `comment line' (leftmost non-blank
3065+character is `#'), or a `code line' (everything else).
3066+
3067+Comment Lines
3068+
3069+Although all comment lines are treated alike by Python, Python mode
3070+recognizes two kinds that act differently with respect to indentation.
3071+
3072+An `indenting comment line' is a comment line with a blank, tab or
3073+nothing after the initial `#'. The indentation commands (see below)
3074+treat these exactly as if they were code lines: a line following an
3075+indenting comment line will be indented like the comment line. All
3076+other comment lines (those with a non-whitespace character immediately
3077+following the initial `#') are `non-indenting comment lines', and
3078+their indentation is ignored by the indentation commands.
3079+
3080+Indenting comment lines are by far the usual case, and should be used
3081+whenever possible. Non-indenting comment lines are useful in cases
3082+like these:
3083+
3084+\ta = b # a very wordy single-line comment that ends up being
3085+\t #... continued onto another line
3086+
3087+\tif a == b:
3088+##\t\tprint 'panic!' # old code we've `commented out'
3089+\t\treturn a
3090+
3091+Since the `#...' and `##' comment lines have a non-whitespace
3092+character following the initial `#', Python mode ignores them when
3093+computing the proper indentation for the next line.
3094+
3095+Continuation Lines and Statements
3096+
3097+The Python-mode commands generally work on statements instead of on
3098+individual lines, where a `statement' is a comment or blank line, or a
3099+code line and all of its following continuation lines (if any)
3100+considered as a single logical unit. The commands in this mode
3101+generally (when it makes sense) automatically move to the start of the
3102+statement containing point, even if point happens to be in the middle
3103+of some continuation line.
3104+
3105+
3106+@INDENTATION
3107+
3108+Primarily for entering new code:
3109+\t\\[indent-for-tab-command]\t indent line appropriately
3110+\t\\[py-newline-and-indent]\t insert newline, then indent
3111+\t\\[py-electric-backspace]\t reduce indentation, or delete single character
3112+
3113+Primarily for reindenting existing code:
3114+\t\\[py-guess-indent-offset]\t guess py-indent-offset from file content; change locally
3115+\t\\[universal-argument] \\[py-guess-indent-offset]\t ditto, but change globally
3116+
3117+\t\\[py-indent-region]\t reindent region to match its context
3118+\t\\[py-shift-region-left]\t shift region left by py-indent-offset
3119+\t\\[py-shift-region-right]\t shift region right by py-indent-offset
3120+
3121+Unlike most programming languages, Python uses indentation, and only
3122+indentation, to specify block structure. Hence the indentation supplied
3123+automatically by Python-mode is just an educated guess: only you know
3124+the block structure you intend, so only you can supply correct
3125+indentation.
3126+
3127+The \\[indent-for-tab-command] and \\[py-newline-and-indent] keys try to suggest plausible indentation, based on
3128+the indentation of preceding statements. E.g., assuming
3129+py-indent-offset is 4, after you enter
3130+\tif a > 0: \\[py-newline-and-indent]
3131+the cursor will be moved to the position of the `_' (_ is not a
3132+character in the file, it's just used here to indicate the location of
3133+the cursor):
3134+\tif a > 0:
3135+\t _
3136+If you then enter `c = d' \\[py-newline-and-indent], the cursor will move
3137+to
3138+\tif a > 0:
3139+\t c = d
3140+\t _
3141+Python-mode cannot know whether that's what you intended, or whether
3142+\tif a > 0:
3143+\t c = d
3144+\t_
3145+was your intent. In general, Python-mode either reproduces the
3146+indentation of the (closest code or indenting-comment) preceding
3147+statement, or adds an extra py-indent-offset blanks if the preceding
3148+statement has `:' as its last significant (non-whitespace and non-
3149+comment) character. If the suggested indentation is too much, use
3150+\\[py-electric-backspace] to reduce it.
3151+
3152+Continuation lines are given extra indentation. If you don't like the
3153+suggested indentation, change it to something you do like, and Python-
3154+mode will strive to indent later lines of the statement in the same way.
3155+
3156+If a line is a continuation line by virtue of being in an unclosed
3157+paren/bracket/brace structure (`list', for short), the suggested
3158+indentation depends on whether the current line contains the first item
3159+in the list. If it does, it's indented py-indent-offset columns beyond
3160+the indentation of the line containing the open bracket. If you don't
3161+like that, change it by hand. The remaining items in the list will mimic
3162+whatever indentation you give to the first item.
3163+
3164+If a line is a continuation line because the line preceding it ends with
3165+a backslash, the third and following lines of the statement inherit their
3166+indentation from the line preceding them. The indentation of the second
3167+line in the statement depends on the form of the first (base) line: if
3168+the base line is an assignment statement with anything more interesting
3169+than the backslash following the leftmost assigning `=', the second line
3170+is indented two columns beyond that `='. Else it's indented to two
3171+columns beyond the leftmost solid chunk of non-whitespace characters on
3172+the base line.
3173+
3174+Warning: indent-region should not normally be used! It calls \\[indent-for-tab-command]
3175+repeatedly, and as explained above, \\[indent-for-tab-command] can't guess the block
3176+structure you intend.
3177+%c:indent-for-tab-command
3178+%c:py-newline-and-indent
3179+%c:py-electric-backspace
3180+
3181+
3182+The next function may be handy when editing code you didn't write:
3183+%c:py-guess-indent-offset
3184+
3185+
3186+The remaining `indent' functions apply to a region of Python code. They
3187+assume the block structure (equals indentation, in Python) of the region
3188+is correct, and alter the indentation in various ways while preserving
3189+the block structure:
3190+%c:py-indent-region
3191+%c:py-shift-region-left
3192+%c:py-shift-region-right
3193+
3194+@MARKING & MANIPULATING REGIONS OF CODE
3195+
3196+\\[py-mark-block]\t mark block of lines
3197+\\[py-mark-def-or-class]\t mark smallest enclosing def
3198+\\[universal-argument] \\[py-mark-def-or-class]\t mark smallest enclosing class
3199+\\[comment-region]\t comment out region of code
3200+\\[universal-argument] \\[comment-region]\t uncomment region of code
3201+%c:py-mark-block
3202+%c:py-mark-def-or-class
3203+%c:comment-region
3204+
3205+@MOVING POINT
3206+
3207+\\[py-previous-statement]\t move to statement preceding point
3208+\\[py-next-statement]\t move to statement following point
3209+\\[py-goto-block-up]\t move up to start of current block
3210+\\[py-beginning-of-def-or-class]\t move to start of def
3211+\\[universal-argument] \\[py-beginning-of-def-or-class]\t move to start of class
3212+\\[py-end-of-def-or-class]\t move to end of def
3213+\\[universal-argument] \\[py-end-of-def-or-class]\t move to end of class
3214+
3215+The first two move to one statement beyond the statement that contains
3216+point. A numeric prefix argument tells them to move that many
3217+statements instead. Blank lines, comment lines, and continuation lines
3218+do not count as `statements' for these commands. So, e.g., you can go
3219+to the first code statement in a file by entering
3220+\t\\[beginning-of-buffer]\t to move to the top of the file
3221+\t\\[py-next-statement]\t to skip over initial comments and blank lines
3222+Or do `\\[py-previous-statement]' with a huge prefix argument.
3223+%c:py-previous-statement
3224+%c:py-next-statement
3225+%c:py-goto-block-up
3226+%c:py-beginning-of-def-or-class
3227+%c:py-end-of-def-or-class
3228+
3229+@LITTLE-KNOWN EMACS COMMANDS PARTICULARLY USEFUL IN PYTHON MODE
3230+
3231+`\\[indent-new-comment-line]' is handy for entering a multi-line comment.
3232+
3233+`\\[set-selective-display]' with a `small' prefix arg is ideally suited for viewing the
3234+overall class and def structure of a module.
3235+
3236+`\\[back-to-indentation]' moves point to a line's first non-blank character.
3237+
3238+`\\[indent-relative]' is handy for creating odd indentation.
3239+
3240+@OTHER EMACS HINTS
3241+
3242+If you don't like the default value of a variable, change its value to
3243+whatever you do like by putting a `setq' line in your .emacs file.
3244+E.g., to set the indentation increment to 4, put this line in your
3245+.emacs:
3246+\t(setq py-indent-offset 4)
3247+To see the value of a variable, do `\\[describe-variable]' and enter the variable
3248+name at the prompt.
3249+
3250+When entering a key sequence like `C-c C-n', it is not necessary to
3251+release the CONTROL key after doing the `C-c' part -- it suffices to
3252+press the CONTROL key, press and release `c' (while still holding down
3253+CONTROL), press and release `n' (while still holding down CONTROL), &
3254+then release CONTROL.
3255+
3256+Entering Python mode calls with no arguments the value of the variable
3257+`python-mode-hook', if that value exists and is not nil; for backward
3258+compatibility it also tries `py-mode-hook'; see the `Hooks' section of
3259+the Elisp manual for details.
3260+
3261+Obscure: When python-mode is first loaded, it looks for all bindings
3262+to newline-and-indent in the global keymap, and shadows them with
3263+local bindings to py-newline-and-indent."))
3264+
3265+(require 'info-look)
3266+;; The info-look package does not always provide this function (it
3267+;; appears this is the case with XEmacs 21.1)
3268+(when (fboundp 'info-lookup-maybe-add-help)
3269+ (info-lookup-maybe-add-help
3270+ :mode 'python-mode
3271+ :regexp "[a-zA-Z0-9_]+"
3272+ :doc-spec '(("(python-lib)Module Index")
3273+ ("(python-lib)Class-Exception-Object Index")
3274+ ("(python-lib)Function-Method-Variable Index")
3275+ ("(python-lib)Miscellaneous Index")))
3276+ )
3277+
3278+
3279+;; Helper functions
3280+(defvar py-parse-state-re
3281+ (concat
3282+ "^[ \t]*\\(elif\\|else\\|while\\|def\\|class\\)\\>"
3283+ "\\|"
3284+ "^[^ #\t\n]"))
3285+
3286+(defun py-parse-state ()
3287+ "Return the parse state at point (see `parse-partial-sexp' docs)."
3288+ (save-excursion
3289+ (let ((here (point))
3290+ pps done)
3291+ (while (not done)
3292+ ;; back up to the first preceding line (if any; else start of
3293+ ;; buffer) that begins with a popular Python keyword, or a
3294+ ;; non- whitespace and non-comment character. These are good
3295+ ;; places to start parsing to see whether where we started is
3296+ ;; at a non-zero nesting level. It may be slow for people who
3297+ ;; write huge code blocks or huge lists ... tough beans.
3298+ (re-search-backward py-parse-state-re nil 'move)
3299+ (beginning-of-line)
3300+ ;; In XEmacs, we have a much better way to test for whether
3301+ ;; we're in a triple-quoted string or not. Emacs does not
3302+ ;; have this built-in function, which is its loss because
3303+ ;; without scanning from the beginning of the buffer, there's
3304+ ;; no accurate way to determine this otherwise.
3305+ (save-excursion (setq pps (parse-partial-sexp (point) here)))
3306+ ;; make sure we don't land inside a triple-quoted string
3307+ (setq done (or (not (nth 3 pps))
3308+ (bobp)))
3309+ ;; Just go ahead and short circuit the test back to the
3310+ ;; beginning of the buffer. This will be slow, but not
3311+ ;; nearly as slow as looping through many
3312+ ;; re-search-backwards.
3313+ (if (not done)
3314+ (goto-char (point-min))))
3315+ pps)))
3316+
3317+(defun py-nesting-level ()
3318+ "Return the buffer position of the last unclosed enclosing list.
3319+If nesting level is zero, return nil."
3320+ (let ((status (py-parse-state)))
3321+ (if (zerop (car status))
3322+ nil ; not in a nest
3323+ (car (cdr status))))) ; char# of open bracket
3324+
3325+(defun py-backslash-continuation-line-p ()
3326+ "Return t iff preceding line ends with backslash that is not in a comment."
3327+ (save-excursion
3328+ (beginning-of-line)
3329+ (and
3330+ ;; use a cheap test first to avoid the regexp if possible
3331+ ;; use 'eq' because char-after may return nil
3332+ (eq (char-after (- (point) 2)) ?\\ )
3333+ ;; make sure; since eq test passed, there is a preceding line
3334+ (forward-line -1) ; always true -- side effect
3335+ (looking-at py-continued-re))))
3336+
3337+(defun py-continuation-line-p ()
3338+ "Return t iff current line is a continuation line."
3339+ (save-excursion
3340+ (beginning-of-line)
3341+ (or (py-backslash-continuation-line-p)
3342+ (py-nesting-level))))
3343+
3344+(defun py-goto-beginning-of-tqs (delim)
3345+ "Go to the beginning of the triple quoted string we find ourselves in.
3346+DELIM is the TQS string delimiter character we're searching backwards
3347+for."
3348+ (let ((skip (and delim (make-string 1 delim)))
3349+ (continue t))
3350+ (when skip
3351+ (save-excursion
3352+ (while continue
3353+ (py-safe (search-backward skip))
3354+ (setq continue (and (not (bobp))
3355+ (= (char-before) ?\\))))
3356+ (if (and (= (char-before) delim)
3357+ (= (char-before (1- (point))) delim))
3358+ (setq skip (make-string 3 delim))))
3359+ ;; we're looking at a triple-quoted string
3360+ (py-safe (search-backward skip)))))
3361+
3362+(defun py-goto-initial-line ()
3363+ "Go to the initial line of the current statement.
3364+Usually this is the line we're on, but if we're on the 2nd or
3365+following lines of a continuation block, we need to go up to the first
3366+line of the block."
3367+ ;; Tricky: We want to avoid quadratic-time behavior for long
3368+ ;; continued blocks, whether of the backslash or open-bracket
3369+ ;; varieties, or a mix of the two. The following manages to do that
3370+ ;; in the usual cases.
3371+ ;;
3372+ ;; Also, if we're sitting inside a triple quoted string, this will
3373+ ;; drop us at the line that begins the string.
3374+ (let (open-bracket-pos)
3375+ (while (py-continuation-line-p)
3376+ (beginning-of-line)
3377+ (if (py-backslash-continuation-line-p)
3378+ (while (py-backslash-continuation-line-p)
3379+ (forward-line -1))
3380+ ;; else zip out of nested brackets/braces/parens
3381+ (while (setq open-bracket-pos (py-nesting-level))
3382+ (goto-char open-bracket-pos)))))
3383+ (beginning-of-line))
3384+
3385+(defun py-goto-beyond-final-line ()
3386+ "Go to the point just beyond the fine line of the current statement.
3387+Usually this is the start of the next line, but if this is a
3388+multi-line statement we need to skip over the continuation lines."
3389+ ;; Tricky: Again we need to be clever to avoid quadratic time
3390+ ;; behavior.
3391+ ;;
3392+ ;; XXX: Not quite the right solution, but deals with multi-line doc
3393+ ;; strings
3394+ (if (looking-at (concat "[ \t]*\\(" py-stringlit-re "\\)"))
3395+ (goto-char (match-end 0)))
3396+ ;;
3397+ (forward-line 1)
3398+ (let (state)
3399+ (while (and (py-continuation-line-p)
3400+ (not (eobp)))
3401+ ;; skip over the backslash flavor
3402+ (while (and (py-backslash-continuation-line-p)
3403+ (not (eobp)))
3404+ (forward-line 1))
3405+ ;; if in nest, zip to the end of the nest
3406+ (setq state (py-parse-state))
3407+ (if (and (not (zerop (car state)))
3408+ (not (eobp)))
3409+ (progn
3410+ (parse-partial-sexp (point) (point-max) 0 nil state)
3411+ (forward-line 1))))))
3412+
3413+(defun py-statement-opens-block-p ()
3414+ "Return t iff the current statement opens a block.
3415+I.e., iff it ends with a colon that is not in a comment. Point should
3416+be at the start of a statement."
3417+ (save-excursion
3418+ (let ((start (point))
3419+ (finish (progn (py-goto-beyond-final-line) (1- (point))))
3420+ (searching t)
3421+ (answer nil)
3422+ state)
3423+ (goto-char start)
3424+ (while searching
3425+ ;; look for a colon with nothing after it except whitespace, and
3426+ ;; maybe a comment
3427+ (if (re-search-forward ":\\([ \t]\\|\\\\\n\\)*\\(#.*\\)?$"
3428+ finish t)
3429+ (if (eq (point) finish) ; note: no `else' clause; just
3430+ ; keep searching if we're not at
3431+ ; the end yet
3432+ ;; sure looks like it opens a block -- but it might
3433+ ;; be in a comment
3434+ (progn
3435+ (setq searching nil) ; search is done either way
3436+ (setq state (parse-partial-sexp start
3437+ (match-beginning 0)))
3438+ (setq answer (not (nth 4 state)))))
3439+ ;; search failed: couldn't find another interesting colon
3440+ (setq searching nil)))
3441+ answer)))
3442+
3443+(defun py-statement-closes-block-p ()
3444+ "Return t iff the current statement closes a block.
3445+I.e., if the line starts with `return', `raise', `break', `continue',
3446+and `pass'. This doesn't catch embedded statements."
3447+ (let ((here (point)))
3448+ (py-goto-initial-line)
3449+ (back-to-indentation)
3450+ (prog1
3451+ (looking-at (concat py-block-closing-keywords-re "\\>"))
3452+ (goto-char here))))
3453+
3454+(defun py-goto-beyond-block ()
3455+ "Go to point just beyond the final line of block begun by the current line.
3456+This is the same as where `py-goto-beyond-final-line' goes unless
3457+we're on colon line, in which case we go to the end of the block.
3458+Assumes point is at the beginning of the line."
3459+ (if (py-statement-opens-block-p)
3460+ (py-mark-block nil 'just-move)
3461+ (py-goto-beyond-final-line)))
3462+
3463+(defun py-goto-statement-at-or-above ()
3464+ "Go to the start of the first statement at or preceding point.
3465+Return t if there is such a statement, otherwise nil. `Statement'
3466+does not include blank lines, comments, or continuation lines."
3467+ (py-goto-initial-line)
3468+ (if (looking-at py-blank-or-comment-re)
3469+ ;; skip back over blank & comment lines
3470+ ;; note: will skip a blank or comment line that happens to be
3471+ ;; a continuation line too
3472+ (if (re-search-backward "^[ \t]*[^ \t#\n]" nil t)
3473+ (progn (py-goto-initial-line) t)
3474+ nil)
3475+ t))
3476+
3477+(defun py-goto-statement-below ()
3478+ "Go to start of the first statement following the statement containing point.
3479+Return t if there is such a statement, otherwise nil. `Statement'
3480+does not include blank lines, comments, or continuation lines."
3481+ (beginning-of-line)
3482+ (let ((start (point)))
3483+ (py-goto-beyond-final-line)
3484+ (while (and
3485+ (or (looking-at py-blank-or-comment-re)
3486+ (py-in-literal))
3487+ (not (eobp)))
3488+ (forward-line 1))
3489+ (if (eobp)
3490+ (progn (goto-char start) nil)
3491+ t)))
3492+
3493+(defun py-go-up-tree-to-keyword (key)
3494+ "Go to begining of statement starting with KEY, at or preceding point.
3495+
3496+KEY is a regular expression describing a Python keyword. Skip blank
3497+lines and non-indenting comments. If the statement found starts with
3498+KEY, then stop, otherwise go back to first enclosing block starting
3499+with KEY. If successful, leave point at the start of the KEY line and
3500+return t. Otherwise, leav point at an undefined place and return nil."
3501+ ;; skip blanks and non-indenting #
3502+ (py-goto-initial-line)
3503+ (while (and
3504+ (looking-at "[ \t]*\\($\\|#[^ \t\n]\\)")
3505+ (zerop (forward-line -1))) ; go back
3506+ nil)
3507+ (py-goto-initial-line)
3508+ (let* ((re (concat "[ \t]*" key "\\b"))
3509+ (case-fold-search nil) ; let* so looking-at sees this
3510+ (found (looking-at re))
3511+ (dead nil))
3512+ (while (not (or found dead))
3513+ (condition-case nil ; in case no enclosing block
3514+ (py-goto-block-up 'no-mark)
3515+ (error (setq dead t)))
3516+ (or dead (setq found (looking-at re))))
3517+ (beginning-of-line)
3518+ found))
3519+
3520+(defun py-suck-up-leading-text ()
3521+ "Return string in buffer from start of indentation to end of line.
3522+Prefix with \"...\" if leading whitespace was skipped."
3523+ (save-excursion
3524+ (back-to-indentation)
3525+ (concat
3526+ (if (bolp) "" "...")
3527+ (buffer-substring (point) (progn (end-of-line) (point))))))
3528+
3529+(defun py-suck-up-first-keyword ()
3530+ "Return first keyword on the line as a Lisp symbol.
3531+`Keyword' is defined (essentially) as the regular expression
3532+([a-z]+). Returns nil if none was found."
3533+ (let ((case-fold-search nil))
3534+ (if (looking-at "[ \t]*\\([a-z]+\\)\\b")
3535+ (intern (buffer-substring (match-beginning 1) (match-end 1)))
3536+ nil)))
3537+
3538+(defun py-current-defun ()
3539+ "Python value for `add-log-current-defun-function'.
3540+This tells add-log.el how to find the current function/method/variable."
3541+ (save-excursion
3542+ (if (re-search-backward py-defun-start-re nil t)
3543+ (or (match-string 3)
3544+ (let ((method (match-string 2)))
3545+ (if (and (not (zerop (length (match-string 1))))
3546+ (re-search-backward py-class-start-re nil t))
3547+ (concat (match-string 1) "." method)
3548+ method)))
3549+ nil)))
3550+
3551+
3552+(defconst py-help-address "python-mode@python.org"
3553+ "Address accepting submission of bug reports.")
3554+
3555+(defun py-version ()
3556+ "Echo the current version of `python-mode' in the minibuffer."
3557+ (interactive)
3558+ (message "Using `python-mode' version %s" py-version)
3559+ (py-keep-region-active))
3560+
3561+;; only works under Emacs 19
3562+;(eval-when-compile
3563+; (require 'reporter))
3564+
3565+(defun py-submit-bug-report (enhancement-p)
3566+ "Submit via mail a bug report on `python-mode'.
3567+With \\[universal-argument] (programmatically, argument ENHANCEMENT-P
3568+non-nil) just submit an enhancement request."
3569+ (interactive
3570+ (list (not (y-or-n-p
3571+ "Is this a bug report (hit `n' to send other comments)? "))))
3572+ (let ((reporter-prompt-for-summary-p (if enhancement-p
3573+ "(Very) brief summary: "
3574+ t)))
3575+ (require 'reporter)
3576+ (reporter-submit-bug-report
3577+ py-help-address ;address
3578+ (concat "python-mode " py-version) ;pkgname
3579+ ;; varlist
3580+ (if enhancement-p nil
3581+ '(py-python-command
3582+ py-indent-offset
3583+ py-block-comment-prefix
3584+ py-temp-directory
3585+ py-beep-if-tab-change))
3586+ nil ;pre-hooks
3587+ nil ;post-hooks
3588+ "Dear Barry,") ;salutation
3589+ (if enhancement-p nil
3590+ (set-mark (point))
3591+ (insert
3592+"Please replace this text with a sufficiently large code sample\n\
3593+and an exact recipe so that I can reproduce your problem. Failure\n\
3594+to do so may mean a greater delay in fixing your bug.\n\n")
3595+ (exchange-point-and-mark)
3596+ (py-keep-region-active))))
3597+
3598+
3599+(defun py-kill-emacs-hook ()
3600+ "Delete files in `py-file-queue'.
3601+These are Python temporary files awaiting execution."
3602+ (mapcar #'(lambda (filename)
3603+ (py-safe (delete-file filename)))
3604+ py-file-queue))
3605+
3606+;; arrange to kill temp files when Emacs exists
3607+(add-hook 'kill-emacs-hook 'py-kill-emacs-hook)
3608+(add-hook 'comint-output-filter-functions 'py-pdbtrack-track-stack-file)
3609+
3610+;; Add a designator to the minor mode strings
3611+(or (assq 'py-pdbtrack-minor-mode-string minor-mode-alist)
3612+ (push '(py-pdbtrack-is-tracking-p py-pdbtrack-minor-mode-string)
3613+ minor-mode-alist))
3614+
3615+
3616+
3617+;;; paragraph and string filling code from Bernhard Herzog
3618+;;; see http://mail.python.org/pipermail/python-list/2002-May/103189.html
3619+
3620+(defun py-fill-comment (&optional justify)
3621+ "Fill the comment paragraph around point"
3622+ (let (;; Non-nil if the current line contains a comment.
3623+ has-comment
3624+
3625+ ;; If has-comment, the appropriate fill-prefix for the comment.
3626+ comment-fill-prefix)
3627+
3628+ ;; Figure out what kind of comment we are looking at.
3629+ (save-excursion
3630+ (beginning-of-line)
3631+ (cond
3632+ ;; A line with nothing but a comment on it?
3633+ ((looking-at "[ \t]*#[# \t]*")
3634+ (setq has-comment t
3635+ comment-fill-prefix (buffer-substring (match-beginning 0)
3636+ (match-end 0))))
3637+
3638+ ;; A line with some code, followed by a comment? Remember that the hash
3639+ ;; which starts the comment shouldn't be part of a string or character.
3640+ ((progn
3641+ (while (not (looking-at "#\\|$"))
3642+ (skip-chars-forward "^#\n\"'\\")
3643+ (cond
3644+ ((eq (char-after (point)) ?\\) (forward-char 2))
3645+ ((memq (char-after (point)) '(?\" ?')) (forward-sexp 1))))
3646+ (looking-at "#+[\t ]*"))
3647+ (setq has-comment t)
3648+ (setq comment-fill-prefix
3649+ (concat (make-string (current-column) ? )
3650+ (buffer-substring (match-beginning 0) (match-end 0)))))))
3651+
3652+ (if (not has-comment)
3653+ (fill-paragraph justify)
3654+
3655+ ;; Narrow to include only the comment, and then fill the region.
3656+ (save-restriction
3657+ (narrow-to-region
3658+
3659+ ;; Find the first line we should include in the region to fill.
3660+ (save-excursion
3661+ (while (and (zerop (forward-line -1))
3662+ (looking-at "^[ \t]*#")))
3663+
3664+ ;; We may have gone to far. Go forward again.
3665+ (or (looking-at "^[ \t]*#")
3666+ (forward-line 1))
3667+ (point))
3668+
3669+ ;; Find the beginning of the first line past the region to fill.
3670+ (save-excursion
3671+ (while (progn (forward-line 1)
3672+ (looking-at "^[ \t]*#")))
3673+ (point)))
3674+
3675+ ;; Lines with only hashes on them can be paragraph boundaries.
3676+ (let ((paragraph-start (concat paragraph-start "\\|[ \t#]*$"))
3677+ (paragraph-separate (concat paragraph-separate "\\|[ \t#]*$"))
3678+ (fill-prefix comment-fill-prefix))
3679+ ;;(message "paragraph-start %S paragraph-separate %S"
3680+ ;;paragraph-start paragraph-separate)
3681+ (fill-paragraph justify))))
3682+ t))
3683+
3684+
3685+(defun py-fill-string (start &optional justify)
3686+ "Fill the paragraph around (point) in the string starting at start"
3687+ ;; basic strategy: narrow to the string and call the default
3688+ ;; implementation
3689+ (let (;; the start of the string's contents
3690+ string-start
3691+ ;; the end of the string's contents
3692+ string-end
3693+ ;; length of the string's delimiter
3694+ delim-length
3695+ ;; The string delimiter
3696+ delim
3697+ )
3698+
3699+ (save-excursion
3700+ (goto-char start)
3701+ (if (looking-at "\\('''\\|\"\"\"\\|'\\|\"\\)\\\\?\n?")
3702+ (setq string-start (match-end 0)
3703+ delim-length (- (match-end 1) (match-beginning 1))
3704+ delim (buffer-substring-no-properties (match-beginning 1)
3705+ (match-end 1)))
3706+ (error "The parameter start is not the beginning of a python string"))
3707+
3708+ ;; if the string is the first token on a line and doesn't start with
3709+ ;; a newline, fill as if the string starts at the beginning of the
3710+ ;; line. this helps with one line docstrings
3711+ (save-excursion
3712+ (beginning-of-line)
3713+ (and (/= (char-before string-start) ?\n)
3714+ (looking-at (concat "[ \t]*" delim))
3715+ (setq string-start (point))))
3716+
3717+ (forward-sexp (if (= delim-length 3) 2 1))
3718+
3719+ ;; with both triple quoted strings and single/double quoted strings
3720+ ;; we're now directly behind the first char of the end delimiter
3721+ ;; (this doesn't work correctly when the triple quoted string
3722+ ;; contains the quote mark itself). The end of the string's contents
3723+ ;; is one less than point
3724+ (setq string-end (1- (point))))
3725+
3726+ ;; Narrow to the string's contents and fill the current paragraph
3727+ (save-restriction
3728+ (narrow-to-region string-start string-end)
3729+ (let ((ends-with-newline (= (char-before (point-max)) ?\n)))
3730+ (fill-paragraph justify)
3731+ (if (and (not ends-with-newline)
3732+ (= (char-before (point-max)) ?\n))
3733+ ;; the default fill-paragraph implementation has inserted a
3734+ ;; newline at the end. Remove it again.
3735+ (save-excursion
3736+ (goto-char (point-max))
3737+ (delete-char -1)))))
3738+
3739+ ;; return t to indicate that we've done our work
3740+ t))
3741+
3742+(defun py-fill-paragraph (&optional justify)
3743+ "Like \\[fill-paragraph], but handle Python comments and strings.
3744+If any of the current line is a comment, fill the comment or the
3745+paragraph of it that point is in, preserving the comment's indentation
3746+and initial `#'s.
3747+If point is inside a string, narrow to that string and fill.
3748+"
3749+ (interactive "P")
3750+ (let* ((bod (py-point 'bod))
3751+ (pps (parse-partial-sexp bod (point))))
3752+ (cond
3753+ ;; are we inside a comment or on a line with only whitespace before
3754+ ;; the comment start?
3755+ ((or (nth 4 pps)
3756+ (save-excursion (beginning-of-line) (looking-at "[ \t]*#")))
3757+ (py-fill-comment justify))
3758+ ;; are we inside a string?
3759+ ((nth 3 pps)
3760+ (py-fill-string (nth 8 pps)))
3761+ ;; otherwise use the default
3762+ (t
3763+ (fill-paragraph justify)))))
3764+
3765+
3766+
3767+(provide 'python-mode)
3768+;;; python-mode.el ends here