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