Mercurial > dotfiles
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 |
