| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 1 | ;;; python-mode.el --- Major mode for editing Python programs | 
|  | 2 |  | 
|  | 3 | ;; Copyright (C) 1992,1993,1994  Tim Peters | 
|  | 4 |  | 
|  | 5 | ;; Author: 1995 Barry A. Warsaw <bwarsaw@cnri.reston.va.us> | 
|  | 6 | ;;         1992-1994 Tim Peters <tim@ksr.com> | 
|  | 7 | ;; Maintainer:    bwarsaw@cnri.reston.va.us | 
|  | 8 | ;; Created:       ??? | 
|  | 9 | ;; Version:       $Revision$ | 
|  | 10 | ;; Last Modified: $Date$ | 
|  | 11 | ;; Keywords: python editing language major-mode | 
|  | 12 |  | 
|  | 13 | ;; This file is not part of GNU Emacs. | 
|  | 14 |  | 
|  | 15 | ;; This program is free software; you can redistribute it and/or modify | 
|  | 16 | ;; it under the terms of the GNU General Public License as published by | 
|  | 17 | ;; the Free Software Foundation; either version 2 of the License, or | 
|  | 18 | ;; (at your option) any later version. | 
|  | 19 | ;; | 
|  | 20 | ;; This program is distributed in the hope that it will be useful, | 
|  | 21 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | 
|  | 22 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
|  | 23 | ;; GNU General Public License for more details. | 
|  | 24 | ;; | 
|  | 25 | ;; You should have received a copy of the GNU General Public License | 
|  | 26 | ;; along with this program; if not, write to the Free Software | 
|  | 27 | ;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 
|  | 28 |  | 
|  | 29 | ;;; Commentary: | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 30 | ;; | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 31 | ;; This is a major mode for editing Python programs.  It was developed | 
|  | 32 | ;; by Tim Peters <tim@ksr.com> after an original idea by Michael | 
|  | 33 | ;; A. Guravage.  Tim doesn't appear to be on the 'net any longer so I | 
|  | 34 | ;; have undertaken maintenance of the mode.  Here is Tim's original | 
|  | 35 | ;; copyright notice: | 
|  | 36 |  | 
|  | 37 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 38 | ;; Copyright (c) 1992,1993,1994  Tim Peters | 
|  | 39 | ;; | 
|  | 40 | ;; This software is provided as-is, without express or implied warranty. | 
|  | 41 | ;; Permission to use, copy, modify, distribute or sell this software, | 
|  | 42 | ;; without fee, for any purpose and by any individual or organization, is | 
|  | 43 | ;; hereby granted, provided that the above copyright notice and this | 
|  | 44 | ;; paragraph appear in all copies. | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 45 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | 
|  | 46 |  | 
|  | 47 | ;; At some point this mode will undergo a rewrite to bring it more in | 
|  | 48 | ;; line with GNU Emacs Lisp coding standards.  But all in all, the | 
|  | 49 | ;; mode works exceedingly well. | 
|  | 50 |  | 
|  | 51 | ;; The following statements, placed in your .emacs file or | 
|  | 52 | ;; site-init.el, will cause this file to be autoloaded, and | 
|  | 53 | ;; python-mode invoked, when visiting .py files (assuming this file is | 
|  | 54 | ;; in your load-path): | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 55 | ;; | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 56 | ;;	(autoload 'python-mode "python-mode" "Python editing mode." t) | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 57 | ;;	(setq auto-mode-alist | 
|  | 58 | ;;	      (cons '("\\.py$" . python-mode) auto-mode-alist)) | 
|  | 59 |  | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 60 | ;; Here's a brief to do list: | 
|  | 61 | ;; | 
|  | 62 | ;; 1. Better integration with gud-mode for debugging. | 
|  | 63 | ;; 2. Rewrite according to GNU Emacs Lisp standards. | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 64 |  | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 65 | ;; If you can think of more things you'd like to see, drop me a line. | 
|  | 66 | ;; If you want to report bugs, use py-submit-bug-report (C-c C-b). | 
|  | 67 | ;; | 
|  | 68 | ;; Note that I only test things on XEmacs (currently 19.11).  If you | 
|  | 69 | ;; port stuff to FSF Emacs 19, or Emacs 18, please send me your | 
|  | 70 | ;; patches. | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 71 |  | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 72 | ;; LCD Archive Entry: | 
|  | 73 | ;; python-mode|Barry A. Warsaw|bwarsaw@cnri.reston.va.us | 
|  | 74 | ;; |Major mode for editing Python programs | 
|  | 75 | ;; |$Date$|$Revision$| | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 76 |  | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 77 | ;;; Code: | 
|  | 78 |  | 
|  | 79 |  | 
|  | 80 | ;; user definable variables | 
|  | 81 | ;; vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 82 |  | 
|  | 83 | (defvar py-python-command "python" | 
|  | 84 | "*Shell command used to start Python interpreter.") | 
|  | 85 |  | 
|  | 86 | (defvar py-indent-offset 8		; argue with Guido <grin> | 
|  | 87 | "*Indentation increment. | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 88 | Note that `\\[py-guess-indent-offset]' can usually guess a good value | 
|  | 89 | when you're editing someone else's Python code.") | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 90 |  | 
|  | 91 | (defvar py-block-comment-prefix "##" | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 92 | "*String used by `py-comment-region' to comment out a block of code. | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 93 | This should follow the convention for non-indenting comment lines so | 
|  | 94 | that the indentation commands won't get confused (i.e., the string | 
|  | 95 | should be of the form `#x...' where `x' is not a blank or a tab, and | 
|  | 96 | `...' is arbitrary).") | 
|  | 97 |  | 
|  | 98 | (defvar py-scroll-process-buffer t | 
|  | 99 | "*Scroll Python process buffer as output arrives. | 
|  | 100 | If nil, the Python process buffer acts, with respect to scrolling, like | 
|  | 101 | Shell-mode buffers normally act.  This is surprisingly complicated and | 
|  | 102 | so won't be explained here; in fact, you can't get the whole story | 
|  | 103 | without studying the Emacs C code. | 
|  | 104 |  | 
|  | 105 | If non-nil, the behavior is different in two respects (which are | 
|  | 106 | slightly inaccurate in the interest of brevity): | 
|  | 107 |  | 
|  | 108 | - If the buffer is in a window, and you left point at its end, the | 
|  | 109 | window will scroll as new output arrives, and point will move to the | 
|  | 110 | buffer's end, even if the window is not the selected window (that | 
|  | 111 | being the one the cursor is in).  The usual behavior for shell-mode | 
|  | 112 | windows is not to scroll, and to leave point where it was, if the | 
|  | 113 | buffer is in a window other than the selected window. | 
|  | 114 |  | 
|  | 115 | - If the buffer is not visible in any window, and you left point at | 
|  | 116 | its end, the buffer will be popped into a window as soon as more | 
|  | 117 | output arrives.  This is handy if you have a long-running | 
|  | 118 | computation and don't want to tie up screen area waiting for the | 
|  | 119 | output.  The usual behavior for a shell-mode buffer is to stay | 
|  | 120 | invisible until you explicitly visit it. | 
|  | 121 |  | 
|  | 122 | Note the `and if you left point at its end' clauses in both of the | 
|  | 123 | above:  you can `turn off' the special behaviors while output is in | 
|  | 124 | progress, by visiting the Python buffer and moving point to anywhere | 
|  | 125 | besides the end.  Then the buffer won't scroll, point will remain where | 
|  | 126 | you leave it, and if you hide the buffer it will stay hidden until you | 
|  | 127 | visit it again.  You can enable and disable the special behaviors as | 
|  | 128 | often as you like, while output is in progress, by (respectively) moving | 
|  | 129 | point to, or away from, the end of the buffer. | 
|  | 130 |  | 
|  | 131 | Warning:  If you expect a large amount of output, you'll probably be | 
|  | 132 | happier setting this option to nil. | 
|  | 133 |  | 
|  | 134 | Obscure:  `End of buffer' above should really say `at or beyond the | 
|  | 135 | process mark', but if you know what that means you didn't need to be | 
|  | 136 | told <grin>.") | 
|  | 137 |  | 
|  | 138 | (defvar py-temp-directory | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 139 | (let ((ok '(lambda (x) | 
|  | 140 | (and x | 
|  | 141 | (setq x (expand-file-name x)) ; always true | 
|  | 142 | (file-directory-p x) | 
|  | 143 | (file-writable-p x) | 
|  | 144 | x)))) | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 145 | (or (funcall ok (getenv "TMPDIR")) | 
|  | 146 | (funcall ok "/usr/tmp") | 
|  | 147 | (funcall ok "/tmp") | 
|  | 148 | (funcall ok  ".") | 
|  | 149 | (error | 
|  | 150 | "Couldn't find a usable temp directory -- set py-temp-directory"))) | 
|  | 151 | "*Directory used for temp files created by a *Python* process. | 
|  | 152 | By default, the first directory from this list that exists and that you | 
|  | 153 | can write into:  the value (if any) of the environment variable TMPDIR, | 
|  | 154 | /usr/tmp, /tmp, or the current directory.") | 
|  | 155 |  | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 156 | (defvar py-beep-if-tab-change t | 
|  | 157 | "*Ring the bell if tab-width is changed. | 
|  | 158 | If a comment of the form | 
|  | 159 |  | 
|  | 160 | \t# vi:set tabsize=<number>: | 
|  | 161 |  | 
|  | 162 | is found before the first code line when the file is entered, and the | 
|  | 163 | current value of (the general Emacs variable) `tab-width' does not | 
|  | 164 | equal <number>, `tab-width' is set to <number>, a message saying so is | 
|  | 165 | displayed in the echo area, and if `py-beep-if-tab-change' is non-nil | 
|  | 166 | the Emacs bell is also rung as a warning.") | 
|  | 167 |  | 
|  | 168 |  | 
|  | 169 |  | 
|  | 170 | ;; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | 
|  | 171 | ;; NO USER DEFINABLE VARIABLES BEYOND THIS POINT | 
|  | 172 |  | 
|  | 173 | ;; Differentiate between Emacs 18, Lucid Emacs, and Emacs 19.  This | 
|  | 174 | ;; seems to be the standard way of checking this. | 
|  | 175 | ;; BAW - This is *not* the right solution.  When at all possible, | 
|  | 176 | ;; instead of testing for the version of Emacs, use feature tests. | 
|  | 177 |  | 
|  | 178 | (setq py-this-is-lucid-emacs-p (string-match "Lucid\\|XEmacs" emacs-version)) | 
|  | 179 | (setq py-this-is-emacs-19-p | 
|  | 180 | (and | 
|  | 181 | (not py-this-is-lucid-emacs-p) | 
|  | 182 | (string-match "^19\\." emacs-version))) | 
|  | 183 |  | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 184 | ;; have to bind py-file-queue before installing the kill-emacs hook | 
|  | 185 | (defvar py-file-queue nil | 
|  | 186 | "Queue of Python temp files awaiting execution. | 
|  | 187 | Currently-active file is at the head of the list.") | 
|  | 188 |  | 
|  | 189 | ;; define a mode-specific abbrev table for those who use such things | 
|  | 190 | (defvar python-mode-abbrev-table nil | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 191 | "Abbrev table in use in `python-mode' buffers.") | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 192 | (define-abbrev-table 'python-mode-abbrev-table nil) | 
|  | 193 |  | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 194 | (defvar python-mode-hook nil | 
|  | 195 | "*Hook called by `python-mode'.") | 
|  | 196 |  | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 197 | ;; in previous version of python-mode.el, the hook was incorrectly | 
|  | 198 | ;; called py-mode-hook, and was not defvar'd.  deprecate its use. | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 199 | (and (fboundp 'make-obsolete-variable) | 
|  | 200 | (make-obsolete-variable 'py-mode-hook 'python-mode-hook)) | 
|  | 201 |  | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 202 | (defvar py-mode-map () | 
|  | 203 | "Keymap used in `python-mode' buffers.") | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 204 |  | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 205 | (if py-mode-map | 
|  | 206 | () | 
|  | 207 | (setq py-mode-map (make-sparse-keymap)) | 
|  | 208 |  | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 209 | ;; shadow global bindings for newline-and-indent w/ the py- version. | 
|  | 210 | ;; BAW - this is extremely bad form, but I'm not going to change it | 
|  | 211 | ;; for now. | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 212 | (mapcar (function (lambda (key) | 
|  | 213 | (define-key | 
|  | 214 | py-mode-map key 'py-newline-and-indent))) | 
|  | 215 | (where-is-internal 'newline-and-indent)) | 
|  | 216 |  | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 217 | ;; BAW - you could do it this way, but its not considered proper | 
|  | 218 | ;; major-mode form. | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 219 | (mapcar (function | 
|  | 220 | (lambda (x) | 
|  | 221 | (define-key py-mode-map (car x) (cdr x)))) | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 222 | '(("\C-c\C-c"  . py-execute-buffer) | 
|  | 223 | ("\C-c|"	 . py-execute-region) | 
|  | 224 | ("\C-c!"	 . py-shell) | 
|  | 225 | ("\177"	 . py-delete-char) | 
|  | 226 | ("\n"	 . py-newline-and-indent) | 
|  | 227 | ("\C-c:"	 . py-guess-indent-offset) | 
|  | 228 | ("\C-c\t"	 . py-indent-region) | 
|  | 229 | ("\C-c<"	 . py-shift-region-left) | 
|  | 230 | ("\C-c>"	 . py-shift-region-right) | 
|  | 231 | ("\C-c\C-n"  . py-next-statement) | 
|  | 232 | ("\C-c\C-p"  . py-previous-statement) | 
|  | 233 | ("\C-c\C-u"  . py-goto-block-up) | 
|  | 234 | ("\C-c\C-b"  . py-mark-block) | 
|  | 235 | ("\C-c#"	 . py-comment-region) | 
|  | 236 | ("\C-c?"	 . py-describe-mode) | 
|  | 237 | ("\C-c\C-hm" . py-describe-mode) | 
|  | 238 | ("\e\C-a"	 . beginning-of-python-def-or-class) | 
|  | 239 | ("\e\C-e"	 . end-of-python-def-or-class) | 
|  | 240 | ( "\e\C-h"	 . mark-python-def-or-class)))) | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 241 |  | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 242 | (defvar py-mode-syntax-table nil | 
|  | 243 | "Syntax table used in `python-mode' buffers.") | 
|  | 244 |  | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 245 | (if py-mode-syntax-table | 
|  | 246 | () | 
|  | 247 | (setq py-mode-syntax-table (make-syntax-table)) | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 248 | ;; BAW - again, blech. | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 249 | (mapcar (function | 
|  | 250 | (lambda (x) (modify-syntax-entry | 
|  | 251 | (car x) (cdr x) py-mode-syntax-table))) | 
|  | 252 | '(( ?\( . "()" ) ( ?\) . ")(" ) | 
|  | 253 | ( ?\[ . "(]" ) ( ?\] . ")[" ) | 
|  | 254 | ( ?\{ . "(}" ) ( ?\} . "){" ) | 
|  | 255 | ;; fix operator symbols misassigned in the std table | 
|  | 256 | ( ?\$ . "." ) ( ?\% . "." ) ( ?\& . "." ) | 
|  | 257 | ( ?\* . "." ) ( ?\+ . "." ) ( ?\- . "." ) | 
|  | 258 | ( ?\/ . "." ) ( ?\< . "." ) ( ?\= . "." ) | 
|  | 259 | ( ?\> . "." ) ( ?\| . "." ) | 
|  | 260 | ( ?\_ . "w" )	; underscore is legit in names | 
|  | 261 | ( ?\' . "\"")	; single quote is string quote | 
|  | 262 | ( ?\" . "\"" )	; double quote is string quote too | 
|  | 263 | ( ?\` . "$")	; backquote is open and close paren | 
|  | 264 | ( ?\# . "<")	; hash starts comment | 
|  | 265 | ( ?\n . ">"))))	; newline ends comment | 
|  | 266 |  | 
|  | 267 | (defconst py-stringlit-re | 
|  | 268 | (concat | 
|  | 269 | "'\\([^'\n\\]\\|\\\\.\\)*'"		; single-quoted | 
|  | 270 | "\\|"				; or | 
|  | 271 | "\"\\([^\"\n\\]\\|\\\\.\\)*\"")	; double-quoted | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 272 | "Regexp matching a Python string literal.") | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 273 |  | 
|  | 274 | ;; this is tricky because a trailing backslash does not mean | 
|  | 275 | ;; continuation if it's in a comment | 
|  | 276 | (defconst py-continued-re | 
|  | 277 | (concat | 
|  | 278 | "\\(" "[^#'\"\n\\]" "\\|" py-stringlit-re "\\)*" | 
|  | 279 | "\\\\$") | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 280 | "Regexp matching Python lines that are continued via backslash.") | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 281 |  | 
|  | 282 | (defconst py-blank-or-comment-re "[ \t]*\\($\\|#\\)" | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 283 | "Regexp matching blank or comment lines.") | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 284 |  | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 285 |  | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 286 |  | 
|  | 287 | ;;;###autoload | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 288 | (defun python-mode () | 
|  | 289 | "Major mode for editing Python files. | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 290 | To submit a problem report, enter `\\[py-submit-bug-report]' from a | 
|  | 291 | `python-mode' buffer.  Do `\\[py-describe-mode]' for detailed | 
|  | 292 | documentation.  To see what version of `python-mode' you are running, | 
|  | 293 | enter `\\[py-version]'. | 
|  | 294 |  | 
|  | 295 | This mode knows about Python indentation, tokens, comments and | 
|  | 296 | continuation lines.  Paragraphs are separated by blank lines only. | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 297 |  | 
|  | 298 | COMMANDS | 
|  | 299 | \\{py-mode-map} | 
|  | 300 | VARIABLES | 
|  | 301 |  | 
|  | 302 | py-indent-offset\tindentation increment | 
|  | 303 | py-block-comment-prefix\tcomment string used by py-comment-region | 
|  | 304 | py-python-command\tshell command to invoke Python interpreter | 
|  | 305 | py-scroll-process-buffer\talways scroll Python process buffer | 
|  | 306 | py-temp-directory\tdirectory used for temp files (if needed) | 
|  | 307 | py-beep-if-tab-change\tring the bell if tab-width is changed" | 
|  | 308 | (interactive) | 
|  | 309 | (kill-all-local-variables) | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 310 | (set-syntax-table py-mode-syntax-table) | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 311 | (setq major-mode 'python-mode | 
|  | 312 | mode-name "Python" | 
|  | 313 | local-abbrev-table python-mode-abbrev-table) | 
|  | 314 | (use-local-map py-mode-map) | 
|  | 315 | ;; BAW -- style... | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 316 | (mapcar (function (lambda (x) | 
|  | 317 | (make-local-variable (car x)) | 
|  | 318 | (set (car x) (cdr x)))) | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 319 | '((paragraph-separate . "^[ \t]*$") | 
|  | 320 | (paragraph-start	 . "^[ \t]*$") | 
|  | 321 | (require-final-newline . t) | 
|  | 322 | (comment-start .		"# ") | 
|  | 323 | (comment-start-skip .	"# *") | 
|  | 324 | (comment-column . 40) | 
|  | 325 | (indent-region-function . py-indent-region) | 
|  | 326 | (indent-line-function . py-indent-line))) | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 327 | ;; hack to allow overriding the tabsize in the file (see tokenizer.c) | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 328 | ;; | 
|  | 329 | ;; not sure where the magic comment has to be; to save time | 
|  | 330 | ;; searching for a rarity, we give up if it's not found prior to the | 
|  | 331 | ;; first executable statement. | 
|  | 332 | ;; | 
|  | 333 | ;; BAW - on first glance, this seems like complete hackery.  Why was | 
|  | 334 | ;; this necessary, and is it still necessary? | 
|  | 335 | (let ((case-fold-search nil) | 
|  | 336 | (start (point)) | 
|  | 337 | new-tab-width) | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 338 | (if (re-search-forward | 
|  | 339 | "^[ \t]*#[ \t]*vi:set[ \t]+tabsize=\\([0-9]+\\):" | 
|  | 340 | (prog2 (py-next-statement 1) (point) (goto-char 1)) | 
|  | 341 | t) | 
|  | 342 | (progn | 
|  | 343 | (setq new-tab-width | 
|  | 344 | (string-to-int | 
|  | 345 | (buffer-substring (match-beginning 1) (match-end 1)))) | 
|  | 346 | (if (= tab-width new-tab-width) | 
|  | 347 | nil | 
|  | 348 | (setq tab-width new-tab-width) | 
|  | 349 | (message "Caution: tab-width changed to %d" new-tab-width) | 
|  | 350 | (if py-beep-if-tab-change (beep))))) | 
|  | 351 | (goto-char start)) | 
|  | 352 |  | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 353 | ;; run the mode hook. py-mode-hook use is deprecated | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 354 | (if python-mode-hook | 
|  | 355 | (run-hooks 'python-mode-hook) | 
|  | 356 | (run-hooks 'py-mode-hook))) | 
|  | 357 |  | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 358 |  | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 359 | ;;; Functions that execute Python commands in a subprocess | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 360 | (defun py-shell () | 
|  | 361 | "Start an interactive Python interpreter in another window. | 
|  | 362 | This is like Shell mode, except that Python is running in the window | 
|  | 363 | instead of a shell.  See the `Interactive Shell' and `Shell Mode' | 
|  | 364 | sections of the Emacs manual for details, especially for the key | 
|  | 365 | bindings active in the `*Python*' buffer. | 
|  | 366 |  | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 367 | See the docs for variable `py-scroll-buffer' for info on scrolling | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 368 | behavior in the process window. | 
|  | 369 |  | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 370 | Warning: Don't use an interactive Python if you change sys.ps1 or | 
|  | 371 | sys.ps2 from their default values, or if you're running code that | 
|  | 372 | prints `>>> ' or `... ' at the start of a line.  `python-mode' can't | 
|  | 373 | distinguish your output from Python's output, and assumes that `>>> ' | 
|  | 374 | at the start of a line is a prompt from Python.  Similarly, the Emacs | 
|  | 375 | Shell mode code assumes that both `>>> ' and `... ' at the start of a | 
|  | 376 | line are Python prompts.  Bad things can happen if you fool either | 
|  | 377 | mode. | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 378 |  | 
|  | 379 | Warning:  If you do any editing *in* the process buffer *while* the | 
|  | 380 | buffer is accepting output from Python, do NOT attempt to `undo' the | 
|  | 381 | changes.  Some of the output (nowhere near the parts you changed!) may | 
|  | 382 | be lost if you do.  This appears to be an Emacs bug, an unfortunate | 
|  | 383 | interaction between undo and process filters; the same problem exists in | 
|  | 384 | non-Python process buffers using the default (Emacs-supplied) process | 
|  | 385 | filter." | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 386 | ;; BAW - should undo be disabled in the python process buffer, if | 
|  | 387 | ;; this bug still exists? | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 388 | (interactive) | 
|  | 389 | (if py-this-is-emacs-19-p | 
|  | 390 | (progn | 
|  | 391 | (require 'comint) | 
|  | 392 | (switch-to-buffer-other-window | 
|  | 393 | (make-comint "Python" py-python-command))) | 
|  | 394 | (progn | 
|  | 395 | (require 'shell) | 
|  | 396 | (switch-to-buffer-other-window | 
|  | 397 | (make-shell "Python" py-python-command)))) | 
|  | 398 | (make-local-variable 'shell-prompt-pattern) | 
|  | 399 | (setq shell-prompt-pattern "^>>> \\|^\\.\\.\\. ") | 
|  | 400 | (set-process-filter (get-buffer-process (current-buffer)) | 
|  | 401 | 'py-process-filter) | 
|  | 402 | (set-syntax-table py-mode-syntax-table)) | 
|  | 403 |  | 
|  | 404 | (defun py-execute-region (start end) | 
|  | 405 | "Send the region between START and END to a Python interpreter. | 
|  | 406 | If there is a *Python* process it is used. | 
|  | 407 |  | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 408 | Hint: If you want to execute part of a Python file several times | 
|  | 409 | \(e.g., perhaps you're developing a function and want to flesh it out | 
|  | 410 | a bit at a time), use `\\[narrow-to-region]' to restrict the buffer to | 
|  | 411 | the region of interest, and send the code to a *Python* process via | 
|  | 412 | `\\[py-execute-buffer]' instead. | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 413 |  | 
|  | 414 | Following are subtleties to note when using a *Python* process: | 
|  | 415 |  | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 416 | If a *Python* process is used, the region is copied into a temporary | 
|  | 417 | file (in directory `py-temp-directory'), and an `execfile' command is | 
|  | 418 | sent to Python naming that file.  If you send regions faster than | 
|  | 419 | Python can execute them, `python-mode' will save them into distinct | 
|  | 420 | temp files, and execute the next one in the queue the next time it | 
|  | 421 | sees a `>>> ' prompt from Python.  Each time this happens, the process | 
|  | 422 | buffer is popped into a window (if it's not already in some window) so | 
|  | 423 | you can see it, and a comment of the form | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 424 |  | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 425 | \t## working on region in file <name> ... | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 426 |  | 
|  | 427 | is inserted at the end. | 
|  | 428 |  | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 429 | Caution: No more than 26 regions can be pending at any given time. | 
|  | 430 | This limit is (indirectly) inherited from libc's mktemp(3). | 
|  | 431 | `python-mode' does not try to protect you from exceeding the limit. | 
|  | 432 | It's extremely unlikely that you'll get anywhere close to the limit in | 
|  | 433 | practice, unless you're trying to be a jerk <grin>. | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 434 |  | 
|  | 435 | See the `\\[py-shell]' docs for additional warnings." | 
|  | 436 | (interactive "r") | 
|  | 437 | (or (< start end) (error "Region is empty")) | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 438 | (let ((pyproc (get-process "Python")) | 
|  | 439 | fname) | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 440 | (if (null pyproc) | 
|  | 441 | (shell-command-on-region start end py-python-command) | 
|  | 442 | ;; else feed it thru a temp file | 
|  | 443 | (setq fname (py-make-temp-name)) | 
|  | 444 | (write-region start end fname nil 'no-msg) | 
|  | 445 | (setq py-file-queue (append py-file-queue (list fname))) | 
|  | 446 | (if (cdr py-file-queue) | 
|  | 447 | (message "File %s queued for execution" fname) | 
|  | 448 | ;; else | 
|  | 449 | (py-execute-file pyproc fname))))) | 
|  | 450 |  | 
|  | 451 | (defun py-execute-file (pyproc fname) | 
|  | 452 | (py-append-to-process-buffer | 
|  | 453 | pyproc | 
|  | 454 | (format "## working on region in file %s ...\n" fname)) | 
|  | 455 | (process-send-string pyproc (format "execfile('%s')\n" fname))) | 
|  | 456 |  | 
|  | 457 | (defun py-process-filter (pyproc string) | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 458 | (let ((curbuf (current-buffer)) | 
|  | 459 | (pbuf (process-buffer pyproc)) | 
|  | 460 | (pmark (process-mark pyproc)) | 
|  | 461 | file-finished) | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 462 |  | 
|  | 463 | ;; make sure we switch to a different buffer at least once.  if we | 
|  | 464 | ;; *don't* do this, then if the process buffer is in the selected | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 465 | ;; window, and point is before the end, and lots of output is | 
|  | 466 | ;; coming at a fast pace, then (a) simple cursor-movement commands | 
|  | 467 | ;; like C-p, C-n, C-f, C-b, C-a, C-e take an incredibly long time | 
|  | 468 | ;; to have a visible effect (the window just doesn't get updated, | 
|  | 469 | ;; sometimes for minutes(!)), and (b) it takes about 5x longer to | 
|  | 470 | ;; get all the process output (until the next python prompt). | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 471 | ;; | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 472 | ;; #b makes no sense to me at all.  #a almost makes sense: unless | 
|  | 473 | ;; we actually change buffers, set_buffer_internal in buffer.c | 
|  | 474 | ;; doesn't set windows_or_buffers_changed to 1, & that in turn | 
|  | 475 | ;; seems to make the Emacs command loop reluctant to update the | 
|  | 476 | ;; display.  Perhaps the default process filter in process.c's | 
|  | 477 | ;; read_process_output has update_mode_lines++ for a similar | 
|  | 478 | ;; reason?  beats me ... | 
|  | 479 |  | 
|  | 480 | ;; BAW - we want to check to see if this still applies | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 481 | (if (eq curbuf pbuf)		; mysterious ugly hack | 
|  | 482 | (set-buffer (get-buffer-create "*scratch*"))) | 
|  | 483 |  | 
|  | 484 | (set-buffer pbuf) | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 485 | (let* ((start (point)) | 
|  | 486 | (goback (< start pmark)) | 
|  | 487 | (buffer-read-only nil)) | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 488 | (goto-char pmark) | 
|  | 489 | (insert string) | 
|  | 490 | (move-marker pmark (point)) | 
|  | 491 | (setq file-finished | 
|  | 492 | (and py-file-queue | 
|  | 493 | (equal ">>> " | 
|  | 494 | (buffer-substring | 
|  | 495 | (prog2 (beginning-of-line) (point) | 
|  | 496 | (goto-char pmark)) | 
|  | 497 | (point))))) | 
|  | 498 | (if goback (goto-char start) | 
|  | 499 | ;; else | 
|  | 500 | (if py-scroll-process-buffer | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 501 | (let* ((pop-up-windows t) | 
|  | 502 | (pwin (display-buffer pbuf))) | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 503 | (set-window-point pwin (point)))))) | 
|  | 504 | (set-buffer curbuf) | 
|  | 505 | (if file-finished | 
|  | 506 | (progn | 
|  | 507 | (py-delete-file-silently (car py-file-queue)) | 
|  | 508 | (setq py-file-queue (cdr py-file-queue)) | 
|  | 509 | (if py-file-queue | 
|  | 510 | (py-execute-file pyproc (car py-file-queue))))))) | 
|  | 511 |  | 
|  | 512 | (defun py-execute-buffer () | 
|  | 513 | "Send the contents of the buffer to a Python interpreter. | 
|  | 514 | If there is a *Python* process buffer it is used.  If a clipping | 
|  | 515 | restriction is in effect, only the accessible portion of the buffer is | 
|  | 516 | sent.  A trailing newline will be supplied if needed. | 
|  | 517 |  | 
|  | 518 | See the `\\[py-execute-region]' docs for an account of some subtleties." | 
|  | 519 | (interactive) | 
|  | 520 | (py-execute-region (point-min) (point-max))) | 
|  | 521 |  | 
|  | 522 |  | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 523 |  | 
|  | 524 | ;; Functions for Python style indentation | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 525 | (defun py-delete-char () | 
|  | 526 | "Reduce indentation or delete character. | 
|  | 527 | If point is at the leftmost column, deletes the preceding newline. | 
|  | 528 |  | 
|  | 529 | Else if point is at the leftmost non-blank character of a line that is | 
|  | 530 | neither a continuation line nor a non-indenting comment line, or if | 
|  | 531 | point is at the end of a blank line, reduces the indentation to match | 
|  | 532 | that of the line that opened the current block of code.  The line that | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 533 | opened the block is displayed in the echo area to help you keep track | 
|  | 534 | of where you are. | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 535 |  | 
|  | 536 | Else the preceding character is deleted, converting a tab to spaces if | 
|  | 537 | needed so that only a single column position is deleted." | 
|  | 538 | (interactive "*") | 
|  | 539 | (if (or (/= (current-indentation) (current-column)) | 
|  | 540 | (bolp) | 
|  | 541 | (py-continuation-line-p) | 
|  | 542 | (looking-at "#[^ \t\n]"))	; non-indenting # | 
|  | 543 | (backward-delete-char-untabify 1) | 
|  | 544 | ;; else indent the same as the colon line that opened the block | 
|  | 545 |  | 
|  | 546 | ;; force non-blank so py-goto-block-up doesn't ignore it | 
|  | 547 | (insert-char ?* 1) | 
|  | 548 | (backward-char) | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 549 | (let ((base-indent 0)		; indentation of base line | 
|  | 550 | (base-text "")		; and text of base line | 
|  | 551 | (base-found-p nil)) | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 552 | (condition-case nil		; in case no enclosing block | 
|  | 553 | (save-excursion | 
|  | 554 | (py-goto-block-up 'no-mark) | 
|  | 555 | (setq base-indent (current-indentation) | 
|  | 556 | base-text   (py-suck-up-leading-text) | 
|  | 557 | base-found-p t)) | 
|  | 558 | (error nil)) | 
|  | 559 | (delete-char 1)			; toss the dummy character | 
|  | 560 | (delete-horizontal-space) | 
|  | 561 | (indent-to base-indent) | 
|  | 562 | (if base-found-p | 
|  | 563 | (message "Closes block: %s" base-text))))) | 
|  | 564 |  | 
|  | 565 | (defun py-indent-line () | 
|  | 566 | "Fix the indentation of the current line according to Python rules." | 
|  | 567 | (interactive) | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 568 | (let* ((ci (current-indentation)) | 
|  | 569 | (move-to-indentation-p (<= (current-column) ci)) | 
|  | 570 | (need (py-compute-indentation)) ) | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 571 | (if (/= ci need) | 
|  | 572 | (save-excursion | 
|  | 573 | (beginning-of-line) | 
|  | 574 | (delete-horizontal-space) | 
|  | 575 | (indent-to need))) | 
|  | 576 | (if move-to-indentation-p (back-to-indentation)))) | 
|  | 577 |  | 
|  | 578 | (defun py-newline-and-indent () | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 579 | "Strives to act like the Emacs `newline-and-indent'. | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 580 | This is just `strives to' because correct indentation can't be computed | 
|  | 581 | from scratch for Python code.  In general, deletes the whitespace before | 
|  | 582 | point, inserts a newline, and takes an educated guess as to how you want | 
|  | 583 | the new line indented." | 
|  | 584 | (interactive) | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 585 | (let ((ci (current-indentation))) | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 586 | (if (< ci (current-column))		; if point beyond indentation | 
|  | 587 | (newline-and-indent) | 
|  | 588 | ;; else try to act like newline-and-indent "normally" acts | 
|  | 589 | (beginning-of-line) | 
|  | 590 | (insert-char ?\n 1) | 
|  | 591 | (move-to-column ci)))) | 
|  | 592 |  | 
|  | 593 | (defun py-compute-indentation () | 
|  | 594 | (save-excursion | 
|  | 595 | (beginning-of-line) | 
|  | 596 | (cond | 
|  | 597 | ;; are we on a continuation line? | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 598 | ((py-continuation-line-p) | 
|  | 599 | (let ((startpos (point)) | 
|  | 600 | (open-bracket-pos (py-nesting-level)) | 
|  | 601 | endpos searching found) | 
|  | 602 | (if open-bracket-pos | 
|  | 603 | (progn | 
|  | 604 | ;; align with first item in list; else a normal | 
|  | 605 | ;; indent beyond the line with the open bracket | 
|  | 606 | (goto-char (1+ open-bracket-pos)) ; just beyond bracket | 
|  | 607 | ;; is the first list item on the same line? | 
|  | 608 | (skip-chars-forward " \t") | 
|  | 609 | (if (null (memq (following-char) '(?\n ?# ?\\))) | 
|  | 610 | ; yes, so line up with it | 
|  | 611 | (current-column) | 
|  | 612 | ;; first list item on another line, or doesn't exist yet | 
|  | 613 | (forward-line 1) | 
|  | 614 | (while (and (< (point) startpos) | 
|  | 615 | (looking-at "[ \t]*[#\n\\\\]")) ; skip noise | 
|  | 616 | (forward-line 1)) | 
|  | 617 | (if (< (point) startpos) | 
|  | 618 | ;; again mimic the first list item | 
|  | 619 | (current-indentation) | 
|  | 620 | ;; else they're about to enter the first item | 
|  | 621 | (goto-char open-bracket-pos) | 
|  | 622 | (+ (current-indentation) py-indent-offset)))) | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 623 |  | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 624 | ;; else on backslash continuation line | 
|  | 625 | (forward-line -1) | 
|  | 626 | (if (py-continuation-line-p)	; on at least 3rd line in block | 
|  | 627 | (current-indentation)	; so just continue the pattern | 
|  | 628 | ;; else started on 2nd line in block, so indent more. | 
|  | 629 | ;; if base line is an assignment with a start on a RHS, | 
|  | 630 | ;; indent to 2 beyond the leftmost "="; else skip first | 
|  | 631 | ;; chunk of non-whitespace characters on base line, + 1 more | 
|  | 632 | ;; column | 
|  | 633 | (end-of-line) | 
|  | 634 | (setq endpos (point)  searching t) | 
|  | 635 | (back-to-indentation) | 
|  | 636 | (setq startpos (point)) | 
|  | 637 | ;; look at all "=" from left to right, stopping at first | 
|  | 638 | ;; one not nested in a list or string | 
|  | 639 | (while searching | 
|  | 640 | (skip-chars-forward "^=" endpos) | 
|  | 641 | (if (= (point) endpos) | 
|  | 642 | (setq searching nil) | 
|  | 643 | (forward-char 1) | 
|  | 644 | (setq state (parse-partial-sexp startpos (point))) | 
|  | 645 | (if (and (zerop (car state)) ; not in a bracket | 
|  | 646 | (null (nth 3 state))) ; & not in a string | 
|  | 647 | (progn | 
|  | 648 | (setq searching nil) ; done searching in any case | 
|  | 649 | (setq found | 
|  | 650 | (not (or | 
|  | 651 | (eq (following-char) ?=) | 
|  | 652 | (memq (char-after (- (point) 2)) | 
|  | 653 | '(?< ?> ?!))))))))) | 
|  | 654 | (if (or (not found)		; not an assignment | 
|  | 655 | (looking-at "[ \t]*\\\\")) ; <=><spaces><backslash> | 
|  | 656 | (progn | 
|  | 657 | (goto-char startpos) | 
|  | 658 | (skip-chars-forward "^ \t\n"))) | 
|  | 659 | (1+ (current-column)))))) | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 660 |  | 
|  | 661 | ;; not on a continuation line | 
|  | 662 |  | 
|  | 663 | ;; if at start of restriction, or on a non-indenting comment line, | 
|  | 664 | ;; assume they intended whatever's there | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 665 | ((or (bobp) (looking-at "[ \t]*#[^ \t\n]")) | 
|  | 666 | (current-indentation)) | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 667 |  | 
|  | 668 | ;; else indentation based on that of the statement that precedes | 
|  | 669 | ;; us; use the first line of that statement to establish the base, | 
|  | 670 | ;; in case the user forced a non-std indentation for the | 
|  | 671 | ;; continuation lines (if any) | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 672 | (t | 
|  | 673 | ;; skip back over blank & non-indenting comment lines | 
|  | 674 | ;; note:  will skip a blank or non-indenting comment line that | 
|  | 675 | ;; happens to be a continuation line too | 
|  | 676 | (re-search-backward "^[ \t]*\\([^ \t\n#]\\|#[ \t\n]\\)" | 
|  | 677 | nil 'move) | 
|  | 678 | ;; if we landed inside a string, go to the beginning of that | 
|  | 679 | ;; string. this handles triple quoted, multi-line spanning | 
|  | 680 | ;; strings. | 
|  | 681 | (let ((state (parse-partial-sexp | 
|  | 682 | (save-excursion (beginning-of-python-def-or-class) | 
|  | 683 | (point)) | 
|  | 684 | (point)))) | 
|  | 685 | (if (nth 3 state) | 
|  | 686 | (goto-char (nth 2 state)))) | 
|  | 687 | (py-goto-initial-line) | 
|  | 688 | (if (py-statement-opens-block-p) | 
|  | 689 | (+ (current-indentation) py-indent-offset) | 
|  | 690 | (current-indentation)))))) | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 691 |  | 
|  | 692 | (defun py-guess-indent-offset (&optional global) | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 693 | "Guess a good value for, and change, `py-indent-offset'. | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 694 | By default (without a prefix arg), makes a buffer-local copy of | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 695 | `py-indent-offset' with the new value.  This will not affect any other | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 696 | Python buffers.  With a prefix arg, changes the global value of | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 697 | `py-indent-offset'.  This affects all Python buffers (that don't have | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 698 | their own buffer-local copy), both those currently existing and those | 
|  | 699 | created later in the Emacs session. | 
|  | 700 |  | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 701 | Some people use a different value for `py-indent-offset' than you use. | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 702 | There's no excuse for such foolishness, but sometimes you have to deal | 
|  | 703 | with their ugly code anyway.  This function examines the file and sets | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 704 | `py-indent-offset' to what it thinks it was when they created the | 
|  | 705 | mess. | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 706 |  | 
|  | 707 | Specifically, it searches forward from the statement containing point, | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 708 | looking for a line that opens a block of code.  `py-indent-offset' is | 
|  | 709 | set to the difference in indentation between that line and the Python | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 710 | statement following it.  If the search doesn't succeed going forward, | 
|  | 711 | it's tried again going backward." | 
|  | 712 | (interactive "P")			; raw prefix arg | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 713 | (let (new-value | 
|  | 714 | (start (point)) | 
|  | 715 | restart | 
|  | 716 | (found nil) | 
|  | 717 | colon-indent) | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 718 | (py-goto-initial-line) | 
|  | 719 | (while (not (or found (eobp))) | 
|  | 720 | (if (re-search-forward ":[ \t]*\\($\\|[#\\]\\)" nil 'move) | 
|  | 721 | (progn | 
|  | 722 | (setq restart (point)) | 
|  | 723 | (py-goto-initial-line) | 
|  | 724 | (if (py-statement-opens-block-p) | 
|  | 725 | (setq found t) | 
|  | 726 | (goto-char restart))))) | 
|  | 727 | (if found | 
|  | 728 | () | 
|  | 729 | (goto-char start) | 
|  | 730 | (py-goto-initial-line) | 
|  | 731 | (while (not (or found (bobp))) | 
|  | 732 | (setq found | 
|  | 733 | (and | 
|  | 734 | (re-search-backward ":[ \t]*\\($\\|[#\\]\\)" nil 'move) | 
|  | 735 | (or (py-goto-initial-line) t) ; always true -- side effect | 
|  | 736 | (py-statement-opens-block-p))))) | 
|  | 737 | (setq colon-indent (current-indentation) | 
|  | 738 | found (and found (zerop (py-next-statement 1))) | 
|  | 739 | new-value (- (current-indentation) colon-indent)) | 
|  | 740 | (goto-char start) | 
|  | 741 | (if found | 
|  | 742 | (progn | 
|  | 743 | (funcall (if global 'kill-local-variable 'make-local-variable) | 
|  | 744 | 'py-indent-offset) | 
|  | 745 | (setq py-indent-offset new-value) | 
|  | 746 | (message "%s value of py-indent-offset set to %d" | 
|  | 747 | (if global "Global" "Local") | 
|  | 748 | py-indent-offset)) | 
|  | 749 | (error "Sorry, couldn't guess a value for py-indent-offset")))) | 
|  | 750 |  | 
|  | 751 | (defun py-shift-region (start end count) | 
|  | 752 | (save-excursion | 
|  | 753 | (goto-char end)   (beginning-of-line) (setq end (point)) | 
|  | 754 | (goto-char start) (beginning-of-line) (setq start (point)) | 
|  | 755 | (indent-rigidly start end count))) | 
|  | 756 |  | 
|  | 757 | (defun py-shift-region-left (start end &optional count) | 
|  | 758 | "Shift region of Python code to the left. | 
|  | 759 | The lines from the line containing the start of the current region up | 
|  | 760 | to (but not including) the line containing the end of the region are | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 761 | shifted to the left, by `py-indent-offset' columns. | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 762 |  | 
|  | 763 | If a prefix argument is given, the region is instead shifted by that | 
|  | 764 | many columns." | 
|  | 765 | (interactive "*r\nP")   ; region; raw prefix arg | 
|  | 766 | (py-shift-region start end | 
|  | 767 | (- (prefix-numeric-value | 
|  | 768 | (or count py-indent-offset))))) | 
|  | 769 |  | 
|  | 770 | (defun py-shift-region-right (start end &optional count) | 
|  | 771 | "Shift region of Python code to the right. | 
|  | 772 | The lines from the line containing the start of the current region up | 
|  | 773 | to (but not including) the line containing the end of the region are | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 774 | shifted to the right, by `py-indent-offset' columns. | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 775 |  | 
|  | 776 | If a prefix argument is given, the region is instead shifted by that | 
|  | 777 | many columns." | 
|  | 778 | (interactive "*r\nP")   ; region; raw prefix arg | 
|  | 779 | (py-shift-region start end (prefix-numeric-value | 
|  | 780 | (or count py-indent-offset)))) | 
|  | 781 |  | 
|  | 782 | (defun py-indent-region (start end &optional indent-offset) | 
|  | 783 | "Reindent a region of Python code. | 
|  | 784 | The lines from the line containing the start of the current region up | 
|  | 785 | to (but not including) the line containing the end of the region are | 
|  | 786 | reindented.  If the first line of the region has a non-whitespace | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 787 | character in the first column, the first line is left alone and the | 
|  | 788 | rest of the region is reindented with respect to it.  Else the entire | 
|  | 789 | region is reindented with respect to the (closest code or | 
|  | 790 | indenting-comment) statement immediately preceding the region. | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 791 |  | 
|  | 792 | This is useful when code blocks are moved or yanked, when enclosing | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 793 | control structures are introduced or removed, or to reformat code | 
|  | 794 | using a new value for the indentation offset. | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 795 |  | 
|  | 796 | If a numeric prefix argument is given, it will be used as the value of | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 797 | the indentation offset.  Else the value of `py-indent-offset' will be | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 798 | used. | 
|  | 799 |  | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 800 | Warning: The region must be consistently indented before this function | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 801 | is called!  This function does not compute proper indentation from | 
|  | 802 | scratch (that's impossible in Python), it merely adjusts the existing | 
|  | 803 | indentation to be correct in context. | 
|  | 804 |  | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 805 | Warning: This function really has no idea what to do with | 
|  | 806 | non-indenting comment lines, and shifts them as if they were indenting | 
|  | 807 | comment lines.  Fixing this appears to require telepathy. | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 808 |  | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 809 | Special cases: whitespace is deleted from blank lines; continuation | 
|  | 810 | lines are shifted by the same amount their initial line was shifted, | 
|  | 811 | in order to preserve their relative indentation with respect to their | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 812 | initial line; and comment lines beginning in column 1 are ignored." | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 813 | (interactive "*r\nP")			; region; raw prefix arg | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 814 | (save-excursion | 
|  | 815 | (goto-char end)   (beginning-of-line) (setq end (point-marker)) | 
|  | 816 | (goto-char start) (beginning-of-line) | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 817 | (let ((py-indent-offset (prefix-numeric-value | 
|  | 818 | (or indent-offset py-indent-offset))) | 
|  | 819 | (indents '(-1))		; stack of active indent levels | 
|  | 820 | (target-column 0)		; column to which to indent | 
|  | 821 | (base-shifted-by 0)		; amount last base line was shifted | 
|  | 822 | (indent-base (if (looking-at "[ \t\n]") | 
|  | 823 | (py-compute-indentation) | 
|  | 824 | 0)) | 
|  | 825 | ci) | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 826 | (while (< (point) end) | 
|  | 827 | (setq ci (current-indentation)) | 
|  | 828 | ;; figure out appropriate target column | 
|  | 829 | (cond | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 830 | ((or (eq (following-char) ?#)	; comment in column 1 | 
|  | 831 | (looking-at "[ \t]*$"))	; entirely blank | 
|  | 832 | (setq target-column 0)) | 
|  | 833 | ((py-continuation-line-p)	; shift relative to base line | 
|  | 834 | (setq target-column (+ ci base-shifted-by))) | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 835 | (t				; new base line | 
|  | 836 | (if (> ci (car indents))	; going deeper; push it | 
|  | 837 | (setq indents (cons ci indents)) | 
|  | 838 | ;; else we should have seen this indent before | 
|  | 839 | (setq indents (memq ci indents)) ; pop deeper indents | 
|  | 840 | (if (null indents) | 
|  | 841 | (error "Bad indentation in region, at line %d" | 
|  | 842 | (save-restriction | 
|  | 843 | (widen) | 
|  | 844 | (1+ (count-lines 1 (point))))))) | 
|  | 845 | (setq target-column (+ indent-base | 
|  | 846 | (* py-indent-offset | 
|  | 847 | (- (length indents) 2)))) | 
|  | 848 | (setq base-shifted-by (- target-column ci)))) | 
|  | 849 | ;; shift as needed | 
|  | 850 | (if (/= ci target-column) | 
|  | 851 | (progn | 
|  | 852 | (delete-horizontal-space) | 
|  | 853 | (indent-to target-column))) | 
|  | 854 | (forward-line 1)))) | 
|  | 855 | (set-marker end nil)) | 
|  | 856 |  | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 857 |  | 
|  | 858 | ;; Functions for moving point | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 859 | (defun py-previous-statement (count) | 
|  | 860 | "Go to the start of previous Python statement. | 
|  | 861 | If the statement at point is the i'th Python statement, goes to the | 
|  | 862 | start of statement i-COUNT.  If there is no such statement, goes to the | 
|  | 863 | first statement.  Returns count of statements left to move. | 
|  | 864 | `Statements' do not include blank, comment, or continuation lines." | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 865 | (interactive "p")			; numeric prefix arg | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 866 | (if (< count 0) (py-next-statement (- count)) | 
|  | 867 | (py-goto-initial-line) | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 868 | (let (start) | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 869 | (while (and | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 870 | (setq start (point))	; always true -- side effect | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 871 | (> count 0) | 
|  | 872 | (zerop (forward-line -1)) | 
|  | 873 | (py-goto-statement-at-or-above)) | 
|  | 874 | (setq count (1- count))) | 
|  | 875 | (if (> count 0) (goto-char start))) | 
|  | 876 | count)) | 
|  | 877 |  | 
|  | 878 | (defun py-next-statement (count) | 
|  | 879 | "Go to the start of next Python statement. | 
|  | 880 | If the statement at point is the i'th Python statement, goes to the | 
|  | 881 | start of statement i+COUNT.  If there is no such statement, goes to the | 
|  | 882 | last statement.  Returns count of statements left to move.  `Statements' | 
|  | 883 | do not include blank, comment, or continuation lines." | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 884 | (interactive "p")			; numeric prefix arg | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 885 | (if (< count 0) (py-previous-statement (- count)) | 
|  | 886 | (beginning-of-line) | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 887 | (let (start) | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 888 | (while (and | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 889 | (setq start (point))	; always true -- side effect | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 890 | (> count 0) | 
|  | 891 | (py-goto-statement-below)) | 
|  | 892 | (setq count (1- count))) | 
|  | 893 | (if (> count 0) (goto-char start))) | 
|  | 894 | count)) | 
|  | 895 |  | 
|  | 896 | (defun py-goto-block-up (&optional nomark) | 
|  | 897 | "Move up to start of current block. | 
|  | 898 | Go to the statement that starts the smallest enclosing block; roughly | 
|  | 899 | speaking, this will be the closest preceding statement that ends with a | 
|  | 900 | colon and is indented less than the statement you started on.  If | 
|  | 901 | successful, also sets the mark to the starting point. | 
|  | 902 |  | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 903 | `\\[py-mark-block]' can be used afterward to mark the whole code | 
|  | 904 | block, if desired. | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 905 |  | 
|  | 906 | If called from a program, the mark will not be set if optional argument | 
|  | 907 | NOMARK is not nil." | 
|  | 908 | (interactive) | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 909 | (let ((start (point)) | 
|  | 910 | (found nil) | 
|  | 911 | initial-indent) | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 912 | (py-goto-initial-line) | 
|  | 913 | ;; if on blank or non-indenting comment line, use the preceding stmt | 
|  | 914 | (if (looking-at "[ \t]*\\($\\|#[^ \t\n]\\)") | 
|  | 915 | (progn | 
|  | 916 | (py-goto-statement-at-or-above) | 
|  | 917 | (setq found (py-statement-opens-block-p)))) | 
|  | 918 | ;; search back for colon line indented less | 
|  | 919 | (setq initial-indent (current-indentation)) | 
|  | 920 | (if (zerop initial-indent) | 
|  | 921 | ;; force fast exit | 
|  | 922 | (goto-char (point-min))) | 
|  | 923 | (while (not (or found (bobp))) | 
|  | 924 | (setq found | 
|  | 925 | (and | 
|  | 926 | (re-search-backward ":[ \t]*\\($\\|[#\\]\\)" nil 'move) | 
|  | 927 | (or (py-goto-initial-line) t) ; always true -- side effect | 
|  | 928 | (< (current-indentation) initial-indent) | 
|  | 929 | (py-statement-opens-block-p)))) | 
|  | 930 | (if found | 
|  | 931 | (progn | 
|  | 932 | (or nomark (push-mark start)) | 
|  | 933 | (back-to-indentation)) | 
|  | 934 | (goto-char start) | 
|  | 935 | (error "Enclosing block not found")))) | 
|  | 936 |  | 
|  | 937 | (defun beginning-of-python-def-or-class (&optional class) | 
|  | 938 | "Move point to start of def (or class, with prefix arg). | 
|  | 939 |  | 
|  | 940 | Searches back for the closest preceding `def'.  If you supply a prefix | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 941 | arg, looks for a `class' instead.  The docs assume the `def' case; | 
|  | 942 | just substitute `class' for `def' for the other case. | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 943 |  | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 944 | If point is in a def statement already, and after the `d', simply | 
|  | 945 | moves point to the start of the statement. | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 946 |  | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 947 | Else (point is not in a def statement, or at or before the `d' of a | 
|  | 948 | def statement), searches for the closest preceding def statement, and | 
|  | 949 | leaves point at its start.  If no such statement can be found, leaves | 
|  | 950 | point at the start of the buffer. | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 951 |  | 
|  | 952 | Returns t iff a def statement is found by these rules. | 
|  | 953 |  | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 954 | Note that doing this command repeatedly will take you closer to the | 
|  | 955 | start of the buffer each time. | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 956 |  | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 957 | If you want to mark the current def/class, see | 
|  | 958 | `\\[mark-python-def-or-class]'." | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 959 | (interactive "P")			; raw prefix arg | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 960 | (let ((at-or-before-p (<= (current-column) (current-indentation))) | 
|  | 961 | (start-of-line (progn (beginning-of-line) (point))) | 
|  | 962 | (start-of-stmt (progn (py-goto-initial-line) (point)))) | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 963 | (if (or (/= start-of-stmt start-of-line) | 
|  | 964 | (not at-or-before-p)) | 
|  | 965 | (end-of-line))			; OK to match on this line | 
|  | 966 | (re-search-backward (if class "^[ \t]*class\\>" "^[ \t]*def\\>") | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 967 | nil 'move))) | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 968 |  | 
|  | 969 | (defun end-of-python-def-or-class (&optional class) | 
|  | 970 | "Move point beyond end of def (or class, with prefix arg) body. | 
|  | 971 |  | 
|  | 972 | By default, looks for an appropriate `def'.  If you supply a prefix arg, | 
|  | 973 | looks for a `class' instead.  The docs assume the `def' case; just | 
|  | 974 | substitute `class' for `def' for the other case. | 
|  | 975 |  | 
|  | 976 | If point is in a def statement already, this is the def we use. | 
|  | 977 |  | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 978 | Else if the def found by `\\[beginning-of-python-def-or-class]' | 
|  | 979 | contains the statement you started on, that's the def we use. | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 980 |  | 
|  | 981 | Else we search forward for the closest following def, and use that. | 
|  | 982 |  | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 983 | If a def can be found by these rules, point is moved to the start of | 
|  | 984 | the line immediately following the def block, and the position of the | 
|  | 985 | start of the def is returned. | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 986 |  | 
|  | 987 | Else point is moved to the end of the buffer, and nil is returned. | 
|  | 988 |  | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 989 | Note that doing this command repeatedly will take you closer to the | 
|  | 990 | end of the buffer each time. | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 991 |  | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 992 | If you want to mark the current def/class, see | 
|  | 993 | `\\[mark-python-def-or-class]'." | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 994 | (interactive "P")			; raw prefix arg | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 995 | (let ((start (progn (py-goto-initial-line) (point))) | 
|  | 996 | (which (if class "class" "def")) | 
|  | 997 | (state 'not-found)) | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 998 | ;; move point to start of appropriate def/class | 
|  | 999 | (if (looking-at (concat "[ \t]*" which "\\>")) ; already on one | 
|  | 1000 | (setq state 'at-beginning) | 
|  | 1001 | ;; else see if beginning-of-python-def-or-class hits container | 
|  | 1002 | (if (and (beginning-of-python-def-or-class class) | 
|  | 1003 | (progn (py-goto-beyond-block) | 
|  | 1004 | (> (point) start))) | 
|  | 1005 | (setq state 'at-end) | 
|  | 1006 | ;; else search forward | 
|  | 1007 | (goto-char start) | 
|  | 1008 | (if (re-search-forward (concat "^[ \t]*" which "\\>") nil 'move) | 
|  | 1009 | (progn (setq state 'at-beginning) | 
|  | 1010 | (beginning-of-line))))) | 
|  | 1011 | (cond | 
|  | 1012 | ((eq state 'at-beginning) (py-goto-beyond-block) t) | 
|  | 1013 | ((eq state 'at-end) t) | 
|  | 1014 | ((eq state 'not-found) nil) | 
|  | 1015 | (t (error "internal error in end-of-python-def-or-class"))))) | 
|  | 1016 |  | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 1017 |  | 
|  | 1018 | ;; Functions for marking regions | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 1019 | (defun py-mark-block (&optional extend just-move) | 
|  | 1020 | "Mark following block of lines.  With prefix arg, mark structure. | 
|  | 1021 | Easier to use than explain.  It sets the region to an `interesting' | 
|  | 1022 | block of succeeding lines.  If point is on a blank line, it goes down to | 
|  | 1023 | the next non-blank line.  That will be the start of the region.  The end | 
|  | 1024 | of the region depends on the kind of line at the start: | 
|  | 1025 |  | 
|  | 1026 | - If a comment, the region will include all succeeding comment lines up | 
|  | 1027 | to (but not including) the next non-comment line (if any). | 
|  | 1028 |  | 
|  | 1029 | - Else if a prefix arg is given, and the line begins one of these | 
|  | 1030 | structures: | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 1031 |  | 
|  | 1032 | if elif else try except finally for while def class | 
|  | 1033 |  | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 1034 | the region will be set to the body of the structure, including | 
|  | 1035 | following blocks that `belong' to it, but excluding trailing blank | 
|  | 1036 | and comment lines.  E.g., if on a `try' statement, the `try' block | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 1037 | and all (if any) of the following `except' and `finally' blocks | 
|  | 1038 | that belong to the `try' structure will be in the region.  Ditto | 
|  | 1039 | for if/elif/else, for/else and while/else structures, and (a bit | 
|  | 1040 | degenerate, since they're always one-block structures) def and | 
|  | 1041 | class blocks. | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 1042 |  | 
|  | 1043 | - Else if no prefix argument is given, and the line begins a Python | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 1044 | block (see list above), and the block is not a `one-liner' (i.e., | 
|  | 1045 | the statement ends with a colon, not with code), the region will | 
|  | 1046 | include all succeeding lines up to (but not including) the next | 
|  | 1047 | code statement (if any) that's indented no more than the starting | 
|  | 1048 | line, except that trailing blank and comment lines are excluded. | 
|  | 1049 | E.g., if the starting line begins a multi-statement `def' | 
|  | 1050 | structure, the region will be set to the full function definition, | 
|  | 1051 | but without any trailing `noise' lines. | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 1052 |  | 
|  | 1053 | - Else the region will include all succeeding lines up to (but not | 
|  | 1054 | including) the next blank line, or code or indenting-comment line | 
|  | 1055 | indented strictly less than the starting line.  Trailing indenting | 
|  | 1056 | comment lines are included in this case, but not trailing blank | 
|  | 1057 | lines. | 
|  | 1058 |  | 
|  | 1059 | A msg identifying the location of the mark is displayed in the echo | 
|  | 1060 | area; or do `\\[exchange-point-and-mark]' to flip down to the end. | 
|  | 1061 |  | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 1062 | If called from a program, optional argument EXTEND plays the role of | 
|  | 1063 | the prefix arg, and if optional argument JUST-MOVE is not nil, just | 
|  | 1064 | moves to the end of the block (& does not set mark or display a msg)." | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 1065 | (interactive "P")			; raw prefix arg | 
|  | 1066 | (py-goto-initial-line) | 
|  | 1067 | ;; skip over blank lines | 
|  | 1068 | (while (and | 
|  | 1069 | (looking-at "[ \t]*$")	; while blank line | 
|  | 1070 | (not (eobp)))			; & somewhere to go | 
|  | 1071 | (forward-line 1)) | 
|  | 1072 | (if (eobp) | 
|  | 1073 | (error "Hit end of buffer without finding a non-blank stmt")) | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 1074 | (let ((initial-pos (point)) | 
|  | 1075 | (initial-indent (current-indentation)) | 
|  | 1076 | last-pos			; position of last stmt in region | 
|  | 1077 | (followers | 
|  | 1078 | '((if elif else) (elif elif else) (else) | 
|  | 1079 | (try except finally) (except except) (finally) | 
|  | 1080 | (for else) (while else) | 
|  | 1081 | (def) (class) ) ) | 
|  | 1082 | first-symbol next-symbol) | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 1083 |  | 
|  | 1084 | (cond | 
|  | 1085 | ;; if comment line, suck up the following comment lines | 
|  | 1086 | ((looking-at "[ \t]*#") | 
|  | 1087 | (re-search-forward "^[ \t]*[^ \t#]" nil 'move) ; look for non-comment | 
|  | 1088 | (re-search-backward "^[ \t]*#")	; and back to last comment in block | 
|  | 1089 | (setq last-pos (point))) | 
|  | 1090 |  | 
|  | 1091 | ;; else if line is a block line and EXTEND given, suck up | 
|  | 1092 | ;; the whole structure | 
|  | 1093 | ((and extend | 
|  | 1094 | (setq first-symbol (py-suck-up-first-keyword) ) | 
|  | 1095 | (assq first-symbol followers)) | 
|  | 1096 | (while (and | 
|  | 1097 | (or (py-goto-beyond-block) t) ; side effect | 
|  | 1098 | (forward-line -1)		; side effect | 
|  | 1099 | (setq last-pos (point))	; side effect | 
|  | 1100 | (py-goto-statement-below) | 
|  | 1101 | (= (current-indentation) initial-indent) | 
|  | 1102 | (setq next-symbol (py-suck-up-first-keyword)) | 
|  | 1103 | (memq next-symbol (cdr (assq first-symbol followers)))) | 
|  | 1104 | (setq first-symbol next-symbol))) | 
|  | 1105 |  | 
|  | 1106 | ;; else if line *opens* a block, search for next stmt indented <= | 
|  | 1107 | ((py-statement-opens-block-p) | 
|  | 1108 | (while (and | 
|  | 1109 | (setq last-pos (point))	; always true -- side effect | 
|  | 1110 | (py-goto-statement-below) | 
|  | 1111 | (> (current-indentation) initial-indent)) | 
|  | 1112 | nil)) | 
|  | 1113 |  | 
|  | 1114 | ;; else plain code line; stop at next blank line, or stmt or | 
|  | 1115 | ;; indenting comment line indented < | 
|  | 1116 | (t | 
|  | 1117 | (while (and | 
|  | 1118 | (setq last-pos (point))	; always true -- side effect | 
|  | 1119 | (or (py-goto-beyond-final-line) t) | 
|  | 1120 | (not (looking-at "[ \t]*$")) ; stop at blank line | 
|  | 1121 | (or | 
|  | 1122 | (>= (current-indentation) initial-indent) | 
|  | 1123 | (looking-at "[ \t]*#[^ \t\n]"))) ; ignore non-indenting # | 
|  | 1124 | nil))) | 
|  | 1125 |  | 
|  | 1126 | ;; skip to end of last stmt | 
|  | 1127 | (goto-char last-pos) | 
|  | 1128 | (py-goto-beyond-final-line) | 
|  | 1129 |  | 
|  | 1130 | ;; set mark & display | 
|  | 1131 | (if just-move | 
|  | 1132 | ()				; just return | 
|  | 1133 | (push-mark (point) 'no-msg) | 
|  | 1134 | (forward-line -1) | 
|  | 1135 | (message "Mark set after: %s" (py-suck-up-leading-text)) | 
|  | 1136 | (goto-char initial-pos)))) | 
|  | 1137 |  | 
|  | 1138 | (defun mark-python-def-or-class (&optional class) | 
|  | 1139 | "Set region to body of def (or class, with prefix arg) enclosing point. | 
|  | 1140 | Pushes the current mark, then point, on the mark ring (all language | 
|  | 1141 | modes do this, but although it's handy it's never documented ...). | 
|  | 1142 |  | 
|  | 1143 | In most Emacs language modes, this function bears at least a | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 1144 | hallucinogenic resemblance to `\\[end-of-python-def-or-class]' and | 
|  | 1145 | `\\[beginning-of-python-def-or-class]'. | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 1146 |  | 
|  | 1147 | And in earlier versions of Python mode, all 3 were tightly connected. | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 1148 | Turned out that was more confusing than useful: the `goto start' and | 
|  | 1149 | `goto end' commands are usually used to search through a file, and | 
|  | 1150 | people expect them to act a lot like `search backward' and `search | 
|  | 1151 | forward' string-search commands.  But because Python `def' and `class' | 
|  | 1152 | can nest to arbitrary levels, finding the smallest def containing | 
|  | 1153 | point cannot be done via a simple backward search: the def containing | 
|  | 1154 | point may not be the closest preceding def, or even the closest | 
|  | 1155 | preceding def that's indented less.  The fancy algorithm required is | 
|  | 1156 | appropriate for the usual uses of this `mark' command, but not for the | 
|  | 1157 | `goto' variations. | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 1158 |  | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 1159 | So the def marked by this command may not be the one either of the | 
|  | 1160 | `goto' commands find: If point is on a blank or non-indenting comment | 
|  | 1161 | line, moves back to start of the closest preceding code statement or | 
|  | 1162 | indenting comment line.  If this is a `def' statement, that's the def | 
|  | 1163 | we use.  Else searches for the smallest enclosing `def' block and uses | 
|  | 1164 | that.  Else signals an error. | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 1165 |  | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 1166 | When an enclosing def is found: The mark is left immediately beyond | 
|  | 1167 | the last line of the def block.  Point is left at the start of the | 
|  | 1168 | def, except that: if the def is preceded by a number of comment lines | 
|  | 1169 | followed by (at most) one optional blank line, point is left at the | 
|  | 1170 | start of the comments; else if the def is preceded by a blank line, | 
|  | 1171 | point is left at its start. | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 1172 |  | 
|  | 1173 | The intent is to mark the containing def/class and its associated | 
|  | 1174 | documentation, to make moving and duplicating functions and classes | 
|  | 1175 | pleasant." | 
|  | 1176 | (interactive "P")			; raw prefix arg | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 1177 | (let ((start (point)) | 
|  | 1178 | (which (if class "class" "def"))) | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 1179 | (push-mark start) | 
|  | 1180 | (if (not (py-go-up-tree-to-keyword which)) | 
|  | 1181 | (progn (goto-char start) | 
|  | 1182 | (error "Enclosing %s not found" which)) | 
|  | 1183 | ;; else enclosing def/class found | 
|  | 1184 | (setq start (point)) | 
|  | 1185 | (py-goto-beyond-block) | 
|  | 1186 | (push-mark (point)) | 
|  | 1187 | (goto-char start) | 
|  | 1188 | (if (zerop (forward-line -1))	; if there is a preceding line | 
|  | 1189 | (progn | 
|  | 1190 | (if (looking-at "[ \t]*$")	; it's blank | 
|  | 1191 | (setq start (point))	; so reset start point | 
|  | 1192 | (goto-char start))	; else try again | 
|  | 1193 | (if (zerop (forward-line -1)) | 
|  | 1194 | (if (looking-at "[ \t]*#") ; a comment | 
|  | 1195 | ;; look back for non-comment line | 
|  | 1196 | ;; tricky: note that the regexp matches a blank | 
|  | 1197 | ;; line, cuz \n is in the 2nd character class | 
|  | 1198 | (and | 
|  | 1199 | (re-search-backward "^[ \t]*[^ \t#]" nil 'move) | 
|  | 1200 | (forward-line 1)) | 
|  | 1201 | ;; no comment, so go back | 
|  | 1202 | (goto-char start)))))))) | 
|  | 1203 |  | 
|  | 1204 | (defun py-comment-region (start end &optional uncomment-p) | 
|  | 1205 | "Comment out region of code; with prefix arg, uncomment region. | 
|  | 1206 | The lines from the line containing the start of the current region up | 
|  | 1207 | to (but not including) the line containing the end of the region are | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 1208 | commented out, by inserting the string `py-block-comment-prefix' at | 
|  | 1209 | the start of each line.  With a prefix arg, removes | 
|  | 1210 | `py-block-comment-prefix' from the start of each line instead." | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 1211 | (interactive "*r\nP")   ; region; raw prefix arg | 
|  | 1212 | (goto-char end)   (beginning-of-line) (setq end (point)) | 
|  | 1213 | (goto-char start) (beginning-of-line) (setq start (point)) | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 1214 | (let ((prefix-len (length py-block-comment-prefix)) ) | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 1215 | (save-excursion | 
|  | 1216 | (save-restriction | 
|  | 1217 | (narrow-to-region start end) | 
|  | 1218 | (while (not (eobp)) | 
|  | 1219 | (if uncomment-p | 
|  | 1220 | (and (string= py-block-comment-prefix | 
|  | 1221 | (buffer-substring | 
|  | 1222 | (point) (+ (point) prefix-len))) | 
|  | 1223 | (delete-char prefix-len)) | 
|  | 1224 | (insert py-block-comment-prefix)) | 
|  | 1225 | (forward-line 1)))))) | 
|  | 1226 |  | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 1227 |  | 
|  | 1228 | ;; Documentation functions | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 1229 |  | 
|  | 1230 | ;; dump the long form of the mode blurb; does the usual doc escapes, | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 1231 | ;; plus lines of the form ^[vc]:name$ to suck variable & command docs | 
|  | 1232 | ;; out of the right places, along with the keys they're on & current | 
|  | 1233 | ;; values | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 1234 | (defun py-dump-help-string (str) | 
|  | 1235 | (with-output-to-temp-buffer "*Help*" | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 1236 | (let ((locals (buffer-local-variables)) | 
|  | 1237 | funckind funcname func funcdoc | 
|  | 1238 | (start 0) mstart end | 
|  | 1239 | keys ) | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 1240 | (while (string-match "^%\\([vc]\\):\\(.+\\)\n" str start) | 
|  | 1241 | (setq mstart (match-beginning 0)  end (match-end 0) | 
|  | 1242 | funckind (substring str (match-beginning 1) (match-end 1)) | 
|  | 1243 | funcname (substring str (match-beginning 2) (match-end 2)) | 
|  | 1244 | func (intern funcname)) | 
|  | 1245 | (princ (substitute-command-keys (substring str start mstart))) | 
|  | 1246 | (cond | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 1247 | ((equal funckind "c")		; command | 
|  | 1248 | (setq funcdoc (documentation func) | 
|  | 1249 | keys (concat | 
|  | 1250 | "Key(s): " | 
|  | 1251 | (mapconcat 'key-description | 
|  | 1252 | (where-is-internal func py-mode-map) | 
|  | 1253 | ", ")))) | 
|  | 1254 | ((equal funckind "v")		; variable | 
|  | 1255 | (setq funcdoc (substitute-command-keys | 
|  | 1256 | (get func 'variable-documentation)) | 
|  | 1257 | keys (if (assq func locals) | 
|  | 1258 | (concat | 
|  | 1259 | "Local/Global values: " | 
|  | 1260 | (prin1-to-string (symbol-value func)) | 
|  | 1261 | " / " | 
|  | 1262 | (prin1-to-string (default-value func))) | 
|  | 1263 | (concat | 
|  | 1264 | "Value: " | 
|  | 1265 | (prin1-to-string (symbol-value func)))))) | 
|  | 1266 | (t				; unexpected | 
|  | 1267 | (error "Error in py-dump-help-string, tag `%s'" funckind))) | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 1268 | (princ (format "\n-> %s:\t%s\t%s\n\n" | 
|  | 1269 | (if (equal funckind "c") "Command" "Variable") | 
|  | 1270 | funcname keys)) | 
|  | 1271 | (princ funcdoc) | 
|  | 1272 | (terpri) | 
|  | 1273 | (setq start end)) | 
|  | 1274 | (princ (substitute-command-keys (substring str start)))) | 
|  | 1275 | (print-help-return-message))) | 
|  | 1276 |  | 
|  | 1277 | (defun py-describe-mode () | 
|  | 1278 | "Dump long form of Python-mode docs." | 
|  | 1279 | (interactive) | 
|  | 1280 | (py-dump-help-string "Major mode for editing Python files. | 
|  | 1281 | Knows about Python indentation, tokens, comments and continuation lines. | 
|  | 1282 | Paragraphs are separated by blank lines only. | 
|  | 1283 |  | 
|  | 1284 | Major sections below begin with the string `@'; specific function and | 
|  | 1285 | variable docs begin with `->'. | 
|  | 1286 |  | 
|  | 1287 | @EXECUTING PYTHON CODE | 
|  | 1288 |  | 
|  | 1289 | \\[py-execute-buffer]\tsends the entire buffer to the Python interpreter | 
|  | 1290 | \\[py-execute-region]\tsends the current region | 
|  | 1291 | \\[py-shell]\tstarts a Python interpreter window; this will be used by | 
|  | 1292 | \tsubsequent \\[py-execute-buffer] or \\[py-execute-region] commands | 
|  | 1293 | %c:py-execute-buffer | 
|  | 1294 | %c:py-execute-region | 
|  | 1295 | %c:py-shell | 
|  | 1296 |  | 
|  | 1297 | @VARIABLES | 
|  | 1298 |  | 
|  | 1299 | py-indent-offset\tindentation increment | 
|  | 1300 | py-block-comment-prefix\tcomment string used by py-comment-region | 
|  | 1301 |  | 
|  | 1302 | py-python-command\tshell command to invoke Python interpreter | 
|  | 1303 | py-scroll-process-buffer\talways scroll Python process buffer | 
|  | 1304 | py-temp-directory\tdirectory used for temp files (if needed) | 
|  | 1305 |  | 
|  | 1306 | py-beep-if-tab-change\tring the bell if tab-width is changed | 
|  | 1307 | %v:py-indent-offset | 
|  | 1308 | %v:py-block-comment-prefix | 
|  | 1309 | %v:py-python-command | 
|  | 1310 | %v:py-scroll-process-buffer | 
|  | 1311 | %v:py-temp-directory | 
|  | 1312 | %v:py-beep-if-tab-change | 
|  | 1313 |  | 
|  | 1314 | @KINDS OF LINES | 
|  | 1315 |  | 
|  | 1316 | Each physical line in the file is either a `continuation line' (the | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 1317 | preceding line ends with a backslash that's not part of a comment, or | 
|  | 1318 | the paren/bracket/brace nesting level at the start of the line is | 
|  | 1319 | non-zero, or both) or an `initial line' (everything else). | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 1320 |  | 
|  | 1321 | An initial line is in turn a `blank line' (contains nothing except | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 1322 | possibly blanks or tabs), a `comment line' (leftmost non-blank | 
|  | 1323 | character is `#'), or a `code line' (everything else). | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 1324 |  | 
|  | 1325 | Comment Lines | 
|  | 1326 |  | 
|  | 1327 | Although all comment lines are treated alike by Python, Python mode | 
|  | 1328 | recognizes two kinds that act differently with respect to indentation. | 
|  | 1329 |  | 
|  | 1330 | An `indenting comment line' is a comment line with a blank, tab or | 
|  | 1331 | nothing after the initial `#'.  The indentation commands (see below) | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 1332 | treat these exactly as if they were code lines: a line following an | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 1333 | indenting comment line will be indented like the comment line.  All | 
|  | 1334 | other comment lines (those with a non-whitespace character immediately | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 1335 | following the initial `#') are `non-indenting comment lines', and | 
|  | 1336 | their indentation is ignored by the indentation commands. | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 1337 |  | 
|  | 1338 | Indenting comment lines are by far the usual case, and should be used | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 1339 | whenever possible.  Non-indenting comment lines are useful in cases | 
|  | 1340 | like these: | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 1341 |  | 
|  | 1342 | \ta = b   # a very wordy single-line comment that ends up being | 
|  | 1343 | \t        #... continued onto another line | 
|  | 1344 |  | 
|  | 1345 | \tif a == b: | 
|  | 1346 | ##\t\tprint 'panic!' # old code we've `commented out' | 
|  | 1347 | \t\treturn a | 
|  | 1348 |  | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 1349 | Since the `#...' and `##' comment lines have a non-whitespace | 
|  | 1350 | character following the initial `#', Python mode ignores them when | 
|  | 1351 | computing the proper indentation for the next line. | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 1352 |  | 
|  | 1353 | Continuation Lines and Statements | 
|  | 1354 |  | 
|  | 1355 | The Python-mode commands generally work on statements instead of on | 
|  | 1356 | individual lines, where a `statement' is a comment or blank line, or a | 
|  | 1357 | code line and all of its following continuation lines (if any) | 
|  | 1358 | considered as a single logical unit.  The commands in this mode | 
|  | 1359 | generally (when it makes sense) automatically move to the start of the | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 1360 | statement containing point, even if point happens to be in the middle | 
|  | 1361 | of some continuation line. | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 1362 |  | 
|  | 1363 |  | 
|  | 1364 | @INDENTATION | 
|  | 1365 |  | 
|  | 1366 | Primarily for entering new code: | 
|  | 1367 | \t\\[indent-for-tab-command]\t indent line appropriately | 
|  | 1368 | \t\\[py-newline-and-indent]\t insert newline, then indent | 
|  | 1369 | \t\\[py-delete-char]\t reduce indentation, or delete single character | 
|  | 1370 |  | 
|  | 1371 | Primarily for reindenting existing code: | 
|  | 1372 | \t\\[py-guess-indent-offset]\t guess py-indent-offset from file content; change locally | 
|  | 1373 | \t\\[universal-argument] \\[py-guess-indent-offset]\t ditto, but change globally | 
|  | 1374 |  | 
|  | 1375 | \t\\[py-indent-region]\t reindent region to match its context | 
|  | 1376 | \t\\[py-shift-region-left]\t shift region left by py-indent-offset | 
|  | 1377 | \t\\[py-shift-region-right]\t shift region right by py-indent-offset | 
|  | 1378 |  | 
|  | 1379 | Unlike most programming languages, Python uses indentation, and only | 
|  | 1380 | indentation, to specify block structure.  Hence the indentation supplied | 
|  | 1381 | automatically by Python-mode is just an educated guess:  only you know | 
|  | 1382 | the block structure you intend, so only you can supply correct | 
|  | 1383 | indentation. | 
|  | 1384 |  | 
|  | 1385 | The \\[indent-for-tab-command] and \\[py-newline-and-indent] keys try to suggest plausible indentation, based on | 
|  | 1386 | the indentation of preceding statements.  E.g., assuming | 
|  | 1387 | py-indent-offset is 4, after you enter | 
|  | 1388 | \tif a > 0: \\[py-newline-and-indent] | 
|  | 1389 | the cursor will be moved to the position of the `_' (_ is not a | 
|  | 1390 | character in the file, it's just used here to indicate the location of | 
|  | 1391 | the cursor): | 
|  | 1392 | \tif a > 0: | 
|  | 1393 | \t    _ | 
|  | 1394 | If you then enter `c = d' \\[py-newline-and-indent], the cursor will move | 
|  | 1395 | to | 
|  | 1396 | \tif a > 0: | 
|  | 1397 | \t    c = d | 
|  | 1398 | \t    _ | 
|  | 1399 | Python-mode cannot know whether that's what you intended, or whether | 
|  | 1400 | \tif a > 0: | 
|  | 1401 | \t    c = d | 
|  | 1402 | \t_ | 
|  | 1403 | was your intent.  In general, Python-mode either reproduces the | 
|  | 1404 | indentation of the (closest code or indenting-comment) preceding | 
|  | 1405 | statement, or adds an extra py-indent-offset blanks if the preceding | 
|  | 1406 | statement has `:' as its last significant (non-whitespace and non- | 
|  | 1407 | comment) character.  If the suggested indentation is too much, use | 
|  | 1408 | \\[py-delete-char] to reduce it. | 
|  | 1409 |  | 
|  | 1410 | Continuation lines are given extra indentation.  If you don't like the | 
|  | 1411 | suggested indentation, change it to something you do like, and Python- | 
|  | 1412 | mode will strive to indent later lines of the statement in the same way. | 
|  | 1413 |  | 
|  | 1414 | If a line is a continuation line by virtue of being in an unclosed | 
|  | 1415 | paren/bracket/brace structure (`list', for short), the suggested | 
|  | 1416 | indentation depends on whether the current line contains the first item | 
|  | 1417 | in the list.  If it does, it's indented py-indent-offset columns beyond | 
|  | 1418 | the indentation of the line containing the open bracket.  If you don't | 
|  | 1419 | like that, change it by hand.  The remaining items in the list will mimic | 
|  | 1420 | whatever indentation you give to the first item. | 
|  | 1421 |  | 
|  | 1422 | If a line is a continuation line because the line preceding it ends with | 
|  | 1423 | a backslash, the third and following lines of the statement inherit their | 
|  | 1424 | indentation from the line preceding them.  The indentation of the second | 
|  | 1425 | line in the statement depends on the form of the first (base) line:  if | 
|  | 1426 | the base line is an assignment statement with anything more interesting | 
|  | 1427 | than the backslash following the leftmost assigning `=', the second line | 
|  | 1428 | is indented two columns beyond that `='.  Else it's indented to two | 
|  | 1429 | columns beyond the leftmost solid chunk of non-whitespace characters on | 
|  | 1430 | the base line. | 
|  | 1431 |  | 
|  | 1432 | Warning:  indent-region should not normally be used!  It calls \\[indent-for-tab-command] | 
|  | 1433 | repeatedly, and as explained above, \\[indent-for-tab-command] can't guess the block | 
|  | 1434 | structure you intend. | 
|  | 1435 | %c:indent-for-tab-command | 
|  | 1436 | %c:py-newline-and-indent | 
|  | 1437 | %c:py-delete-char | 
|  | 1438 |  | 
|  | 1439 |  | 
|  | 1440 | The next function may be handy when editing code you didn't write: | 
|  | 1441 | %c:py-guess-indent-offset | 
|  | 1442 |  | 
|  | 1443 |  | 
|  | 1444 | The remaining `indent' functions apply to a region of Python code.  They | 
|  | 1445 | assume the block structure (equals indentation, in Python) of the region | 
|  | 1446 | is correct, and alter the indentation in various ways while preserving | 
|  | 1447 | the block structure: | 
|  | 1448 | %c:py-indent-region | 
|  | 1449 | %c:py-shift-region-left | 
|  | 1450 | %c:py-shift-region-right | 
|  | 1451 |  | 
|  | 1452 | @MARKING & MANIPULATING REGIONS OF CODE | 
|  | 1453 |  | 
|  | 1454 | \\[py-mark-block]\t mark block of lines | 
|  | 1455 | \\[mark-python-def-or-class]\t mark smallest enclosing def | 
|  | 1456 | \\[universal-argument] \\[mark-python-def-or-class]\t mark smallest enclosing class | 
|  | 1457 | \\[py-comment-region]\t comment out region of code | 
|  | 1458 | \\[universal-argument] \\[py-comment-region]\t uncomment region of code | 
|  | 1459 | %c:py-mark-block | 
|  | 1460 | %c:mark-python-def-or-class | 
|  | 1461 | %c:py-comment-region | 
|  | 1462 |  | 
|  | 1463 | @MOVING POINT | 
|  | 1464 |  | 
|  | 1465 | \\[py-previous-statement]\t move to statement preceding point | 
|  | 1466 | \\[py-next-statement]\t move to statement following point | 
|  | 1467 | \\[py-goto-block-up]\t move up to start of current block | 
|  | 1468 | \\[beginning-of-python-def-or-class]\t move to start of def | 
|  | 1469 | \\[universal-argument] \\[beginning-of-python-def-or-class]\t move to start of class | 
|  | 1470 | \\[end-of-python-def-or-class]\t move to end of def | 
|  | 1471 | \\[universal-argument] \\[end-of-python-def-or-class]\t move to end of class | 
|  | 1472 |  | 
|  | 1473 | The first two move to one statement beyond the statement that contains | 
|  | 1474 | point.  A numeric prefix argument tells them to move that many | 
|  | 1475 | statements instead.  Blank lines, comment lines, and continuation lines | 
|  | 1476 | do not count as `statements' for these commands.  So, e.g., you can go | 
|  | 1477 | to the first code statement in a file by entering | 
|  | 1478 | \t\\[beginning-of-buffer]\t to move to the top of the file | 
|  | 1479 | \t\\[py-next-statement]\t to skip over initial comments and blank lines | 
|  | 1480 | Or do `\\[py-previous-statement]' with a huge prefix argument. | 
|  | 1481 | %c:py-previous-statement | 
|  | 1482 | %c:py-next-statement | 
|  | 1483 | %c:py-goto-block-up | 
|  | 1484 | %c:beginning-of-python-def-or-class | 
|  | 1485 | %c:end-of-python-def-or-class | 
|  | 1486 |  | 
|  | 1487 | @LITTLE-KNOWN EMACS COMMANDS PARTICULARLY USEFUL IN PYTHON MODE | 
|  | 1488 |  | 
|  | 1489 | `\\[indent-new-comment-line]' is handy for entering a multi-line comment. | 
|  | 1490 |  | 
|  | 1491 | `\\[set-selective-display]' with a `small' prefix arg is ideally suited for viewing the | 
|  | 1492 | overall class and def structure of a module. | 
|  | 1493 |  | 
|  | 1494 | `\\[back-to-indentation]' moves point to a line's first non-blank character. | 
|  | 1495 |  | 
|  | 1496 | `\\[indent-relative]' is handy for creating odd indentation. | 
|  | 1497 |  | 
|  | 1498 | @OTHER EMACS HINTS | 
|  | 1499 |  | 
|  | 1500 | If you don't like the default value of a variable, change its value to | 
|  | 1501 | whatever you do like by putting a `setq' line in your .emacs file. | 
|  | 1502 | E.g., to set the indentation increment to 4, put this line in your | 
|  | 1503 | .emacs: | 
|  | 1504 | \t(setq  py-indent-offset  4) | 
|  | 1505 | To see the value of a variable, do `\\[describe-variable]' and enter the variable | 
|  | 1506 | name at the prompt. | 
|  | 1507 |  | 
|  | 1508 | When entering a key sequence like `C-c C-n', it is not necessary to | 
|  | 1509 | release the CONTROL key after doing the `C-c' part -- it suffices to | 
|  | 1510 | press the CONTROL key, press and release `c' (while still holding down | 
|  | 1511 | CONTROL), press and release `n' (while still holding down CONTROL), & | 
|  | 1512 | then release CONTROL. | 
|  | 1513 |  | 
|  | 1514 | Entering Python mode calls with no arguments the value of the variable | 
|  | 1515 | `python-mode-hook', if that value exists and is not nil; for backward | 
|  | 1516 | compatibility it also tries `py-mode-hook'; see the `Hooks' section of | 
|  | 1517 | the Elisp manual for details. | 
|  | 1518 |  | 
|  | 1519 | Obscure:  When python-mode is first loaded, it looks for all bindings | 
|  | 1520 | to newline-and-indent in the global keymap, and shadows them with | 
|  | 1521 | local bindings to py-newline-and-indent.")) | 
|  | 1522 |  | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 1523 |  | 
|  | 1524 | ;; Helper functions | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 1525 |  | 
|  | 1526 | (defvar py-parse-state-re | 
|  | 1527 | (concat | 
|  | 1528 | "^[ \t]*\\(if\\|elif\\|else\\|while\\|def\\|class\\)\\>" | 
|  | 1529 | "\\|" | 
|  | 1530 | "^[^ #\t\n]")) | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 1531 |  | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 1532 | ;; returns the parse state at point (see parse-partial-sexp docs) | 
|  | 1533 | (defun py-parse-state () | 
|  | 1534 | (save-excursion | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 1535 | (let ((here (point)) ) | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 1536 | ;; back up to the first preceding line (if any; else start of | 
|  | 1537 | ;; buffer) that begins with a popular Python keyword, or a non- | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 1538 | ;; whitespace and non-comment character.  These are good places | 
|  | 1539 | ;; to start parsing to see whether where we started is at a | 
|  | 1540 | ;; non-zero nesting level.  It may be slow for people who write | 
|  | 1541 | ;; huge code blocks or huge lists ... tough beans. | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 1542 | (re-search-backward py-parse-state-re nil 'move) | 
|  | 1543 | (beginning-of-line) | 
|  | 1544 | (parse-partial-sexp (point) here)))) | 
|  | 1545 |  | 
|  | 1546 | ;; if point is at a non-zero nesting level, returns the number of the | 
|  | 1547 | ;; character that opens the smallest enclosing unclosed list; else | 
|  | 1548 | ;; returns nil. | 
|  | 1549 | (defun py-nesting-level () | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 1550 | (let ((status (py-parse-state)) ) | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 1551 | (if (zerop (car status)) | 
|  | 1552 | nil				; not in a nest | 
|  | 1553 | (car (cdr status)))))		; char# of open bracket | 
|  | 1554 |  | 
|  | 1555 | ;; t iff preceding line ends with backslash that's not in a comment | 
|  | 1556 | (defun py-backslash-continuation-line-p () | 
|  | 1557 | (save-excursion | 
|  | 1558 | (beginning-of-line) | 
|  | 1559 | (and | 
|  | 1560 | ;; use a cheap test first to avoid the regexp if possible | 
|  | 1561 | ;; use 'eq' because char-after may return nil | 
|  | 1562 | (eq (char-after (- (point) 2)) ?\\ ) | 
|  | 1563 | ;; make sure; since eq test passed, there is a preceding line | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 1564 | (forward-line -1)			; always true -- side effect | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 1565 | (looking-at py-continued-re)))) | 
|  | 1566 |  | 
|  | 1567 | ;; t iff current line is a continuation line | 
|  | 1568 | (defun py-continuation-line-p () | 
|  | 1569 | (save-excursion | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 1570 | (beginning-of-line) | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 1571 | (or (py-backslash-continuation-line-p) | 
|  | 1572 | (py-nesting-level)))) | 
|  | 1573 |  | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 1574 | ;; go to initial line of current statement; usually this is the line | 
|  | 1575 | ;; we're on, but if we're on the 2nd or following lines of a | 
|  | 1576 | ;; continuation block, we need to go up to the first line of the | 
|  | 1577 | ;; block. | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 1578 | ;; | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 1579 | ;; Tricky: We want to avoid quadratic-time behavior for long continued | 
|  | 1580 | ;; blocks, whether of the backslash or open-bracket varieties, or a | 
|  | 1581 | ;; mix of the two.  The following manages to do that in the usual | 
|  | 1582 | ;; cases. | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 1583 | (defun py-goto-initial-line () | 
|  | 1584 | (let ( open-bracket-pos ) | 
|  | 1585 | (while (py-continuation-line-p) | 
|  | 1586 | (beginning-of-line) | 
|  | 1587 | (if (py-backslash-continuation-line-p) | 
|  | 1588 | (while (py-backslash-continuation-line-p) | 
|  | 1589 | (forward-line -1)) | 
|  | 1590 | ;; else zip out of nested brackets/braces/parens | 
|  | 1591 | (while (setq open-bracket-pos (py-nesting-level)) | 
|  | 1592 | (goto-char open-bracket-pos))))) | 
|  | 1593 | (beginning-of-line)) | 
|  | 1594 |  | 
|  | 1595 | ;; go to point right beyond final line of current statement; usually | 
|  | 1596 | ;; this is the start of the next line, but if this is a multi-line | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 1597 | ;; statement we need to skip over the continuation lines.  Tricky: | 
|  | 1598 | ;; Again we need to be clever to avoid quadratic time behavior. | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 1599 | (defun py-goto-beyond-final-line () | 
|  | 1600 | (forward-line 1) | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 1601 | (let (state) | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 1602 | (while (and (py-continuation-line-p) | 
|  | 1603 | (not (eobp))) | 
|  | 1604 | ;; skip over the backslash flavor | 
|  | 1605 | (while (and (py-backslash-continuation-line-p) | 
|  | 1606 | (not (eobp))) | 
|  | 1607 | (forward-line 1)) | 
|  | 1608 | ;; if in nest, zip to the end of the nest | 
|  | 1609 | (setq state (py-parse-state)) | 
|  | 1610 | (if (and (not (zerop (car state))) | 
|  | 1611 | (not (eobp))) | 
|  | 1612 | (progn | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 1613 | ;; BUG ALERT: I could swear, from reading the docs, that | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 1614 | ;; the 3rd argument should be plain 0 | 
|  | 1615 | (parse-partial-sexp (point) (point-max) (- 0 (car state)) | 
|  | 1616 | nil state) | 
|  | 1617 | (forward-line 1)))))) | 
|  | 1618 |  | 
|  | 1619 | ;; t iff statement opens a block == iff it ends with a colon that's | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 1620 | ;; not in a comment.  point should be at the start of a statement | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 1621 | (defun py-statement-opens-block-p () | 
|  | 1622 | (save-excursion | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 1623 | (let ((start (point)) | 
|  | 1624 | (finish (progn (py-goto-beyond-final-line) (1- (point)))) | 
|  | 1625 | (searching t) | 
|  | 1626 | (answer nil) | 
|  | 1627 | state) | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 1628 | (goto-char start) | 
|  | 1629 | (while searching | 
|  | 1630 | ;; look for a colon with nothing after it except whitespace, and | 
|  | 1631 | ;; maybe a comment | 
|  | 1632 | (if (re-search-forward ":\\([ \t]\\|\\\\\n\\)*\\(#.*\\)?$" | 
|  | 1633 | finish t) | 
|  | 1634 | (if (eq (point) finish)	; note: no `else' clause; just | 
|  | 1635 | ; keep searching if we're not at | 
|  | 1636 | ; the end yet | 
|  | 1637 | ;; sure looks like it opens a block -- but it might | 
|  | 1638 | ;; be in a comment | 
|  | 1639 | (progn | 
|  | 1640 | (setq searching nil)	; search is done either way | 
|  | 1641 | (setq state (parse-partial-sexp start | 
|  | 1642 | (match-beginning 0))) | 
|  | 1643 | (setq answer (not (nth 4 state))))) | 
|  | 1644 | ;; search failed: couldn't find another interesting colon | 
|  | 1645 | (setq searching nil))) | 
|  | 1646 | answer))) | 
|  | 1647 |  | 
|  | 1648 | ;; go to point right beyond final line of block begun by the current | 
|  | 1649 | ;; line.  This is the same as where py-goto-beyond-final-line goes | 
|  | 1650 | ;; unless we're on colon line, in which case we go to the end of the | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 1651 | ;; block.  assumes point is at bolp | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 1652 | (defun py-goto-beyond-block () | 
|  | 1653 | (if (py-statement-opens-block-p) | 
|  | 1654 | (py-mark-block nil 'just-move) | 
|  | 1655 | (py-goto-beyond-final-line))) | 
|  | 1656 |  | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 1657 | ;; go to start of first statement (not blank or comment or | 
|  | 1658 | ;; continuation line) at or preceding point.  returns t if there is | 
|  | 1659 | ;; one, else nil | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 1660 | (defun py-goto-statement-at-or-above () | 
|  | 1661 | (py-goto-initial-line) | 
|  | 1662 | (if (looking-at py-blank-or-comment-re) | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 1663 | ;; skip back over blank & comment lines | 
|  | 1664 | ;; note:  will skip a blank or comment line that happens to be | 
|  | 1665 | ;; a continuation line too | 
|  | 1666 | (if (re-search-backward "^[ \t]*[^ \t#\n]" nil t) | 
|  | 1667 | (progn (py-goto-initial-line) t) | 
|  | 1668 | nil) | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 1669 | t)) | 
|  | 1670 |  | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 1671 | ;; go to start of first statement (not blank or comment or | 
|  | 1672 | ;; continuation line) following the statement containing point returns | 
|  | 1673 | ;; t if there is one, else nil | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 1674 | (defun py-goto-statement-below () | 
|  | 1675 | (beginning-of-line) | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 1676 | (let ((start (point))) | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 1677 | (py-goto-beyond-final-line) | 
|  | 1678 | (while (and | 
|  | 1679 | (looking-at py-blank-or-comment-re) | 
|  | 1680 | (not (eobp))) | 
|  | 1681 | (forward-line 1)) | 
|  | 1682 | (if (eobp) | 
|  | 1683 | (progn (goto-char start) nil) | 
|  | 1684 | t))) | 
|  | 1685 |  | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 1686 | ;; go to start of statement, at or preceding point, starting with | 
|  | 1687 | ;; keyword KEY.  Skips blank lines and non-indenting comments upward | 
|  | 1688 | ;; first.  If that statement starts with KEY, done, else go back to | 
|  | 1689 | ;; first enclosing block starting with KEY.  If successful, leaves | 
|  | 1690 | ;; point at the start of the KEY line & returns t.  Else leaves point | 
|  | 1691 | ;; at an undefined place & returns nil. | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 1692 | (defun py-go-up-tree-to-keyword (key) | 
|  | 1693 | ;; skip blanks and non-indenting # | 
|  | 1694 | (py-goto-initial-line) | 
|  | 1695 | (while (and | 
|  | 1696 | (looking-at "[ \t]*\\($\\|#[^ \t\n]\\)") | 
|  | 1697 | (zerop (forward-line -1)))	; go back | 
|  | 1698 | nil) | 
|  | 1699 | (py-goto-initial-line) | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 1700 | (let* ((re (concat "[ \t]*" key "\\b")) | 
|  | 1701 | (case-fold-search nil)		; let* so looking-at sees this | 
|  | 1702 | (found (looking-at re)) | 
|  | 1703 | (dead nil)) | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 1704 | (while (not (or found dead)) | 
|  | 1705 | (condition-case nil		; in case no enclosing block | 
|  | 1706 | (py-goto-block-up 'no-mark) | 
|  | 1707 | (error (setq dead t))) | 
|  | 1708 | (or dead (setq found (looking-at re)))) | 
|  | 1709 | (beginning-of-line) | 
|  | 1710 | found)) | 
|  | 1711 |  | 
|  | 1712 | ;; return string in buffer from start of indentation to end of line; | 
|  | 1713 | ;; prefix "..." if leading whitespace was skipped | 
|  | 1714 | (defun py-suck-up-leading-text () | 
|  | 1715 | (save-excursion | 
|  | 1716 | (back-to-indentation) | 
|  | 1717 | (concat | 
|  | 1718 | (if (bolp) "" "...") | 
|  | 1719 | (buffer-substring (point) (progn (end-of-line) (point)))))) | 
|  | 1720 |  | 
|  | 1721 | ;; assuming point at bolp, return first keyword ([a-z]+) on the line, | 
|  | 1722 | ;; as a Lisp symbol; return nil if none | 
|  | 1723 | (defun py-suck-up-first-keyword () | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 1724 | (let ((case-fold-search nil)) | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 1725 | (if (looking-at "[ \t]*\\([a-z]+\\)\\b") | 
|  | 1726 | (intern (buffer-substring (match-beginning 1) (match-end 1))) | 
|  | 1727 | nil))) | 
|  | 1728 |  | 
|  | 1729 | (defun py-make-temp-name () | 
|  | 1730 | (make-temp-name | 
|  | 1731 | (concat (file-name-as-directory py-temp-directory) "python"))) | 
|  | 1732 |  | 
|  | 1733 | (defun py-delete-file-silently (fname) | 
|  | 1734 | (condition-case nil | 
|  | 1735 | (delete-file fname) | 
|  | 1736 | (error nil))) | 
|  | 1737 |  | 
|  | 1738 | (defun py-kill-emacs-hook () | 
|  | 1739 | ;; delete our temp files | 
|  | 1740 | (while py-file-queue | 
|  | 1741 | (py-delete-file-silently (car py-file-queue)) | 
|  | 1742 | (setq py-file-queue (cdr py-file-queue))) | 
|  | 1743 | (if (not (or py-this-is-lucid-emacs-p py-this-is-emacs-19-p)) | 
|  | 1744 | ;; run the hook we inherited, if any | 
|  | 1745 | (and py-inherited-kill-emacs-hook | 
|  | 1746 | (funcall py-inherited-kill-emacs-hook)))) | 
|  | 1747 |  | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 1748 | ;; make PROCESS's buffer visible, append STRING to it, and force | 
|  | 1749 | ;; display; also make shell-mode believe the user typed this string, | 
|  | 1750 | ;; so that kill-output-from-shell and show-output-from-shell work | 
|  | 1751 | ;; "right" | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 1752 | (defun py-append-to-process-buffer (process string) | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 1753 | (let ((cbuf (current-buffer)) | 
|  | 1754 | (pbuf (process-buffer process)) | 
|  | 1755 | (py-scroll-process-buffer t)) | 
| Barry Warsaw | 7ae7768 | 1994-12-12 20:38:05 +0000 | [diff] [blame] | 1756 | (set-buffer pbuf) | 
|  | 1757 | (goto-char (point-max)) | 
|  | 1758 | (move-marker (process-mark process) (point)) | 
|  | 1759 | (if (not py-this-is-emacs-19-p) | 
|  | 1760 | (move-marker last-input-start (point))) ; muck w/ shell-mode | 
|  | 1761 | (funcall (process-filter process) process string) | 
|  | 1762 | (if (not py-this-is-emacs-19-p) | 
|  | 1763 | (move-marker last-input-end (point))) ; muck w/ shell-mode | 
|  | 1764 | (set-buffer cbuf)) | 
|  | 1765 | (sit-for 0)) | 
|  | 1766 |  | 
| Barry Warsaw | 7b0f568 | 1995-03-08 21:33:04 +0000 | [diff] [blame] | 1767 |  | 
|  | 1768 |  | 
|  | 1769 | ;; initializations | 
|  | 1770 |  | 
|  | 1771 | ;; arrange to kill temp files when Emacs exists | 
|  | 1772 | (if (or py-this-is-emacs-19-p py-this-is-lucid-emacs-p) | 
|  | 1773 | (add-hook 'kill-emacs-hook 'py-kill-emacs-hook) | 
|  | 1774 | ;; have to trust that other people are as respectful of our hook | 
|  | 1775 | ;; fiddling as we are of theirs | 
|  | 1776 | (if (boundp 'py-inherited-kill-emacs-hook) | 
|  | 1777 | ;; we were loaded before -- trust others not to have screwed us | 
|  | 1778 | ;; in the meantime (no choice, really) | 
|  | 1779 | nil | 
|  | 1780 | ;; else arrange for our hook to run theirs | 
|  | 1781 | (setq py-inherited-kill-emacs-hook kill-emacs-hook) | 
|  | 1782 | (setq kill-emacs-hook 'py-kill-emacs-hook))) | 
|  | 1783 |  | 
|  | 1784 |  | 
|  | 1785 |  | 
|  | 1786 | (provide 'python-mode) | 
|  | 1787 | ;;; python-mode.el ends here |