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