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