comparison .elisp/python-mode.el @ 174:014e745b2d04

python-mode: updating to current bzr version This is bzr revision 351, which is revision-id: barry@python.org-20090320013721-awwzwv1mfl7hicdf
author Augie Fackler <durin42@gmail.com>
date Wed, 16 Dec 2009 22:57:36 -0600
parents b5d75594b356
children 4741c022c7ae
comparison
equal deleted inserted replaced
173:fd92c15701ae 174:014e745b2d04
1 ;;; python-mode.el --- Major mode for editing Python programs 1 ;;; python-mode.el --- Major mode for editing Python programs
2 2
3 ;; Copyright (C) 1992,1993,1994 Tim Peters 3 ;; Copyright (C) 1992,1993,1994 Tim Peters
4 4
5 ;; Author: 2003-2004 http://sf.net/projects/python-mode 5 ;; Author: 2003-2009 https://launchpad.net/python-mode
6 ;; 1995-2002 Barry A. Warsaw 6 ;; 1995-2002 Barry A. Warsaw
7 ;; 1992-1994 Tim Peters 7 ;; 1992-1994 Tim Peters
8 ;; Maintainer: python-mode@python.org 8 ;; Maintainer: python-mode@python.org
9 ;; Created: Feb 1992 9 ;; Created: Feb 1992
10 ;; Keywords: python languages oop 10 ;; Keywords: python languages oop
11 11
12 (defconst py-version "$Revision: 4.75 $" 12 (defconst py-version "5.1.0+"
13 "`python-mode' version number.") 13 "`python-mode' version number.")
14 14
15 ;; This software is provided as-is, without express or implied 15 ;; This file is part of python-mode.el.
16 ;; warranty. Permission to use, copy, modify, distribute or sell this 16 ;;
17 ;; software, without fee, for any purpose and by any individual or 17 ;; python-mode.el is free software: you can redistribute it and/or modify it
18 ;; organization, is hereby granted, provided that the above copyright 18 ;; under the terms of the GNU General Public License as published by the Free
19 ;; notice and this paragraph appear in all copies. 19 ;; Software Foundation, either version 3 of the License, or (at your option)
20 ;; any later version.
21 ;;
22 ;; python-mode.el is distributed in the hope that it will be useful, but
23 ;; WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
24 ;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
25 ;; for more details.
26 ;;
27 ;; You should have received a copy of the GNU General Public License along
28 ;; with python-mode.el. If not, see <http://www.gnu.org/licenses/>.
20 29
21 ;;; Commentary: 30 ;;; Commentary:
22 31
23 ;; This is a major mode for editing Python programs. It was developed by Tim 32 ;; 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 33 ;; 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 34 ;; left the net and in 1995, Barry Warsaw inherited the mode. Tim came back
26 ;; but disavows all responsibility for the mode. In fact, we suspect he 35 ;; but disavowed 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 36 ;; doesn't even use Emacs any more <wink>. In 2003, python-mode.el was moved
28 ;; own SourceForge project apart from the Python project, and now is 37 ;; to its own SourceForge project apart from the Python project, and in 2008
29 ;; maintained by the volunteers at the python-mode@python.org mailing list. 38 ;; it was moved to Launchpad for all project administration. python-mode.el
39 ;; is maintained by the volunteers at the python-mode@python.org mailing
40 ;; list.
41
42 ;; python-mode.el is different than, and pre-dates by many years, the
43 ;; python.el that comes with FSF Emacs. We'd like to merge the two modes but
44 ;; have few cycles to do so. Volunteers are welcome.
30 45
31 ;; pdbtrack support contributed by Ken Manheimer, April 2001. Skip Montanaro 46 ;; pdbtrack support contributed by Ken Manheimer, April 2001. Skip Montanaro
32 ;; has also contributed significantly to python-mode's development. 47 ;; has also contributed significantly to python-mode's development.
33 48
34 ;; Please use the SourceForge Python project to submit bugs or 49 ;; Please use Launchpad to submit bugs or patches:
35 ;; patches:
36 ;; 50 ;;
37 ;; http://sourceforge.net/projects/python 51 ;; https://launchpad.net/python-mode
38 52
39 ;; INSTALLATION: 53 ;; INSTALLATION:
40 54
41 ;; To install, just drop this file into a directory on your load-path and 55 ;; 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 56 ;; byte-compile it. To set up Emacs to automatically edit files ending in
50 ;; In XEmacs syntax highlighting should be enabled automatically. In GNU 64 ;; In XEmacs syntax highlighting should be enabled automatically. In GNU
51 ;; Emacs you may have to add these lines to your ~/.emacs file: 65 ;; Emacs you may have to add these lines to your ~/.emacs file:
52 ;; (global-font-lock-mode t) 66 ;; (global-font-lock-mode t)
53 ;; (setq font-lock-maximum-decoration t) 67 ;; (setq font-lock-maximum-decoration t)
54 68
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: 69 ;; BUG REPORTING:
65 70
66 ;; As mentioned above, please use the SourceForge Python project for 71 ;; As mentioned above, please use the Launchpad python-mode project for
67 ;; submitting bug reports or patches. The old recommendation, to use 72 ;; submitting bug reports or patches. The old recommendation, to use C-c C-b
68 ;; C-c C-b will still work, but those reports have a higher chance of 73 ;; will still work, but those reports have a higher chance of getting buried
69 ;; getting buried in my mailbox. Please include a complete, but 74 ;; in our inboxes. Please include a complete, but concise code sample and a
70 ;; concise code sample and a recipe for reproducing the bug. Send 75 ;; recipe for reproducing the bug. Send suggestions and other comments to
71 ;; suggestions and other comments to python-mode@python.org. 76 ;; python-mode@python.org.
72 77
73 ;; When in a Python mode buffer, do a C-h m for more help. It's 78 ;; When in a Python mode buffer, do a C-h m for more help. It's doubtful that
74 ;; doubtful that a texinfo manual would be very useful, but if you 79 ;; a texinfo manual would be very useful, but if you want to contribute one,
75 ;; want to contribute one, I'll certainly accept it! 80 ;; we'll certainly accept it!
76 81
77 ;;; Code: 82 ;;; Code:
78 83
79 (require 'comint) 84 (require 'comint)
80 (require 'custom) 85 (require 'custom)
123 128
124 Note that this variable is consulted only the first time that a Python 129 Note that this variable is consulted only the first time that a Python
125 mode buffer is visited during an Emacs session. After that, use 130 mode buffer is visited during an Emacs session. After that, use
126 \\[py-toggle-shells] to change the interpreter shell." 131 \\[py-toggle-shells] to change the interpreter shell."
127 :type '(choice (const :tag "Python (a.k.a. CPython)" cpython) 132 :type '(choice (const :tag "Python (a.k.a. CPython)" cpython)
128 (const :tag "Jython" jython)) 133 (const :tag "Jython" jython))
129 :group 'python) 134 :group 'python)
130 135
131 (defcustom py-python-command-args '("-i") 136 (defcustom py-python-command-args '("-i")
132 "*List of string arguments to be used when starting a Python shell." 137 "*List of string arguments to be used when starting a Python shell."
133 :type '(repeat string) 138 :type '(repeat string)
181 "*Flag describing how multi-line triple quoted strings are aligned. 186 "*Flag describing how multi-line triple quoted strings are aligned.
182 When this flag is non-nil, continuation lines are lined up under the 187 When this flag is non-nil, continuation lines are lined up under the
183 preceding line's indentation. When this flag is nil, continuation 188 preceding line's indentation. When this flag is nil, continuation
184 lines are aligned to column zero." 189 lines are aligned to column zero."
185 :type '(choice (const :tag "Align under preceding line" t) 190 :type '(choice (const :tag "Align under preceding line" t)
186 (const :tag "Align to column zero" nil)) 191 (const :tag "Align to column zero" nil))
187 :group 'python) 192 :group 'python)
188 193
189 (defcustom py-block-comment-prefix "##" 194 (defcustom py-block-comment-prefix "##"
190 "*String used by \\[comment-region] to comment out a block of code. 195 "*String used by \\[comment-region] to comment out a block of code.
191 This should follow the convention for non-indenting comment lines so 196 This should follow the convention for non-indenting comment lines so
209 purposes. 214 purposes.
210 215
211 When not nil or t, comment lines that begin with a single `#' are used 216 When not nil or t, comment lines that begin with a single `#' are used
212 as indentation hints, unless the comment character is in column zero." 217 as indentation hints, unless the comment character is in column zero."
213 :type '(choice 218 :type '(choice
214 (const :tag "Skip all comment lines (fast)" nil) 219 (const :tag "Skip all comment lines (fast)" nil)
215 (const :tag "Single # `sets' indentation for next line" t) 220 (const :tag "Single # `sets' indentation for next line" t)
216 (const :tag "Single # `sets' indentation except at column zero" 221 (const :tag "Single # `sets' indentation except at column zero"
217 other) 222 other)
218 ) 223 )
219 :group 'python) 224 :group 'python)
220 225
221 (defcustom py-temp-directory 226 (defcustom py-temp-directory
222 (let ((ok '(lambda (x) 227 (let ((ok '(lambda (x)
223 (and x 228 (and x
224 (setq x (expand-file-name x)) ; always true 229 (setq x (expand-file-name x)) ; always true
225 (file-directory-p x) 230 (file-directory-p x)
226 (file-writable-p x) 231 (file-writable-p x)
227 x)))) 232 x))))
228 (or (funcall ok (getenv "TMPDIR")) 233 (or (funcall ok (getenv "TMPDIR"))
229 (funcall ok "/usr/tmp") 234 (funcall ok "/usr/tmp")
230 (funcall ok "/tmp") 235 (funcall ok "/tmp")
231 (funcall ok "/var/tmp") 236 (funcall ok "/var/tmp")
232 (funcall ok ".") 237 (funcall ok ".")
233 (error 238 (error
234 "Couldn't find a usable temp directory -- set `py-temp-directory'"))) 239 "Couldn't find a usable temp directory -- set `py-temp-directory'")))
235 "*Directory used for temporary files created by a *Python* process. 240 "*Directory used for temporary files created by a *Python* process.
236 By default, the first directory from this list that exists and that you 241 By default, the first directory from this list that exists and that you
237 can write into: the value (if any) of the environment variable TMPDIR, 242 can write into: the value (if any) of the environment variable TMPDIR,
238 /usr/tmp, /tmp, /var/tmp, or the current directory." 243 /usr/tmp, /tmp, /var/tmp, or the current directory."
239 :type 'string 244 :type 'string
400 ;; Face for builtins 405 ;; Face for builtins
401 (defvar py-builtins-face 'py-builtins-face 406 (defvar py-builtins-face 'py-builtins-face
402 "Face for builtins like TypeError, object, open, and exec.") 407 "Face for builtins like TypeError, object, open, and exec.")
403 (make-face 'py-builtins-face) 408 (make-face 'py-builtins-face)
404 409
410 ;; XXX, TODO, and FIXME comments and such
411 (defvar py-XXX-tag-face 'py-XXX-tag-face
412 "Face for XXX, TODO, and FIXME tags")
413 (make-face 'py-XXX-tag-face)
414
405 (defun py-font-lock-mode-hook () 415 (defun py-font-lock-mode-hook ()
406 (or (face-differs-from-default-p 'py-pseudo-keyword-face) 416 (or (face-differs-from-default-p 'py-pseudo-keyword-face)
407 (copy-face 'font-lock-keyword-face 'py-pseudo-keyword-face)) 417 (copy-face 'font-lock-keyword-face 'py-pseudo-keyword-face))
408 (or (face-differs-from-default-p 'py-builtins-face) 418 (or (face-differs-from-default-p 'py-builtins-face)
409 (copy-face 'font-lock-keyword-face 'py-builtins-face)) 419 (copy-face 'font-lock-keyword-face 'py-builtins-face))
410 (or (face-differs-from-default-p 'py-decorators-face) 420 (or (face-differs-from-default-p 'py-decorators-face)
411 (copy-face 'py-pseudo-keyword-face 'py-decorators-face)) 421 (copy-face 'py-pseudo-keyword-face 'py-decorators-face))
422 (or (face-differs-from-default-p 'py-XXX-tag-face)
423 (copy-face 'font-lock-comment-face 'py-XXX-tag-face))
412 ) 424 )
413 (add-hook 'font-lock-mode-hook 'py-font-lock-mode-hook) 425 (add-hook 'font-lock-mode-hook 'py-font-lock-mode-hook)
414 426
415 (defvar python-font-lock-keywords 427 (defvar python-font-lock-keywords
416 (let ((kw1 (mapconcat 'identity 428 (let ((kw1 (mapconcat 'identity
417 '("and" "assert" "break" "class" 429 '("and" "assert" "break" "class"
418 "continue" "def" "del" "elif" 430 "continue" "def" "del" "elif"
419 "else" "except" "exec" "for" 431 "else" "except" "for" "from"
420 "from" "global" "if" "import" 432 "global" "if" "import" "in"
421 "in" "is" "lambda" "not" 433 "is" "lambda" "not" "or"
422 "or" "pass" "print" "raise" 434 "pass" "raise" "as" "return"
423 "return" "while" "yield" 435 "while" "with" "yield"
424 ) 436 )
425 "\\|")) 437 "\\|"))
426 (kw2 (mapconcat 'identity 438 (kw2 (mapconcat 'identity
427 '("else:" "except:" "finally:" "try:") 439 '("else:" "except:" "finally:" "try:")
428 "\\|")) 440 "\\|"))
429 (kw3 (mapconcat 'identity 441 (kw3 (mapconcat 'identity
430 ;; Don't include True, False, None, or 442 ;; Don't include Ellipsis in this list, since it is
431 ;; Ellipsis in this list, since they are 443 ;; already defined as a pseudo keyword.
432 ;; already defined as pseudo keywords. 444 '("__debug__"
433 '("__debug__" 445 "__import__" "__name__" "abs" "all" "any" "apply"
434 "__import__" "__name__" "abs" "apply" "basestring" 446 "basestring" "bin" "bool" "buffer" "bytearray"
435 "bool" "buffer" "callable" "chr" "classmethod" 447 "callable" "chr" "classmethod" "cmp" "coerce"
436 "cmp" "coerce" "compile" "complex" "copyright" 448 "compile" "complex" "copyright" "credits"
437 "delattr" "dict" "dir" "divmod" 449 "delattr" "dict" "dir" "divmod" "enumerate" "eval"
438 "enumerate" "eval" "execfile" "exit" "file" 450 "exec" "execfile" "exit" "file" "filter" "float"
439 "filter" "float" "getattr" "globals" "hasattr" 451 "format" "getattr" "globals" "hasattr" "hash" "help"
440 "hash" "hex" "id" "input" "int" "intern" 452 "hex" "id" "input" "int" "intern" "isinstance"
441 "isinstance" "issubclass" "iter" "len" "license" 453 "issubclass" "iter" "len" "license" "list" "locals"
442 "list" "locals" "long" "map" "max" "min" "object" 454 "long" "map" "max" "memoryview" "min" "next"
443 "oct" "open" "ord" "pow" "property" "range" 455 "object" "oct" "open" "ord" "pow" "print" "property"
444 "raw_input" "reduce" "reload" "repr" "round" 456 "quit" "range" "raw_input" "reduce" "reload" "repr"
445 "setattr" "slice" "staticmethod" "str" "sum" 457 "round" "set" "setattr" "slice" "sorted"
446 "super" "tuple" "type" "unichr" "unicode" "vars" 458 "staticmethod" "str" "sum" "super" "tuple" "type"
447 "xrange" "zip") 459 "unichr" "unicode" "vars" "xrange" "zip")
448 "\\|")) 460 "\\|"))
449 (kw4 (mapconcat 'identity 461 (kw4 (mapconcat 'identity
450 ;; Exceptions and warnings 462 ;; Exceptions and warnings
451 '("ArithmeticError" "AssertionError" 463 '("ArithmeticError" "AssertionError"
452 "AttributeError" "DeprecationWarning" "EOFError" 464 "AttributeError" "BaseException" "BufferError"
453 "EnvironmentError" "Exception" 465 "BytesWarning" "DeprecationWarning" "EOFError"
454 "FloatingPointError" "FutureWarning" "IOError" 466 "EnvironmentError" "Exception"
455 "ImportError" "IndentationError" "IndexError" 467 "FloatingPointError" "FutureWarning" "GeneratorExit"
456 "KeyError" "KeyboardInterrupt" "LookupError" 468 "IOError" "ImportError" "ImportWarning"
457 "MemoryError" "NameError" "NotImplemented" 469 "IndentationError" "IndexError"
458 "NotImplementedError" "OSError" "OverflowError" 470 "KeyError" "KeyboardInterrupt" "LookupError"
459 "OverflowWarning" "PendingDeprecationWarning" 471 "MemoryError" "NameError" "NotImplemented"
460 "ReferenceError" "RuntimeError" "RuntimeWarning" 472 "NotImplementedError" "OSError" "OverflowError"
461 "StandardError" "StopIteration" "SyntaxError" 473 "PendingDeprecationWarning" "ReferenceError"
462 "SyntaxWarning" "SystemError" "SystemExit" 474 "RuntimeError" "RuntimeWarning" "StandardError"
463 "TabError" "TypeError" "UnboundLocalError" 475 "StopIteration" "SyntaxError" "SyntaxWarning"
464 "UnicodeDecodeError" "UnicodeEncodeError" 476 "SystemError" "SystemExit" "TabError" "TypeError"
465 "UnicodeError" "UnicodeTranslateError" 477 "UnboundLocalError" "UnicodeDecodeError"
466 "UserWarning" "ValueError" "Warning" 478 "UnicodeEncodeError" "UnicodeError"
467 "ZeroDivisionError") 479 "UnicodeTranslateError" "UnicodeWarning"
468 "\\|")) 480 "UserWarning" "ValueError" "Warning"
469 ) 481 "ZeroDivisionError")
482 "\\|"))
483 )
470 (list 484 (list
471 '("^[ \t]*\\(@.+\\)" 1 'py-decorators-face) 485 '("^[ \t]*\\(@.+\\)" 1 'py-decorators-face)
472 ;; keywords 486 ;; keywords
473 (cons (concat "\\<\\(" kw1 "\\)\\>[ \n\t(]") 1) 487 (cons (concat "\\<\\(" kw1 "\\)\\>[ \n\t(]") 1)
474 ;; builtins when they don't appear as object attributes 488 ;; builtins when they don't appear as object attributes
475 (list (concat "\\([^. \t]\\|^\\)[ \t]*\\<\\(" kw3 "\\)\\>[ \n\t(]") 2 489 (list (concat "\\([^. \t]\\|^\\)[ \t]*\\<\\(" kw3 "\\)\\>[ \n\t(]") 2
476 'py-builtins-face) 490 'py-builtins-face)
477 ;; block introducing keywords with immediately following colons. 491 ;; block introducing keywords with immediately following colons.
478 ;; Yes "except" is in both lists. 492 ;; Yes "except" is in both lists.
479 (cons (concat "\\<\\(" kw2 "\\)[ \n\t(]") 1) 493 (cons (concat "\\<\\(" kw2 "\\)[ \n\t(]") 1)
480 ;; Exceptions 494 ;; Exceptions
481 (list (concat "\\<\\(" kw4 "\\)[ \n\t:,(]") 1 'py-builtins-face) 495 (list (concat "\\<\\(" kw4 "\\)[ \n\t:,(]") 1 'py-builtins-face)
482 ;; `as' but only in "import foo as bar"
483 '("[ \t]*\\(\\<from\\>.*\\)?\\<import\\>.*\\<\\(as\\)\\>" . 2)
484
485 ;; classes 496 ;; classes
486 '("\\<class[ \t]+\\([a-zA-Z_]+[a-zA-Z0-9_]*\\)" 1 font-lock-type-face) 497 '("\\<class[ \t]+\\([a-zA-Z_]+[a-zA-Z0-9_]*\\)" 1 font-lock-type-face)
487 ;; functions 498 ;; functions
488 '("\\<def[ \t]+\\([a-zA-Z_]+[a-zA-Z0-9_]*\\)" 499 '("\\<def[ \t]+\\([a-zA-Z_]+[a-zA-Z0-9_]*\\)"
489 1 font-lock-function-name-face) 500 1 font-lock-function-name-face)
490 ;; pseudo-keywords 501 ;; pseudo-keywords
491 '("\\<\\(self\\|None\\|True\\|False\\|Ellipsis\\)\\>" 502 '("\\<\\(self\\|Ellipsis\\|True\\|False\\|None\\)\\>"
492 1 py-pseudo-keyword-face) 503 1 py-pseudo-keyword-face)
504 ;; XXX, TODO, and FIXME tags
505 '("XXX\\|TODO\\|FIXME" 0 py-XXX-tag-face t)
493 )) 506 ))
494 "Additional expressions to highlight in Python mode.") 507 "Additional expressions to highlight in Python mode.")
495 (put 'python-mode 'font-lock-defaults '(python-font-lock-keywords)) 508 (put 'python-mode 'font-lock-defaults '(python-font-lock-keywords))
496 509
497 ;; have to bind py-file-queue before installing the kill-emacs-hook 510 ;; have to bind py-file-queue before installing the kill-emacs-hook
519 "\\|" 532 "\\|"
520 ;; (maybe raw), long double quoted triple quoted strings (DQTQ), 533 ;; (maybe raw), long double quoted triple quoted strings (DQTQ),
521 ;; with potential embedded double quotes 534 ;; with potential embedded double quotes
522 "[rR]?\"\"\"[^\"]*\\(\\(\"[^\"]\\|\"\"[^\"]\\)[^\"]*\\)*\"\"\"" 535 "[rR]?\"\"\"[^\"]*\\(\\(\"[^\"]\\|\"\"[^\"]\\)[^\"]*\\)*\"\"\""
523 "\\|" 536 "\\|"
524 "[rR]?'\\([^'\n\\]\\|\\\\.\\)*'" ; single-quoted 537 "[rR]?'\\([^'\n\\]\\|\\\\.\\)*'" ; single-quoted
525 "\\|" ; or 538 "\\|" ; or
526 "[rR]?\"\\([^\"\n\\]\\|\\\\.\\)*\"" ; double-quoted 539 "[rR]?\"\\([^\"\n\\]\\|\\\\.\\)*\"" ; double-quoted
527 ) 540 )
528 "Regular expression matching a Python string literal.") 541 "Regular expression matching a Python string literal.")
529 542
530 (defconst py-continued-re 543 (defconst py-continued-re
531 ;; This is tricky because a trailing backslash does not mean 544 ;; This is tricky because a trailing backslash does not mean
538 (defconst py-blank-or-comment-re "[ \t]*\\($\\|#\\)" 551 (defconst py-blank-or-comment-re "[ \t]*\\($\\|#\\)"
539 "Regular expression matching a blank or comment line.") 552 "Regular expression matching a blank or comment line.")
540 553
541 (defconst py-outdent-re 554 (defconst py-outdent-re
542 (concat "\\(" (mapconcat 'identity 555 (concat "\\(" (mapconcat 'identity
543 '("else:" 556 '("else:"
544 "except\\(\\s +.*\\)?:" 557 "except\\(\\s +.*\\)?:"
545 "finally:" 558 "finally:"
546 "elif\\s +.*:") 559 "elif\\s +.*:")
547 "\\|") 560 "\\|")
548 "\\)") 561 "\\)")
549 "Regular expression matching statements to be dedented one level.") 562 "Regular expression matching statements to be dedented one level.")
550 563
551 (defconst py-block-closing-keywords-re 564 (defconst py-block-closing-keywords-re
552 "\\(return\\|raise\\|break\\|continue\\|pass\\)" 565 "\\(return\\|raise\\|break\\|continue\\|pass\\)"
553 "Regular expression matching keywords which typically close a block.") 566 "Regular expression matching keywords which typically close a block.")
554 567
555 (defconst py-no-outdent-re 568 (defconst py-no-outdent-re
556 (concat 569 (concat
557 "\\(" 570 "\\("
558 (mapconcat 'identity 571 (mapconcat 'identity
559 (list "try:" 572 (list "try:"
560 "except\\(\\s +.*\\)?:" 573 "except\\(\\s +.*\\)?:"
561 "while\\s +.*:" 574 "while\\s +.*:"
562 "for\\s +.*:" 575 "for\\s +.*:"
563 "if\\s +.*:" 576 "if\\s +.*:"
564 "elif\\s +.*:" 577 "elif\\s +.*:"
565 (concat py-block-closing-keywords-re "[ \t\n]") 578 (concat py-block-closing-keywords-re "[ \t\n]")
566 ) 579 )
567 "\\|") 580 "\\|")
568 "\\)") 581 "\\)")
569 "Regular expression matching lines not to dedent after.") 582 "Regular expression matching lines not to dedent after.")
570 583
571 (defvar py-traceback-line-re 584 (defvar py-traceback-line-re
572 "[ \t]+File \"\\([^\"]+\\)\", line \\([0-9]+\\)" 585 "[ \t]+File \"\\([^\"]+\\)\", line \\([0-9]+\\)"
573 "Regular expression that describes tracebacks.") 586 "Regular expression that describes tracebacks.")
652 (define-key py-mode-map "\C-c\C-k" 'py-mark-block) 665 (define-key py-mode-map "\C-c\C-k" 'py-mark-block)
653 ;; Miscellaneous 666 ;; Miscellaneous
654 (define-key py-mode-map "\C-c:" 'py-guess-indent-offset) 667 (define-key py-mode-map "\C-c:" 'py-guess-indent-offset)
655 (define-key py-mode-map "\C-c\t" 'py-indent-region) 668 (define-key py-mode-map "\C-c\t" 'py-indent-region)
656 (define-key py-mode-map "\C-c\C-d" 'py-pdbtrack-toggle-stack-tracking) 669 (define-key py-mode-map "\C-c\C-d" 'py-pdbtrack-toggle-stack-tracking)
670 (define-key py-mode-map "\C-c\C-f" 'py-sort-imports)
657 (define-key py-mode-map "\C-c\C-n" 'py-next-statement) 671 (define-key py-mode-map "\C-c\C-n" 'py-next-statement)
658 (define-key py-mode-map "\C-c\C-p" 'py-previous-statement) 672 (define-key py-mode-map "\C-c\C-p" 'py-previous-statement)
659 (define-key py-mode-map "\C-c\C-u" 'py-goto-block-up) 673 (define-key py-mode-map "\C-c\C-u" 'py-goto-block-up)
660 (define-key py-mode-map "\C-c#" 'py-comment-region) 674 (define-key py-mode-map "\C-c#" 'py-comment-region)
661 (define-key py-mode-map "\C-c?" 'py-describe-mode) 675 (define-key py-mode-map "\C-c?" 'py-describe-mode)
672 (define-key py-mode-map "\C-c\C-v" 'py-version) 686 (define-key py-mode-map "\C-c\C-v" 'py-version)
673 (define-key py-mode-map "\C-c\C-w" 'py-pychecker-run) 687 (define-key py-mode-map "\C-c\C-w" 'py-pychecker-run)
674 ;; shadow global bindings for newline-and-indent w/ the py- version. 688 ;; shadow global bindings for newline-and-indent w/ the py- version.
675 ;; BAW - this is extremely bad form, but I'm not going to change it 689 ;; BAW - this is extremely bad form, but I'm not going to change it
676 ;; for now. 690 ;; for now.
677 (mapcar #'(lambda (key) 691 (mapc #'(lambda (key)
678 (define-key py-mode-map key 'py-newline-and-indent)) 692 (define-key py-mode-map key 'py-newline-and-indent))
679 (where-is-internal 'newline-and-indent)) 693 (where-is-internal 'newline-and-indent))
680 ;; Force RET to be py-newline-and-indent even if it didn't get 694 ;; Force RET to be py-newline-and-indent even if it didn't get
681 ;; mapped by the above code. motivation: Emacs' default binding for 695 ;; mapped by the above code. motivation: Emacs' default binding for
682 ;; RET is `newline' and C-j is `newline-and-indent'. Most Pythoneers 696 ;; RET is `newline' and C-j is `newline-and-indent'. Most Pythoneers
683 ;; expect RET to do a `py-newline-and-indent' and any Emacsers who 697 ;; expect RET to do a `py-newline-and-indent' and any Emacsers who
684 ;; dislike this are probably knowledgeable enough to do a rebind. 698 ;; dislike this are probably knowledgeable enough to do a rebind.
695 (setq py-mode-output-map (make-sparse-keymap)) 709 (setq py-mode-output-map (make-sparse-keymap))
696 (define-key py-mode-output-map [button2] 'py-mouseto-exception) 710 (define-key py-mode-output-map [button2] 'py-mouseto-exception)
697 (define-key py-mode-output-map "\C-c\C-c" 'py-goto-exception) 711 (define-key py-mode-output-map "\C-c\C-c" 'py-goto-exception)
698 ;; TBD: Disable all self-inserting keys. This is bogus, we should 712 ;; TBD: Disable all self-inserting keys. This is bogus, we should
699 ;; really implement this as *Python Output* buffer being read-only 713 ;; really implement this as *Python Output* buffer being read-only
700 (mapcar #' (lambda (key) 714 (mapc #' (lambda (key)
701 (define-key py-mode-output-map key 715 (define-key py-mode-output-map key
702 #'(lambda () (interactive) (beep)))) 716 #'(lambda () (interactive) (beep))))
703 (where-is-internal 'self-insert-command)) 717 (where-is-internal 'self-insert-command))
704 ) 718 )
705 719
706 (defvar py-shell-map nil 720 (defvar py-shell-map nil
707 "Keymap used in *Python* shell buffers.") 721 "Keymap used in *Python* shell buffers.")
708 (if py-shell-map 722 (if py-shell-map
760 ;; symbol class for simplicity 774 ;; symbol class for simplicity
761 (defvar py-dotted-expression-syntax-table nil 775 (defvar py-dotted-expression-syntax-table nil
762 "Syntax table used to identify Python dotted expressions.") 776 "Syntax table used to identify Python dotted expressions.")
763 (when (not py-dotted-expression-syntax-table) 777 (when (not py-dotted-expression-syntax-table)
764 (setq py-dotted-expression-syntax-table 778 (setq py-dotted-expression-syntax-table
765 (copy-syntax-table py-mode-syntax-table)) 779 (copy-syntax-table py-mode-syntax-table))
766 (modify-syntax-entry ?_ "_" py-dotted-expression-syntax-table) 780 (modify-syntax-entry ?_ "_" py-dotted-expression-syntax-table)
767 (modify-syntax-entry ?. "_" py-dotted-expression-syntax-table)) 781 (modify-syntax-entry ?. "_" py-dotted-expression-syntax-table))
768 782
769 783
770 784
771 ;; Utilities 785 ;; Utilities
772 (defmacro py-safe (&rest body) 786 (defmacro py-safe (&rest body)
773 "Safely execute BODY, return nil if an error occurred." 787 "Safely execute BODY, return nil if an error occurred."
774 (` (condition-case nil 788 `(condition-case nil
775 (progn (,@ body)) 789 (progn ,@ body)
776 (error nil)))) 790 (error nil)))
777 791
778 (defsubst py-keep-region-active () 792 (defsubst py-keep-region-active ()
779 "Keep the region active in XEmacs." 793 "Keep the region active in XEmacs."
780 ;; Ignore byte-compiler warnings you might see. Also note that 794 ;; Ignore byte-compiler warnings you might see. Also note that
781 ;; FSF's Emacs 19 does it differently; its policy doesn't require us 795 ;; FSF's Emacs 19 does it differently; its policy doesn't require us
802 ((eq position 'bol) (beginning-of-line)) 816 ((eq position 'bol) (beginning-of-line))
803 ((eq position 'eol) (end-of-line)) 817 ((eq position 'eol) (end-of-line))
804 ((eq position 'bod) (py-beginning-of-def-or-class 'either)) 818 ((eq position 'bod) (py-beginning-of-def-or-class 'either))
805 ((eq position 'eod) (py-end-of-def-or-class 'either)) 819 ((eq position 'eod) (py-end-of-def-or-class 'either))
806 ;; Kind of funny, I know, but useful for py-up-exception. 820 ;; Kind of funny, I know, but useful for py-up-exception.
807 ((eq position 'bob) (beginning-of-buffer)) 821 ((eq position 'bob) (goto-char (point-min)))
808 ((eq position 'eob) (end-of-buffer)) 822 ((eq position 'eob) (goto-char (point-max)))
809 ((eq position 'boi) (back-to-indentation)) 823 ((eq position 'boi) (back-to-indentation))
810 ((eq position 'bos) (py-goto-initial-line)) 824 ((eq position 'bos) (py-goto-initial-line))
811 (t (error "Unknown buffer position requested: %s" position)) 825 (t (error "Unknown buffer position requested: %s" position))
812 ) 826 )
813 (prog1 827 (prog1
814 (point) 828 (point)
815 (goto-char here)))) 829 (goto-char here))))
816 830
817 (defsubst py-highlight-line (from to file line) 831 (defsubst py-highlight-line (from to file line)
818 (cond 832 (cond
819 ((fboundp 'make-extent) 833 ((fboundp 'make-extent)
834 ;; This is the version used for non-XEmacs, which has a nicer 848 ;; This is the version used for non-XEmacs, which has a nicer
835 ;; interface. 849 ;; interface.
836 ;; 850 ;;
837 ;; WARNING: Watch out for infinite recursion. 851 ;; WARNING: Watch out for infinite recursion.
838 (let* ((lim (or lim (py-point 'bod))) 852 (let* ((lim (or lim (py-point 'bod)))
839 (state (parse-partial-sexp lim (point)))) 853 (state (parse-partial-sexp lim (point))))
840 (cond 854 (cond
841 ((nth 3 state) 'string) 855 ((nth 3 state) 'string)
842 ((nth 4 state) 'comment) 856 ((nth 4 state) 'comment)
843 (t nil)))) 857 (t nil))))
844 858
864 878
865 (and (py-safe (require 'easymenu) t) 879 (and (py-safe (require 'easymenu) t)
866 (easy-menu-define 880 (easy-menu-define
867 py-menu py-mode-map "Python Mode menu" 881 py-menu py-mode-map "Python Mode menu"
868 '("Python" 882 '("Python"
869 ["Comment Out Region" py-comment-region (mark)] 883 ["Comment Out Region" py-comment-region (mark)]
870 ["Uncomment Region" (py-comment-region (point) (mark) '(4)) (mark)] 884 ["Uncomment Region" (py-comment-region (point) (mark) '(4)) (mark)]
871 "-" 885 "-"
872 ["Mark current block" py-mark-block t] 886 ["Mark current block" py-mark-block t]
873 ["Mark current def" py-mark-def-or-class t] 887 ["Mark current def" py-mark-def-or-class t]
874 ["Mark current class" (py-mark-def-or-class t) t] 888 ["Mark current class" (py-mark-def-or-class t) t]
875 "-" 889 "-"
876 ["Shift region left" py-shift-region-left (mark)] 890 ["Shift region left" py-shift-region-left (mark)]
877 ["Shift region right" py-shift-region-right (mark)] 891 ["Shift region right" py-shift-region-right (mark)]
878 "-" 892 "-"
879 ["Import/reload file" py-execute-import-or-reload t] 893 ["Import/reload file" py-execute-import-or-reload t]
880 ["Execute buffer" py-execute-buffer t] 894 ["Execute buffer" py-execute-buffer t]
881 ["Execute region" py-execute-region (mark)] 895 ["Execute region" py-execute-region (mark)]
882 ["Execute def or class" py-execute-def-or-class (mark)] 896 ["Execute def or class" py-execute-def-or-class (mark)]
883 ["Execute string" py-execute-string t] 897 ["Execute string" py-execute-string t]
884 ["Start interpreter..." py-shell t] 898 ["Start interpreter..." py-shell t]
885 "-" 899 "-"
886 ["Go to start of block" py-goto-block-up t] 900 ["Go to start of block" py-goto-block-up t]
887 ["Go to start of class" (py-beginning-of-def-or-class t) t] 901 ["Go to start of class" (py-beginning-of-def-or-class t) t]
888 ["Move to end of class" (py-end-of-def-or-class t) t] 902 ["Move to end of class" (py-end-of-def-or-class t) t]
889 ["Move to start of def" py-beginning-of-def-or-class t] 903 ["Move to start of def" py-beginning-of-def-or-class t]
890 ["Move to end of def" py-end-of-def-or-class t] 904 ["Move to end of def" py-end-of-def-or-class t]
891 "-" 905 "-"
892 ["Describe mode" py-describe-mode t] 906 ["Describe mode" py-describe-mode t]
893 ))) 907 )))
894 908
895 909
896 910
897 ;; Imenu definitions 911 ;; Imenu definitions
898 (defvar py-imenu-class-regexp 912 (defvar py-imenu-class-regexp
899 (concat ; <<classes>> 913 (concat ; <<classes>>
900 "\\(" ; 914 "\\(" ;
901 "^[ \t]*" ; newline and maybe whitespace 915 "^[ \t]*" ; newline and maybe whitespace
902 "\\(class[ \t]+[a-zA-Z0-9_]+\\)" ; class name 916 "\\(class[ \t]+[a-zA-Z0-9_]+\\)" ; class name
903 ; possibly multiple superclasses 917 ; possibly multiple superclasses
904 "\\([ \t]*\\((\\([a-zA-Z0-9_,. \t\n]\\)*)\\)?\\)" 918 "\\([ \t]*\\((\\([a-zA-Z0-9_,. \t\n]\\)*)\\)?\\)"
905 "[ \t]*:" ; and the final : 919 "[ \t]*:" ; and the final :
906 "\\)" ; >>classes<< 920 "\\)" ; >>classes<<
907 ) 921 )
908 "Regexp for Python classes for use with the Imenu package." 922 "Regexp for Python classes for use with the Imenu package."
909 ) 923 )
910 924
911 (defvar py-imenu-method-regexp 925 (defvar py-imenu-method-regexp
912 (concat ; <<methods and functions>> 926 (concat ; <<methods and functions>>
913 "\\(" ; 927 "\\(" ;
914 "^[ \t]*" ; new line and maybe whitespace 928 "^[ \t]*" ; new line and maybe whitespace
915 "\\(def[ \t]+" ; function definitions start with def 929 "\\(def[ \t]+" ; function definitions start with def
916 "\\([a-zA-Z0-9_]+\\)" ; name is here 930 "\\([a-zA-Z0-9_]+\\)" ; name is here
917 ; function arguments... 931 ; function arguments...
918 ;; "[ \t]*(\\([-+/a-zA-Z0-9_=,\* \t\n.()\"'#]*\\))" 932 ;; "[ \t]*(\\([-+/a-zA-Z0-9_=,\* \t\n.()\"'#]*\\))"
919 "[ \t]*(\\([^:#]*\\))" 933 "[ \t]*(\\([^:#]*\\))"
920 "\\)" ; end of def 934 "\\)" ; end of def
921 "[ \t]*:" ; and then the : 935 "[ \t]*:" ; and then the :
922 "\\)" ; >>methods and functions<< 936 "\\)" ; >>methods and functions<<
946 ;; it. 960 ;; it.
947 (defvar py-imenu-generic-expression 961 (defvar py-imenu-generic-expression
948 (cons 962 (cons
949 (concat 963 (concat
950 py-imenu-class-regexp 964 py-imenu-class-regexp
951 "\\|" ; or... 965 "\\|" ; or...
952 py-imenu-method-regexp 966 py-imenu-method-regexp
953 ) 967 )
954 py-imenu-method-no-arg-parens) 968 py-imenu-method-no-arg-parens)
955 "Generic Python expression which may be used directly with Imenu. 969 "Generic Python expression which may be used directly with Imenu.
956 Used by setting the variable `imenu-generic-expression' to this value. 970 Used by setting the variable `imenu-generic-expression' to this value.
968 "Python interface function for the Imenu package. 982 "Python interface function for the Imenu package.
969 Finds all Python classes and functions/methods. Calls function 983 Finds all Python classes and functions/methods. Calls function
970 \\[py-imenu-create-index-engine]. See that function for the details 984 \\[py-imenu-create-index-engine]. See that function for the details
971 of how this works." 985 of how this works."
972 (setq py-imenu-generic-regexp (car py-imenu-generic-expression) 986 (setq py-imenu-generic-regexp (car py-imenu-generic-expression)
973 py-imenu-generic-parens (if py-imenu-show-method-args-p 987 py-imenu-generic-parens (if py-imenu-show-method-args-p
974 py-imenu-method-arg-parens 988 py-imenu-method-arg-parens
975 py-imenu-method-no-arg-parens)) 989 py-imenu-method-no-arg-parens))
976 (goto-char (point-min)) 990 (goto-char (point-min))
977 ;; Warning: When the buffer has no classes or functions, this will 991 ;; Warning: When the buffer has no classes or functions, this will
978 ;; return nil, which seems proper according to the Imenu API, but 992 ;; return nil, which seems proper according to the Imenu API, but
979 ;; causes an error in the XEmacs port of Imenu. Sigh. 993 ;; causes an error in the XEmacs port of Imenu. Sigh.
980 (py-imenu-create-index-engine nil)) 994 (py-imenu-create-index-engine nil))
985 Finds all definitions (classes, methods, or functions) in a Python 999 Finds all definitions (classes, methods, or functions) in a Python
986 file for the Imenu package. 1000 file for the Imenu package.
987 1001
988 Returns a possibly nested alist of the form 1002 Returns a possibly nested alist of the form
989 1003
990 (INDEX-NAME . INDEX-POSITION) 1004 (INDEX-NAME . INDEX-POSITION)
991 1005
992 The second element of the alist may be an alist, producing a nested 1006 The second element of the alist may be an alist, producing a nested
993 list as in 1007 list as in
994 1008
995 (INDEX-NAME . INDEX-ALIST) 1009 (INDEX-NAME . INDEX-ALIST)
996 1010
997 This function should not be called directly, as it calls itself 1011 This function should not be called directly, as it calls itself
998 recursively and requires some setup. Rather this is the engine for 1012 recursively and requires some setup. Rather this is the engine for
999 the function \\[py-imenu-create-index-function]. 1013 the function \\[py-imenu-create-index-function].
1000 1014
1009 The optional argument START-INDENT indicates the starting indentation 1023 The optional argument START-INDENT indicates the starting indentation
1010 at which to continue looking for Python classes, methods, or 1024 at which to continue looking for Python classes, methods, or
1011 functions. If this is not supplied, the function uses the indentation 1025 functions. If this is not supplied, the function uses the indentation
1012 of the first definition found." 1026 of the first definition found."
1013 (let (index-alist 1027 (let (index-alist
1014 sub-method-alist 1028 sub-method-alist
1015 looking-p 1029 looking-p
1016 def-name prev-name 1030 def-name prev-name
1017 cur-indent def-pos 1031 cur-indent def-pos
1018 (class-paren (first py-imenu-generic-parens)) 1032 (class-paren (first py-imenu-generic-parens))
1019 (def-paren (second py-imenu-generic-parens))) 1033 (def-paren (second py-imenu-generic-parens)))
1020 (setq looking-p 1034 (setq looking-p
1021 (re-search-forward py-imenu-generic-regexp (point-max) t)) 1035 (re-search-forward py-imenu-generic-regexp (point-max) t))
1022 (while looking-p 1036 (while looking-p
1023 (save-excursion 1037 (save-excursion
1024 ;; used to set def-name to this value but generic-extract-name 1038 ;; used to set def-name to this value but generic-extract-name
1025 ;; is new to imenu-1.14. this way it still works with 1039 ;; is new to imenu-1.14. this way it still works with
1026 ;; imenu-1.11 1040 ;; imenu-1.11
1027 ;;(imenu--generic-extract-name py-imenu-generic-parens)) 1041 ;;(imenu--generic-extract-name py-imenu-generic-parens))
1028 (let ((cur-paren (if (match-beginning class-paren) 1042 (let ((cur-paren (if (match-beginning class-paren)
1029 class-paren def-paren))) 1043 class-paren def-paren)))
1030 (setq def-name 1044 (setq def-name
1031 (buffer-substring-no-properties (match-beginning cur-paren) 1045 (buffer-substring-no-properties (match-beginning cur-paren)
1032 (match-end cur-paren)))) 1046 (match-end cur-paren))))
1033 (save-match-data 1047 (save-match-data
1034 (py-beginning-of-def-or-class 'either)) 1048 (py-beginning-of-def-or-class 'either))
1035 (beginning-of-line) 1049 (beginning-of-line)
1036 (setq cur-indent (current-indentation))) 1050 (setq cur-indent (current-indentation)))
1037 ;; HACK: want to go to the next correct definition location. We 1051 ;; HACK: want to go to the next correct definition location. We
1038 ;; explicitly list them here but it would be better to have them 1052 ;; explicitly list them here but it would be better to have them
1039 ;; in a list. 1053 ;; in a list.
1040 (setq def-pos 1054 (setq def-pos
1041 (or (match-beginning class-paren) 1055 (or (match-beginning class-paren)
1042 (match-beginning def-paren))) 1056 (match-beginning def-paren)))
1043 ;; if we don't have a starting indent level, take this one 1057 ;; if we don't have a starting indent level, take this one
1044 (or start-indent 1058 (or start-indent
1045 (setq start-indent cur-indent)) 1059 (setq start-indent cur-indent))
1046 ;; if we don't have class name yet, take this one 1060 ;; if we don't have class name yet, take this one
1047 (or prev-name 1061 (or prev-name
1048 (setq prev-name def-name)) 1062 (setq prev-name def-name))
1049 ;; what level is the next definition on? must be same, deeper 1063 ;; what level is the next definition on? must be same, deeper
1050 ;; or shallower indentation 1064 ;; or shallower indentation
1051 (cond 1065 (cond
1052 ;; Skip code in comments and strings 1066 ;; Skip code in comments and strings
1053 ((py-in-literal)) 1067 ((py-in-literal))
1054 ;; at the same indent level, add it to the list... 1068 ;; at the same indent level, add it to the list...
1055 ((= start-indent cur-indent) 1069 ((= start-indent cur-indent)
1056 (push (cons def-name def-pos) index-alist)) 1070 (push (cons def-name def-pos) index-alist))
1057 ;; deeper indented expression, recurse 1071 ;; deeper indented expression, recurse
1058 ((< start-indent cur-indent) 1072 ((< start-indent cur-indent)
1059 ;; the point is currently on the expression we're supposed to 1073 ;; the point is currently on the expression we're supposed to
1060 ;; start on, so go back to the last expression. The recursive 1074 ;; start on, so go back to the last expression. The recursive
1061 ;; call will find this place again and add it to the correct 1075 ;; call will find this place again and add it to the correct
1062 ;; list 1076 ;; list
1063 (re-search-backward py-imenu-generic-regexp (point-min) 'move) 1077 (re-search-backward py-imenu-generic-regexp (point-min) 'move)
1064 (setq sub-method-alist (py-imenu-create-index-engine cur-indent)) 1078 (setq sub-method-alist (py-imenu-create-index-engine cur-indent))
1065 (if sub-method-alist 1079 (if sub-method-alist
1066 ;; we put the last element on the index-alist on the start 1080 ;; we put the last element on the index-alist on the start
1067 ;; of the submethod alist so the user can still get to it. 1081 ;; of the submethod alist so the user can still get to it.
1068 (let ((save-elmt (pop index-alist))) 1082 (let ((save-elmt (pop index-alist)))
1069 (push (cons prev-name 1083 (push (cons prev-name
1070 (cons save-elmt sub-method-alist)) 1084 (cons save-elmt sub-method-alist))
1071 index-alist)))) 1085 index-alist))))
1072 ;; found less indented expression, we're done. 1086 ;; found less indented expression, we're done.
1073 (t 1087 (t
1074 (setq looking-p nil) 1088 (setq looking-p nil)
1075 (re-search-backward py-imenu-generic-regexp (point-min) t))) 1089 (re-search-backward py-imenu-generic-regexp (point-min) t)))
1076 ;; end-cond 1090 ;; end-cond
1077 (setq prev-name def-name) 1091 (setq prev-name def-name)
1078 (and looking-p 1092 (and looking-p
1079 (setq looking-p 1093 (setq looking-p
1080 (re-search-forward py-imenu-generic-regexp 1094 (re-search-forward py-imenu-generic-regexp
1081 (point-max) 'move)))) 1095 (point-max) 'move))))
1082 (nreverse index-alist))) 1096 (nreverse index-alist)))
1083 1097
1084 1098
1085 1099
1086 (defun py-choose-shell-by-shebang () 1100 (defun py-choose-shell-by-shebang ()
1089 Used by `py-choose-shell', and similar to but distinct from 1103 Used by `py-choose-shell', and similar to but distinct from
1090 `set-auto-mode', though it uses `auto-mode-interpreter-regexp' (if available)." 1104 `set-auto-mode', though it uses `auto-mode-interpreter-regexp' (if available)."
1091 ;; look for an interpreter specified in the first line 1105 ;; look for an interpreter specified in the first line
1092 ;; similar to set-auto-mode (files.el) 1106 ;; similar to set-auto-mode (files.el)
1093 (let* ((re (if (boundp 'auto-mode-interpreter-regexp) 1107 (let* ((re (if (boundp 'auto-mode-interpreter-regexp)
1094 auto-mode-interpreter-regexp 1108 auto-mode-interpreter-regexp
1095 ;; stolen from Emacs 21.2 1109 ;; stolen from Emacs 21.2
1096 "#![ \t]?\\([^ \t\n]*/bin/env[ \t]\\)?\\([^ \t\n]+\\)")) 1110 "#![ \t]?\\([^ \t\n]*/bin/env[ \t]\\)?\\([^ \t\n]+\\)"))
1097 (interpreter (save-excursion 1111 (interpreter (save-excursion
1098 (goto-char (point-min)) 1112 (goto-char (point-min))
1099 (if (looking-at re) 1113 (if (looking-at re)
1100 (match-string 2) 1114 (match-string 2)
1101 ""))) 1115 "")))
1102 elt) 1116 elt)
1103 ;; Map interpreter name to a mode. 1117 ;; Map interpreter name to a mode.
1104 (setq elt (assoc (file-name-nondirectory interpreter) 1118 (setq elt (assoc (file-name-nondirectory interpreter)
1105 py-shell-alist)) 1119 py-shell-alist))
1106 (and elt (caddr elt)))) 1120 (and elt (caddr elt))))
1107 1121
1108 1122
1109 1123
1110 (defun py-choose-shell-by-import () 1124 (defun py-choose-shell-by-import ()
1114 return `jython', otherwise return nil." 1128 return `jython', otherwise return nil."
1115 (let (mode) 1129 (let (mode)
1116 (save-excursion 1130 (save-excursion
1117 (goto-char (point-min)) 1131 (goto-char (point-min))
1118 (while (and (not mode) 1132 (while (and (not mode)
1119 (search-forward-regexp 1133 (search-forward-regexp
1120 "^\\(\\(from\\)\\|\\(import\\)\\) \\([^ \t\n.]+\\)" 1134 "^\\(\\(from\\)\\|\\(import\\)\\) \\([^ \t\n.]+\\)"
1121 py-import-check-point-max t)) 1135 py-import-check-point-max t))
1122 (setq mode (and (member (match-string 4) py-jython-packages) 1136 (setq mode (and (member (match-string 4) py-jython-packages)
1123 'jython 1137 'jython
1124 )))) 1138 ))))
1125 mode)) 1139 mode))
1126 1140
1127 1141
1128 (defun py-choose-shell () 1142 (defun py-choose-shell ()
1129 "Choose CPython or Jython mode. Returns the appropriate mode function. 1143 "Choose CPython or Jython mode. Returns the appropriate mode function.
1177 (make-local-variable 'add-log-current-defun-function) 1191 (make-local-variable 'add-log-current-defun-function)
1178 (make-local-variable 'fill-paragraph-function) 1192 (make-local-variable 'fill-paragraph-function)
1179 ;; 1193 ;;
1180 (set-syntax-table py-mode-syntax-table) 1194 (set-syntax-table py-mode-syntax-table)
1181 (setq major-mode 'python-mode 1195 (setq major-mode 'python-mode
1182 mode-name "Python" 1196 mode-name "Python"
1183 local-abbrev-table python-mode-abbrev-table 1197 local-abbrev-table python-mode-abbrev-table
1184 font-lock-defaults '(python-font-lock-keywords) 1198 font-lock-defaults '(python-font-lock-keywords)
1185 paragraph-separate "^[ \t]*$" 1199 paragraph-separate "^[ \t]*$"
1186 paragraph-start "^[ \t]*$" 1200 paragraph-start "^[ \t]*$"
1187 require-final-newline t 1201 require-final-newline t
1188 comment-start "# " 1202 comment-start "# "
1189 comment-end "" 1203 comment-end ""
1190 comment-start-skip "# *" 1204 comment-start-skip "# *"
1191 comment-column 40 1205 comment-column 40
1192 comment-indent-function 'py-comment-indent-function 1206 comment-indent-function 'py-comment-indent-function
1193 indent-region-function 'py-indent-region 1207 indent-region-function 'py-indent-region
1194 indent-line-function 'py-indent-line 1208 indent-line-function 'py-indent-line
1195 ;; tell add-log.el how to find the current function/method/variable 1209 ;; tell add-log.el how to find the current function/method/variable
1196 add-log-current-defun-function 'py-current-defun 1210 add-log-current-defun-function 'py-current-defun
1197 1211
1198 fill-paragraph-function 'py-fill-paragraph 1212 fill-paragraph-function 'py-fill-paragraph
1199 ) 1213 )
1200 (use-local-map py-mode-map) 1214 (use-local-map py-mode-map)
1201 ;; add the menu 1215 ;; add the menu
1202 (if py-menu 1216 (if py-menu
1203 (easy-menu-add py-menu)) 1217 (easy-menu-add py-menu))
1204 ;; Emacs 19 requires this 1218 ;; Emacs 19 requires this
1207 ;; Install Imenu if available 1221 ;; Install Imenu if available
1208 (when (py-safe (require 'imenu)) 1222 (when (py-safe (require 'imenu))
1209 (setq imenu-create-index-function #'py-imenu-create-index-function) 1223 (setq imenu-create-index-function #'py-imenu-create-index-function)
1210 (setq imenu-generic-expression py-imenu-generic-expression) 1224 (setq imenu-generic-expression py-imenu-generic-expression)
1211 (if (fboundp 'imenu-add-to-menubar) 1225 (if (fboundp 'imenu-add-to-menubar)
1212 (imenu-add-to-menubar (format "%s-%s" "IM" mode-name))) 1226 (imenu-add-to-menubar (format "%s-%s" "IM" mode-name)))
1213 ) 1227 )
1214 ;; Run the mode hook. Note that py-mode-hook is deprecated. 1228 ;; Run the mode hook. Note that py-mode-hook is deprecated.
1215 (if python-mode-hook 1229 (if python-mode-hook
1216 (run-hooks 'python-mode-hook) 1230 (run-hooks 'python-mode-hook)
1217 (run-hooks 'py-mode-hook)) 1231 (run-hooks 'py-mode-hook))
1218 ;; Now do the automagical guessing 1232 ;; Now do the automagical guessing
1219 (if py-smart-indentation 1233 (if py-smart-indentation
1220 (let ((offset py-indent-offset)) 1234 (let ((offset py-indent-offset))
1221 ;; It's okay if this fails to guess a good value 1235 ;; It's okay if this fails to guess a good value
1222 (if (and (py-safe (py-guess-indent-offset)) 1236 (if (and (py-safe (py-guess-indent-offset))
1223 (<= py-indent-offset 8) 1237 (<= py-indent-offset 8)
1224 (>= py-indent-offset 2)) 1238 (>= py-indent-offset 2))
1225 (setq offset py-indent-offset)) 1239 (setq offset py-indent-offset))
1226 (setq py-indent-offset offset) 1240 (setq py-indent-offset offset)
1227 ;; Only turn indent-tabs-mode off if tab-width != 1241 ;; Only turn indent-tabs-mode off if tab-width !=
1228 ;; py-indent-offset. Never turn it on, because the user must 1242 ;; py-indent-offset. Never turn it on, because the user must
1229 ;; have explicitly turned it off. 1243 ;; have explicitly turned it off.
1230 (if (/= tab-width py-indent-offset) 1244 (if (/= tab-width py-indent-offset)
1231 (setq indent-tabs-mode nil)) 1245 (setq indent-tabs-mode nil))
1232 )) 1246 ))
1233 ;; Set the default shell if not already set 1247 ;; Set the default shell if not already set
1234 (when (null py-which-shell) 1248 (when (null py-which-shell)
1235 (py-toggle-shells (py-choose-shell)))) 1249 (py-toggle-shells (py-choose-shell))))
1236 1250
1254 ;; can specify different `derived-modes' based on the #! line, but 1268 ;; can specify different `derived-modes' based on the #! line, but
1255 ;; with the latter, we can't. So we just won't add them if they're 1269 ;; with the latter, we can't. So we just won't add them if they're
1256 ;; already added. 1270 ;; already added.
1257 ;;;###autoload 1271 ;;;###autoload
1258 (let ((modes '(("jython" . jython-mode) 1272 (let ((modes '(("jython" . jython-mode)
1259 ("python" . python-mode)))) 1273 ("python" . python-mode))))
1260 (while modes 1274 (while modes
1261 (when (not (assoc (car modes) interpreter-mode-alist)) 1275 (when (not (assoc (car modes) interpreter-mode-alist))
1262 (push (car modes) interpreter-mode-alist)) 1276 (push (car modes) interpreter-mode-alist))
1263 (setq modes (cdr modes)))) 1277 (setq modes (cdr modes))))
1264 ;;;###autoload 1278 ;;;###autoload
1265 (when (not (or (rassq 'python-mode auto-mode-alist) 1279 (when (not (or (rassq 'python-mode auto-mode-alist)
1266 (rassq 'jython-mode auto-mode-alist))) 1280 (rassq 'jython-mode auto-mode-alist)))
1267 (push '("\\.py$" . python-mode) auto-mode-alist)) 1281 (push '("\\.py$" . python-mode) auto-mode-alist))
1268 1282
1269 1283
1270 1284
1271 ;; electric characters 1285 ;; electric characters
1272 (defun py-outdent-p () 1286 (defun py-outdent-p ()
1273 "Returns non-nil if the current line should dedent one level." 1287 "Returns non-nil if the current line should dedent one level."
1274 (save-excursion 1288 (save-excursion
1275 (and (progn (back-to-indentation) 1289 (and (progn (back-to-indentation)
1276 (looking-at py-outdent-re)) 1290 (looking-at py-outdent-re))
1277 ;; short circuit infloop on illegal construct 1291 ;; short circuit infloop on illegal construct
1278 (not (bobp)) 1292 (not (bobp))
1279 (progn (forward-line -1) 1293 (progn (forward-line -1)
1280 (py-goto-initial-line) 1294 (py-goto-initial-line)
1281 (back-to-indentation) 1295 (back-to-indentation)
1282 (while (or (looking-at py-blank-or-comment-re) 1296 (while (or (looking-at py-blank-or-comment-re)
1283 (bobp)) 1297 (bobp))
1284 (backward-to-indentation 1)) 1298 (backward-to-indentation 1))
1285 (not (looking-at py-no-outdent-re))) 1299 (not (looking-at py-no-outdent-re)))
1286 ))) 1300 )))
1287 1301
1288 (defun py-electric-colon (arg) 1302 (defun py-electric-colon (arg)
1289 "Insert a colon. 1303 "Insert a colon.
1290 In certain cases the line is dedented appropriately. If a numeric 1304 In certain cases the line is dedented appropriately. If a numeric
1291 argument ARG is provided, that many colons are inserted 1305 argument ARG is provided, that many colons are inserted
1293 comment." 1307 comment."
1294 (interactive "*P") 1308 (interactive "*P")
1295 (self-insert-command (prefix-numeric-value arg)) 1309 (self-insert-command (prefix-numeric-value arg))
1296 ;; are we in a string or comment? 1310 ;; are we in a string or comment?
1297 (if (save-excursion 1311 (if (save-excursion
1298 (let ((pps (parse-partial-sexp (save-excursion 1312 (let ((pps (parse-partial-sexp (save-excursion
1299 (py-beginning-of-def-or-class) 1313 (py-beginning-of-def-or-class)
1300 (point)) 1314 (point))
1301 (point)))) 1315 (point))))
1302 (not (or (nth 3 pps) (nth 4 pps))))) 1316 (not (or (nth 3 pps) (nth 4 pps)))))
1303 (save-excursion 1317 (save-excursion
1304 (let ((here (point)) 1318 (let ((here (point))
1305 (outdent 0) 1319 (outdent 0)
1306 (indent (py-compute-indentation t))) 1320 (indent (py-compute-indentation t)))
1307 (if (and (not arg) 1321 (if (and (not arg)
1308 (py-outdent-p) 1322 (py-outdent-p)
1309 (= indent (save-excursion 1323 (= indent (save-excursion
1310 (py-next-statement -1) 1324 (py-next-statement -1)
1311 (py-compute-indentation t))) 1325 (py-compute-indentation t)))
1312 ) 1326 )
1313 (setq outdent py-indent-offset)) 1327 (setq outdent py-indent-offset))
1314 ;; Don't indent, only dedent. This assumes that any lines 1328 ;; Don't indent, only dedent. This assumes that any lines
1315 ;; that are already dedented relative to 1329 ;; that are already dedented relative to
1316 ;; py-compute-indentation were put there on purpose. It's 1330 ;; py-compute-indentation were put there on purpose. It's
1317 ;; highly annoying to have `:' indent for you. Use TAB, C-c 1331 ;; highly annoying to have `:' indent for you. Use TAB, C-c
1318 ;; C-l or C-c C-r to adjust. TBD: Is there a better way to 1332 ;; C-l or C-c C-r to adjust. TBD: Is there a better way to
1319 ;; determine this??? 1333 ;; determine this???
1320 (if (< (current-indentation) indent) nil 1334 (if (< (current-indentation) indent) nil
1321 (goto-char here) 1335 (goto-char here)
1322 (beginning-of-line) 1336 (beginning-of-line)
1323 (delete-horizontal-space) 1337 (delete-horizontal-space)
1324 (indent-to (- indent outdent)) 1338 (indent-to (- indent outdent))
1325 ))))) 1339 )))))
1326 1340
1327 1341
1328 ;; Python subprocess utilities and filters 1342 ;; Python subprocess utilities and filters
1329 (defun py-execute-file (proc filename) 1343 (defun py-execute-file (proc filename)
1330 "Send to Python interpreter process PROC \"execfile('FILENAME')\". 1344 "Send to Python interpreter process PROC \"execfile('FILENAME')\".
1331 Make that process's buffer visible and force display. Also make 1345 Make that process's buffer visible and force display. Also make
1332 comint believe the user typed this string so that 1346 comint believe the user typed this string so that
1333 `kill-output-from-shell' does The Right Thing." 1347 `kill-output-from-shell' does The Right Thing."
1334 (let ((curbuf (current-buffer)) 1348 (let ((curbuf (current-buffer))
1335 (procbuf (process-buffer proc)) 1349 (procbuf (process-buffer proc))
1336 ; (comint-scroll-to-bottom-on-output t) 1350 ; (comint-scroll-to-bottom-on-output t)
1337 (msg (format "## working on region in file %s...\n" filename)) 1351 (msg (format "## working on region in file %s...\n" filename))
1338 ;; add some comment, so that we can filter it out of history 1352 ;; add some comment, so that we can filter it out of history
1339 (cmd (format "execfile(r'%s') # PYTHON-MODE\n" filename))) 1353 (cmd (format "execfile(r'%s') # PYTHON-MODE\n" filename)))
1340 (unwind-protect 1354 (unwind-protect
1341 (save-excursion 1355 (save-excursion
1342 (set-buffer procbuf) 1356 (set-buffer procbuf)
1343 (goto-char (point-max)) 1357 (goto-char (point-max))
1344 (move-marker (process-mark proc) (point)) 1358 (move-marker (process-mark proc) (point))
1345 (funcall (process-filter proc) proc msg)) 1359 (funcall (process-filter proc) proc msg))
1346 (set-buffer curbuf)) 1360 (set-buffer curbuf))
1347 (process-send-string proc cmd))) 1361 (process-send-string proc cmd)))
1348 1362
1349 (defun py-comint-output-filter-function (string) 1363 (defun py-comint-output-filter-function (string)
1350 "Watch output for Python prompt and exec next file waiting in queue. 1364 "Watch output for Python prompt and exec next file waiting in queue.
1357 (if py-shell-switch-buffers-on-execute 1371 (if py-shell-switch-buffers-on-execute
1358 (pop-to-buffer (current-buffer))) 1372 (pop-to-buffer (current-buffer)))
1359 (py-safe (delete-file (car py-file-queue))) 1373 (py-safe (delete-file (car py-file-queue)))
1360 (setq py-file-queue (cdr py-file-queue)) 1374 (setq py-file-queue (cdr py-file-queue))
1361 (if py-file-queue 1375 (if py-file-queue
1362 (let ((pyproc (get-buffer-process (current-buffer)))) 1376 (let ((pyproc (get-buffer-process (current-buffer))))
1363 (py-execute-file pyproc (car py-file-queue)))) 1377 (py-execute-file pyproc (car py-file-queue))))
1364 )) 1378 ))
1365 1379
1366 (defun py-pdbtrack-overlay-arrow (activation) 1380 (defun py-pdbtrack-overlay-arrow (activation)
1367 "Activate or de arrow at beginning-of-line in current buffer." 1381 "Activate or de arrow at beginning-of-line in current buffer."
1368 ;; This was derived/simplified from edebug-overlay-arrow 1382 ;; This was derived/simplified from edebug-overlay-arrow
1369 (cond (activation 1383 (cond (activation
1370 (setq overlay-arrow-position (make-marker)) 1384 (setq overlay-arrow-position (make-marker))
1371 (setq overlay-arrow-string "=>") 1385 (setq overlay-arrow-string "=>")
1372 (set-marker overlay-arrow-position (py-point 'bol) (current-buffer)) 1386 (set-marker overlay-arrow-position (py-point 'bol) (current-buffer))
1373 (setq py-pdbtrack-is-tracking-p t)) 1387 (setq py-pdbtrack-is-tracking-p t))
1374 (overlay-arrow-position 1388 (overlay-arrow-position
1375 (setq overlay-arrow-position nil) 1389 (setq overlay-arrow-position nil)
1376 (setq py-pdbtrack-is-tracking-p nil)) 1390 (setq py-pdbtrack-is-tracking-p nil))
1377 )) 1391 ))
1378 1392
1379 (defun py-pdbtrack-track-stack-file (text) 1393 (defun py-pdbtrack-track-stack-file (text)
1380 "Show the file indicated by the pdb stack entry line, in a separate window. 1394 "Show the file indicated by the pdb stack entry line, in a separate window.
1381 1395
1382 Activity is disabled if the buffer-local variable 1396 Activity is disabled if the buffer-local variable
1399 ;; Also, we're very conservative about clearing the overlay arrow, 1413 ;; Also, we're very conservative about clearing the overlay arrow,
1400 ;; to minimize residue. This means, for instance, that executing 1414 ;; to minimize residue. This means, for instance, that executing
1401 ;; other pdb commands wipe out the highlight. You can always do a 1415 ;; other pdb commands wipe out the highlight. You can always do a
1402 ;; 'where' (aka 'w') command to reveal the overlay arrow. 1416 ;; 'where' (aka 'w') command to reveal the overlay arrow.
1403 (let* ((origbuf (current-buffer)) 1417 (let* ((origbuf (current-buffer))
1404 (currproc (get-buffer-process origbuf))) 1418 (currproc (get-buffer-process origbuf)))
1405 1419
1406 (if (not (and currproc py-pdbtrack-do-tracking-p)) 1420 (if (not (and currproc py-pdbtrack-do-tracking-p))
1407 (py-pdbtrack-overlay-arrow nil) 1421 (py-pdbtrack-overlay-arrow nil)
1408 1422
1409 (let* ((procmark (process-mark currproc)) 1423 (let* ((procmark (process-mark currproc))
1447 (if (not (string-match py-pdbtrack-stack-entry-regexp block)) 1461 (if (not (string-match py-pdbtrack-stack-entry-regexp block))
1448 1462
1449 "Traceback cue not found" 1463 "Traceback cue not found"
1450 1464
1451 (let* ((filename (match-string 1 block)) 1465 (let* ((filename (match-string 1 block))
1452 (lineno (string-to-int (match-string 2 block))) 1466 (lineno (string-to-number (match-string 2 block)))
1453 (funcname (match-string 3 block)) 1467 (funcname (match-string 3 block))
1454 funcbuffer) 1468 funcbuffer)
1455 1469
1456 (cond ((file-exists-p filename) 1470 (cond ((file-exists-p filename)
1457 (list lineno (find-file-noselect filename))) 1471 (list lineno (find-file-noselect filename)))
1507 "Highlight exceptions found in BUF. 1521 "Highlight exceptions found in BUF.
1508 If an exception occurred return t, otherwise return nil. BUF must exist." 1522 If an exception occurred return t, otherwise return nil. BUF must exist."
1509 (let (line file bol err-p) 1523 (let (line file bol err-p)
1510 (save-excursion 1524 (save-excursion
1511 (set-buffer buf) 1525 (set-buffer buf)
1512 (beginning-of-buffer) 1526 (goto-char (point-min))
1513 (while (re-search-forward py-traceback-line-re nil t) 1527 (while (re-search-forward py-traceback-line-re nil t)
1514 (setq file (match-string 1) 1528 (setq file (match-string 1)
1515 line (string-to-int (match-string 2)) 1529 line (string-to-number (match-string 2))
1516 bol (py-point 'bol)) 1530 bol (py-point 'bol))
1517 (py-highlight-line bol (py-point 'eol) file line))) 1531 (py-highlight-line bol (py-point 'eol) file line)))
1518 (when (and py-jump-on-exception line) 1532 (when (and py-jump-on-exception line)
1519 (beep) 1533 (beep)
1520 (py-jump-to-exception file line) 1534 (py-jump-to-exception file line)
1521 (setq err-p t)) 1535 (setq err-p t))
1522 err-p)) 1536 err-p))
1526 ;;; Subprocess commands 1540 ;;; Subprocess commands
1527 1541
1528 ;; only used when (memq 'broken-temp-names py-emacs-features) 1542 ;; only used when (memq 'broken-temp-names py-emacs-features)
1529 (defvar py-serial-number 0) 1543 (defvar py-serial-number 0)
1530 (defvar py-exception-buffer nil) 1544 (defvar py-exception-buffer nil)
1531 (defconst py-output-buffer "*Python Output*") 1545 (defvar py-output-buffer "*Python Output*")
1532 (make-variable-buffer-local 'py-output-buffer) 1546 (make-variable-buffer-local 'py-output-buffer)
1533 1547
1534 ;; for toggling between CPython and Jython 1548 ;; for toggling between CPython and Jython
1535 (defvar py-which-shell nil) 1549 (defvar py-which-shell nil)
1536 (defvar py-which-args py-python-command-args) 1550 (defvar py-which-args py-python-command-args)
1555 ;; preprocess arg 1569 ;; preprocess arg
1556 (cond 1570 (cond
1557 ((equal arg 0) 1571 ((equal arg 0)
1558 ;; toggle 1572 ;; toggle
1559 (if (string-equal py-which-bufname "Python") 1573 (if (string-equal py-which-bufname "Python")
1560 (setq arg -1) 1574 (setq arg -1)
1561 (setq arg 1))) 1575 (setq arg 1)))
1562 ((equal arg 'cpython) (setq arg 1)) 1576 ((equal arg 'cpython) (setq arg 1))
1563 ((equal arg 'jython) (setq arg -1))) 1577 ((equal arg 'jython) (setq arg -1)))
1564 (let (msg) 1578 (let (msg)
1565 (cond 1579 (cond
1566 ((< 0 arg) 1580 ((< 0 arg)
1567 ;; set to CPython 1581 ;; set to CPython
1568 (setq py-which-shell py-python-command 1582 (setq py-which-shell py-python-command
1569 py-which-args py-python-command-args 1583 py-which-args py-python-command-args
1570 py-which-bufname "Python" 1584 py-which-bufname "Python"
1571 msg "CPython") 1585 msg "CPython")
1572 (if (string-equal py-which-bufname "Jython") 1586 (if (string-equal py-which-bufname "Jython")
1573 (setq mode-name "Python"))) 1587 (setq mode-name "Python")))
1574 ((> 0 arg) 1588 ((> 0 arg)
1575 (setq py-which-shell py-jython-command 1589 (setq py-which-shell py-jython-command
1576 py-which-args py-jython-command-args 1590 py-which-args py-jython-command-args
1577 py-which-bufname "Jython" 1591 py-which-bufname "Jython"
1578 msg "Jython") 1592 msg "Jython")
1579 (if (string-equal py-which-bufname "Python") 1593 (if (string-equal py-which-bufname "Python")
1580 (setq mode-name "Jython"))) 1594 (setq mode-name "Jython")))
1581 ) 1595 )
1582 (message "Using the %s shell" msg) 1596 (message "Using the %s shell" msg)
1583 (setq py-output-buffer (format "*%s Output*" py-which-bufname)))) 1597 (setq py-output-buffer (format "*%s Output*" py-which-bufname))))
1584 1598
1585 ;;;###autoload 1599 ;;;###autoload
1624 ;; Set the default shell if not already set 1638 ;; Set the default shell if not already set
1625 (when (null py-which-shell) 1639 (when (null py-which-shell)
1626 (py-toggle-shells py-default-interpreter)) 1640 (py-toggle-shells py-default-interpreter))
1627 (let ((args py-which-args)) 1641 (let ((args py-which-args))
1628 (when (and argprompt 1642 (when (and argprompt
1629 (interactive-p) 1643 (interactive-p)
1630 (fboundp 'split-string)) 1644 (fboundp 'split-string))
1631 ;; TBD: Perhaps force "-i" in the final list? 1645 ;; TBD: Perhaps force "-i" in the final list?
1632 (setq args (split-string 1646 (setq args (split-string
1633 (read-string (concat py-which-bufname 1647 (read-string (concat py-which-bufname
1634 " arguments: ") 1648 " arguments: ")
1635 (concat 1649 (concat
1636 (mapconcat 'identity py-which-args " ") " ") 1650 (mapconcat 'identity py-which-args " ") " ")
1637 )))) 1651 ))))
1638 (if (not (equal (buffer-name) "*Python*")) 1652 (if (not (equal (buffer-name) "*Python*"))
1639 (switch-to-buffer-other-window 1653 (switch-to-buffer-other-window
1640 (apply 'make-comint py-which-bufname py-which-shell nil args)) 1654 (apply 'make-comint py-which-bufname py-which-shell nil args))
1641 (apply 'make-comint py-which-bufname py-which-shell nil args)) 1655 (apply 'make-comint py-which-bufname py-which-shell nil args))
1642 (make-local-variable 'comint-prompt-regexp) 1656 (make-local-variable 'comint-prompt-regexp)
1643 (setq comint-prompt-regexp (concat py-shell-input-prompt-1-regexp "\\|" 1657 (setq comint-prompt-regexp (concat py-shell-input-prompt-1-regexp "\\|"
1644 py-shell-input-prompt-2-regexp "\\|" 1658 py-shell-input-prompt-2-regexp "\\|"
1645 "^([Pp]db) ")) 1659 "^([Pp]db) "))
1646 (add-hook 'comint-output-filter-functions 1660 (add-hook 'comint-output-filter-functions
1647 'py-comint-output-filter-function) 1661 'py-comint-output-filter-function)
1648 ;; pdbtrack 1662 ;; pdbtrack
1649 (add-hook 'comint-output-filter-functions 'py-pdbtrack-track-stack-file) 1663 (add-hook 'comint-output-filter-functions 'py-pdbtrack-track-stack-file)
1650 (setq py-pdbtrack-do-tracking-p t) 1664 (setq py-pdbtrack-do-tracking-p t)
1651 (set-syntax-table py-mode-syntax-table) 1665 (set-syntax-table py-mode-syntax-table)
1652 (use-local-map py-shell-map) 1666 (use-local-map py-shell-map)
1655 1669
1656 (defun py-clear-queue () 1670 (defun py-clear-queue ()
1657 "Clear the queue of temporary files waiting to execute." 1671 "Clear the queue of temporary files waiting to execute."
1658 (interactive) 1672 (interactive)
1659 (let ((n (length py-file-queue))) 1673 (let ((n (length py-file-queue)))
1660 (mapcar 'delete-file py-file-queue) 1674 (mapc 'delete-file py-file-queue)
1661 (setq py-file-queue nil) 1675 (setq py-file-queue nil)
1662 (message "%d pending files de-queued." n))) 1676 (message "%d pending files de-queued." n)))
1663 1677
1664 1678
1665 (defun py-execute-region (start end &optional async) 1679 (defun py-execute-region (start end &optional async)
1688 1702
1689 is inserted at the end. See also the command `py-clear-queue'." 1703 is inserted at the end. See also the command `py-clear-queue'."
1690 (interactive "r\nP") 1704 (interactive "r\nP")
1691 ;; Skip ahead to the first non-blank line 1705 ;; Skip ahead to the first non-blank line
1692 (let* ((proc (get-process py-which-bufname)) 1706 (let* ((proc (get-process py-which-bufname))
1693 (temp (if (memq 'broken-temp-names py-emacs-features) 1707 (temp (if (memq 'broken-temp-names py-emacs-features)
1694 (let 1708 (let
1695 ((sn py-serial-number) 1709 ((sn py-serial-number)
1696 (pid (and (fboundp 'emacs-pid) (emacs-pid)))) 1710 (pid (and (fboundp 'emacs-pid) (emacs-pid))))
1697 (setq py-serial-number (1+ py-serial-number)) 1711 (setq py-serial-number (1+ py-serial-number))
1698 (if pid 1712 (if pid
1699 (format "python-%d-%d" sn pid) 1713 (format "python-%d-%d" sn pid)
1700 (format "python-%d" sn))) 1714 (format "python-%d" sn)))
1701 (make-temp-name "python-"))) 1715 (make-temp-name "python-")))
1702 (file (concat (expand-file-name temp py-temp-directory) ".py")) 1716 (file (concat (expand-file-name temp py-temp-directory) ".py"))
1703 (cur (current-buffer)) 1717 (cur (current-buffer))
1704 (buf (get-buffer-create file)) 1718 (buf (get-buffer-create file))
1705 shell) 1719 shell)
1706 ;; Write the contents of the buffer, watching out for indented regions. 1720 ;; Write the contents of the buffer, watching out for indented regions.
1707 (save-excursion 1721 (save-excursion
1708 (goto-char start) 1722 (goto-char start)
1709 (beginning-of-line) 1723 (beginning-of-line)
1710 (while (and (looking-at "\\s *$") 1724 (while (and (looking-at "\\s *$")
1711 (< (point) end)) 1725 (< (point) end))
1712 (forward-line 1)) 1726 (forward-line 1))
1713 (setq start (point)) 1727 (setq start (point))
1714 (or (< start end) 1728 (or (< start end)
1715 (error "Region is empty")) 1729 (error "Region is empty"))
1716 (setq py-line-number-offset (count-lines 1 start)) 1730 (setq py-line-number-offset (count-lines 1 start))
1717 (let ((needs-if (/= (py-point 'bol) (py-point 'boi)))) 1731 (let ((needs-if (/= (py-point 'bol) (py-point 'boi))))
1718 (set-buffer buf) 1732 (set-buffer buf)
1719 (python-mode) 1733 (python-mode)
1720 (when needs-if 1734 (when needs-if
1721 (insert "if 1:\n") 1735 (insert "if 1:\n")
1722 (setq py-line-number-offset (- py-line-number-offset 1))) 1736 (setq py-line-number-offset (- py-line-number-offset 1)))
1723 (insert-buffer-substring cur start end) 1737 (insert-buffer-substring cur start end)
1724 ;; Set the shell either to the #! line command, or to the 1738 ;; Set the shell either to the #! line command, or to the
1725 ;; py-which-shell buffer local variable. 1739 ;; py-which-shell buffer local variable.
1726 (setq shell (or (py-choose-shell-by-shebang) 1740 (setq shell (or (py-choose-shell-by-shebang)
1727 (py-choose-shell-by-import) 1741 (py-choose-shell-by-import)
1728 py-which-shell)))) 1742 py-which-shell))))
1729 (cond 1743 (cond
1730 ;; always run the code in its own asynchronous subprocess 1744 ;; always run the code in its own asynchronous subprocess
1731 (async 1745 (async
1732 ;; User explicitly wants this to run in its own async subprocess 1746 ;; User explicitly wants this to run in its own async subprocess
1733 (save-excursion 1747 (save-excursion
1734 (set-buffer buf) 1748 (set-buffer buf)
1735 (write-region (point-min) (point-max) file nil 'nomsg)) 1749 (write-region (point-min) (point-max) file nil 'nomsg))
1736 (let* ((buf (generate-new-buffer-name py-output-buffer)) 1750 (let* ((buf (generate-new-buffer-name py-output-buffer))
1737 ;; TBD: a horrible hack, but why create new Custom variables? 1751 ;; TBD: a horrible hack, but why create new Custom variables?
1738 (arg (if (string-equal py-which-bufname "Python") 1752 (arg (if (string-equal py-which-bufname "Python")
1739 "-u" ""))) 1753 "-u" "")))
1740 (start-process py-which-bufname buf shell arg file) 1754 (start-process py-which-bufname buf shell arg file)
1741 (pop-to-buffer buf) 1755 (pop-to-buffer buf)
1742 (py-postprocess-output-buffer buf) 1756 (py-postprocess-output-buffer buf)
1743 ;; TBD: clean up the temporary file! 1757 ;; TBD: clean up the temporary file!
1744 )) 1758 ))
1745 ;; if the Python interpreter shell is running, queue it up for 1759 ;; if the Python interpreter shell is running, queue it up for
1746 ;; execution there. 1760 ;; execution there.
1747 (proc 1761 (proc
1748 ;; use the existing python shell 1762 ;; use the existing python shell
1749 (save-excursion 1763 (save-excursion
1750 (set-buffer buf) 1764 (set-buffer buf)
1751 (write-region (point-min) (point-max) file nil 'nomsg)) 1765 (write-region (point-min) (point-max) file nil 'nomsg))
1752 (if (not py-file-queue) 1766 (if (not py-file-queue)
1753 (py-execute-file proc file) 1767 (py-execute-file proc file)
1754 (message "File %s queued for execution" file)) 1768 (message "File %s queued for execution" file))
1755 (setq py-file-queue (append py-file-queue (list file))) 1769 (setq py-file-queue (append py-file-queue (list file)))
1756 (setq py-exception-buffer (cons file (current-buffer)))) 1770 (setq py-exception-buffer (cons file (current-buffer))))
1757 (t 1771 (t
1758 ;; TBD: a horrible hack, but why create new Custom variables? 1772 ;; TBD: a horrible hack, but why create new Custom variables?
1759 (let ((cmd (concat py-which-shell (if (string-equal py-which-bufname 1773 (let ((cmd (concat py-which-shell (if (string-equal py-which-bufname
1760 "Jython") 1774 "Jython")
1761 " -" "")))) 1775 " -" ""))))
1762 ;; otherwise either run it synchronously in a subprocess 1776 ;; otherwise either run it synchronously in a subprocess
1763 (save-excursion 1777 (save-excursion
1764 (set-buffer buf) 1778 (set-buffer buf)
1765 (shell-command-on-region (point-min) (point-max) 1779 (shell-command-on-region (point-min) (point-max)
1766 cmd py-output-buffer)) 1780 cmd py-output-buffer))
1767 ;; shell-command-on-region kills the output buffer if it never 1781 ;; shell-command-on-region kills the output buffer if it never
1768 ;; existed and there's no output from the command 1782 ;; existed and there's no output from the command
1769 (if (not (get-buffer py-output-buffer)) 1783 (if (not (get-buffer py-output-buffer))
1770 (message "No output.") 1784 (message "No output.")
1771 (setq py-exception-buffer (current-buffer)) 1785 (setq py-exception-buffer (current-buffer))
1772 (let ((err-p (py-postprocess-output-buffer py-output-buffer))) 1786 (let ((err-p (py-postprocess-output-buffer py-output-buffer)))
1773 (pop-to-buffer py-output-buffer) 1787 (pop-to-buffer py-output-buffer)
1774 (if err-p 1788 (if err-p
1775 (pop-to-buffer py-exception-buffer))) 1789 (pop-to-buffer py-exception-buffer)))
1776 )) 1790 ))
1777 )) 1791 ))
1778 ;; Clean up after ourselves. 1792 ;; Clean up after ourselves.
1779 (kill-buffer buf))) 1793 (kill-buffer buf)))
1780 1794
1781 1795
1834 (find-file-noselect filename)))) 1848 (find-file-noselect filename))))
1835 (set-buffer buffer))) 1849 (set-buffer buffer)))
1836 (let ((file (buffer-file-name (current-buffer)))) 1850 (let ((file (buffer-file-name (current-buffer))))
1837 (if file 1851 (if file
1838 (progn 1852 (progn
1839 ;; Maybe save some buffers 1853 ;; Maybe save some buffers
1840 (save-some-buffers (not py-ask-about-save) nil) 1854 (save-some-buffers (not py-ask-about-save) nil)
1841 (py-execute-string 1855 (py-execute-string
1842 (if (string-match "\\.py$" file) 1856 (if (string-match "\\.py$" file)
1843 (let ((f (file-name-sans-extension 1857 (let ((f (file-name-sans-extension
1844 (file-name-nondirectory file)))) 1858 (file-name-nondirectory file))))
1845 (format "if globals().has_key('%s'):\n reload(%s)\nelse:\n import %s\n" 1859 (format "if globals().has_key('%s'):\n reload(%s)\nelse:\n import %s\n"
1846 f f f)) 1860 f f f))
1847 (format "execfile(r'%s')\n" file)) 1861 (format "execfile(r'%s')\n" file))
1848 async)) 1862 async))
1849 ;; else 1863 ;; else
1881 1895
1882 1896
1883 (defun py-jump-to-exception (file line) 1897 (defun py-jump-to-exception (file line)
1884 "Jump to the Python code in FILE at LINE." 1898 "Jump to the Python code in FILE at LINE."
1885 (let ((buffer (cond ((string-equal file "<stdin>") 1899 (let ((buffer (cond ((string-equal file "<stdin>")
1886 (if (consp py-exception-buffer) 1900 (if (consp py-exception-buffer)
1887 (cdr py-exception-buffer) 1901 (cdr py-exception-buffer)
1888 py-exception-buffer)) 1902 py-exception-buffer))
1889 ((and (consp py-exception-buffer) 1903 ((and (consp py-exception-buffer)
1890 (string-equal file (car py-exception-buffer))) 1904 (string-equal file (car py-exception-buffer)))
1891 (cdr py-exception-buffer)) 1905 (cdr py-exception-buffer))
1892 ((py-safe (find-file-noselect file))) 1906 ((py-safe (find-file-noselect file)))
1893 ;; could not figure out what file the exception 1907 ;; could not figure out what file the exception
1894 ;; is pointing to, so prompt for it 1908 ;; is pointing to, so prompt for it
1895 (t (find-file (read-file-name "Exception file: " 1909 (t (find-file (read-file-name "Exception file: "
1896 nil 1910 nil
1897 file t)))))) 1911 file t))))))
1898 ;; Fiddle about with line number 1912 ;; Fiddle about with line number
1899 (setq line (+ py-line-number-offset line)) 1913 (setq line (+ py-line-number-offset line))
1900 1914
1901 (pop-to-buffer buffer) 1915 (pop-to-buffer buffer)
1902 ;; Force Python mode 1916 ;; Force Python mode
1903 (if (not (eq major-mode 'python-mode)) 1917 (if (not (eq major-mode 'python-mode))
1904 (python-mode)) 1918 (python-mode))
1905 (goto-line line) 1919 (goto-line line)
1906 (message "Jumping to exception in file %s on line %d" file line))) 1920 (message "Jumping to exception in file %s on line %d" file line)))
1907 1921
1908 (defun py-mouseto-exception (event) 1922 (defun py-mouseto-exception (event)
1909 "Jump to the code which caused the Python exception at EVENT. 1923 "Jump to the code which caused the Python exception at EVENT.
1911 (interactive "e") 1925 (interactive "e")
1912 (cond 1926 (cond
1913 ((fboundp 'event-point) 1927 ((fboundp 'event-point)
1914 ;; XEmacs 1928 ;; XEmacs
1915 (let* ((point (event-point event)) 1929 (let* ((point (event-point event))
1916 (buffer (event-buffer event)) 1930 (buffer (event-buffer event))
1917 (e (and point buffer (extent-at point buffer 'py-exc-info))) 1931 (e (and point buffer (extent-at point buffer 'py-exc-info)))
1918 (info (and e (extent-property e 'py-exc-info)))) 1932 (info (and e (extent-property e 'py-exc-info))))
1919 (message "Event point: %d, info: %s" point info) 1933 (message "Event point: %d, info: %s" point info)
1920 (and info 1934 (and info
1921 (py-jump-to-exception (car info) (cdr info))) 1935 (py-jump-to-exception (car info) (cdr info)))
1922 )) 1936 ))
1923 ;; Emacs -- Please port this! 1937 ;; Emacs -- Please port this!
1924 )) 1938 ))
1925 1939
1926 (defun py-goto-exception () 1940 (defun py-goto-exception ()
1928 (interactive) 1942 (interactive)
1929 (let (file line) 1943 (let (file line)
1930 (save-excursion 1944 (save-excursion
1931 (beginning-of-line) 1945 (beginning-of-line)
1932 (if (looking-at py-traceback-line-re) 1946 (if (looking-at py-traceback-line-re)
1933 (setq file (match-string 1) 1947 (setq file (match-string 1)
1934 line (string-to-int (match-string 2))))) 1948 line (string-to-number (match-string 2)))))
1935 (if (not file) 1949 (if (not file)
1936 (error "Not on a traceback line")) 1950 (error "Not on a traceback line"))
1937 (py-jump-to-exception file line))) 1951 (py-jump-to-exception file line)))
1938 1952
1939 (defun py-find-next-exception (start buffer searchdir errwhere) 1953 (defun py-find-next-exception (start buffer searchdir errwhere)
1940 "Find the next Python exception and jump to the code that caused it. 1954 "Find the next Python exception and jump to the code that caused it.
1941 START is the buffer position in BUFFER from which to begin searching 1955 START is the buffer position in BUFFER from which to begin searching
1946 (let (file line) 1960 (let (file line)
1947 (save-excursion 1961 (save-excursion
1948 (set-buffer buffer) 1962 (set-buffer buffer)
1949 (goto-char (py-point start)) 1963 (goto-char (py-point start))
1950 (if (funcall searchdir py-traceback-line-re nil t) 1964 (if (funcall searchdir py-traceback-line-re nil t)
1951 (setq file (match-string 1) 1965 (setq file (match-string 1)
1952 line (string-to-int (match-string 2))))) 1966 line (string-to-number (match-string 2)))))
1953 (if (and file line) 1967 (if (and file line)
1954 (py-jump-to-exception file line) 1968 (py-jump-to-exception file line)
1955 (error "%s of traceback" errwhere)))) 1969 (error "%s of traceback" errwhere))))
1956 1970
1957 (defun py-down-exception (&optional bottom) 1971 (defun py-down-exception (&optional bottom)
1958 "Go to the next line down in the traceback. 1972 "Go to the next line down in the traceback.
1959 With \\[univeral-argument] (programmatically, optional argument 1973 With \\[univeral-argument] (programmatically, optional argument
1960 BOTTOM), jump to the bottom (innermost) exception in the exception 1974 BOTTOM), jump to the bottom (innermost) exception in the exception
1961 stack." 1975 stack."
1962 (interactive "P") 1976 (interactive "P")
1963 (let* ((proc (get-process "Python")) 1977 (let* ((proc (get-process "Python"))
1964 (buffer (if proc "*Python*" py-output-buffer))) 1978 (buffer (if proc "*Python*" py-output-buffer)))
1965 (if bottom 1979 (if bottom
1966 (py-find-next-exception 'eob buffer 're-search-backward "Bottom") 1980 (py-find-next-exception 'eob buffer 're-search-backward "Bottom")
1967 (py-find-next-exception 'eol buffer 're-search-forward "Bottom")))) 1981 (py-find-next-exception 'eol buffer 're-search-forward "Bottom"))))
1968 1982
1969 (defun py-up-exception (&optional top) 1983 (defun py-up-exception (&optional top)
1970 "Go to the previous line up in the traceback. 1984 "Go to the previous line up in the traceback.
1971 With \\[universal-argument] (programmatically, optional argument TOP) 1985 With \\[universal-argument] (programmatically, optional argument TOP)
1972 jump to the top (outermost) exception in the exception stack." 1986 jump to the top (outermost) exception in the exception stack."
1973 (interactive "P") 1987 (interactive "P")
1974 (let* ((proc (get-process "Python")) 1988 (let* ((proc (get-process "Python"))
1975 (buffer (if proc "*Python*" py-output-buffer))) 1989 (buffer (if proc "*Python*" py-output-buffer)))
1976 (if top 1990 (if top
1977 (py-find-next-exception 'bob buffer 're-search-forward "Top") 1991 (py-find-next-exception 'bob buffer 're-search-forward "Top")
1978 (py-find-next-exception 'bol buffer 're-search-backward "Top")))) 1992 (py-find-next-exception 'bol buffer 're-search-backward "Top"))))
1979 1993
1980 1994
1981 ;; Electric deletion 1995 ;; Electric deletion
1982 (defun py-electric-backspace (arg) 1996 (defun py-electric-backspace (arg)
2003 When used programmatically, argument ARG specifies the number of 2017 When used programmatically, argument ARG specifies the number of
2004 blocks to dedent, or the number of characters to delete, as indicated 2018 blocks to dedent, or the number of characters to delete, as indicated
2005 above." 2019 above."
2006 (interactive "*p") 2020 (interactive "*p")
2007 (if (or (/= (current-indentation) (current-column)) 2021 (if (or (/= (current-indentation) (current-column))
2008 (bolp) 2022 (bolp)
2009 (py-continuation-line-p) 2023 (py-continuation-line-p)
2010 ; (not py-honor-comment-indentation) 2024 ; (not py-honor-comment-indentation)
2011 ; (looking-at "#[^ \t\n]") ; non-indenting # 2025 ; (looking-at "#[^ \t\n]") ; non-indenting #
2012 ) 2026 )
2013 (funcall py-backspace-function arg) 2027 (funcall py-backspace-function arg)
2014 ;; else indent the same as the colon line that opened the block 2028 ;; else indent the same as the colon line that opened the block
2015 ;; force non-blank so py-goto-block-up doesn't ignore it 2029 ;; force non-blank so py-goto-block-up doesn't ignore it
2016 (insert-char ?* 1) 2030 (insert-char ?* 1)
2017 (backward-char) 2031 (backward-char)
2018 (let ((base-indent 0) ; indentation of base line 2032 (let ((base-indent 0) ; indentation of base line
2019 (base-text "") ; and text of base line 2033 (base-text "") ; and text of base line
2020 (base-found-p nil)) 2034 (base-found-p nil))
2021 (save-excursion 2035 (save-excursion
2022 (while (< 0 arg) 2036 (while (< 0 arg)
2023 (condition-case nil ; in case no enclosing block 2037 (condition-case nil ; in case no enclosing block
2024 (progn 2038 (progn
2025 (py-goto-block-up 'no-mark) 2039 (py-goto-block-up 'no-mark)
2026 (setq base-indent (current-indentation) 2040 (setq base-indent (current-indentation)
2027 base-text (py-suck-up-leading-text) 2041 base-text (py-suck-up-leading-text)
2028 base-found-p t)) 2042 base-found-p t))
2029 (error nil)) 2043 (error nil))
2030 (setq arg (1- arg)))) 2044 (setq arg (1- arg))))
2031 (delete-char 1) ; toss the dummy character 2045 (delete-char 1) ; toss the dummy character
2032 (delete-horizontal-space) 2046 (delete-horizontal-space)
2033 (indent-to base-indent) 2047 (indent-to base-indent)
2034 (if base-found-p 2048 (if base-found-p
2035 (message "Closes block: %s" base-text))))) 2049 (message "Closes block: %s" base-text)))))
2036 2050
2037 2051
2038 (defun py-electric-delete (arg) 2052 (defun py-electric-delete (arg)
2039 "Delete preceding or following character or levels of whitespace. 2053 "Delete preceding or following character or levels of whitespace.
2040 2054
2049 2063
2050 \\[universal-argument] (programmatically, argument ARG) specifies the 2064 \\[universal-argument] (programmatically, argument ARG) specifies the
2051 number of characters to delete (default is 1)." 2065 number of characters to delete (default is 1)."
2052 (interactive "*p") 2066 (interactive "*p")
2053 (if (or (and (fboundp 'delete-forward-p) ;XEmacs 21 2067 (if (or (and (fboundp 'delete-forward-p) ;XEmacs 21
2054 (delete-forward-p)) 2068 (delete-forward-p))
2055 (and (boundp 'delete-key-deletes-forward) ;XEmacs 20 2069 (and (boundp 'delete-key-deletes-forward) ;XEmacs 20
2056 delete-key-deletes-forward)) 2070 delete-key-deletes-forward))
2057 (funcall py-delete-function arg) 2071 (funcall py-delete-function arg)
2058 (py-electric-backspace arg))) 2072 (py-electric-backspace arg)))
2059 2073
2060 ;; required for pending-del and delsel modes 2074 ;; required for pending-del and delsel modes
2061 (put 'py-electric-colon 'delete-selection t) ;delsel 2075 (put 'py-electric-colon 'delete-selection t) ;delsel
2075 2089
2076 This function is normally bound to `indent-line-function' so 2090 This function is normally bound to `indent-line-function' so
2077 \\[indent-for-tab-command] will call it." 2091 \\[indent-for-tab-command] will call it."
2078 (interactive "P") 2092 (interactive "P")
2079 (let* ((ci (current-indentation)) 2093 (let* ((ci (current-indentation))
2080 (move-to-indentation-p (<= (current-column) ci)) 2094 (move-to-indentation-p (<= (current-column) ci))
2081 (need (py-compute-indentation (not arg))) 2095 (need (py-compute-indentation (not arg)))
2082 (cc (current-column))) 2096 (cc (current-column)))
2083 ;; dedent out a level if previous command was the same unless we're in 2097 ;; dedent out a level if previous command was the same unless we're in
2084 ;; column 1 2098 ;; column 1
2085 (if (and (equal last-command this-command) 2099 (if (and (equal last-command this-command)
2086 (/= cc 0)) 2100 (/= cc 0))
2087 (progn 2101 (progn
2088 (beginning-of-line) 2102 (beginning-of-line)
2089 (delete-horizontal-space) 2103 (delete-horizontal-space)
2090 (indent-to (* (/ (- cc 1) py-indent-offset) py-indent-offset))) 2104 (indent-to (* (/ (- cc 1) py-indent-offset) py-indent-offset)))
2091 (progn 2105 (progn
2092 ;; see if we need to dedent 2106 ;; see if we need to dedent
2093 (if (py-outdent-p) 2107 (if (py-outdent-p)
2094 (setq need (- need py-indent-offset))) 2108 (setq need (- need py-indent-offset)))
2095 (if (or py-tab-always-indent 2109 (if (or py-tab-always-indent
2096 move-to-indentation-p) 2110 move-to-indentation-p)
2097 (progn (if (/= ci need) 2111 (progn (if (/= ci need)
2098 (save-excursion 2112 (save-excursion
2099 (beginning-of-line) 2113 (beginning-of-line)
2100 (delete-horizontal-space) 2114 (delete-horizontal-space)
2101 (indent-to need))) 2115 (indent-to need)))
2102 (if move-to-indentation-p (back-to-indentation))) 2116 (if move-to-indentation-p (back-to-indentation)))
2103 (insert-tab)))))) 2117 (insert-tab))))))
2104 2118
2105 (defun py-newline-and-indent () 2119 (defun py-newline-and-indent ()
2106 "Strives to act like the Emacs `newline-and-indent'. 2120 "Strives to act like the Emacs `newline-and-indent'.
2107 This is just `strives to' because correct indentation can't be computed 2121 This is just `strives to' because correct indentation can't be computed
2108 from scratch for Python code. In general, deletes the whitespace before 2122 from scratch for Python code. In general, deletes the whitespace before
2109 point, inserts a newline, and takes an educated guess as to how you want 2123 point, inserts a newline, and takes an educated guess as to how you want
2110 the new line indented." 2124 the new line indented."
2111 (interactive) 2125 (interactive)
2112 (let ((ci (current-indentation))) 2126 (let ((ci (current-indentation)))
2113 (if (< ci (current-column)) ; if point beyond indentation 2127 (if (< ci (current-column)) ; if point beyond indentation
2114 (newline-and-indent) 2128 (newline-and-indent)
2115 ;; else try to act like newline-and-indent "normally" acts 2129 ;; else try to act like newline-and-indent "normally" acts
2116 (beginning-of-line) 2130 (beginning-of-line)
2117 (insert-char ?\n 1) 2131 (insert-char ?\n 1)
2118 (move-to-column ci)))) 2132 (move-to-column ci))))
2119 2133
2123 `raise', `break', `continue', and `pass' force one level of 2137 `raise', `break', `continue', and `pass' force one level of
2124 dedenting." 2138 dedenting."
2125 (save-excursion 2139 (save-excursion
2126 (beginning-of-line) 2140 (beginning-of-line)
2127 (let* ((bod (py-point 'bod)) 2141 (let* ((bod (py-point 'bod))
2128 (pps (parse-partial-sexp bod (point))) 2142 (pps (parse-partial-sexp bod (point)))
2129 (boipps (parse-partial-sexp bod (py-point 'boi))) 2143 (boipps (parse-partial-sexp bod (py-point 'boi)))
2130 placeholder) 2144 placeholder)
2131 (cond 2145 (cond
2132 ;; are we inside a multi-line string or comment? 2146 ;; are we inside a multi-line string or comment?
2133 ((or (and (nth 3 pps) (nth 3 boipps)) 2147 ((or (and (nth 3 pps) (nth 3 boipps))
2134 (and (nth 4 pps) (nth 4 boipps))) 2148 (and (nth 4 pps) (nth 4 boipps)))
2135 (save-excursion 2149 (save-excursion
2136 (if (not py-align-multiline-strings-p) 0 2150 (if (not py-align-multiline-strings-p) 0
2137 ;; skip back over blank & non-indenting comment lines 2151 ;; skip back over blank & non-indenting comment lines
2138 ;; note: will skip a blank or non-indenting comment line 2152 ;; note: will skip a blank or non-indenting comment line
2139 ;; that happens to be a continuation line too 2153 ;; that happens to be a continuation line too
2140 (re-search-backward "^[ \t]*\\([^ \t\n#]\\|#[ \t\n]\\)" nil 'move) 2154 (re-search-backward "^[ \t]*\\([^ \t\n#]\\|#[ \t\n]\\)" nil 'move)
2141 (back-to-indentation) 2155 (back-to-indentation)
2142 (current-column)))) 2156 (current-column))))
2143 ;; are we on a continuation line? 2157 ;; are we on a continuation line?
2144 ((py-continuation-line-p) 2158 ((py-continuation-line-p)
2145 (let ((startpos (point)) 2159 (let ((startpos (point))
2146 (open-bracket-pos (py-nesting-level)) 2160 (open-bracket-pos (py-nesting-level))
2147 endpos searching found state) 2161 endpos searching found state cind cline)
2148 (if open-bracket-pos 2162 (if open-bracket-pos
2149 (progn 2163 (progn
2150 ;; align with first item in list; else a normal 2164 (setq endpos (py-point 'bol))
2151 ;; indent beyond the line with the open bracket 2165 (py-goto-initial-line)
2152 (goto-char (1+ open-bracket-pos)) ; just beyond bracket 2166 (setq cind (current-indentation))
2153 ;; is the first list item on the same line? 2167 (setq cline cind)
2154 (skip-chars-forward " \t") 2168 (dolist (bp
2155 (if (null (memq (following-char) '(?\n ?# ?\\))) 2169 (nth 9 (save-excursion
2156 ; yes, so line up with it 2170 (parse-partial-sexp (point) endpos)))
2157 (current-column) 2171 cind)
2158 ;; first list item on another line, or doesn't exist yet 2172 (if (search-forward "\n" bp t) (setq cline cind))
2159 (forward-line 1) 2173 (goto-char (1+ bp))
2160 (while (and (< (point) startpos) 2174 (skip-chars-forward " \t")
2161 (looking-at "[ \t]*[#\n\\\\]")) ; skip noise 2175 (setq cind (if (memq (following-char) '(?\n ?# ?\\))
2162 (forward-line 1)) 2176 (+ cline py-indent-offset)
2163 (if (and (< (point) startpos) 2177 (current-column)))))
2164 (/= startpos 2178 ;; else on backslash continuation line
2165 (save-excursion 2179 (forward-line -1)
2166 (goto-char (1+ open-bracket-pos)) 2180 (if (py-continuation-line-p) ; on at least 3rd line in block
2167 (forward-comment (point-max)) 2181 (current-indentation) ; so just continue the pattern
2168 (point)))) 2182 ;; else started on 2nd line in block, so indent more.
2169 ;; again mimic the first list item 2183 ;; if base line is an assignment with a start on a RHS,
2170 (current-indentation) 2184 ;; indent to 2 beyond the leftmost "="; else skip first
2171 ;; else they're about to enter the first item 2185 ;; chunk of non-whitespace characters on base line, + 1 more
2172 (goto-char open-bracket-pos) 2186 ;; column
2173 (setq placeholder (point)) 2187 (end-of-line)
2174 (py-goto-initial-line) 2188 (setq endpos (point)
2175 (py-goto-beginning-of-tqs 2189 searching t)
2176 (save-excursion (nth 3 (parse-partial-sexp 2190 (back-to-indentation)
2177 placeholder (point))))) 2191 (setq startpos (point))
2178 (+ (current-indentation) py-indent-offset)))) 2192 ;; look at all "=" from left to right, stopping at first
2179 2193 ;; one not nested in a list or string
2180 ;; else on backslash continuation line 2194 (while searching
2181 (forward-line -1) 2195 (skip-chars-forward "^=" endpos)
2182 (if (py-continuation-line-p) ; on at least 3rd line in block 2196 (if (= (point) endpos)
2183 (current-indentation) ; so just continue the pattern 2197 (setq searching nil)
2184 ;; else started on 2nd line in block, so indent more. 2198 (forward-char 1)
2185 ;; if base line is an assignment with a start on a RHS, 2199 (setq state (parse-partial-sexp startpos (point)))
2186 ;; indent to 2 beyond the leftmost "="; else skip first 2200 (if (and (zerop (car state)) ; not in a bracket
2187 ;; chunk of non-whitespace characters on base line, + 1 more 2201 (null (nth 3 state))) ; & not in a string
2188 ;; column 2202 (progn
2189 (end-of-line) 2203 (setq searching nil) ; done searching in any case
2190 (setq endpos (point) 2204 (setq found
2191 searching t) 2205 (not (or
2192 (back-to-indentation) 2206 (eq (following-char) ?=)
2193 (setq startpos (point)) 2207 (memq (char-after (- (point) 2))
2194 ;; look at all "=" from left to right, stopping at first 2208 '(?< ?> ?!)))))))))
2195 ;; one not nested in a list or string 2209 (if (or (not found) ; not an assignment
2196 (while searching 2210 (looking-at "[ \t]*\\\\")) ; <=><spaces><backslash>
2197 (skip-chars-forward "^=" endpos) 2211 (progn
2198 (if (= (point) endpos) 2212 (goto-char startpos)
2199 (setq searching nil) 2213 (skip-chars-forward "^ \t\n")))
2200 (forward-char 1) 2214 ;; if this is a continuation for a block opening
2201 (setq state (parse-partial-sexp startpos (point))) 2215 ;; statement, add some extra offset.
2202 (if (and (zerop (car state)) ; not in a bracket 2216 (+ (current-column) (if (py-statement-opens-block-p)
2203 (null (nth 3 state))) ; & not in a string 2217 py-continuation-offset 0)
2204 (progn 2218 1)
2205 (setq searching nil) ; done searching in any case 2219 ))))
2206 (setq found
2207 (not (or
2208 (eq (following-char) ?=)
2209 (memq (char-after (- (point) 2))
2210 '(?< ?> ?!)))))))))
2211 (if (or (not found) ; not an assignment
2212 (looking-at "[ \t]*\\\\")) ; <=><spaces><backslash>
2213 (progn
2214 (goto-char startpos)
2215 (skip-chars-forward "^ \t\n")))
2216 ;; if this is a continuation for a block opening
2217 ;; statement, add some extra offset.
2218 (+ (current-column) (if (py-statement-opens-block-p)
2219 py-continuation-offset 0)
2220 1)
2221 ))))
2222 2220
2223 ;; not on a continuation line 2221 ;; not on a continuation line
2224 ((bobp) (current-indentation)) 2222 ((bobp) (current-indentation))
2225 2223
2226 ;; Dfn: "Indenting comment line". A line containing only a 2224 ;; Dfn: "Indenting comment line". A line containing only a
2246 ;; indenting comment line? If so, we assume that it's been 2244 ;; indenting comment line? If so, we assume that it's been
2247 ;; placed at the desired indentation, so leave it alone. 2245 ;; placed at the desired indentation, so leave it alone.
2248 ;; Indenting comment lines are aligned as statements down 2246 ;; Indenting comment lines are aligned as statements down
2249 ;; below. 2247 ;; below.
2250 ((and (looking-at "[ \t]*#[^ \t\n]") 2248 ((and (looking-at "[ \t]*#[^ \t\n]")
2251 ;; NOTE: this test will not be performed in older Emacsen 2249 ;; NOTE: this test will not be performed in older Emacsen
2252 (fboundp 'forward-comment) 2250 (fboundp 'forward-comment)
2253 (<= (current-indentation) 2251 (<= (current-indentation)
2254 (save-excursion 2252 (save-excursion
2255 (forward-comment (- (point-max))) 2253 (forward-comment (- (point-max)))
2256 (current-indentation)))) 2254 (current-indentation))))
2257 (current-indentation)) 2255 (current-indentation))
2258 2256
2259 ;; else indentation based on that of the statement that 2257 ;; else indentation based on that of the statement that
2260 ;; precedes us; use the first line of that statement to 2258 ;; precedes us; use the first line of that statement to
2261 ;; establish the base, in case the user forced a non-std 2259 ;; establish the base, in case the user forced a non-std
2262 ;; indentation for the continuation lines (if any) 2260 ;; indentation for the continuation lines (if any)
2263 (t 2261 (t
2264 ;; skip back over blank & non-indenting comment lines note: 2262 ;; skip back over blank & non-indenting comment lines note:
2265 ;; will skip a blank or non-indenting comment line that 2263 ;; will skip a blank or non-indenting comment line that
2266 ;; happens to be a continuation line too. use fast Emacs 19 2264 ;; happens to be a continuation line too. use fast Emacs 19
2267 ;; function if it's there. 2265 ;; function if it's there.
2268 (if (and (eq py-honor-comment-indentation nil) 2266 (if (and (eq py-honor-comment-indentation nil)
2269 (fboundp 'forward-comment)) 2267 (fboundp 'forward-comment))
2270 (forward-comment (- (point-max))) 2268 (forward-comment (- (point-max)))
2271 (let ((prefix-re (concat py-block-comment-prefix "[ \t]*")) 2269 (let ((prefix-re (concat py-block-comment-prefix "[ \t]*"))
2272 done) 2270 done)
2273 (while (not done) 2271 (while (not done)
2274 (re-search-backward "^[ \t]*\\([^ \t\n#]\\|#\\)" nil 'move) 2272 (re-search-backward "^[ \t]*\\([^ \t\n#]\\|#\\)" nil 'move)
2275 (setq done (or (bobp) 2273 (setq done (or (bobp)
2276 (and (eq py-honor-comment-indentation t) 2274 (and (eq py-honor-comment-indentation t)
2277 (save-excursion 2275 (save-excursion
2278 (back-to-indentation) 2276 (back-to-indentation)
2279 (not (looking-at prefix-re)) 2277 (not (looking-at prefix-re))
2280 )) 2278 ))
2281 (and (not (eq py-honor-comment-indentation t)) 2279 (and (not (eq py-honor-comment-indentation t))
2282 (save-excursion 2280 (save-excursion
2283 (back-to-indentation) 2281 (back-to-indentation)
2284 (and (not (looking-at prefix-re)) 2282 (and (not (looking-at prefix-re))
2285 (or (looking-at "[^#]") 2283 (or (looking-at "[^#]")
2286 (not (zerop (current-column))) 2284 (not (zerop (current-column)))
2287 )) 2285 ))
2288 )) 2286 ))
2289 )) 2287 ))
2290 ))) 2288 )))
2291 ;; if we landed inside a string, go to the beginning of that 2289 ;; if we landed inside a string, go to the beginning of that
2292 ;; string. this handles triple quoted, multi-line spanning 2290 ;; string. this handles triple quoted, multi-line spanning
2293 ;; strings. 2291 ;; strings.
2294 (py-goto-beginning-of-tqs (nth 3 (parse-partial-sexp bod (point)))) 2292 (py-goto-beginning-of-tqs (nth 3 (parse-partial-sexp bod (point))))
2295 ;; now skip backward over continued lines 2293 ;; now skip backward over continued lines
2296 (setq placeholder (point)) 2294 (setq placeholder (point))
2297 (py-goto-initial-line) 2295 (py-goto-initial-line)
2298 ;; we may *now* have landed in a TQS, so find the beginning of 2296 ;; we may *now* have landed in a TQS, so find the beginning of
2299 ;; this string. 2297 ;; this string.
2300 (py-goto-beginning-of-tqs 2298 (py-goto-beginning-of-tqs
2301 (save-excursion (nth 3 (parse-partial-sexp 2299 (save-excursion (nth 3 (parse-partial-sexp
2302 placeholder (point))))) 2300 placeholder (point)))))
2303 (+ (current-indentation) 2301 (+ (current-indentation)
2304 (if (py-statement-opens-block-p) 2302 (if (py-statement-opens-block-p)
2305 py-indent-offset 2303 py-indent-offset
2306 (if (and honor-block-close-p (py-statement-closes-block-p)) 2304 (if (and honor-block-close-p (py-statement-closes-block-p))
2307 (- py-indent-offset) 2305 (- py-indent-offset)
2308 0))) 2306 0)))
2309 ))))) 2307 )))))
2310 2308
2311 (defun py-guess-indent-offset (&optional global) 2309 (defun py-guess-indent-offset (&optional global)
2312 "Guess a good value for, and change, `py-indent-offset'. 2310 "Guess a good value for, and change, `py-indent-offset'.
2313 2311
2314 By default, make a buffer-local copy of `py-indent-offset' with the 2312 By default, make a buffer-local copy of `py-indent-offset' with the
2327 Specifically, it searches forward from the statement containing point, 2325 Specifically, it searches forward from the statement containing point,
2328 looking for a line that opens a block of code. `py-indent-offset' is 2326 looking for a line that opens a block of code. `py-indent-offset' is
2329 set to the difference in indentation between that line and the Python 2327 set to the difference in indentation between that line and the Python
2330 statement following it. If the search doesn't succeed going forward, 2328 statement following it. If the search doesn't succeed going forward,
2331 it's tried again going backward." 2329 it's tried again going backward."
2332 (interactive "P") ; raw prefix arg 2330 (interactive "P") ; raw prefix arg
2333 (let (new-value 2331 (let (new-value
2334 (start (point)) 2332 (start (point))
2335 (restart (point)) 2333 (restart (point))
2336 (found nil) 2334 (found nil)
2337 colon-indent) 2335 colon-indent)
2338 (py-goto-initial-line) 2336 (py-goto-initial-line)
2339 (while (not (or found (eobp))) 2337 (while (not (or found (eobp)))
2340 (when (and (re-search-forward ":[ \t]*\\($\\|[#\\]\\)" nil 'move) 2338 (when (and (re-search-forward ":[ \t]*\\($\\|[#\\]\\)" nil 'move)
2341 (not (py-in-literal restart))) 2339 (not (py-in-literal restart)))
2342 (setq restart (point)) 2340 (setq restart (point))
2343 (py-goto-initial-line) 2341 (py-goto-initial-line)
2344 (if (py-statement-opens-block-p) 2342 (if (py-statement-opens-block-p)
2345 (setq found t) 2343 (setq found t)
2346 (goto-char restart)))) 2344 (goto-char restart))))
2347 (unless found 2345 (unless found
2348 (goto-char start) 2346 (goto-char start)
2349 (py-goto-initial-line) 2347 (py-goto-initial-line)
2350 (while (not (or found (bobp))) 2348 (while (not (or found (bobp)))
2351 (setq found (and 2349 (setq found (and
2352 (re-search-backward ":[ \t]*\\($\\|[#\\]\\)" nil 'move) 2350 (re-search-backward ":[ \t]*\\($\\|[#\\]\\)" nil 'move)
2353 (or (py-goto-initial-line) t) ; always true -- side effect 2351 (or (py-goto-initial-line) t) ; always true -- side effect
2354 (py-statement-opens-block-p))))) 2352 (py-statement-opens-block-p)))))
2355 (setq colon-indent (current-indentation) 2353 (setq colon-indent (current-indentation)
2356 found (and found (zerop (py-next-statement 1))) 2354 found (and found (zerop (py-next-statement 1)))
2357 new-value (- (current-indentation) colon-indent)) 2355 new-value (- (current-indentation) colon-indent))
2358 (goto-char start) 2356 (goto-char start)
2359 (if (not found) 2357 (if (not found)
2360 (error "Sorry, couldn't guess a value for py-indent-offset") 2358 (error "Sorry, couldn't guess a value for py-indent-offset")
2361 (funcall (if global 'kill-local-variable 'make-local-variable) 2359 (funcall (if global 'kill-local-variable 'make-local-variable)
2362 'py-indent-offset) 2360 'py-indent-offset)
2363 (setq py-indent-offset new-value) 2361 (setq py-indent-offset new-value)
2364 (or noninteractive 2362 (or noninteractive
2365 (message "%s value of py-indent-offset set to %d" 2363 (message "%s value of py-indent-offset set to %d"
2366 (if global "Global" "Local") 2364 (if global "Global" "Local")
2367 py-indent-offset))) 2365 py-indent-offset)))
2368 )) 2366 ))
2369 2367
2370 (defun py-comment-indent-function () 2368 (defun py-comment-indent-function ()
2371 "Python version of `comment-indent-function'." 2369 "Python version of `comment-indent-function'."
2372 ;; This is required when filladapt is turned off. Without it, when 2370 ;; This is required when filladapt is turned off. Without it, when
2374 ;; cascade one character to the right 2372 ;; cascade one character to the right
2375 (save-excursion 2373 (save-excursion
2376 (beginning-of-line) 2374 (beginning-of-line)
2377 (let ((eol (py-point 'eol))) 2375 (let ((eol (py-point 'eol)))
2378 (and comment-start-skip 2376 (and comment-start-skip
2379 (re-search-forward comment-start-skip eol t) 2377 (re-search-forward comment-start-skip eol t)
2380 (setq eol (match-beginning 0))) 2378 (setq eol (match-beginning 0)))
2381 (goto-char eol) 2379 (goto-char eol)
2382 (skip-chars-backward " \t") 2380 (skip-chars-backward " \t")
2383 (max comment-column (+ (current-column) (if (bolp) 0 1))) 2381 (max comment-column (+ (current-column) (if (bolp) 0 1)))
2384 ))) 2382 )))
2385 2383
2403 (beginning-of-line) 2401 (beginning-of-line)
2404 (setq end (point)) 2402 (setq end (point))
2405 (goto-char start) 2403 (goto-char start)
2406 (beginning-of-line) 2404 (beginning-of-line)
2407 (setq start (point)) 2405 (setq start (point))
2408 (indent-rigidly start end count))) 2406 (let (deactivate-mark)
2407 (indent-rigidly start end count))))
2409 2408
2410 (defun py-shift-region-left (start end &optional count) 2409 (defun py-shift-region-left (start end &optional count)
2411 "Shift region of Python code to the left. 2410 "Shift region of Python code to the left.
2412 The lines from the line containing the start of the current region up 2411 The lines from the line containing the start of the current region up
2413 to (but not including) the line containing the end of the region are 2412 to (but not including) the line containing the end of the region are
2416 If a prefix argument is given, the region is instead shifted by that 2415 If a prefix argument is given, the region is instead shifted by that
2417 many columns. With no active region, dedent only the current line. 2416 many columns. With no active region, dedent only the current line.
2418 You cannot dedent the region if any line is already at column zero." 2417 You cannot dedent the region if any line is already at column zero."
2419 (interactive 2418 (interactive
2420 (let ((p (point)) 2419 (let ((p (point))
2421 (m (mark)) 2420 (m (condition-case nil (mark) (mark-inactive nil)))
2422 (arg current-prefix-arg)) 2421 (arg current-prefix-arg))
2423 (if m 2422 (if m
2424 (list (min p m) (max p m) arg) 2423 (list (min p m) (max p m) arg)
2425 (list p (save-excursion (forward-line 1) (point)) arg)))) 2424 (list p (save-excursion (forward-line 1) (point)) arg))))
2426 ;; if any line is at column zero, don't shift the region 2425 ;; if any line is at column zero, don't shift the region
2427 (save-excursion 2426 (save-excursion
2428 (goto-char start) 2427 (goto-char start)
2429 (while (< (point) end) 2428 (while (< (point) end)
2430 (back-to-indentation) 2429 (back-to-indentation)
2431 (if (and (zerop (current-column)) 2430 (if (and (zerop (current-column))
2432 (not (looking-at "\\s *$"))) 2431 (not (looking-at "\\s *$")))
2433 (error "Region is at left edge")) 2432 (error "Region is at left edge"))
2434 (forward-line 1))) 2433 (forward-line 1)))
2435 (py-shift-region start end (- (prefix-numeric-value 2434 (py-shift-region start end (- (prefix-numeric-value
2436 (or count py-indent-offset)))) 2435 (or count py-indent-offset))))
2437 (py-keep-region-active)) 2436 (py-keep-region-active))
2438 2437
2439 (defun py-shift-region-right (start end &optional count) 2438 (defun py-shift-region-right (start end &optional count)
2440 "Shift region of Python code to the right. 2439 "Shift region of Python code to the right.
2441 The lines from the line containing the start of the current region up 2440 The lines from the line containing the start of the current region up
2444 2443
2445 If a prefix argument is given, the region is instead shifted by that 2444 If a prefix argument is given, the region is instead shifted by that
2446 many columns. With no active region, indent only the current line." 2445 many columns. With no active region, indent only the current line."
2447 (interactive 2446 (interactive
2448 (let ((p (point)) 2447 (let ((p (point))
2449 (m (mark)) 2448 (m (condition-case nil (mark) (mark-inactive nil)))
2450 (arg current-prefix-arg)) 2449 (arg current-prefix-arg))
2451 (if m 2450 (if m
2452 (list (min p m) (max p m) arg) 2451 (list (min p m) (max p m) arg)
2453 (list p (save-excursion (forward-line 1) (point)) arg)))) 2452 (list p (save-excursion (forward-line 1) (point)) arg))))
2454 (py-shift-region start end (prefix-numeric-value 2453 (py-shift-region start end (prefix-numeric-value
2455 (or count py-indent-offset))) 2454 (or count py-indent-offset)))
2456 (py-keep-region-active)) 2455 (py-keep-region-active))
2457 2456
2458 (defun py-indent-region (start end &optional indent-offset) 2457 (defun py-indent-region (start end &optional indent-offset)
2459 "Reindent a region of Python code. 2458 "Reindent a region of Python code.
2460 2459
2485 2484
2486 Special cases: whitespace is deleted from blank lines; continuation 2485 Special cases: whitespace is deleted from blank lines; continuation
2487 lines are shifted by the same amount their initial line was shifted, 2486 lines are shifted by the same amount their initial line was shifted,
2488 in order to preserve their relative indentation with respect to their 2487 in order to preserve their relative indentation with respect to their
2489 initial line; and comment lines beginning in column 1 are ignored." 2488 initial line; and comment lines beginning in column 1 are ignored."
2490 (interactive "*r\nP") ; region; raw prefix arg 2489 (interactive "*r\nP") ; region; raw prefix arg
2491 (save-excursion 2490 (save-excursion
2492 (goto-char end) (beginning-of-line) (setq end (point-marker)) 2491 (goto-char end) (beginning-of-line) (setq end (point-marker))
2493 (goto-char start) (beginning-of-line) 2492 (goto-char start) (beginning-of-line)
2494 (let ((py-indent-offset (prefix-numeric-value 2493 (let ((py-indent-offset (prefix-numeric-value
2495 (or indent-offset py-indent-offset))) 2494 (or indent-offset py-indent-offset)))
2496 (indents '(-1)) ; stack of active indent levels 2495 (indents '(-1)) ; stack of active indent levels
2497 (target-column 0) ; column to which to indent 2496 (target-column 0) ; column to which to indent
2498 (base-shifted-by 0) ; amount last base line was shifted 2497 (base-shifted-by 0) ; amount last base line was shifted
2499 (indent-base (if (looking-at "[ \t\n]") 2498 (indent-base (if (looking-at "[ \t\n]")
2500 (py-compute-indentation t) 2499 (py-compute-indentation t)
2501 0)) 2500 0))
2502 ci) 2501 ci)
2503 (while (< (point) end) 2502 (while (< (point) end)
2504 (setq ci (current-indentation)) 2503 (setq ci (current-indentation))
2505 ;; figure out appropriate target column 2504 ;; figure out appropriate target column
2506 (cond 2505 (cond
2507 ((or (eq (following-char) ?#) ; comment in column 1 2506 ((or (eq (following-char) ?#) ; comment in column 1
2508 (looking-at "[ \t]*$")) ; entirely blank 2507 (looking-at "[ \t]*$")) ; entirely blank
2509 (setq target-column 0)) 2508 (setq target-column 0))
2510 ((py-continuation-line-p) ; shift relative to base line 2509 ((py-continuation-line-p) ; shift relative to base line
2511 (setq target-column (+ ci base-shifted-by))) 2510 (setq target-column (+ ci base-shifted-by)))
2512 (t ; new base line 2511 (t ; new base line
2513 (if (> ci (car indents)) ; going deeper; push it 2512 (if (> ci (car indents)) ; going deeper; push it
2514 (setq indents (cons ci indents)) 2513 (setq indents (cons ci indents))
2515 ;; else we should have seen this indent before 2514 ;; else we should have seen this indent before
2516 (setq indents (memq ci indents)) ; pop deeper indents 2515 (setq indents (memq ci indents)) ; pop deeper indents
2517 (if (null indents) 2516 (if (null indents)
2518 (error "Bad indentation in region, at line %d" 2517 (error "Bad indentation in region, at line %d"
2519 (save-restriction 2518 (save-restriction
2520 (widen) 2519 (widen)
2521 (1+ (count-lines 1 (point))))))) 2520 (1+ (count-lines 1 (point)))))))
2522 (setq target-column (+ indent-base 2521 (setq target-column (+ indent-base
2523 (* py-indent-offset 2522 (* py-indent-offset
2524 (- (length indents) 2)))) 2523 (- (length indents) 2))))
2525 (setq base-shifted-by (- target-column ci)))) 2524 (setq base-shifted-by (- target-column ci))))
2526 ;; shift as needed 2525 ;; shift as needed
2527 (if (/= ci target-column) 2526 (if (/= ci target-column)
2528 (progn 2527 (progn
2529 (delete-horizontal-space) 2528 (delete-horizontal-space)
2530 (indent-to target-column))) 2529 (indent-to target-column)))
2531 (forward-line 1)))) 2530 (forward-line 1))))
2532 (set-marker end nil)) 2531 (set-marker end nil))
2533 2532
2534 (defun py-comment-region (beg end &optional arg) 2533 (defun py-comment-region (beg end &optional arg)
2535 "Like `comment-region' but uses double hash (`#') comment starter." 2534 "Like `comment-region' but uses double hash (`#') comment starter."
2536 (interactive "r\nP") 2535 (interactive "r\nP")
2537 (let ((comment-start py-block-comment-prefix)) 2536 (let ((comment-start py-block-comment-prefix))
2538 (comment-region beg end arg))) 2537 (comment-region beg end arg)))
2538
2539 (defun py-join-words-wrapping (words separator line-prefix line-length)
2540 (let ((lines ())
2541 (current-line line-prefix))
2542 (while words
2543 (let* ((word (car words))
2544 (maybe-line (concat current-line word separator)))
2545 (if (> (length maybe-line) line-length)
2546 (setq lines (cons (substring current-line 0 -1) lines)
2547 current-line (concat line-prefix word separator " "))
2548 (setq current-line (concat maybe-line " "))))
2549 (setq words (cdr words)))
2550 (setq lines (cons (substring
2551 current-line 0 (- 0 (length separator) 1)) lines))
2552 (mapconcat 'identity (nreverse lines) "\n")))
2553
2554 (defun py-sort-imports ()
2555 "Sort multiline imports.
2556 Put point inside the parentheses of a multiline import and hit
2557 \\[py-sort-imports] to sort the imports lexicographically"
2558 (interactive)
2559 (save-excursion
2560 (let ((open-paren (save-excursion (progn (up-list -1) (point))))
2561 (close-paren (save-excursion (progn (up-list 1) (point))))
2562 sorted-imports)
2563 (goto-char (1+ open-paren))
2564 (skip-chars-forward " \n\t")
2565 (setq sorted-imports
2566 (sort
2567 (delete-dups
2568 (split-string (buffer-substring
2569 (point)
2570 (save-excursion (goto-char (1- close-paren))
2571 (skip-chars-backward " \n\t")
2572 (point)))
2573 ", *\\(\n *\\)?"))
2574 ;; XXX Should this sort case insensitively?
2575 'string-lessp))
2576 ;; Remove empty strings.
2577 (delete-region open-paren close-paren)
2578 (goto-char open-paren)
2579 (insert "(\n")
2580 (insert (py-join-words-wrapping (remove "" sorted-imports) "," " " 78))
2581 (insert ")")
2582 )))
2583
2539 2584
2540 2585
2541 ;; Functions for moving point 2586 ;; Functions for moving point
2542 (defun py-previous-statement (count) 2587 (defun py-previous-statement (count)
2543 "Go to the start of the COUNTth preceding Python statement. 2588 "Go to the start of the COUNTth preceding Python statement.
2544 By default, goes to the previous statement. If there is no such 2589 By default, goes to the previous statement. If there is no such
2545 statement, goes to the first statement. Return count of statements 2590 statement, goes to the first statement. Return count of statements
2546 left to move. `Statements' do not include blank, comment, or 2591 left to move. `Statements' do not include blank, comment, or
2547 continuation lines." 2592 continuation lines."
2548 (interactive "p") ; numeric prefix arg 2593 (interactive "p") ; numeric prefix arg
2549 (if (< count 0) (py-next-statement (- count)) 2594 (if (< count 0) (py-next-statement (- count))
2550 (py-goto-initial-line) 2595 (py-goto-initial-line)
2551 (let (start) 2596 (let (start)
2552 (while (and 2597 (while (and
2553 (setq start (point)) ; always true -- side effect 2598 (setq start (point)) ; always true -- side effect
2554 (> count 0) 2599 (> count 0)
2555 (zerop (forward-line -1)) 2600 (zerop (forward-line -1))
2556 (py-goto-statement-at-or-above)) 2601 (py-goto-statement-at-or-above))
2557 (setq count (1- count))) 2602 (setq count (1- count)))
2558 (if (> count 0) (goto-char start))) 2603 (if (> count 0) (goto-char start)))
2559 count)) 2604 count))
2560 2605
2561 (defun py-next-statement (count) 2606 (defun py-next-statement (count)
2562 "Go to the start of next Python statement. 2607 "Go to the start of next Python statement.
2563 If the statement at point is the i'th Python statement, goes to the 2608 If the statement at point is the i'th Python statement, goes to the
2564 start of statement i+COUNT. If there is no such statement, goes to the 2609 start of statement i+COUNT. If there is no such statement, goes to the
2565 last statement. Returns count of statements left to move. `Statements' 2610 last statement. Returns count of statements left to move. `Statements'
2566 do not include blank, comment, or continuation lines." 2611 do not include blank, comment, or continuation lines."
2567 (interactive "p") ; numeric prefix arg 2612 (interactive "p") ; numeric prefix arg
2568 (if (< count 0) (py-previous-statement (- count)) 2613 (if (< count 0) (py-previous-statement (- count))
2569 (beginning-of-line) 2614 (beginning-of-line)
2570 (let (start) 2615 (let (start)
2571 (while (and 2616 (while (and
2572 (setq start (point)) ; always true -- side effect 2617 (setq start (point)) ; always true -- side effect
2573 (> count 0) 2618 (> count 0)
2574 (py-goto-statement-below)) 2619 (py-goto-statement-below))
2575 (setq count (1- count))) 2620 (setq count (1- count)))
2576 (if (> count 0) (goto-char start))) 2621 (if (> count 0) (goto-char start)))
2577 count)) 2622 count))
2578 2623
2579 (defun py-goto-block-up (&optional nomark) 2624 (defun py-goto-block-up (&optional nomark)
2580 "Move up to start of current block. 2625 "Move up to start of current block.
2588 2633
2589 If called from a program, the mark will not be set if optional argument 2634 If called from a program, the mark will not be set if optional argument
2590 NOMARK is not nil." 2635 NOMARK is not nil."
2591 (interactive) 2636 (interactive)
2592 (let ((start (point)) 2637 (let ((start (point))
2593 (found nil) 2638 (found nil)
2594 initial-indent) 2639 initial-indent)
2595 (py-goto-initial-line) 2640 (py-goto-initial-line)
2596 ;; if on blank or non-indenting comment line, use the preceding stmt 2641 ;; if on blank or non-indenting comment line, use the preceding stmt
2597 (if (looking-at "[ \t]*\\($\\|#[^ \t\n]\\)") 2642 (if (looking-at "[ \t]*\\($\\|#[^ \t\n]\\)")
2598 (progn 2643 (progn
2599 (py-goto-statement-at-or-above) 2644 (py-goto-statement-at-or-above)
2600 (setq found (py-statement-opens-block-p)))) 2645 (setq found (py-statement-opens-block-p))))
2601 ;; search back for colon line indented less 2646 ;; search back for colon line indented less
2602 (setq initial-indent (current-indentation)) 2647 (setq initial-indent (current-indentation))
2603 (if (zerop initial-indent) 2648 (if (zerop initial-indent)
2604 ;; force fast exit 2649 ;; force fast exit
2605 (goto-char (point-min))) 2650 (goto-char (point-min)))
2606 (while (not (or found (bobp))) 2651 (while (not (or found (bobp)))
2607 (setq found 2652 (setq found
2608 (and 2653 (and
2609 (re-search-backward ":[ \t]*\\($\\|[#\\]\\)" nil 'move) 2654 (re-search-backward ":[ \t]*\\($\\|[#\\]\\)" nil 'move)
2610 (or (py-goto-initial-line) t) ; always true -- side effect 2655 (or (py-goto-initial-line) t) ; always true -- side effect
2611 (< (current-indentation) initial-indent) 2656 (< (current-indentation) initial-indent)
2612 (py-statement-opens-block-p)))) 2657 (py-statement-opens-block-p))))
2613 (if found 2658 (if found
2614 (progn 2659 (progn
2615 (or nomark (push-mark start)) 2660 (or nomark (push-mark start))
2616 (back-to-indentation)) 2661 (back-to-indentation))
2617 (goto-char start) 2662 (goto-char start)
2618 (error "Enclosing block not found")))) 2663 (error "Enclosing block not found"))))
2619 2664
2620 (defun py-beginning-of-def-or-class (&optional class count) 2665 (defun py-beginning-of-def-or-class (&optional class count)
2621 "Move point to start of `def' or `class'. 2666 "Move point to start of `def' or `class'.
2641 2686
2642 Note that doing this command repeatedly will take you closer to the 2687 Note that doing this command repeatedly will take you closer to the
2643 start of the buffer each time. 2688 start of the buffer each time.
2644 2689
2645 To mark the current `def', see `\\[py-mark-def-or-class]'." 2690 To mark the current `def', see `\\[py-mark-def-or-class]'."
2646 (interactive "P") ; raw prefix arg 2691 (interactive "P") ; raw prefix arg
2647 (setq count (or count 1)) 2692 (setq count (or count 1))
2648 (let ((at-or-before-p (<= (current-column) (current-indentation))) 2693 (let ((at-or-before-p (<= (current-column) (current-indentation)))
2649 (start-of-line (goto-char (py-point 'bol))) 2694 (start-of-line (goto-char (py-point 'bol)))
2650 (start-of-stmt (goto-char (py-point 'bos))) 2695 (start-of-stmt (goto-char (py-point 'bos)))
2651 (start-re (cond ((eq class 'either) "^[ \t]*\\(class\\|def\\)\\>") 2696 (start-re (cond ((eq class 'either) "^[ \t]*\\(class\\|def\\)\\>")
2652 (class "^[ \t]*class\\>") 2697 (class "^[ \t]*class\\>")
2653 (t "^[ \t]*def\\>"))) 2698 (t "^[ \t]*def\\>")))
2654 ) 2699 )
2655 ;; searching backward 2700 ;; searching backward
2656 (if (and (< 0 count) 2701 (if (and (< 0 count)
2657 (or (/= start-of-stmt start-of-line) 2702 (or (/= start-of-stmt start-of-line)
2658 (not at-or-before-p))) 2703 (not at-or-before-p)))
2659 (end-of-line)) 2704 (end-of-line))
2660 ;; search forward 2705 ;; search forward
2661 (if (and (> 0 count) 2706 (if (and (> 0 count)
2662 (zerop (current-column)) 2707 (zerop (current-column))
2663 (looking-at start-re)) 2708 (looking-at start-re))
2664 (end-of-line)) 2709 (end-of-line))
2665 (if (re-search-backward start-re nil 'move count) 2710 (if (re-search-backward start-re nil 'move count)
2666 (goto-char (match-beginning 0))))) 2711 (goto-char (match-beginning 0)))))
2667 2712
2668 ;; Backwards compatibility 2713 ;; Backwards compatibility
2669 (defalias 'beginning-of-python-def-or-class 'py-beginning-of-def-or-class) 2714 (defalias 'beginning-of-python-def-or-class 'py-beginning-of-def-or-class)
2670 2715
2671 (defun py-end-of-def-or-class (&optional class count) 2716 (defun py-end-of-def-or-class (&optional class count)
2695 2740
2696 Note that doing this command repeatedly will take you closer to the 2741 Note that doing this command repeatedly will take you closer to the
2697 end of the buffer each time. 2742 end of the buffer each time.
2698 2743
2699 To mark the current `def', see `\\[py-mark-def-or-class]'." 2744 To mark the current `def', see `\\[py-mark-def-or-class]'."
2700 (interactive "P") ; raw prefix arg 2745 (interactive "P") ; raw prefix arg
2701 (if (and count (/= count 1)) 2746 (if (and count (/= count 1))
2702 (py-beginning-of-def-or-class (- 1 count))) 2747 (py-beginning-of-def-or-class (- 1 count)))
2703 (let ((start (progn (py-goto-initial-line) (point))) 2748 (let ((start (progn (py-goto-initial-line) (point)))
2704 (which (cond ((eq class 'either) "\\(class\\|def\\)") 2749 (which (cond ((eq class 'either) "\\(class\\|def\\)")
2705 (class "class") 2750 (class "class")
2706 (t "def"))) 2751 (t "def")))
2707 (state 'not-found)) 2752 (state 'not-found))
2708 ;; move point to start of appropriate def/class 2753 ;; move point to start of appropriate def/class
2709 (if (looking-at (concat "[ \t]*" which "\\>")) ; already on one 2754 (if (looking-at (concat "[ \t]*" which "\\>")) ; already on one
2710 (setq state 'at-beginning) 2755 (setq state 'at-beginning)
2711 ;; else see if py-beginning-of-def-or-class hits container 2756 ;; else see if py-beginning-of-def-or-class hits container
2712 (if (and (py-beginning-of-def-or-class class) 2757 (if (and (py-beginning-of-def-or-class class)
2713 (progn (py-goto-beyond-block) 2758 (progn (py-goto-beyond-block)
2714 (> (point) start))) 2759 (> (point) start)))
2715 (setq state 'at-end) 2760 (setq state 'at-end)
2716 ;; else search forward 2761 ;; else search forward
2717 (goto-char start) 2762 (goto-char start)
2718 (if (re-search-forward (concat "^[ \t]*" which "\\>") nil 'move) 2763 (if (re-search-forward (concat "^[ \t]*" which "\\>") nil 'move)
2719 (progn (setq state 'at-beginning) 2764 (progn (setq state 'at-beginning)
2720 (beginning-of-line))))) 2765 (beginning-of-line)))))
2721 (cond 2766 (cond
2722 ((eq state 'at-beginning) (py-goto-beyond-block) t) 2767 ((eq state 'at-beginning) (py-goto-beyond-block) t)
2723 ((eq state 'at-end) t) 2768 ((eq state 'at-end) t)
2724 ((eq state 'not-found) nil) 2769 ((eq state 'not-found) nil)
2725 (t (error "Internal error in `py-end-of-def-or-class'"))))) 2770 (t (error "Internal error in `py-end-of-def-or-class'")))))
2773 area; or do `\\[exchange-point-and-mark]' to flip down to the end. 2818 area; or do `\\[exchange-point-and-mark]' to flip down to the end.
2774 2819
2775 If called from a program, optional argument EXTEND plays the role of 2820 If called from a program, optional argument EXTEND plays the role of
2776 the prefix arg, and if optional argument JUST-MOVE is not nil, just 2821 the prefix arg, and if optional argument JUST-MOVE is not nil, just
2777 moves to the end of the block (& does not set mark or display a msg)." 2822 moves to the end of the block (& does not set mark or display a msg)."
2778 (interactive "P") ; raw prefix arg 2823 (interactive "P") ; raw prefix arg
2779 (py-goto-initial-line) 2824 (py-goto-initial-line)
2780 ;; skip over blank lines 2825 ;; skip over blank lines
2781 (while (and 2826 (while (and
2782 (looking-at "[ \t]*$") ; while blank line 2827 (looking-at "[ \t]*$") ; while blank line
2783 (not (eobp))) ; & somewhere to go 2828 (not (eobp))) ; & somewhere to go
2784 (forward-line 1)) 2829 (forward-line 1))
2785 (if (eobp) 2830 (if (eobp)
2786 (error "Hit end of buffer without finding a non-blank stmt")) 2831 (error "Hit end of buffer without finding a non-blank stmt"))
2787 (let ((initial-pos (point)) 2832 (let ((initial-pos (point))
2788 (initial-indent (current-indentation)) 2833 (initial-indent (current-indentation))
2789 last-pos ; position of last stmt in region 2834 last-pos ; position of last stmt in region
2790 (followers 2835 (followers
2791 '((if elif else) (elif elif else) (else) 2836 '((if elif else) (elif elif else) (else)
2792 (try except finally) (except except) (finally) 2837 (try except finally) (except except) (finally)
2793 (for else) (while else) 2838 (for else) (while else)
2794 (def) (class) ) ) 2839 (def) (class) ) )
2795 first-symbol next-symbol) 2840 first-symbol next-symbol)
2796 2841
2797 (cond 2842 (cond
2798 ;; if comment line, suck up the following comment lines 2843 ;; if comment line, suck up the following comment lines
2799 ((looking-at "[ \t]*#") 2844 ((looking-at "[ \t]*#")
2800 (re-search-forward "^[ \t]*[^ \t#]" nil 'move) ; look for non-comment 2845 (re-search-forward "^[ \t]*[^ \t#]" nil 'move) ; look for non-comment
2801 (re-search-backward "^[ \t]*#") ; and back to last comment in block 2846 (re-search-backward "^[ \t]*#") ; and back to last comment in block
2802 (setq last-pos (point))) 2847 (setq last-pos (point)))
2803 2848
2804 ;; else if line is a block line and EXTEND given, suck up 2849 ;; else if line is a block line and EXTEND given, suck up
2805 ;; the whole structure 2850 ;; the whole structure
2806 ((and extend 2851 ((and extend
2807 (setq first-symbol (py-suck-up-first-keyword) ) 2852 (setq first-symbol (py-suck-up-first-keyword) )
2808 (assq first-symbol followers)) 2853 (assq first-symbol followers))
2809 (while (and 2854 (while (and
2810 (or (py-goto-beyond-block) t) ; side effect 2855 (or (py-goto-beyond-block) t) ; side effect
2811 (forward-line -1) ; side effect 2856 (forward-line -1) ; side effect
2812 (setq last-pos (point)) ; side effect 2857 (setq last-pos (point)) ; side effect
2813 (py-goto-statement-below) 2858 (py-goto-statement-below)
2814 (= (current-indentation) initial-indent) 2859 (= (current-indentation) initial-indent)
2815 (setq next-symbol (py-suck-up-first-keyword)) 2860 (setq next-symbol (py-suck-up-first-keyword))
2816 (memq next-symbol (cdr (assq first-symbol followers)))) 2861 (memq next-symbol (cdr (assq first-symbol followers))))
2817 (setq first-symbol next-symbol))) 2862 (setq first-symbol next-symbol)))
2818 2863
2819 ;; else if line *opens* a block, search for next stmt indented <= 2864 ;; else if line *opens* a block, search for next stmt indented <=
2820 ((py-statement-opens-block-p) 2865 ((py-statement-opens-block-p)
2821 (while (and 2866 (while (and
2822 (setq last-pos (point)) ; always true -- side effect 2867 (setq last-pos (point)) ; always true -- side effect
2823 (py-goto-statement-below) 2868 (py-goto-statement-below)
2824 (> (current-indentation) initial-indent) 2869 (> (current-indentation) initial-indent)
2825 ))) 2870 )))
2826 2871
2827 ;; else plain code line; stop at next blank line, or stmt or 2872 ;; else plain code line; stop at next blank line, or stmt or
2828 ;; indenting comment line indented < 2873 ;; indenting comment line indented <
2829 (t 2874 (t
2830 (while (and 2875 (while (and
2831 (setq last-pos (point)) ; always true -- side effect 2876 (setq last-pos (point)) ; always true -- side effect
2832 (or (py-goto-beyond-final-line) t) 2877 (or (py-goto-beyond-final-line) t)
2833 (not (looking-at "[ \t]*$")) ; stop at blank line 2878 (not (looking-at "[ \t]*$")) ; stop at blank line
2834 (or 2879 (or
2835 (>= (current-indentation) initial-indent) 2880 (>= (current-indentation) initial-indent)
2836 (looking-at "[ \t]*#[^ \t\n]"))) ; ignore non-indenting # 2881 (looking-at "[ \t]*#[^ \t\n]"))) ; ignore non-indenting #
2837 nil))) 2882 nil)))
2838 2883
2839 ;; skip to end of last stmt 2884 ;; skip to end of last stmt
2840 (goto-char last-pos) 2885 (goto-char last-pos)
2841 (py-goto-beyond-final-line) 2886 (py-goto-beyond-final-line)
2842 2887
2843 ;; set mark & display 2888 ;; set mark & display
2844 (if just-move 2889 (if just-move
2845 () ; just return 2890 () ; just return
2846 (push-mark (point) 'no-msg) 2891 (push-mark (point) 'no-msg)
2847 (forward-line -1) 2892 (forward-line -1)
2848 (message "Mark set after: %s" (py-suck-up-leading-text)) 2893 (message "Mark set after: %s" (py-suck-up-leading-text))
2849 (goto-char initial-pos)))) 2894 (goto-char initial-pos))))
2850 2895
2884 point is left at its start. 2929 point is left at its start.
2885 2930
2886 The intent is to mark the containing def/class and its associated 2931 The intent is to mark the containing def/class and its associated
2887 documentation, to make moving and duplicating functions and classes 2932 documentation, to make moving and duplicating functions and classes
2888 pleasant." 2933 pleasant."
2889 (interactive "P") ; raw prefix arg 2934 (interactive "P") ; raw prefix arg
2890 (let ((start (point)) 2935 (let ((start (point))
2891 (which (cond ((eq class 'either) "\\(class\\|def\\)") 2936 (which (cond ((eq class 'either) "\\(class\\|def\\)")
2892 (class "class") 2937 (class "class")
2893 (t "def")))) 2938 (t "def"))))
2894 (push-mark start) 2939 (push-mark start)
2895 (if (not (py-go-up-tree-to-keyword which)) 2940 (if (not (py-go-up-tree-to-keyword which))
2896 (progn (goto-char start) 2941 (progn (goto-char start)
2897 (error "Enclosing %s not found" 2942 (error "Enclosing %s not found"
2898 (if (eq class 'either) 2943 (if (eq class 'either)
2899 "def or class" 2944 "def or class"
2900 which))) 2945 which)))
2901 ;; else enclosing def/class found 2946 ;; else enclosing def/class found
2902 (setq start (point)) 2947 (setq start (point))
2903 (py-goto-beyond-block) 2948 (py-goto-beyond-block)
2904 (push-mark (point)) 2949 (push-mark (point))
2905 (goto-char start) 2950 (goto-char start)
2906 (if (zerop (forward-line -1)) ; if there is a preceding line 2951 (if (zerop (forward-line -1)) ; if there is a preceding line
2907 (progn 2952 (progn
2908 (if (looking-at "[ \t]*$") ; it's blank 2953 (if (looking-at "[ \t]*$") ; it's blank
2909 (setq start (point)) ; so reset start point 2954 (setq start (point)) ; so reset start point
2910 (goto-char start)) ; else try again 2955 (goto-char start)) ; else try again
2911 (if (zerop (forward-line -1)) 2956 (if (zerop (forward-line -1))
2912 (if (looking-at "[ \t]*#") ; a comment 2957 (if (looking-at "[ \t]*#") ; a comment
2913 ;; look back for non-comment line 2958 ;; look back for non-comment line
2914 ;; tricky: note that the regexp matches a blank 2959 ;; tricky: note that the regexp matches a blank
2915 ;; line, cuz \n is in the 2nd character class 2960 ;; line, cuz \n is in the 2nd character class
2916 (and 2961 (and
2917 (re-search-backward "^[ \t]*[^ \t#]" nil 'move) 2962 (re-search-backward "^[ \t]*[^ \t#]" nil 'move)
2918 (forward-line 1)) 2963 (forward-line 1))
2919 ;; no comment, so go back 2964 ;; no comment, so go back
2920 (goto-char start))))))) 2965 (goto-char start)))))))
2921 (exchange-point-and-mark) 2966 (exchange-point-and-mark)
2922 (py-keep-region-active)) 2967 (py-keep-region-active))
2923 2968
2924 ;; ripped from cc-mode 2969 ;; ripped from cc-mode
2925 (defun py-forward-into-nomenclature (&optional arg) 2970 (defun py-forward-into-nomenclature (&optional arg)
2929 2974
2930 A `nomenclature' is a fancy way of saying AWordWithMixedCaseNotUnderscores." 2975 A `nomenclature' is a fancy way of saying AWordWithMixedCaseNotUnderscores."
2931 (interactive "p") 2976 (interactive "p")
2932 (let ((case-fold-search nil)) 2977 (let ((case-fold-search nil))
2933 (if (> arg 0) 2978 (if (> arg 0)
2934 (re-search-forward 2979 (re-search-forward
2935 "\\(\\W\\|[_]\\)*\\([A-Z]*[a-z0-9]*\\)" 2980 "\\(\\W\\|[_]\\)*\\([A-Z]*[a-z0-9]*\\)"
2936 (point-max) t arg) 2981 (point-max) t arg)
2937 (while (and (< arg 0) 2982 (while (and (< arg 0)
2938 (re-search-backward 2983 (re-search-backward
2939 "\\(\\W\\|[a-z0-9]\\)[A-Z]+\\|\\(\\W\\|[_]\\)\\w+" 2984 "\\(\\W\\|[a-z0-9]\\)[A-Z]+\\|\\(\\W\\|[_]\\)\\w+"
2940 (point-min) 0)) 2985 (point-min) 0))
2941 (forward-char 1) 2986 (forward-char 1)
2942 (setq arg (1+ arg))))) 2987 (setq arg (1+ arg)))))
2943 (py-keep-region-active)) 2988 (py-keep-region-active))
2944 2989
2945 (defun py-backward-into-nomenclature (&optional arg) 2990 (defun py-backward-into-nomenclature (&optional arg)
2946 "Move backward to beginning of a nomenclature section or word. 2991 "Move backward to beginning of a nomenclature section or word.
2947 With optional ARG, move that many times. If ARG is negative, move 2992 With optional ARG, move that many times. If ARG is negative, move
2959 (interactive "P") 3004 (interactive "P")
2960 (if (not (get-buffer-process (current-buffer))) 3005 (if (not (get-buffer-process (current-buffer)))
2961 (error "No process associated with buffer '%s'" (current-buffer))) 3006 (error "No process associated with buffer '%s'" (current-buffer)))
2962 ;; missing or 0 is toggle, >0 turn on, <0 turn off 3007 ;; missing or 0 is toggle, >0 turn on, <0 turn off
2963 (if (or (not arg) 3008 (if (or (not arg)
2964 (zerop (setq arg (prefix-numeric-value arg)))) 3009 (zerop (setq arg (prefix-numeric-value arg))))
2965 (setq py-pdbtrack-do-tracking-p (not py-pdbtrack-do-tracking-p)) 3010 (setq py-pdbtrack-do-tracking-p (not py-pdbtrack-do-tracking-p))
2966 (setq py-pdbtrack-do-tracking-p (> arg 0))) 3011 (setq py-pdbtrack-do-tracking-p (> arg 0)))
2967 (message "%sabled Python's pdbtrack" 3012 (message "%sabled Python's pdbtrack"
2968 (if py-pdbtrack-do-tracking-p "En" "Dis"))) 3013 (if py-pdbtrack-do-tracking-p "En" "Dis")))
2969 3014
2986 (defun py-pychecker-run (command) 3031 (defun py-pychecker-run (command)
2987 "*Run pychecker (default on the file currently visited)." 3032 "*Run pychecker (default on the file currently visited)."
2988 (interactive 3033 (interactive
2989 (let ((default 3034 (let ((default
2990 (format "%s %s %s" py-pychecker-command 3035 (format "%s %s %s" py-pychecker-command
2991 (mapconcat 'identity py-pychecker-command-args " ") 3036 (mapconcat 'identity py-pychecker-command-args " ")
2992 (buffer-file-name))) 3037 (buffer-file-name)))
2993 (last (when py-pychecker-history 3038 (last (when py-pychecker-history
2994 (let* ((lastcmd (car py-pychecker-history)) 3039 (let* ((lastcmd (car py-pychecker-history))
2995 (cmd (cdr (reverse (split-string lastcmd)))) 3040 (cmd (cdr (reverse (split-string lastcmd))))
2996 (newcmd (reverse (cons (buffer-file-name) cmd)))) 3041 (newcmd (reverse (cons (buffer-file-name) cmd))))
2997 (mapconcat 'identity newcmd " "))))) 3042 (mapconcat 'identity newcmd " ")))))
2998 3043
2999 (list 3044 (list
3000 (if (fboundp 'read-shell-command) 3045 (if (fboundp 'read-shell-command)
3001 (read-shell-command "Run pychecker like this: " 3046 (read-shell-command "Run pychecker like this: "
3002 (if last 3047 (if last
3003 last 3048 last
3004 default) 3049 default)
3005 'py-pychecker-history) 3050 'py-pychecker-history)
3006 (read-string "Run pychecker like this: " 3051 (read-string "Run pychecker like this: "
3007 (if last 3052 (if last
3008 last 3053 last
3009 default) 3054 default)
3010 'py-pychecker-history)) 3055 'py-pychecker-history))
3011 ))) 3056 )))
3012 (save-some-buffers (not py-ask-about-save) nil) 3057 (save-some-buffers (not py-ask-about-save) nil)
3013 (compile-internal command "No more errors")) 3058 (if (fboundp 'compilation-start)
3059 ;; Emacs.
3060 (compilation-start command)
3061 ;; XEmacs.
3062 (compile-internal command "No more errors")))
3014 3063
3015 3064
3016 3065
3017 ;; pydoc commands. The guts of this function is stolen from XEmacs's 3066 ;; pydoc commands. The guts of this function is stolen from XEmacs's
3018 ;; symbol-near-point, but without the useless regexp-quote call on the 3067 ;; symbol-near-point, but without the useless regexp-quote call on the
3024 "Return the first textual item to the nearest point." 3073 "Return the first textual item to the nearest point."
3025 ;; alg stolen from etag.el 3074 ;; alg stolen from etag.el
3026 (save-excursion 3075 (save-excursion
3027 (with-syntax-table py-dotted-expression-syntax-table 3076 (with-syntax-table py-dotted-expression-syntax-table
3028 (if (or (bobp) (not (memq (char-syntax (char-before)) '(?w ?_)))) 3077 (if (or (bobp) (not (memq (char-syntax (char-before)) '(?w ?_))))
3029 (while (not (looking-at "\\sw\\|\\s_\\|\\'")) 3078 (while (not (looking-at "\\sw\\|\\s_\\|\\'"))
3030 (forward-char 1))) 3079 (forward-char 1)))
3031 (while (looking-at "\\sw\\|\\s_") 3080 (while (looking-at "\\sw\\|\\s_")
3032 (forward-char 1)) 3081 (forward-char 1))
3033 (if (re-search-backward "\\sw\\|\\s_" nil t) 3082 (if (re-search-backward "\\sw\\|\\s_" nil t)
3034 (progn (forward-char 1) 3083 (progn (forward-char 1)
3035 (buffer-substring (point) 3084 (buffer-substring (point)
3036 (progn (forward-sexp -1) 3085 (progn (forward-sexp -1)
3037 (while (looking-at "\\s'") 3086 (while (looking-at "\\s'")
3038 (forward-char 1)) 3087 (forward-char 1))
3039 (point)))) 3088 (point))))
3040 nil)))) 3089 nil))))
3041 3090
3042 (defun py-help-at-point () 3091 (defun py-help-at-point ()
3043 "Get help from Python based on the symbol nearest point." 3092 "Get help from Python based on the symbol nearest point."
3044 (interactive) 3093 (interactive)
3045 (let* ((sym (py-symbol-near-point)) 3094 (let* ((sym (py-symbol-near-point))
3046 (base (substring sym 0 (or (search "." sym :from-end t) 0))) 3095 (base (substring sym 0 (or (search "." sym :from-end t) 0)))
3047 cmd) 3096 cmd)
3048 (if (not (equal base "")) 3097 (if (not (equal base ""))
3049 (setq cmd (concat "import " base "\n"))) 3098 (setq cmd (concat "import " base "\n")))
3050 (setq cmd (concat "import pydoc\n" 3099 (setq cmd (concat "import pydoc\n"
3051 cmd 3100 cmd
3052 "try: pydoc.help('" sym "')\n" 3101 "try: pydoc.help('" sym "')\n"
3053 "except: print 'No help available on:', \"" sym "\"")) 3102 "except: print 'No help available on:', \"" sym "\""))
3054 (message cmd) 3103 (message cmd)
3055 (py-execute-string cmd) 3104 (py-execute-string cmd)
3056 (set-buffer "*Python Output*") 3105 (set-buffer "*Python Output*")
3057 ;; BAW: Should we really be leaving the output buffer in help-mode? 3106 ;; BAW: Should we really be leaving the output buffer in help-mode?
3058 (help-mode))) 3107 (help-mode)))
3066 ;; out of the right places, along with the keys they're on & current 3115 ;; out of the right places, along with the keys they're on & current
3067 ;; values 3116 ;; values
3068 (defun py-dump-help-string (str) 3117 (defun py-dump-help-string (str)
3069 (with-output-to-temp-buffer "*Help*" 3118 (with-output-to-temp-buffer "*Help*"
3070 (let ((locals (buffer-local-variables)) 3119 (let ((locals (buffer-local-variables))
3071 funckind funcname func funcdoc 3120 funckind funcname func funcdoc
3072 (start 0) mstart end 3121 (start 0) mstart end
3073 keys ) 3122 keys )
3074 (while (string-match "^%\\([vc]\\):\\(.+\\)\n" str start) 3123 (while (string-match "^%\\([vc]\\):\\(.+\\)\n" str start)
3075 (setq mstart (match-beginning 0) end (match-end 0) 3124 (setq mstart (match-beginning 0) end (match-end 0)
3076 funckind (substring str (match-beginning 1) (match-end 1)) 3125 funckind (substring str (match-beginning 1) (match-end 1))
3077 funcname (substring str (match-beginning 2) (match-end 2)) 3126 funcname (substring str (match-beginning 2) (match-end 2))
3078 func (intern funcname)) 3127 func (intern funcname))
3079 (princ (substitute-command-keys (substring str start mstart))) 3128 (princ (substitute-command-keys (substring str start mstart)))
3080 (cond 3129 (cond
3081 ((equal funckind "c") ; command 3130 ((equal funckind "c") ; command
3082 (setq funcdoc (documentation func) 3131 (setq funcdoc (documentation func)
3083 keys (concat 3132 keys (concat
3084 "Key(s): " 3133 "Key(s): "
3085 (mapconcat 'key-description 3134 (mapconcat 'key-description
3086 (where-is-internal func py-mode-map) 3135 (where-is-internal func py-mode-map)
3087 ", ")))) 3136 ", "))))
3088 ((equal funckind "v") ; variable 3137 ((equal funckind "v") ; variable
3089 (setq funcdoc (documentation-property func 'variable-documentation) 3138 (setq funcdoc (documentation-property func 'variable-documentation)
3090 keys (if (assq func locals) 3139 keys (if (assq func locals)
3091 (concat 3140 (concat
3092 "Local/Global values: " 3141 "Local/Global values: "
3093 (prin1-to-string (symbol-value func)) 3142 (prin1-to-string (symbol-value func))
3094 " / " 3143 " / "
3095 (prin1-to-string (default-value func))) 3144 (prin1-to-string (default-value func)))
3096 (concat 3145 (concat
3097 "Value: " 3146 "Value: "
3098 (prin1-to-string (symbol-value func)))))) 3147 (prin1-to-string (symbol-value func))))))
3099 (t ; unexpected 3148 (t ; unexpected
3100 (error "Error in py-dump-help-string, tag `%s'" funckind))) 3149 (error "Error in py-dump-help-string, tag `%s'" funckind)))
3101 (princ (format "\n-> %s:\t%s\t%s\n\n" 3150 (princ (format "\n-> %s:\t%s\t%s\n\n"
3102 (if (equal funckind "c") "Command" "Variable") 3151 (if (equal funckind "c") "Command" "Variable")
3103 funcname keys)) 3152 funcname keys))
3104 (princ funcdoc) 3153 (princ funcdoc)
3105 (terpri) 3154 (terpri)
3106 (setq start end)) 3155 (setq start end))
3107 (princ (substitute-command-keys (substring str start)))) 3156 (princ (substitute-command-keys (substring str start))))
3108 (print-help-return-message))) 3157 (print-help-return-message)))
3109 3158
3110 (defun py-describe-mode () 3159 (defun py-describe-mode ()
3111 "Dump long form of Python-mode docs." 3160 "Dump long form of Python-mode docs."
3363 (when (fboundp 'info-lookup-maybe-add-help) 3412 (when (fboundp 'info-lookup-maybe-add-help)
3364 (info-lookup-maybe-add-help 3413 (info-lookup-maybe-add-help
3365 :mode 'python-mode 3414 :mode 'python-mode
3366 :regexp "[a-zA-Z0-9_]+" 3415 :regexp "[a-zA-Z0-9_]+"
3367 :doc-spec '(("(python-lib)Module Index") 3416 :doc-spec '(("(python-lib)Module Index")
3368 ("(python-lib)Class-Exception-Object Index") 3417 ("(python-lib)Class-Exception-Object Index")
3369 ("(python-lib)Function-Method-Variable Index") 3418 ("(python-lib)Function-Method-Variable Index")
3370 ("(python-lib)Miscellaneous Index"))) 3419 ("(python-lib)Miscellaneous Index")))
3371 ) 3420 )
3372 3421
3373 3422
3374 ;; Helper functions 3423 ;; Helper functions
3375 (defvar py-parse-state-re 3424 (defvar py-parse-state-re
3380 3429
3381 (defun py-parse-state () 3430 (defun py-parse-state ()
3382 "Return the parse state at point (see `parse-partial-sexp' docs)." 3431 "Return the parse state at point (see `parse-partial-sexp' docs)."
3383 (save-excursion 3432 (save-excursion
3384 (let ((here (point)) 3433 (let ((here (point))
3385 pps done) 3434 pps done)
3386 (while (not done) 3435 (while (not done)
3387 ;; back up to the first preceding line (if any; else start of 3436 ;; back up to the first preceding line (if any; else start of
3388 ;; buffer) that begins with a popular Python keyword, or a 3437 ;; buffer) that begins with a popular Python keyword, or a
3389 ;; non- whitespace and non-comment character. These are good 3438 ;; non- whitespace and non-comment character. These are good
3390 ;; places to start parsing to see whether where we started is 3439 ;; places to start parsing to see whether where we started is
3391 ;; at a non-zero nesting level. It may be slow for people who 3440 ;; at a non-zero nesting level. It may be slow for people who
3392 ;; write huge code blocks or huge lists ... tough beans. 3441 ;; write huge code blocks or huge lists ... tough beans.
3393 (re-search-backward py-parse-state-re nil 'move) 3442 (re-search-backward py-parse-state-re nil 'move)
3394 (beginning-of-line) 3443 (beginning-of-line)
3395 ;; In XEmacs, we have a much better way to test for whether 3444 ;; In XEmacs, we have a much better way to test for whether
3396 ;; we're in a triple-quoted string or not. Emacs does not 3445 ;; we're in a triple-quoted string or not. Emacs does not
3397 ;; have this built-in function, which is its loss because 3446 ;; have this built-in function, which is its loss because
3398 ;; without scanning from the beginning of the buffer, there's 3447 ;; without scanning from the beginning of the buffer, there's
3399 ;; no accurate way to determine this otherwise. 3448 ;; no accurate way to determine this otherwise.
3400 (save-excursion (setq pps (parse-partial-sexp (point) here))) 3449 (save-excursion (setq pps (parse-partial-sexp (point) here)))
3401 ;; make sure we don't land inside a triple-quoted string 3450 ;; make sure we don't land inside a triple-quoted string
3402 (setq done (or (not (nth 3 pps)) 3451 (setq done (or (not (nth 3 pps))
3403 (bobp))) 3452 (bobp)))
3404 ;; Just go ahead and short circuit the test back to the 3453 ;; Just go ahead and short circuit the test back to the
3405 ;; beginning of the buffer. This will be slow, but not 3454 ;; beginning of the buffer. This will be slow, but not
3406 ;; nearly as slow as looping through many 3455 ;; nearly as slow as looping through many
3407 ;; re-search-backwards. 3456 ;; re-search-backwards.
3408 (if (not done) 3457 (if (not done)
3409 (goto-char (point-min)))) 3458 (goto-char (point-min))))
3410 pps))) 3459 pps)))
3411 3460
3412 (defun py-nesting-level () 3461 (defun py-nesting-level ()
3413 "Return the buffer position of the last unclosed enclosing list. 3462 "Return the buffer position of the last unclosed enclosing list.
3414 If nesting level is zero, return nil." 3463 If nesting level is zero, return nil."
3415 (let ((status (py-parse-state))) 3464 (let ((status (py-parse-state)))
3416 (if (zerop (car status)) 3465 (if (zerop (car status))
3417 nil ; not in a nest 3466 nil ; not in a nest
3418 (car (cdr status))))) ; char# of open bracket 3467 (car (cdr status))))) ; char# of open bracket
3419 3468
3420 (defun py-backslash-continuation-line-p () 3469 (defun py-backslash-continuation-line-p ()
3421 "Return t iff preceding line ends with backslash that is not in a comment." 3470 "Return t iff preceding line ends with backslash that is not in a comment."
3422 (save-excursion 3471 (save-excursion
3423 (beginning-of-line) 3472 (beginning-of-line)
3424 (and 3473 (and
3425 ;; use a cheap test first to avoid the regexp if possible 3474 ;; use a cheap test first to avoid the regexp if possible
3426 ;; use 'eq' because char-after may return nil 3475 ;; use 'eq' because char-after may return nil
3427 (eq (char-after (- (point) 2)) ?\\ ) 3476 (eq (char-after (- (point) 2)) ?\\ )
3428 ;; make sure; since eq test passed, there is a preceding line 3477 ;; make sure; since eq test passed, there is a preceding line
3429 (forward-line -1) ; always true -- side effect 3478 (forward-line -1) ; always true -- side effect
3430 (looking-at py-continued-re)))) 3479 (looking-at py-continued-re))))
3431 3480
3432 (defun py-continuation-line-p () 3481 (defun py-continuation-line-p ()
3433 "Return t iff current line is a continuation line." 3482 "Return t iff current line is a continuation line."
3434 (save-excursion 3483 (save-excursion
3435 (beginning-of-line) 3484 (beginning-of-line)
3436 (or (py-backslash-continuation-line-p) 3485 (or (py-backslash-continuation-line-p)
3437 (py-nesting-level)))) 3486 (py-nesting-level))))
3438 3487
3439 (defun py-goto-beginning-of-tqs (delim) 3488 (defun py-goto-beginning-of-tqs (delim)
3440 "Go to the beginning of the triple quoted string we find ourselves in. 3489 "Go to the beginning of the triple quoted string we find ourselves in.
3441 DELIM is the TQS string delimiter character we're searching backwards 3490 DELIM is the TQS string delimiter character we're searching backwards
3442 for." 3491 for."
3443 (let ((skip (and delim (make-string 1 delim))) 3492 (let ((skip (and delim (make-string 1 delim)))
3444 (continue t)) 3493 (continue t))
3445 (when skip 3494 (when skip
3446 (save-excursion 3495 (save-excursion
3447 (while continue 3496 (while continue
3448 (py-safe (search-backward skip)) 3497 (py-safe (search-backward skip))
3449 (setq continue (and (not (bobp)) 3498 (setq continue (and (not (bobp))
3450 (= (char-before) ?\\)))) 3499 (= (char-before) ?\\))))
3451 (if (and (= (char-before) delim) 3500 (if (and (= (char-before) delim)
3452 (= (char-before (1- (point))) delim)) 3501 (= (char-before (1- (point))) delim))
3453 (setq skip (make-string 3 delim)))) 3502 (setq skip (make-string 3 delim))))
3454 ;; we're looking at a triple-quoted string 3503 ;; we're looking at a triple-quoted string
3455 (py-safe (search-backward skip))))) 3504 (py-safe (search-backward skip)))))
3456 3505
3457 (defun py-goto-initial-line () 3506 (defun py-goto-initial-line ()
3458 "Go to the initial line of the current statement. 3507 "Go to the initial line of the current statement.
3468 ;; drop us at the line that begins the string. 3517 ;; drop us at the line that begins the string.
3469 (let (open-bracket-pos) 3518 (let (open-bracket-pos)
3470 (while (py-continuation-line-p) 3519 (while (py-continuation-line-p)
3471 (beginning-of-line) 3520 (beginning-of-line)
3472 (if (py-backslash-continuation-line-p) 3521 (if (py-backslash-continuation-line-p)
3473 (while (py-backslash-continuation-line-p) 3522 (while (py-backslash-continuation-line-p)
3474 (forward-line -1)) 3523 (forward-line -1))
3475 ;; else zip out of nested brackets/braces/parens 3524 ;; else zip out of nested brackets/braces/parens
3476 (while (setq open-bracket-pos (py-nesting-level)) 3525 (while (setq open-bracket-pos (py-nesting-level))
3477 (goto-char open-bracket-pos))))) 3526 (goto-char open-bracket-pos)))))
3478 (beginning-of-line)) 3527 (beginning-of-line))
3479 3528
3480 (defun py-goto-beyond-final-line () 3529 (defun py-goto-beyond-final-line ()
3481 "Go to the point just beyond the fine line of the current statement. 3530 "Go to the point just beyond the fine line of the current statement.
3482 Usually this is the start of the next line, but if this is a 3531 Usually this is the start of the next line, but if this is a
3490 (goto-char (match-end 0))) 3539 (goto-char (match-end 0)))
3491 ;; 3540 ;;
3492 (forward-line 1) 3541 (forward-line 1)
3493 (let (state) 3542 (let (state)
3494 (while (and (py-continuation-line-p) 3543 (while (and (py-continuation-line-p)
3495 (not (eobp))) 3544 (not (eobp)))
3496 ;; skip over the backslash flavor 3545 ;; skip over the backslash flavor
3497 (while (and (py-backslash-continuation-line-p) 3546 (while (and (py-backslash-continuation-line-p)
3498 (not (eobp))) 3547 (not (eobp)))
3499 (forward-line 1)) 3548 (forward-line 1))
3500 ;; if in nest, zip to the end of the nest 3549 ;; if in nest, zip to the end of the nest
3501 (setq state (py-parse-state)) 3550 (setq state (py-parse-state))
3502 (if (and (not (zerop (car state))) 3551 (if (and (not (zerop (car state)))
3503 (not (eobp))) 3552 (not (eobp)))
3504 (progn 3553 (progn
3505 (parse-partial-sexp (point) (point-max) 0 nil state) 3554 (parse-partial-sexp (point) (point-max) 0 nil state)
3506 (forward-line 1)))))) 3555 (forward-line 1))))))
3507 3556
3508 (defun py-statement-opens-block-p () 3557 (defun py-statement-opens-block-p ()
3509 "Return t iff the current statement opens a block. 3558 "Return t iff the current statement opens a block.
3510 I.e., iff it ends with a colon that is not in a comment. Point should 3559 I.e., iff it ends with a colon that is not in a comment. Point should
3511 be at the start of a statement." 3560 be at the start of a statement."
3512 (save-excursion 3561 (save-excursion
3513 (let ((start (point)) 3562 (let ((start (point))
3514 (finish (progn (py-goto-beyond-final-line) (1- (point)))) 3563 (finish (progn (py-goto-beyond-final-line) (1- (point))))
3515 (searching t) 3564 (searching t)
3516 (answer nil) 3565 (answer nil)
3517 state) 3566 state)
3518 (goto-char start) 3567 (goto-char start)
3519 (while searching 3568 (while searching
3520 ;; look for a colon with nothing after it except whitespace, and 3569 ;; look for a colon with nothing after it except whitespace, and
3521 ;; maybe a comment 3570 ;; maybe a comment
3522 (if (re-search-forward ":\\([ \t]\\|\\\\\n\\)*\\(#.*\\)?$" 3571 (if (re-search-forward ":\\([ \t]\\|\\\\\n\\)*\\(#.*\\)?$"
3523 finish t) 3572 finish t)
3524 (if (eq (point) finish) ; note: no `else' clause; just 3573 (if (eq (point) finish) ; note: no `else' clause; just
3525 ; keep searching if we're not at 3574 ; keep searching if we're not at
3526 ; the end yet 3575 ; the end yet
3527 ;; sure looks like it opens a block -- but it might 3576 ;; sure looks like it opens a block -- but it might
3528 ;; be in a comment 3577 ;; be in a comment
3529 (progn 3578 (progn
3530 (setq searching nil) ; search is done either way 3579 (setq searching nil) ; search is done either way
3531 (setq state (parse-partial-sexp start 3580 (setq state (parse-partial-sexp start
3532 (match-beginning 0))) 3581 (match-beginning 0)))
3533 (setq answer (not (nth 4 state))))) 3582 (setq answer (not (nth 4 state)))))
3534 ;; search failed: couldn't find another interesting colon 3583 ;; search failed: couldn't find another interesting colon
3535 (setq searching nil))) 3584 (setq searching nil)))
3536 answer))) 3585 answer)))
3537 3586
3538 (defun py-statement-closes-block-p () 3587 (defun py-statement-closes-block-p ()
3539 "Return t iff the current statement closes a block. 3588 "Return t iff the current statement closes a block.
3540 I.e., if the line starts with `return', `raise', `break', `continue', 3589 I.e., if the line starts with `return', `raise', `break', `continue',
3541 and `pass'. This doesn't catch embedded statements." 3590 and `pass'. This doesn't catch embedded statements."
3542 (let ((here (point))) 3591 (let ((here (point)))
3543 (py-goto-initial-line) 3592 (py-goto-initial-line)
3544 (back-to-indentation) 3593 (back-to-indentation)
3545 (prog1 3594 (prog1
3546 (looking-at (concat py-block-closing-keywords-re "\\>")) 3595 (looking-at (concat py-block-closing-keywords-re "\\>"))
3547 (goto-char here)))) 3596 (goto-char here))))
3548 3597
3549 (defun py-goto-beyond-block () 3598 (defun py-goto-beyond-block ()
3550 "Go to point just beyond the final line of block begun by the current line. 3599 "Go to point just beyond the final line of block begun by the current line.
3551 This is the same as where `py-goto-beyond-final-line' goes unless 3600 This is the same as where `py-goto-beyond-final-line' goes unless
3563 (if (looking-at py-blank-or-comment-re) 3612 (if (looking-at py-blank-or-comment-re)
3564 ;; skip back over blank & comment lines 3613 ;; skip back over blank & comment lines
3565 ;; note: will skip a blank or comment line that happens to be 3614 ;; note: will skip a blank or comment line that happens to be
3566 ;; a continuation line too 3615 ;; a continuation line too
3567 (if (re-search-backward "^[ \t]*[^ \t#\n]" nil t) 3616 (if (re-search-backward "^[ \t]*[^ \t#\n]" nil t)
3568 (progn (py-goto-initial-line) t) 3617 (progn (py-goto-initial-line) t)
3569 nil) 3618 nil)
3570 t)) 3619 t))
3571 3620
3572 (defun py-goto-statement-below () 3621 (defun py-goto-statement-below ()
3573 "Go to start of the first statement following the statement containing point. 3622 "Go to start of the first statement following the statement containing point.
3574 Return t if there is such a statement, otherwise nil. `Statement' 3623 Return t if there is such a statement, otherwise nil. `Statement'
3575 does not include blank lines, comments, or continuation lines." 3624 does not include blank lines, comments, or continuation lines."
3576 (beginning-of-line) 3625 (beginning-of-line)
3577 (let ((start (point))) 3626 (let ((start (point)))
3578 (py-goto-beyond-final-line) 3627 (py-goto-beyond-final-line)
3579 (while (and 3628 (while (and
3580 (or (looking-at py-blank-or-comment-re) 3629 (or (looking-at py-blank-or-comment-re)
3581 (py-in-literal)) 3630 (py-in-literal))
3582 (not (eobp))) 3631 (not (eobp)))
3583 (forward-line 1)) 3632 (forward-line 1))
3584 (if (eobp) 3633 (if (eobp)
3585 (progn (goto-char start) nil) 3634 (progn (goto-char start) nil)
3586 t))) 3635 t)))
3587 3636
3588 (defun py-go-up-tree-to-keyword (key) 3637 (defun py-go-up-tree-to-keyword (key)
3589 "Go to begining of statement starting with KEY, at or preceding point. 3638 "Go to begining of statement starting with KEY, at or preceding point.
3590 3639
3594 with KEY. If successful, leave point at the start of the KEY line and 3643 with KEY. If successful, leave point at the start of the KEY line and
3595 return t. Otherwise, leave point at an undefined place and return nil." 3644 return t. Otherwise, leave point at an undefined place and return nil."
3596 ;; skip blanks and non-indenting # 3645 ;; skip blanks and non-indenting #
3597 (py-goto-initial-line) 3646 (py-goto-initial-line)
3598 (while (and 3647 (while (and
3599 (looking-at "[ \t]*\\($\\|#[^ \t\n]\\)") 3648 (looking-at "[ \t]*\\($\\|#[^ \t\n]\\)")
3600 (zerop (forward-line -1))) ; go back 3649 (zerop (forward-line -1))) ; go back
3601 nil) 3650 nil)
3602 (py-goto-initial-line) 3651 (py-goto-initial-line)
3603 (let* ((re (concat "[ \t]*" key "\\>")) 3652 (let* ((re (concat "[ \t]*" key "\\>"))
3604 (case-fold-search nil) ; let* so looking-at sees this 3653 (case-fold-search nil) ; let* so looking-at sees this
3605 (found (looking-at re)) 3654 (found (looking-at re))
3606 (dead nil)) 3655 (dead nil))
3607 (while (not (or found dead)) 3656 (while (not (or found dead))
3608 (condition-case nil ; in case no enclosing block 3657 (condition-case nil ; in case no enclosing block
3609 (py-goto-block-up 'no-mark) 3658 (py-goto-block-up 'no-mark)
3610 (error (setq dead t))) 3659 (error (setq dead t)))
3611 (or dead (setq found (looking-at re)))) 3660 (or dead (setq found (looking-at re))))
3612 (beginning-of-line) 3661 (beginning-of-line)
3613 found)) 3662 found))
3614 3663
3615 (defun py-suck-up-leading-text () 3664 (defun py-suck-up-leading-text ()
3625 "Return first keyword on the line as a Lisp symbol. 3674 "Return first keyword on the line as a Lisp symbol.
3626 `Keyword' is defined (essentially) as the regular expression 3675 `Keyword' is defined (essentially) as the regular expression
3627 ([a-z]+). Returns nil if none was found." 3676 ([a-z]+). Returns nil if none was found."
3628 (let ((case-fold-search nil)) 3677 (let ((case-fold-search nil))
3629 (if (looking-at "[ \t]*\\([a-z]+\\)\\>") 3678 (if (looking-at "[ \t]*\\([a-z]+\\)\\>")
3630 (intern (buffer-substring (match-beginning 1) (match-end 1))) 3679 (intern (buffer-substring (match-beginning 1) (match-end 1)))
3631 nil))) 3680 nil)))
3632 3681
3633 (defun py-current-defun () 3682 (defun py-current-defun ()
3634 "Python value for `add-log-current-defun-function'. 3683 "Python value for `add-log-current-defun-function'.
3635 This tells add-log.el how to find the current function/method/variable." 3684 This tells add-log.el how to find the current function/method/variable."
3638 ;; Move back to start of the current statement. 3687 ;; Move back to start of the current statement.
3639 3688
3640 (py-goto-initial-line) 3689 (py-goto-initial-line)
3641 (back-to-indentation) 3690 (back-to-indentation)
3642 (while (and (or (looking-at py-blank-or-comment-re) 3691 (while (and (or (looking-at py-blank-or-comment-re)
3643 (py-in-literal)) 3692 (py-in-literal))
3644 (not (bobp))) 3693 (not (bobp)))
3645 (backward-to-indentation 1)) 3694 (backward-to-indentation 1))
3646 (py-goto-initial-line) 3695 (py-goto-initial-line)
3647 3696
3648 (let ((scopes "") 3697 (let ((scopes "")
3649 (sep "") 3698 (sep "")
3650 dead assignment) 3699 dead assignment)
3651 3700
3652 ;; Check for an assignment. If this assignment exists inside a 3701 ;; Check for an assignment. If this assignment exists inside a
3653 ;; def, it will be overwritten inside the while loop. If it 3702 ;; def, it will be overwritten inside the while loop. If it
3654 ;; exists at top lever or inside a class, it will be preserved. 3703 ;; exists at top lever or inside a class, it will be preserved.
3655 3704
3656 (when (looking-at "[ \t]*\\([a-zA-Z0-9_]+\\)[ \t]*=") 3705 (when (looking-at "[ \t]*\\([a-zA-Z0-9_]+\\)[ \t]*=")
3657 (setq scopes (buffer-substring (match-beginning 1) (match-end 1))) 3706 (setq scopes (buffer-substring (match-beginning 1) (match-end 1)))
3658 (setq assignment t) 3707 (setq assignment t)
3659 (setq sep ".")) 3708 (setq sep "."))
3660 3709
3661 ;; Prepend the name of each outer socpe (def or class). 3710 ;; Prepend the name of each outer socpe (def or class).
3662 3711
3663 (while (not dead) 3712 (while (not dead)
3664 (if (and (py-go-up-tree-to-keyword "\\(class\\|def\\)") 3713 (if (and (py-go-up-tree-to-keyword "\\(class\\|def\\)")
3665 (looking-at 3714 (looking-at
3666 "[ \t]*\\(class\\|def\\)[ \t]*\\([a-zA-Z0-9_]+\\)[ \t]*")) 3715 "[ \t]*\\(class\\|def\\)[ \t]*\\([a-zA-Z0-9_]+\\)[ \t]*"))
3667 (let ((name (buffer-substring (match-beginning 2) (match-end 2)))) 3716 (let ((name (buffer-substring (match-beginning 2) (match-end 2))))
3668 (if (and assignment (looking-at "[ \t]*def")) 3717 (if (and assignment (looking-at "[ \t]*def"))
3669 (setq scopes name) 3718 (setq scopes name)
3670 (setq scopes (concat name sep scopes)) 3719 (setq scopes (concat name sep scopes))
3671 (setq sep ".")))) 3720 (setq sep "."))))
3672 (setq assignment nil) 3721 (setq assignment nil)
3673 (condition-case nil ; Terminate nicely at top level. 3722 (condition-case nil ; Terminate nicely at top level.
3674 (py-goto-block-up 'no-mark) 3723 (py-goto-block-up 'no-mark)
3675 (error (setq dead t)))) 3724 (error (setq dead t))))
3676 (if (string= scopes "") 3725 (if (string= scopes "")
3677 nil 3726 nil
3678 scopes)))) 3727 scopes))))
3679 3728
3680 3729
3681 3730
3682 (defconst py-help-address "python-mode@python.org" 3731 (defconst py-help-address "python-mode@python.org"
3683 "Address accepting submission of bug reports.") 3732 "Address accepting submission of bug reports.")
3696 "Submit via mail a bug report on `python-mode'. 3745 "Submit via mail a bug report on `python-mode'.
3697 With \\[universal-argument] (programmatically, argument ENHANCEMENT-P 3746 With \\[universal-argument] (programmatically, argument ENHANCEMENT-P
3698 non-nil) just submit an enhancement request." 3747 non-nil) just submit an enhancement request."
3699 (interactive 3748 (interactive
3700 (list (not (y-or-n-p 3749 (list (not (y-or-n-p
3701 "Is this a bug report (hit `n' to send other comments)? ")))) 3750 "Is this a bug report (hit `n' to send other comments)? "))))
3702 (let ((reporter-prompt-for-summary-p (if enhancement-p 3751 (let ((reporter-prompt-for-summary-p (if enhancement-p
3703 "(Very) brief summary: " 3752 "(Very) brief summary: "
3704 t))) 3753 t)))
3705 (require 'reporter) 3754 (require 'reporter)
3706 (reporter-submit-bug-report 3755 (reporter-submit-bug-report
3707 py-help-address ;address 3756 py-help-address ;address
3708 (concat "python-mode " py-version) ;pkgname 3757 (concat "python-mode " py-version) ;pkgname
3709 ;; varlist 3758 ;; varlist
3710 (if enhancement-p nil 3759 (if enhancement-p nil
3711 '(py-python-command 3760 '(py-python-command
3712 py-indent-offset 3761 py-indent-offset
3713 py-block-comment-prefix 3762 py-block-comment-prefix
3714 py-temp-directory 3763 py-temp-directory
3715 py-beep-if-tab-change)) 3764 py-beep-if-tab-change))
3716 nil ;pre-hooks 3765 nil ;pre-hooks
3717 nil ;post-hooks 3766 nil ;post-hooks
3718 "Dear Barry,") ;salutation 3767 "Dear Barry,") ;salutation
3719 (if enhancement-p nil 3768 (if enhancement-p nil
3720 (set-mark (point)) 3769 (set-mark (point))
3721 (insert 3770 (insert
3722 "Please replace this text with a sufficiently large code sample\n\ 3771 "Please replace this text with a sufficiently large code sample\n\
3723 and an exact recipe so that I can reproduce your problem. Failure\n\ 3772 and an exact recipe so that I can reproduce your problem. Failure\n\
3727 3776
3728 3777
3729 (defun py-kill-emacs-hook () 3778 (defun py-kill-emacs-hook ()
3730 "Delete files in `py-file-queue'. 3779 "Delete files in `py-file-queue'.
3731 These are Python temporary files awaiting execution." 3780 These are Python temporary files awaiting execution."
3732 (mapcar #'(lambda (filename) 3781 (mapc #'(lambda (filename)
3733 (py-safe (delete-file filename))) 3782 (py-safe (delete-file filename)))
3734 py-file-queue)) 3783 py-file-queue))
3735 3784
3736 ;; arrange to kill temp files when Emacs exists 3785 ;; arrange to kill temp files when Emacs exists
3737 (add-hook 'kill-emacs-hook 'py-kill-emacs-hook) 3786 (add-hook 'kill-emacs-hook 'py-kill-emacs-hook)
3738 (add-hook 'comint-output-filter-functions 'py-pdbtrack-track-stack-file) 3787 (add-hook 'comint-output-filter-functions 'py-pdbtrack-track-stack-file)
3739 3788
3740 ;; Add a designator to the minor mode strings 3789 ;; Add a designator to the minor mode strings
3741 (or (assq 'py-pdbtrack-is-tracking-p minor-mode-alist) 3790 (or (assq 'py-pdbtrack-is-tracking-p minor-mode-alist)
3742 (push '(py-pdbtrack-is-tracking-p py-pdbtrack-minor-mode-string) 3791 (push '(py-pdbtrack-is-tracking-p py-pdbtrack-minor-mode-string)
3743 minor-mode-alist)) 3792 minor-mode-alist))
3744 3793
3745 3794
3746 3795
3747 ;;; paragraph and string filling code from Bernhard Herzog 3796 ;;; paragraph and string filling code from Bernhard Herzog
3748 ;;; see http://mail.python.org/pipermail/python-list/2002-May/103189.html 3797 ;;; see http://mail.python.org/pipermail/python-list/2002-May/103189.html
3749 3798
3750 (defun py-fill-comment (&optional justify) 3799 (defun py-fill-comment (&optional justify)
3751 "Fill the comment paragraph around point" 3800 "Fill the comment paragraph around point"
3752 (let (;; Non-nil if the current line contains a comment. 3801 (let (;; Non-nil if the current line contains a comment.
3753 has-comment 3802 has-comment
3754 3803
3755 ;; If has-comment, the appropriate fill-prefix for the comment. 3804 ;; If has-comment, the appropriate fill-prefix for the comment.
3756 comment-fill-prefix) 3805 comment-fill-prefix)
3757 3806
3758 ;; Figure out what kind of comment we are looking at. 3807 ;; Figure out what kind of comment we are looking at.
3759 (save-excursion 3808 (save-excursion
3760 (beginning-of-line) 3809 (beginning-of-line)
3761 (cond 3810 (cond
3762 ;; A line with nothing but a comment on it? 3811 ;; A line with nothing but a comment on it?
3763 ((looking-at "[ \t]*#[# \t]*") 3812 ((looking-at "[ \t]*#[# \t]*")
3764 (setq has-comment t 3813 (setq has-comment t
3765 comment-fill-prefix (buffer-substring (match-beginning 0) 3814 comment-fill-prefix (buffer-substring (match-beginning 0)
3766 (match-end 0)))) 3815 (match-end 0))))
3767 3816
3768 ;; A line with some code, followed by a comment? Remember that the hash 3817 ;; A line with some code, followed by a comment? Remember that the hash
3769 ;; which starts the comment shouldn't be part of a string or character. 3818 ;; which starts the comment shouldn't be part of a string or character.
3770 ((progn 3819 ((progn
3771 (while (not (looking-at "#\\|$")) 3820 (while (not (looking-at "#\\|$"))
3772 (skip-chars-forward "^#\n\"'\\") 3821 (skip-chars-forward "^#\n\"'\\")
3773 (cond 3822 (cond
3774 ((eq (char-after (point)) ?\\) (forward-char 2)) 3823 ((eq (char-after (point)) ?\\) (forward-char 2))
3775 ((memq (char-after (point)) '(?\" ?')) (forward-sexp 1)))) 3824 ((memq (char-after (point)) '(?\" ?')) (forward-sexp 1))))
3776 (looking-at "#+[\t ]*")) 3825 (looking-at "#+[\t ]*"))
3777 (setq has-comment t) 3826 (setq has-comment t)
3778 (setq comment-fill-prefix 3827 (setq comment-fill-prefix
3779 (concat (make-string (current-column) ? ) 3828 (concat (make-string (current-column) ? )
3780 (buffer-substring (match-beginning 0) (match-end 0))))))) 3829 (buffer-substring (match-beginning 0) (match-end 0)))))))
3781 3830
3782 (if (not has-comment) 3831 (if (not has-comment)
3783 (fill-paragraph justify) 3832 (fill-paragraph justify)
3784 3833
3785 ;; Narrow to include only the comment, and then fill the region. 3834 ;; Narrow to include only the comment, and then fill the region.
3786 (save-restriction 3835 (save-restriction
3787 (narrow-to-region 3836 (narrow-to-region
3788 3837
3789 ;; Find the first line we should include in the region to fill. 3838 ;; Find the first line we should include in the region to fill.
3790 (save-excursion 3839 (save-excursion
3791 (while (and (zerop (forward-line -1)) 3840 (while (and (zerop (forward-line -1))
3792 (looking-at "^[ \t]*#"))) 3841 (looking-at "^[ \t]*#")))
3793 3842
3794 ;; We may have gone to far. Go forward again. 3843 ;; We may have gone to far. Go forward again.
3795 (or (looking-at "^[ \t]*#") 3844 (or (looking-at "^[ \t]*#")
3796 (forward-line 1)) 3845 (forward-line 1))
3797 (point)) 3846 (point))
3798 3847
3799 ;; Find the beginning of the first line past the region to fill. 3848 ;; Find the beginning of the first line past the region to fill.
3800 (save-excursion 3849 (save-excursion
3801 (while (progn (forward-line 1) 3850 (while (progn (forward-line 1)
3802 (looking-at "^[ \t]*#"))) 3851 (looking-at "^[ \t]*#")))
3803 (point))) 3852 (point)))
3804 3853
3805 ;; Lines with only hashes on them can be paragraph boundaries. 3854 ;; Lines with only hashes on them can be paragraph boundaries.
3806 (let ((paragraph-start (concat paragraph-start "\\|[ \t#]*$")) 3855 (let ((paragraph-start (concat paragraph-start "\\|[ \t#]*$"))
3807 (paragraph-separate (concat paragraph-separate "\\|[ \t#]*$")) 3856 (paragraph-separate (concat paragraph-separate "\\|[ \t#]*$"))
3808 (fill-prefix comment-fill-prefix)) 3857 (fill-prefix comment-fill-prefix))
3809 ;;(message "paragraph-start %S paragraph-separate %S" 3858 ;;(message "paragraph-start %S paragraph-separate %S"
3810 ;;paragraph-start paragraph-separate) 3859 ;;paragraph-start paragraph-separate)
3811 (fill-paragraph justify)))) 3860 (fill-paragraph justify))))
3812 t)) 3861 t))
3813 3862
3814 3863
3815 (defun py-fill-string (start &optional justify) 3864 (defun py-fill-string (start &optional justify)
3816 "Fill the paragraph around (point) in the string starting at start" 3865 "Fill the paragraph around (point) in the string starting at start"
3817 ;; basic strategy: narrow to the string and call the default 3866 ;; basic strategy: narrow to the string and call the default
3818 ;; implementation 3867 ;; implementation
3819 (let (;; the start of the string's contents 3868 (let (;; the start of the string's contents
3820 string-start 3869 string-start
3821 ;; the end of the string's contents 3870 ;; the end of the string's contents
3822 string-end 3871 string-end
3823 ;; length of the string's delimiter 3872 ;; length of the string's delimiter
3824 delim-length 3873 delim-length
3825 ;; The string delimiter 3874 ;; The string delimiter
3826 delim 3875 delim
3827 ) 3876 )
3828 3877
3829 (save-excursion 3878 (save-excursion
3830 (goto-char start) 3879 (goto-char start)
3831 (if (looking-at "\\('''\\|\"\"\"\\|'\\|\"\\)\\\\?\n?") 3880 (if (looking-at "\\('''\\|\"\"\"\\|'\\|\"\\)\\\\?\n?")
3832 (setq string-start (match-end 0) 3881 (setq string-start (match-end 0)
3833 delim-length (- (match-end 1) (match-beginning 1)) 3882 delim-length (- (match-end 1) (match-beginning 1))
3834 delim (buffer-substring-no-properties (match-beginning 1) 3883 delim (buffer-substring-no-properties (match-beginning 1)
3835 (match-end 1))) 3884 (match-end 1)))
3836 (error "The parameter start is not the beginning of a python string")) 3885 (error "The parameter start is not the beginning of a python string"))
3837 3886
3838 ;; if the string is the first token on a line and doesn't start with 3887 ;; if the string is the first token on a line and doesn't start with
3839 ;; a newline, fill as if the string starts at the beginning of the 3888 ;; a newline, fill as if the string starts at the beginning of the
3840 ;; line. this helps with one line docstrings 3889 ;; line. this helps with one line docstrings
3841 (save-excursion 3890 (save-excursion
3842 (beginning-of-line) 3891 (beginning-of-line)
3843 (and (/= (char-before string-start) ?\n) 3892 (and (/= (char-before string-start) ?\n)
3844 (looking-at (concat "[ \t]*" delim)) 3893 (looking-at (concat "[ \t]*" delim))
3845 (setq string-start (point)))) 3894 (setq string-start (point))))
3846 3895
3847 (forward-sexp (if (= delim-length 3) 2 1)) 3896 (forward-sexp (if (= delim-length 3) 2 1))
3848 3897
3849 ;; with both triple quoted strings and single/double quoted strings 3898 ;; with both triple quoted strings and single/double quoted strings
3850 ;; we're now directly behind the first char of the end delimiter 3899 ;; we're now directly behind the first char of the end delimiter
3855 3904
3856 ;; Narrow to the string's contents and fill the current paragraph 3905 ;; Narrow to the string's contents and fill the current paragraph
3857 (save-restriction 3906 (save-restriction
3858 (narrow-to-region string-start string-end) 3907 (narrow-to-region string-start string-end)
3859 (let ((ends-with-newline (= (char-before (point-max)) ?\n))) 3908 (let ((ends-with-newline (= (char-before (point-max)) ?\n)))
3860 (fill-paragraph justify) 3909 (fill-paragraph justify)
3861 (if (and (not ends-with-newline) 3910 (if (and (not ends-with-newline)
3862 (= (char-before (point-max)) ?\n)) 3911 (= (char-before (point-max)) ?\n))
3863 ;; the default fill-paragraph implementation has inserted a 3912 ;; the default fill-paragraph implementation has inserted a
3864 ;; newline at the end. Remove it again. 3913 ;; newline at the end. Remove it again.
3865 (save-excursion 3914 (save-excursion
3866 (goto-char (point-max)) 3915 (goto-char (point-max))
3867 (delete-char -1))))) 3916 (delete-char -1)))))
3868 3917
3869 ;; return t to indicate that we've done our work 3918 ;; return t to indicate that we've done our work
3870 t)) 3919 t))
3871 3920
3872 (defun py-fill-paragraph (&optional justify) 3921 (defun py-fill-paragraph (&optional justify)
3875 paragraph of it that point is in, preserving the comment's indentation 3924 paragraph of it that point is in, preserving the comment's indentation
3876 and initial `#'s. 3925 and initial `#'s.
3877 If point is inside a string, narrow to that string and fill. 3926 If point is inside a string, narrow to that string and fill.
3878 " 3927 "
3879 (interactive "P") 3928 (interactive "P")
3880 (let* ((bod (py-point 'bod)) 3929 ;; fill-paragraph will narrow incorrectly
3881 (pps (parse-partial-sexp bod (point)))) 3930 (save-restriction
3882 (cond 3931 (widen)
3883 ;; are we inside a comment or on a line with only whitespace before 3932 (let* ((bod (py-point 'bod))
3884 ;; the comment start? 3933 (pps (parse-partial-sexp bod (point))))
3885 ((or (nth 4 pps) 3934 (cond
3886 (save-excursion (beginning-of-line) (looking-at "[ \t]*#"))) 3935 ;; are we inside a comment or on a line with only whitespace before
3887 (py-fill-comment justify)) 3936 ;; the comment start?
3888 ;; are we inside a string? 3937 ((or (nth 4 pps)
3889 ((nth 3 pps) 3938 (save-excursion (beginning-of-line) (looking-at "[ \t]*#")))
3890 (py-fill-string (nth 8 pps))) 3939 (py-fill-comment justify))
3891 ;; are we at the opening quote of a string, or in the indentation? 3940 ;; are we inside a string?
3892 ((save-excursion 3941 ((nth 3 pps)
3893 (forward-word 1) 3942 (py-fill-string (nth 8 pps)))
3894 (eq (py-in-literal) 'string)) 3943 ;; are we at the opening quote of a string, or in the indentation?
3895 (save-excursion 3944 ((save-excursion
3896 (py-fill-string (py-point 'boi)))) 3945 (forward-word 1)
3897 ;; are we at or after the closing quote of a string? 3946 (eq (py-in-literal) 'string))
3898 ((save-excursion 3947 (save-excursion
3899 (backward-word 1) 3948 (py-fill-string (py-point 'boi))))
3900 (eq (py-in-literal) 'string)) 3949 ;; are we at or after the closing quote of a string?
3901 (save-excursion 3950 ((save-excursion
3902 (py-fill-string (py-point 'boi)))) 3951 (backward-word 1)
3903 ;; otherwise use the default 3952 (eq (py-in-literal) 'string))
3904 (t 3953 (save-excursion
3905 (fill-paragraph justify))))) 3954 (py-fill-string (py-point 'boi))))
3955 ;; otherwise use the default
3956 (t
3957 (fill-paragraph justify))))))
3906 3958
3907 3959
3908 3960
3909 (provide 'python-mode) 3961 (provide 'python-mode)
3910 ;;; python-mode.el ends here 3962 ;;; python-mode.el ends here