comparison lisp/progmodes/python.el @ 89909:68c22ea6027c

Sync to HEAD
author Kenichi Handa <handa@m17n.org>
date Fri, 16 Apr 2004 12:51:06 +0000
parents
children 4c90ffeb71c5
comparison
equal deleted inserted replaced
89908:ee1402f7b568 89909:68c22ea6027c
1 ;;; python.el --- silly walks for Python
2
3 ;; Copyright (C) 2003, 04 Free Software Foundation, Inc.
4
5 ;; Author: Dave Love <fx@gnu.org>
6 ;; Created: Nov 2003
7 ;; Keywords: languages
8
9 ;; This file is part of GNU Emacs.
10
11 ;; This file is free software; you can redistribute it and/or modify
12 ;; it under the terms of the GNU General Public License as published by
13 ;; the Free Software Foundation; either version 2, or (at your option)
14 ;; any later version.
15
16 ;; This file is distributed in the hope that it will be useful,
17 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 ;; GNU General Public License for more details.
20
21 ;; You should have received a copy of the GNU General Public License
22 ;; along with GNU Emacs; see the file COPYING. If not, write to
23 ;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
24 ;; Boston, MA 02111-1307, USA.
25
26 ;;; Commentary:
27
28 ;; Major mode for editing Python, with support for inferior processes.
29
30 ;; There is another Python mode, python-mode.el, used by XEmacs and
31 ;; maintained with Python. That isn't covered by an FSF copyright
32 ;; assignment, unlike this code, and seems not to be well-maintained
33 ;; for Emacs (though I've submitted fixes). This mode is rather
34 ;; simpler and is, perhaps, better in other ways. In particular,
35 ;; using the syntax functions with text properties maintained by
36 ;; font-lock should make it more correct with arbitrary string and
37 ;; comment contents.
38
39 ;; This doesn't implement all the facilities of python-mode.el. Some
40 ;; just need doing, e.g. catching exceptions in the inferior Python
41 ;; buffer (but see M-x pdb for debugging). [Actually, the use of
42 ;; `compilation-minor-mode' now is probably enough for that.] Others
43 ;; don't seem appropriate. For instance, `forward-into-nomenclature'
44 ;; should be done separately, since it's not specific to Python, and
45 ;; I've installed a minor mode to do the job properly in Emacs 22.
46 ;; Other things seem more natural or canonical here, e.g. the
47 ;; {beginning,end}-of-defun implementation dealing with nested
48 ;; definitions, and the inferior mode following `cmuscheme'. (The
49 ;; inferior mode should be able to find the source of errors from
50 ;; `python-send-region' & al via `compilation-minor-mode', but I can't
51 ;; make that work with the current (March '04) compile.el.)
52 ;; Successive TABs cycle between possible indentations for the line.
53
54 ;; Even where it has similar facilities, this is incompatible with
55 ;; python-mode.el in various respects. For instance, various key
56 ;; bindings are changed to obey Emacs conventions, and things like
57 ;; marking blocks and `beginning-of-defun' behave differently.
58
59 ;; TODO: See various Fixmes below. It should be possible to arrange
60 ;; some sort of completion using the inferior interpreter.
61
62 ;;; Code:
63
64 ;; It's messy to autoload the relevant comint functions so that comint
65 ;; is only required when inferior Python is used.
66 (require 'comint)
67 (eval-when-compile
68 (require 'compile)
69 (autoload 'Info-last "info")
70 (autoload 'Info-exit "info")
71 (autoload 'info-lookup-maybe-add-help "info-look"))
72 (autoload 'compilation-start "compile") ; spurious compiler warning anyway
73
74 (defgroup python nil
75 "Silly walks in the Python language"
76 :group 'languages
77 :version "21.4"
78 :link '(emacs-commentary-link "python"))
79
80 ;;;###autoload
81 (add-to-list 'interpreter-mode-alist '("jython" . jython-mode))
82 ;;;###autoload
83 (add-to-list 'interpreter-mode-alist '("python" . python-mode))
84 ;;;###autoload
85 (add-to-list 'auto-mode-alist '("\\.py\\'" . python-mode))
86
87 ;;;; Font lock
88
89 (defvar python-font-lock-keywords
90 `(,(rx (and word-start
91 ;; From v 2.3 reference.
92 ;; def and class dealt with separately below
93 (or "and" "assert" "break" "continue" "del" "elif" "else"
94 "except" "exec" "finally" "for" "from" "global" "if"
95 "import" "in" "is" "lambda" "not" "or" "pass" "print"
96 "raise" "return" "try" "while" "yield"
97 ;; Future keywords
98 "as" "None")
99 word-end))
100 (,(rx (and word-start (group "class") (1+ space) (group (1+ word))))
101 (1 font-lock-keyword-face) (2 font-lock-type-face))
102 (,(rx (and word-start (group "def") (1+ space) (group (1+ word))))
103 (1 font-lock-keyword-face) (2 font-lock-function-name-face))))
104
105 (defconst python-font-lock-syntactic-keywords
106 ;; Make outer chars of matching triple-quote sequences into generic
107 ;; string delimiters. Fixme: Is there a better way?
108 `((,(rx (and (group (optional (any "uUrR"))) ; prefix gets syntax property
109 (optional (any "rR")) ; possible second prefix
110 (group (syntax string-quote)) ; maybe gets property
111 (backref 2) ; per first quote
112 (group (backref 2)))) ; maybe gets property
113 (1 (python-quote-syntax 1))
114 (2 (python-quote-syntax 2))
115 (3 (python-quote-syntax 3)))
116 ;; This doesn't really help.
117 ;;; (,(rx (and ?\\ (group ?\n))) (1 " "))
118 ))
119
120 (defun python-quote-syntax (n)
121 "Put `syntax-table' property correctly on triple quote.
122 Used for syntactic keywords. N is the match number (1, 2 or 3)."
123 ;; Given a triple quote, we have to check the context to know
124 ;; whether this is an opening or closing triple or whether it's
125 ;; quoted anyhow, and should be ignored. (For that we need to do
126 ;; the same job as `syntax-ppss' to be correct and it seems to be OK
127 ;; to use it here despite initial worries.) We also have to sort
128 ;; out a possible prefix -- well, we don't _have_ to, but I think it
129 ;; should be treated as part of the string.
130
131 ;; Test cases:
132 ;; ur"""ar""" x='"' # """
133 ;; x = ''' """ ' a
134 ;; '''
135 ;; x '"""' x
136 (save-excursion
137 (goto-char (match-beginning 0))
138 (unless (eq ?\\ (char-before))
139 (cond
140 ;; Consider property for the last char if in a fenced string.
141 ((= n 3)
142 (let ((syntax (syntax-ppss)))
143 (when (eq t (nth 3 syntax)) ; after unclosed fence
144 (goto-char (nth 8 syntax)) ; fence position
145 ;; Skip any prefix.
146 (if (memq (char-after) '(?u ?U ?R ?r))
147 (skip-chars-forward "uUrR"))
148 ;; Is it a matching sequence?
149 (if (eq (char-after) (char-after (match-beginning 2)))
150 (eval-when-compile (string-to-syntax "|"))))))
151 ;; Consider property for initial char, accounting for prefixes.
152 ((or (and (= n 2) ; not prefix
153 (= (match-beginning 1) (match-end 1))) ; prefix is null
154 (and (= n 1) ; prefix
155 (/= (match-beginning 1) (match-end 1)))) ; non-empty
156 (unless (eq 'string (syntax-ppss-context (syntax-ppss)))
157 (eval-when-compile (string-to-syntax "|")))))
158 ;; Otherwise (we're in a non-matching string) the property is
159 ;; nil, which is OK.
160 )))
161
162 ;; This isn't currently in `font-lock-defaults' as probably not worth
163 ;; it -- we basically only mess with a few normally-symbol characters.
164
165 ;; (defun python-font-lock-syntactic-face-function (state)
166 ;; "`font-lock-syntactic-face-function' for Python mode.
167 ;; Returns the string or comment face as usual, with side effect of putting
168 ;; a `syntax-table' property on the inside of the string or comment which is
169 ;; the standard syntax table."
170 ;; (if (nth 3 state)
171 ;; (save-excursion
172 ;; (goto-char (nth 8 state))
173 ;; (condition-case nil
174 ;; (forward-sexp)
175 ;; (error nil))
176 ;; (put-text-property (1+ (nth 8 state)) (1- (point))
177 ;; 'syntax-table (standard-syntax-table))
178 ;; 'font-lock-string-face)
179 ;; (put-text-property (1+ (nth 8 state)) (line-end-position)
180 ;; 'syntax-table (standard-syntax-table))
181 ;; 'font-lock-comment-face))
182
183 ;;;; Keymap and syntax
184
185 (defvar python-mode-map
186 (let ((map (make-sparse-keymap)))
187 ;; Mostly taken from python-mode.el.
188 (define-key map ":" 'python-electric-colon)
189 (define-key map "\177" 'python-backspace)
190 (define-key map "\C-c<" 'python-shift-left)
191 (define-key map "\C-c>" 'python-shift-right)
192 (define-key map "\C-c\C-k" 'python-mark-block)
193 (define-key map "\C-c\C-n" 'python-next-statement)
194 (define-key map "\C-c\C-p" 'python-previous-statement)
195 (define-key map "\C-c\C-u" 'python-beginning-of-block)
196 (define-key map "\C-c\C-f" 'python-describe-symbol)
197 (define-key map "\C-c\C-w" 'python-check)
198 (define-key map "\C-c\C-v" 'python-check) ; a la sgml-mode
199 (define-key map "\C-c\C-s" 'python-send-string)
200 (define-key map [?\C-\M-x] 'python-send-defun)
201 (define-key map "\C-c\C-r" 'python-send-region)
202 (define-key map "\C-c\M-r" 'python-send-region-and-go)
203 (define-key map "\C-c\C-c" 'python-send-buffer)
204 (define-key map "\C-c\C-z" 'python-switch-to-python)
205 (define-key map "\C-c\C-m" 'python-load-file)
206 (define-key map "\C-c\C-l" 'python-load-file) ; a la cmuscheme
207 ;; Fixme: Add :help to menu.
208 (easy-menu-define python-menu map "Python Mode menu"
209 '("Python"
210 ["Shift region left" python-shift-left :active mark-active]
211 ["Shift region right" python-shift-right :active mark-active]
212 "-"
213 ["Mark block" python-mark-block]
214 ["Mark def/class" mark-defun
215 :help "Mark innermost definition around point"]
216 "-"
217 ["Start of block" python-beginning-of-block]
218 ["End of block" python-end-of-block]
219 ["Start of def/class" beginning-of-defun
220 :help "Go to start of innermost definition around point"]
221 ["End of def/class" end-of-defun
222 :help "Go to end of innermost definition around point"]
223 "-"
224 ["Start interpreter" run-python
225 :help "Run `inferior' Python in separate buffer"]
226 ["Import/reload file" python-load-file
227 :help "Load into inferior Python session"]
228 ["Eval buffer" python-send-buffer
229 :help "Evaluate buffer en bloc in inferior Python session"]
230 ["Eval region" python-send-region :active mark-active
231 :help "Evaluate region en bloc in inferior Python session"]
232 ["Eval def/class" python-send-defun
233 :help "Evaluate current definition in inferior Python session"]
234 ["Switch to interpreter" python-switch-to-python
235 :help "Switch to inferior Python buffer"]
236 ["Check file" python-check :help "Run pychecker"]
237 ["Debugger" pdb :help "Run pdb under GUD"]
238 "-"
239 ["Help on symbol" python-describe-symbol
240 :help "Use pydoc on symbol at point"]))
241 map))
242
243 (defvar python-mode-syntax-table
244 (let ((table (make-syntax-table)))
245 ;; Give punctuation syntax to ASCII that normally has symbol
246 ;; syntax or has word syntax and isn't a letter.
247 (let ((symbol (string-to-syntax "_"))
248 (sst (standard-syntax-table)))
249 (dotimes (i 128)
250 (unless (= i ?_)
251 (if (equal symbol (aref sst i))
252 (modify-syntax-entry i "." table)))))
253 (modify-syntax-entry ?$ "." table)
254 (modify-syntax-entry ?% "." table)
255 ;; exceptions
256 (modify-syntax-entry ?# "<" table)
257 (modify-syntax-entry ?\n ">" table)
258 (modify-syntax-entry ?' "\"" table)
259 (modify-syntax-entry ?` "$" table)
260 table))
261
262 ;;;; Utility stuff
263
264 (defsubst python-in-string/comment ()
265 "Return non-nil if point is in a Python literal (a comment or string).
266 Optional argument LIM indicates the beginning of the containing form,
267 i.e. the limit on how far back to scan."
268 (syntax-ppss-context (syntax-ppss)))
269
270 (defconst python-space-backslash-table
271 (let ((table (copy-syntax-table python-mode-syntax-table)))
272 (modify-syntax-entry ?\\ " " table)
273 table)
274 "`python-mode-syntax-table' with backslash given whitespace syntax.")
275
276 (defun python-skip-comments/blanks (&optional backward)
277 "Skip comments and blank lines.
278 BACKWARD non-nil means go backwards, otherwise go forwards. Backslash is
279 treated as whitespace so that continued blank lines are skipped.
280 Doesn't move out of comments -- should be outside or at end of line."
281 (with-syntax-table python-space-backslash-table
282 (forward-comment (if backward
283 most-negative-fixnum
284 most-positive-fixnum))))
285
286 (defun python-backslash-continuation-line-p ()
287 "Non-nil if preceding line ends with backslash that is not in a comment."
288 (and (eq ?\\ (char-before (line-end-position 0)))
289 (not (syntax-ppss-context (syntax-ppss)))))
290
291 (defun python-continuation-line-p ()
292 "Return non-nil if current line continues a previous one.
293 The criteria are that the previous line ends in a backslash outside
294 comments and strings, or that the bracket/paren nesting depth is nonzero."
295 (or (and (eq ?\\ (char-before (line-end-position 0)))
296 (not (syntax-ppss-context (syntax-ppss))))
297 (/= 0 (syntax-ppss-depth
298 (save-excursion ; syntax-ppss with arg changes point
299 (syntax-ppss (line-beginning-position)))))))
300
301 (defun python-comment-line-p ()
302 "Return non-nil if current line has only a comment or is blank."
303 (save-excursion
304 (back-to-indentation)
305 (looking-at (rx (or (syntax comment-start) line-end)))))
306
307 (defun python-beginning-of-string ()
308 "Go to beginning of string around point.
309 Do nothing if not in string."
310 (let ((state (syntax-ppss)))
311 (when (nth 3 state)
312 (goto-char (nth 8 state)))))
313
314 (defun python-open-block-statement-p (&optional bos)
315 "Return non-nil if statement at point opens a block.
316 BOS non-nil means point is known to be at beginning of statement."
317 (save-excursion
318 (unless bos (python-beginning-of-statement))
319 (and (not (python-comment-line-p))
320 (re-search-forward (rx (and ?: (0+ space)
321 (optional (and (syntax comment-start)
322 (0+ not-newline)))
323 line-end))
324 (save-excursion (python-end-of-statement))
325 t)
326 (not (python-in-string/comment)))))
327
328 (defun python-close-block-statement-p (&optional bos)
329 "Return non-nil if current line is a statement closing a block.
330 BOS non-nil means point is at beginning of statement.
331 The criteria are that the line isn't a comment or in string and starts with
332 keyword `raise', `break', `continue' or `pass'."
333 (save-excursion
334 (unless bos (python-beginning-of-statement))
335 (back-to-indentation)
336 (looking-at (rx (and (or "return" "raise" "break" "continue" "pass")
337 word-end)))))
338
339 (defun python-outdent-p ()
340 "Return non-nil if current line should outdent a level."
341 (save-excursion
342 (back-to-indentation)
343 (and (looking-at (rx (and (or (and (or "else" "finally") word-end)
344 (and (or "except" "elif") word-end
345 (1+ (not (any ?:)))))
346 (optional space) ":" (optional space)
347 (or (syntax comment-start) line-end))))
348 (progn (end-of-line)
349 (not (python-in-string/comment)))
350 ;; Ensure there's a previous statement and move to it.
351 (zerop (python-previous-statement))
352 (not (python-close-block-statement-p t))
353 ;; Fixme: check this
354 (not (looking-at (rx (and (or (and (or "if" "elif" "except"
355 "for" "while")
356 word-end (1+ (not (any ?:))))
357 (and "try" word-end))
358 (optional space) ":" (optional space)
359 (or (syntax comment-start) line-end)))))
360 (progn (end-of-line)
361 (not (python-in-string/comment))))))
362
363 ;;;; Indentation.
364
365 (defcustom python-indent 4
366 "*Number of columns for a unit of indentation in Python mode.
367 See also `\\[python-guess-indent]'"
368 :group 'python
369 :type 'integer)
370
371 (defcustom python-guess-indent t
372 "*Non-nil means Python mode guesses `python-indent' for the buffer."
373 :type 'boolean
374 :group 'python)
375
376 (defcustom python-indent-string-contents t
377 "*Non-nil means indent contents of multi-line strings together.
378 This means indent them the same as the preceding non-blank line.
379 Otherwise indent them to column zero."
380 :type '(choice (const :tag "Align with preceding" t)
381 (const :tag "Indent to column 0" nil))
382 :group 'python)
383
384 (defcustom python-honour-comment-indentation nil
385 "Non-nil means indent relative to preceding comment line.
386 Only do this for comments where the leading comment character is followed
387 by space."
388 :type 'boolean
389 :group 'python)
390
391 (defcustom python-continuation-offset 4
392 "*Number of columns of additional indentation for continuation lines.
393 Continuation lines follow a backslash-terminated line starting a statement."
394 :group 'python
395 :type 'integer)
396
397 (defun python-guess-indent ()
398 "Guess step for indentation of current buffer.
399 Set `python-indent' locally to the value guessed."
400 (interactive)
401 (save-excursion
402 (save-restriction
403 (widen)
404 (goto-char (point-min))
405 (let (done indent)
406 (while (and (not done) (not (eobp)))
407 (when (and (re-search-forward (rx (and ?: (0+ space)
408 (or (syntax comment-start)
409 line-end)))
410 nil 'move)
411 (python-open-block-statement-p))
412 (save-excursion
413 (python-beginning-of-statement)
414 (let ((initial (current-indentation)))
415 (if (zerop (python-next-statement))
416 (setq indent (- (current-indentation) initial)))
417 (if (and (>= indent 2) (<= indent 8)) ; sanity check
418 (setq done t))))))
419 (when done
420 (when (/= indent (default-value 'python-indent))
421 (set (make-local-variable 'python-indent) indent)
422 (unless (= tab-width python-indent)
423 (setq indent-tabs-mode nil)))
424 indent)))))
425
426 (defun python-calculate-indentation ()
427 "Calculate Python indentation for line at point."
428 (save-excursion
429 (beginning-of-line)
430 (let ((syntax (syntax-ppss))
431 start)
432 (cond
433 ((eq 'string (syntax-ppss-context syntax)) ; multi-line string
434 (if (not python-indent-string-contents)
435 0
436 (save-excursion
437 ;; Find indentation of preceding non-blank line within string.
438 (setq start (nth 8 syntax))
439 (forward-line -1)
440 (while (and (< start (point)) (looking-at "\\s-*$"))
441 (forward-line -1))
442 (current-indentation))))
443 ((python-continuation-line-p)
444 (let ((point (point))
445 (open-start (cadr syntax)))
446 (if open-start
447 ;; Inside bracketed expression.
448 (progn
449 (goto-char (1+ open-start))
450 ;; Look for first item in list (preceding point) and
451 ;; align with it, if found.
452 (if (with-syntax-table python-space-backslash-table
453 (let ((parse-sexp-ignore-comments t))
454 (condition-case ()
455 (progn (forward-sexp)
456 (backward-sexp)
457 (< (point) point))
458 (error nil))))
459 (current-column)
460 ;; Otherwise indent relative to statement start, one
461 ;; level per bracketing level.
462 (goto-char (1+ open-start))
463 (python-beginning-of-statement)
464 (+ (current-indentation) (* (car syntax) python-indent))))
465 ;; Otherwise backslash-continued.
466 (forward-line -1)
467 (if (python-continuation-line-p)
468 ;; We're past first continuation line. Align with
469 ;; previous line.
470 (current-indentation)
471 ;; First continuation line. Indent one step, with an
472 ;; extra one if statement opens a block.
473 (save-excursion
474 (python-beginning-of-statement)
475 (+ (current-indentation) python-continuation-offset
476 (if (python-open-block-statement-p t)
477 python-indent
478 0)))))))
479 ((bobp) 0)
480 ;; Fixme: Like python-mode.el; not convinced by this.
481 ((looking-at (rx (and (0+ space) (syntax comment-start)
482 (not (any " \t\n"))))) ; non-indentable comment
483 (current-indentation))
484 (t (let ((point (point)))
485 (if python-honour-comment-indentation
486 ;; Back over whitespace, newlines, non-indentable comments.
487 (catch 'done
488 (while t
489 (if (cond ((bobp))
490 ;; not at comment start
491 ((not (forward-comment -1))
492 (python-beginning-of-statement)
493 t)
494 ;; trailing comment
495 ((/= (current-column) (current-indentation))
496 (python-beginning-of-statement)
497 t)
498 ;; indentable comment like python-mode.el
499 ((and (looking-at (rx (and (syntax comment-start)
500 (or space line-end))))
501 (/= 0 (current-column)))))
502 (throw 'done t))))
503 ;; Else back over all comments.
504 (python-skip-comments/blanks t)
505 (python-beginning-of-statement))
506 ;; don't lose on bogus outdent
507 (max 0 (+ (current-indentation)
508 (or (cond ((python-open-block-statement-p t)
509 python-indent)
510 ((python-close-block-statement-p t)
511 (- python-indent)))
512 (progn (goto-char point)
513 (if (python-outdent-p)
514 (- python-indent)))
515 0)))))))))
516
517 ;;;; Cycling through the possible indentations with successive TABs.
518
519 ;; These don't need to be buffer-local since they're only relevant
520 ;; during a cycle.
521
522 ;; Alist of possible indentations and start of statement they would close.
523 (defvar python-indent-list nil
524 "Internal use.")
525 ;; Length of the above
526 (defvar python-indent-list-length nil
527 "Internal use.")
528 ;; Current index into the alist.
529 (defvar python-indent-index nil
530 "Internal use.")
531
532 (defun python-initial-text ()
533 "Text of line following indentation and ignoring any trailing comment."
534 (buffer-substring (+ (line-beginning-position) (current-indentation))
535 (save-excursion
536 (end-of-line)
537 (forward-comment -1)
538 (point))))
539
540 (defun python-indentation-levels ()
541 "Return a list of possible indentations for this statement.
542 Includes the default indentation and those which would close all
543 enclosing blocks."
544 (save-excursion
545 (let ((levels (list (cons (current-indentation) nil))))
546 ;; Only one possibility if we immediately follow a block open or
547 ;; are in a continuation line.
548 (unless (or (python-continuation-line-p)
549 (save-excursion (and (python-previous-statement)
550 (python-open-block-statement-p t))))
551 (while (python-beginning-of-block)
552 (push (cons (current-indentation) (python-initial-text))
553 levels)))
554 levels)))
555
556 ;; This is basically what `python-indent-line' would be if we didn't
557 ;; do the cycling.
558 (defun python-indent-line-1 ()
559 "Subroutine of `python-indent-line'."
560 (let ((target (python-calculate-indentation))
561 (pos (- (point-max) (point))))
562 (if (= target (current-indentation))
563 (if (< (current-column) (current-indentation))
564 (back-to-indentation))
565 (beginning-of-line)
566 (delete-horizontal-space)
567 (indent-to target)
568 (if (> (- (point-max) pos) (point))
569 (goto-char (- (point-max) pos))))))
570
571 ;; Fixme: Is the arg necessary?
572 (defun python-indent-line (&optional arg)
573 "Indent current line as Python code.
574 When invoked via `indent-for-tab-command', cycle through possible
575 indentations for current line. The cycle is broken by a command different
576 from `indent-for-tab-command', i.e. successive TABs do the cycling."
577 (interactive)
578 ;; Don't do extra work if invoked via `indent-region', for instance.
579 (if (not (eq this-command 'indent-for-tab-command))
580 (python-indent-line-1)
581 (if (eq last-command this-command)
582 (if (= 1 python-indent-list-length)
583 (message "Sole indentation")
584 (progn (setq python-indent-index (% (1+ python-indent-index)
585 python-indent-list-length))
586 (beginning-of-line)
587 (delete-horizontal-space)
588 (indent-to (car (nth python-indent-index python-indent-list)))
589 (let ((text (cdr (nth python-indent-index
590 python-indent-list))))
591 (if text (message "Closes: %s" text)))))
592 (python-indent-line-1)
593 (setq python-indent-list (python-indentation-levels)
594 python-indent-list-length (length python-indent-list)
595 python-indent-index (1- python-indent-list-length)))))
596
597 ;;;; Movement.
598
599 (defun python-beginning-of-defun ()
600 "`beginning-of-defun-function' for Python.
601 Finds beginning of innermost nested class or method definition.
602 Returns the name of the definition found at the end, or nil if reached
603 start of buffer."
604 (let ((ci (current-indentation))
605 (def-re (rx (and line-start (0+ space) (or "def" "class")
606 (1+ space)
607 (group (1+ (or word (syntax symbol)))))))
608 found lep def-line)
609 (if (python-comment-line-p)
610 (setq ci most-positive-fixnum))
611 (while (and (not (bobp)) (not found))
612 ;; Treat bol at beginning of function as outside function so
613 ;; that successive C-M-a makes progress backwards.
614 (setq def-line (looking-at def-re))
615 (unless (bolp) (end-of-line))
616 (setq lep (line-end-position))
617 (if (and (re-search-backward def-re nil 'move)
618 ;; Must be less indented or matching top level, or
619 ;; equally indented if we started on a definition line.
620 (let ((in (current-indentation)))
621 (or (and (zerop ci) (zerop in))
622 (= lep (line-end-position)) ; on initial line
623 (and def-line (= in ci))
624 (< in ci)))
625 (not (python-in-string/comment)))
626 (setq found t)))))
627
628 (defun python-end-of-defun ()
629 "`end-of-defun-function' for Python.
630 Finds end of innermost nested class or method definition."
631 (let ((orig (point))
632 (pattern (rx (and line-start (0+ space)
633 (or "def" "class") space))))
634 ;; Go to start of current block and check whether it's at top
635 ;; level. If it is, and not a block start, look forward for
636 ;; definition statement.
637 (when (python-comment-line-p)
638 (end-of-line)
639 (forward-comment most-positive-fixnum))
640 (if (not (python-open-block-statement-p))
641 (python-beginning-of-block))
642 (if (zerop (current-indentation))
643 (unless (python-open-block-statement-p)
644 (while (and (re-search-forward pattern nil 'move)
645 (python-in-string/comment))) ; just loop
646 (unless (eobp)
647 (beginning-of-line)))
648 ;; Don't move before top-level statement that would end defun.
649 (end-of-line)
650 (python-beginning-of-defun))
651 ;; If we got to the start of buffer, look forward for
652 ;; definition statement.
653 (if (and (bobp) (not (looking-at "def\\|class")))
654 (while (and (not (eobp))
655 (re-search-forward pattern nil 'move)
656 (python-in-string/comment)))) ; just loop
657 ;; We're at a definition statement (or end-of-buffer).
658 (unless (eobp)
659 (python-end-of-block)
660 ;; Count trailing space in defun (but not trailing comments).
661 (skip-syntax-forward " >")
662 (beginning-of-line))
663 ;; Catch pathological case like this, where the beginning-of-defun
664 ;; skips to a definition we're not in:
665 ;; if ...:
666 ;; ...
667 ;; else:
668 ;; ... # point here
669 ;; ...
670 ;; def ...
671 (if (< (point) orig)
672 (goto-char (point-max)))))
673
674 (defun python-beginning-of-statement ()
675 "Go to start of current statement.
676 Accounts for continuation lines, multi-line strings, and multi-line bracketed
677 expressions."
678 (beginning-of-line)
679 (python-beginning-of-string)
680 (while (python-continuation-line-p)
681 (beginning-of-line)
682 (if (python-backslash-continuation-line-p)
683 (while (python-backslash-continuation-line-p)
684 (forward-line -1))
685 (python-beginning-of-string)
686 ;; Skip forward out of nested brackets.
687 (condition-case () ; beware invalid syntax
688 (progn (backward-up-list (syntax-ppss-depth (syntax-ppss))) t)
689 (error (end-of-line)))))
690 (back-to-indentation))
691
692 (defun python-end-of-statement ()
693 "Go to the end of the current statement and return point.
694 Usually this is the start of the next line, but if this is a
695 multi-line statement we need to skip over the continuation lines.
696 On a comment line, go to end of line."
697 (end-of-line)
698 (while (let (comment)
699 ;; Move past any enclosing strings and sexps, or stop if
700 ;; we're in a comment.
701 (while (let ((s (syntax-ppss)))
702 (cond ((eq 'comment (syntax-ppss-context s))
703 (setq comment t)
704 nil)
705 ((eq 'string (syntax-ppss-context s))
706 ;; Go to start of string and skip it.
707 (goto-char (nth 8 s))
708 (condition-case () ; beware invalid syntax
709 (progn (forward-sexp) t)
710 (error (end-of-line))))
711 ((> (syntax-ppss-depth s) 0)
712 ;; Skip forward out of nested brackets.
713 (condition-case () ; beware invalid syntax
714 (progn (backward-up-list
715 (- (syntax-ppss-depth s)))
716 t)
717 (error (end-of-line))))))
718 (end-of-line))
719 (unless comment
720 (eq ?\\ (char-before)))) ; Line continued?
721 (end-of-line 2)) ; Try next line.
722 (point))
723
724 (defun python-previous-statement (&optional count)
725 "Go to start of previous statement.
726 With argument COUNT, do it COUNT times. Stop at beginning of buffer.
727 Return count of statements left to move."
728 (interactive "p")
729 (unless count (setq count 1))
730 (if (< count 0)
731 (python-next-statement (- count))
732 (python-beginning-of-statement)
733 (while (and (> count 0) (not (bobp)))
734 (python-skip-comments/blanks t)
735 (python-beginning-of-statement)
736 (unless (bobp) (setq count (1- count))))
737 count))
738
739 (defun python-next-statement (&optional count)
740 "Go to start of next statement.
741 With argument COUNT, do it COUNT times. Stop at end of buffer.
742 Return count of statements left to move."
743 (interactive "p")
744 (unless count (setq count 1))
745 (if (< count 0)
746 (python-previous-statement (- count))
747 (beginning-of-line)
748 (while (and (> count 0) (not (eobp)))
749 (python-end-of-statement)
750 (python-skip-comments/blanks)
751 (setq count (1- count)))
752 count))
753
754 (defun python-beginning-of-block (&optional arg)
755 "Go to start of current block.
756 With numeric arg, do it that many times. If ARG is negative, call
757 `python-end-of-block' instead.
758 If point is on the first line of a block, use its outer block.
759 If current statement is in column zero, don't move and return nil.
760 Otherwise return non-nil."
761 (interactive "p")
762 (unless arg (setq arg 1))
763 (cond
764 ((zerop arg))
765 ((< arg 0) (python-end-of-block (- arg)))
766 (t
767 (let ((point (point)))
768 (if (python-comment-line-p)
769 (python-skip-comments/blanks t))
770 (python-beginning-of-statement)
771 (let ((ci (current-indentation)))
772 (if (zerop ci)
773 (not (goto-char point)) ; return nil
774 ;; Look upwards for less indented statement.
775 (if (catch 'done
776 ;;; This is slower than the below.
777 ;;; (while (zerop (python-previous-statement))
778 ;;; (when (and (< (current-indentation) ci)
779 ;;; (python-open-block-statement-p t))
780 ;;; (beginning-of-line)
781 ;;; (throw 'done t)))
782 (while (and (zerop (forward-line -1)))
783 (when (and (< (current-indentation) ci)
784 (not (python-comment-line-p))
785 ;; Move to beginning to save effort in case
786 ;; this is in string.
787 (progn (python-beginning-of-statement) t)
788 (python-open-block-statement-p t))
789 (beginning-of-line)
790 (throw 'done t)))
791 (not (goto-char point))) ; Failed -- return nil
792 (python-beginning-of-block (1- arg)))))))))
793
794 (defun python-end-of-block (&optional arg)
795 "Go to end of current block.
796 With numeric arg, do it that many times. If ARG is negative, call
797 `python-beginning-of-block' instead.
798 If current statement is in column zero and doesn't open a block, don't
799 move and return nil. Otherwise return t."
800 (interactive "p")
801 (unless arg (setq arg 1))
802 (if (< arg 0)
803 (python-beginning-of-block (- arg)))
804 (while (and (> arg 0)
805 (let* ((point (point))
806 (_ (if (python-comment-line-p)
807 (python-skip-comments/blanks t)))
808 (ci (current-indentation))
809 (open (python-open-block-statement-p)))
810 (if (and (zerop ci) (not open))
811 (not (goto-char point))
812 (catch 'done
813 (while (zerop (python-next-statement))
814 (when (or (and open (<= (current-indentation) ci))
815 (< (current-indentation) ci))
816 (python-skip-comments/blanks t)
817 (beginning-of-line 2)
818 (throw 'done t)))
819 (not (goto-char point))))))
820 (setq arg (1- arg)))
821 (zerop arg))
822
823 ;;;; Imenu.
824
825 (defvar python-recursing)
826 (defun python-imenu-create-index ()
827 "`imenu-create-index-function' for Python.
828
829 Makes nested Imenu menus from nested `class' and `def' statements.
830 The nested menus are headed by an item referencing the outer
831 definition; it has a space prepended to the name so that it sorts
832 first with `imenu--sort-by-name'."
833 (unless (boundp 'python-recursing) ; dynamically bound below
834 (goto-char (point-min))) ; normal call from Imenu
835 (let (index-alist ; accumulated value to return
836 name)
837 (while (re-search-forward
838 (rx (and line-start (0+ space) ; leading space
839 (or (group "def") (group "class")) ; type
840 (1+ space) (group (1+ (or word ?_))))) ; name
841 nil t)
842 (unless (python-in-string/comment)
843 (let ((pos (match-beginning 0))
844 (name (match-string-no-properties 3)))
845 (if (match-beginning 2) ; def or class?
846 (setq name (concat "class " name)))
847 (save-restriction
848 (narrow-to-defun)
849 (let* ((python-recursing t)
850 (sublist (python-imenu-create-index)))
851 (if sublist
852 (progn (push (cons (concat " " name) pos) sublist)
853 (push (cons name sublist) index-alist))
854 (push (cons name pos) index-alist)))))))
855 (nreverse index-alist)))
856
857 ;;;; `Electric' commands.
858
859 (defun python-electric-colon (arg)
860 "Insert a colon and maybe outdent the line if it is a statement like `else'.
861 With numeric ARG, just insert that many colons. With \\[universal-argument],
862 just insert a single colon."
863 (interactive "*P")
864 (self-insert-command (if (not (integerp arg)) 1 arg))
865 (and (not arg)
866 (eolp)
867 (python-outdent-p)
868 (not (python-in-string/comment))
869 (> (current-indentation) (python-calculate-indentation))
870 (python-indent-line))) ; OK, do it
871 (put 'python-electric-colon 'delete-selection t)
872
873 (defun python-backspace (arg)
874 "Maybe delete a level of indentation on the current line.
875 If not at the end of line's indentation, or on a comment line, just call
876 `backward-delete-char-untabify'. With ARG, repeat that many times."
877 (interactive "*p")
878 (if (or (/= (current-indentation) (current-column))
879 (bolp)
880 (python-continuation-line-p))
881 (backward-delete-char-untabify arg)
882 (let ((indent 0))
883 (save-excursion
884 (while (and (> arg 0) (python-beginning-of-block))
885 (setq arg (1- arg)))
886 (when (zerop arg)
887 (setq indent (current-indentation))
888 (message "Closes %s" (python-initial-text))))
889 (delete-horizontal-space)
890 (indent-to indent))))
891 (put 'python-backspace 'delete-selection 'supersede)
892
893 ;;;; pychecker
894
895 (defcustom python-check-command "pychecker --stdlib"
896 "*Command used to check a Python file."
897 :type 'string
898 :group 'python)
899
900 (defvar python-saved-check-command nil
901 "Internal use.")
902
903 ;; After `sgml-validate-command'.
904 (defun python-check (command)
905 "Check a Python file (default current buffer's file).
906 Runs COMMAND, a shell command, as if by `compile'.
907 See `python-check-command' for the default."
908 (interactive
909 (list (read-string "Checker command: "
910 (or python-saved-check-command
911 (concat python-check-command " "
912 (let ((name (buffer-file-name)))
913 (if name
914 (file-name-nondirectory name))))))))
915 (setq python-saved-check-command command)
916 (save-some-buffers (not compilation-ask-about-save) nil)
917 (compilation-start command))
918
919 ;;;; Inferior mode stuff (following cmuscheme).
920
921 (defcustom python-python-command "python"
922 "*Shell command to run Python interpreter.
923 Any arguments can't contain whitespace."
924 :group 'python
925 :type 'string)
926
927 (defcustom python-jython-command "jython"
928 "*Shell command to run Jython interpreter.
929 Any arguments can't contain whitespace."
930 :group 'python
931 :type 'string)
932
933 (defvar python-command python-python-command
934 "Actual command used to run Python.
935 May be `python-python-command' or `python-jython-command'.
936 Additional arguments are added when the command is used by `run-python'
937 et al.")
938
939 (defvar python-buffer nil
940 "*The current python process buffer.
941 To run multiple Python processes, start the first with \\[run-python].
942 It will be in a buffer named *Python*. Rename that with
943 \\[rename-buffer]. Now start a new process with \\[run-python]. It
944 will be in a new buffer, named *Python*. Switch between the different
945 process buffers with \\[switch-to-buffer].
946
947 Commands that send text from source buffers to Python processes have
948 to choose a process to send to. This is determined by global variable
949 `python-buffer'. Suppose you have three inferior Pythons running:
950 Buffer Process
951 foo python
952 bar python<2>
953 *Python* python<3>
954 If you do a \\[python-send-region-and-go] command on some Python source
955 code, what process does it go to?
956
957 - In a process buffer (foo, bar, or *Python*), send it to that process.
958 - In some other buffer (e.g. a source file), send it to the process
959 attached to `python-buffer'.
960 Process selection is done by function `python-proc'.
961
962 Whenever \\[run-python] starts a new process, it resets `python-buffer'
963 to be the new process's buffer. If you only run one process, this will
964 do the right thing. If you run multiple processes, you can change
965 `python-buffer' to another process buffer with \\[set-variable].")
966
967 (defconst python-compilation-regexp-alist
968 `((,(rx (and line-start (1+ (any " \t")) "File \""
969 (group (1+ (not (any "\"<")))) ; avoid `<stdin>' &c
970 "\", line " (group (1+ digit))))
971 1 python-compilation-line-number))
972 "`compilation-error-regexp-alist' for inferior Python.")
973
974 (define-derived-mode inferior-python-mode comint-mode "Inferior Python"
975 "Major mode for interacting with an inferior Python process.
976 A Python process can be started with \\[run-python].
977
978 Hooks `comint-mode-hook' and `inferior-python-mode-hook' are run in
979 that order.
980
981 You can send text to the inferior Python process from other buffers containing
982 Python source.
983 * `python-switch-to-python' switches the current buffer to the Python
984 process buffer.
985 * `python-send-region' sends the current region to the Python process.
986 * `python-send-region-and-go' switches to the Python process buffer
987 after sending the text.
988 For running multiple processes in multiple buffers, see `python-buffer'.
989
990 \\{inferior-python-mode-map}"
991 :group 'python
992 (set-syntax-table python-mode-syntax-table)
993 (setq mode-line-process '(":%s"))
994 ;; Fixme: Maybe install some python-mode bindings too.
995 (define-key inferior-python-mode-map "\C-c\C-l" 'python-load-file)
996 (define-key inferior-python-mode-map "\C-c\C-z" 'python-switch-to-python)
997 (add-hook 'comint-input-filter-functions 'python-input-filter nil t)
998 (add-hook 'comint-preoutput-filter-functions #'python-preoutput-filter
999 nil t)
1000 ;; Still required by `comint-redirect-send-command', for instance:
1001 (set (make-local-variable 'comint-prompt-regexp) "^\\([>.]\\{3\\} \\)+")
1002 (set (make-local-variable 'compilation-error-regexp-alist)
1003 python-compilation-regexp-alist)
1004 (compilation-shell-minor-mode 1))
1005
1006 (defcustom inferior-python-filter-regexp "\\`\\s-*\\S-?\\S-?\\s-*\\'"
1007 "*Input matching this regexp is not saved on the history list.
1008 Default ignores all inputs of 0, 1, or 2 non-blank characters."
1009 :type 'regexp
1010 :group 'python)
1011
1012 (defvar python-orig-start nil
1013 "Marker to the start of the region passed to the inferior Python.
1014 It can also be a filename.")
1015
1016 (defun python-input-filter (str)
1017 "`comint-input-filter' function for inferior Python.
1018 Don't save anything for STR matching `inferior-python-filter-regexp'.
1019 Also resets variables for adjusting error messages."
1020 (setq python-orig-start nil)
1021 (not (string-match inferior-python-filter-regexp str)))
1022
1023 ;; Fixme: Loses with quoted whitespace.
1024 (defun python-args-to-list (string)
1025 (let ((where (string-match "[ \t]" string)))
1026 (cond ((null where) (list string))
1027 ((not (= where 0))
1028 (cons (substring string 0 where)
1029 (python-args-to-list (substring string (+ 1 where)))))
1030 (t (let ((pos (string-match "[^ \t]" string)))
1031 (if pos (python-args-to-list (substring string pos))))))))
1032
1033 (defun python-compilation-line-number (file col)
1034 "Return error descriptor of error found for FILE, column COL.
1035 Used as line-number hook function in `python-compilation-regexp-alist'."
1036 (let ((line (string-to-number (match-string 2))))
1037 (cons (point-marker)
1038 (if (and (markerp python-orig-start)
1039 (marker-buffer python-orig-start))
1040 (with-current-buffer (marker-buffer python-orig-start)
1041 (goto-char python-orig-start)
1042 (forward-line (1- line)))
1043 (list (if (stringp python-orig-start) python-orig-start file)
1044 line nil)))))
1045
1046 (defvar python-preoutput-result nil
1047 "Data from output line last `_emacs_out' line seen by the preoutput filter.")
1048
1049 (defvar python-preoutput-continuation nil
1050 "If non-nil, funcall this when `python-preoutput-filter' sees `_emacs_ok'.")
1051
1052 ;; Using this stops us getting lines in the buffer like
1053 ;; >>> ... ... >>>
1054 ;; Also look for (and delete) an `_emacs_ok' string and call
1055 ;; `python-preoutput-continuation' if we get it.
1056 (defun python-preoutput-filter (s)
1057 "`comint-preoutput-filter-functions' function: ignore prompts not at bol."
1058 (cond ((and (string-match "\\`[.>]\\{3\\} \\'" s)
1059 (/= (let ((inhibit-field-text-motion t))
1060 (line-beginning-position))
1061 (point)))
1062 "")
1063 ((string= s "_emacs_ok\n")
1064 (when python-preoutput-continuation
1065 (funcall python-preoutput-continuation)
1066 (setq python-preoutput-continuation nil))
1067 "")
1068 ((string-match "_emacs_out \\(.*\\)\n" s)
1069 (setq python-preoutput-result (match-string 1 s))
1070 "")
1071 (t s)))
1072
1073 ;;;###autoload
1074 (defun run-python (&optional cmd noshow)
1075 "Run an inferior Python process, input and output via buffer *Python*.
1076 CMD is the Python command to run. NOSHOW non-nil means don't show the
1077 buffer automatically.
1078 If there is a process already running in `*Python*', switch to
1079 that buffer. Interactively a prefix arg, allows you to edit the initial
1080 command line (default is the value of `python-command'); `-i' etc. args
1081 will be added to this as appropriate. Runs the hooks
1082 `inferior-python-mode-hook' (after the `comint-mode-hook' is run).
1083 \(Type \\[describe-mode] in the process buffer for a list of commands.)"
1084 (interactive (list (if current-prefix-arg
1085 (read-string "Run Python: " python-command)
1086 python-command)))
1087 (unless cmd (setq cmd python-python-command))
1088 (setq python-command cmd)
1089 ;; Fixme: Consider making `python-buffer' buffer-local as a buffer
1090 ;; (not a name) in Python buffers from which `run-python' &c is
1091 ;; invoked. Would support multiple processes better.
1092 (unless (comint-check-proc "*Python*")
1093 (let ((cmdlist (append (python-args-to-list cmd) '("-i"))))
1094 (set-buffer (apply 'make-comint "Python" (car cmdlist) nil
1095 (cdr cmdlist))))
1096 (inferior-python-mode)
1097 ;; Load function defintions we need.
1098 ;; Before the preoutput function was used, this was done via -c in
1099 ;; cmdlist, but that loses the banner and doesn't run the startup
1100 ;; file.
1101 (python-send-string "\
1102 def _emacs_execfile (file): # execute file and remove it
1103 from os import remove
1104 try: execfile (file, globals (), globals ())
1105 finally: remove (file)
1106
1107 def _emacs_args (name): # get arglist of name for eldoc &c
1108 import inspect
1109 parts = name.split ('.')
1110 if len (parts) > 1:
1111 try: exec 'import ' + parts[0]
1112 except: return None
1113 try: exec 'func='+name # lose if name is keyword or undefined
1114 except: return None
1115 if inspect.isbuiltin (func):
1116 doc = func.__doc__
1117 if doc.find (' ->') != -1:
1118 print '_emacs_out', doc.split (' ->')[0]
1119 elif doc.find ('\\n') != -1:
1120 print '_emacs_out', doc.split ('\\n')[0]
1121 return None
1122 if inspect.ismethod (func): func = func.im_func
1123 if not inspect.isfunction (func):
1124 return None
1125 (args, varargs, varkw, defaults) = inspect.getargspec (func)
1126 print '_emacs_out', func.__name__+inspect.formatargspec (args, varargs, varkw, defaults)
1127
1128 print '_emacs_ok'"))
1129 (unless noshow (pop-to-buffer (setq python-buffer "*Python*"))))
1130
1131 (defun python-send-region (start end)
1132 "Send the region to the inferior Python process."
1133 ;; The region is evaluated from a temporary file. This avoids
1134 ;; problems with blank lines, which have different semantics
1135 ;; interactively and in files. It also saves the inferior process
1136 ;; buffer filling up with interpreter prompts. We need a function
1137 ;; to remove the temporary file when it has been evaluated, which
1138 ;; unfortunately means using a not-quite pristine interpreter
1139 ;; initially. Unfortunately we also get tracebacks which look like:
1140 ;;
1141 ;; >>> Traceback (most recent call last):
1142 ;; File "<stdin>", line 1, in ?
1143 ;; File "<string>", line 4, in _emacs_execfile
1144 ;; File "/tmp/py7734RSB", line 11
1145 ;;
1146 ;; The compilation-minor-mode parsing takes care of relating the
1147 ;; reference to the temporary file to the source. Fixme:
1148 ;; comint-filter the first two lines of the traceback?
1149 (interactive "r")
1150 (let* ((f (make-temp-file "py"))
1151 (command (format "_emacs_execfile(%S)" f))
1152 (orig-start (copy-marker start)))
1153 (if (save-excursion
1154 (goto-char start)
1155 (/= 0 (current-indentation))) ; need dummy block
1156 (write-region "if True:\n" nil f nil 'nomsg))
1157 (write-region start end f t 'nomsg)
1158 (when python-buffer
1159 (with-current-buffer python-buffer
1160 (let ((end (marker-position (process-mark (python-proc)))))
1161 (set (make-local-variable 'python-orig-start) orig-start)
1162 (set (make-local-variable 'compilation-error-list) nil)
1163 (let ((comint-input-filter-functions
1164 (delete 'python-input-filter comint-input-filter-functions)))
1165 (python-send-string command))
1166 (set-marker compilation-parsing-end end)
1167 (setq compilation-last-buffer (current-buffer)))))))
1168
1169 (defun python-send-string (string)
1170 "Evaluate STRING in inferior Python process."
1171 (interactive "sPython command: ")
1172 (comint-send-string (python-proc) string)
1173 (comint-send-string (python-proc) "\n\n"))
1174
1175 (defun python-send-buffer ()
1176 "Send the current buffer to the inferior Python process."
1177 (interactive)
1178 (python-send-region (point-min) (point-max)))
1179
1180 (defun python-send-defun ()
1181 "Send the current defun (class or method) to the inferior Python process."
1182 (interactive)
1183 (save-excursion (python-send-region (progn (beginning-of-defun) (point))
1184 (progn (end-of-defun) (point)))))
1185
1186 (defun python-switch-to-python (eob-p)
1187 "Switch to the Python process buffer.
1188 With prefix arg, position cursor at end of buffer."
1189 (interactive "P")
1190 (if (get-buffer python-buffer)
1191 (pop-to-buffer python-buffer)
1192 (error "No current process buffer. See variable `python-buffer'"))
1193 (when eob-p
1194 (push-mark)
1195 (goto-char (point-max))))
1196
1197 (add-to-list 'debug-ignored-errors "^No current process buffer.")
1198
1199 (defun python-send-region-and-go (start end)
1200 "Send the region to the inferior Python process.
1201 Then switch to the process buffer."
1202 (interactive "r")
1203 (python-send-region start end)
1204 (python-switch-to-python t))
1205
1206 (defcustom python-source-modes '(python-mode jython-mode)
1207 "*Used to determine if a buffer contains Python source code.
1208 If it's loaded into a buffer that is in one of these major modes, it's
1209 considered a Python source file by `python-load-file'.
1210 Used by these commands to determine defaults."
1211 :type '(repeat function)
1212 :group 'python)
1213
1214 (defvar python-prev-dir/file nil
1215 "Caches (directory . file) pair used in the last `python-load-file' command.
1216 Used for determining the default in the next one.")
1217
1218 (defun python-load-file (file-name)
1219 "Load a Python file FILE-NAME into the inferior Python process.
1220 If the file has extension `.py' import or reload it as a module.
1221 Treating it as a module keeps the global namespace clean, provides
1222 function location information for debugging, and supports users of
1223 module-qualified names."
1224 (interactive (comint-get-source "Load Python file: " python-prev-dir/file
1225 python-source-modes
1226 t)) ; because execfile needs exact name
1227 (comint-check-source file-name) ; Check to see if buffer needs saved.
1228 (setq python-prev-dir/file (cons (file-name-directory file-name)
1229 (file-name-nondirectory file-name)))
1230 (when python-buffer
1231 (with-current-buffer python-buffer
1232 (let ((end (marker-position (process-mark (python-proc)))))
1233 (set (make-local-variable 'compilation-error-list) nil)
1234 ;; (set (make-local-variable 'compilation-old-error-list) nil)
1235 (let ((comint-input-filter-functions
1236 (delete 'python-input-filter comint-input-filter-functions)))
1237 (python-send-string
1238 (if (string-match "\\.py\\'" file-name)
1239 ;; Fixme: make sure the directory is in the path list
1240 (let ((module (file-name-sans-extension
1241 (file-name-nondirectory file-name))))
1242 (set (make-local-variable 'python-orig-start) nil)
1243 (format "\
1244 if globals().has_key(%S): reload(%s)
1245 else: import %s
1246 " module module module))
1247 (set (make-local-variable 'python-orig-start) file-name)
1248 (format "execfile('%s')" file-name))))
1249 (set-marker compilation-parsing-end end)
1250 (setq compilation-last-buffer (current-buffer))))))
1251
1252 ;; Fixme: Should this start a process if there isn't one? (Unlike cmuscheme.)
1253 (defun python-proc ()
1254 "Return the current Python process. See variable `python-buffer'."
1255 (let ((proc (get-buffer-process (if (eq major-mode 'inferior-python-mode)
1256 (current-buffer)
1257 python-buffer))))
1258 (or proc (error "No current process. See variable `python-buffer'"))))
1259
1260 ;;;; Context-sensitive help.
1261
1262 (defconst python-dotty-syntax-table
1263 (let ((table (make-syntax-table)))
1264 (set-char-table-parent table python-mode-syntax-table)
1265 (modify-syntax-entry ?. "_" table)
1266 table)
1267 "Syntax table giving `.' symbol syntax.
1268 Otherwise inherits from `python-mode-syntax-table'.")
1269
1270 ;; Fixme: Should this actually be used instead of info-look, i.e. be
1271 ;; bound to C-h S?
1272 (defun python-describe-symbol (symbol)
1273 "Get help on SYMBOL using `pydoc'.
1274 Interactively, prompt for symbol."
1275 ;; Note that we do this in the inferior process, not a separate one to
1276 ;; ensure the environment is appropriate.
1277 (interactive
1278 (let ((symbol (with-syntax-table python-dotty-syntax-table
1279 (current-word)))
1280 (enable-recursive-minibuffers t)
1281 val)
1282 (setq val (read-string (if symbol
1283 (format "Describe symbol (default %s): "
1284 symbol)
1285 "Describe symbol: ")
1286 nil nil symbol))
1287 (list (or val symbol))))
1288 (if (equal symbol "") (error "No symbol"))
1289 (let* ((func `(lambda ()
1290 (comint-redirect-send-command (format "help(%S)\n" ,symbol)
1291 "*Help*" nil))))
1292 ;; Ensure we have a suitable help buffer.
1293 (let (temp-buffer-show-hook) ; avoid xref stuff
1294 (with-output-to-temp-buffer "*Help*"
1295 (with-current-buffer standard-output
1296 (set (make-local-variable 'comint-redirect-subvert-readonly) t))))
1297 (if (and python-buffer (get-buffer python-buffer))
1298 (with-current-buffer python-buffer
1299 (funcall func))
1300 (setq python-preoutput-continuation func)
1301 (run-python nil t))))
1302
1303 (add-to-list 'debug-ignored-errors "^No symbol")
1304
1305 ;; Fixme: try to make it work with point in the arglist. Also, is
1306 ;; there anything reasonable we can do with random methods?
1307 ;; (Currently only works with functions.)
1308 (defun python-eldoc-function ()
1309 "`eldoc-print-current-symbol-info' for Python.
1310 Only works when point is in a function name, not its arglist, for instance.
1311 Assumes an inferior Python is running."
1312 (let ((symbol (with-syntax-table python-dotty-syntax-table
1313 (current-word)))
1314 (proc (and python-buffer (python-proc))))
1315 (when (and proc symbol)
1316 (python-send-string
1317 (format "_emacs_args(%S)" symbol))
1318 (setq python-preoutput-result nil)
1319 (accept-process-output proc 1)
1320 python-preoutput-result)))
1321
1322 ;;;; Info-look functionality.
1323
1324 (defun python-after-info-look ()
1325 "Set up info-look for Python.
1326 Used with `eval-after-load'."
1327 (let* ((version (let ((s (shell-command-to-string (concat python-command
1328 " -V"))))
1329 (string-match "^Python \\([0-9]+\\.[0-9]+\\>\\)" s)
1330 (match-string 1 s)))
1331 ;; Whether info files have a Python version suffix, e.g. in Debian.
1332 (versioned
1333 (with-temp-buffer
1334 (Info-mode)
1335 (condition-case ()
1336 ;; Don't use `info' because it would pop-up a *info* buffer.
1337 (Info-goto-node (format "(python%s-lib)Miscellaneous Index"
1338 version))
1339 (error nil)))))
1340 (info-lookup-maybe-add-help
1341 :mode 'python-mode
1342 :regexp "[[:alnum:]_]+"
1343 :doc-spec
1344 ;; Fixme: Can this reasonably be made specific to indices with
1345 ;; different rules? Is the order of indices optimal?
1346 ;; (Miscellaneous in -ref first prefers lookup of keywords, for
1347 ;; instance.)
1348 (if versioned
1349 ;; The empty prefix just gets us highlighted terms.
1350 `((,(concat "(python" version "-ref)Miscellaneous Index") nil "")
1351 (,(concat "(python" version "-ref)Module Index" nil ""))
1352 (,(concat "(python" version "-ref)Function-Method-Variable Index"
1353 nil ""))
1354 (,(concat "(python" version "-ref)Class-Exception-Object Index"
1355 nil ""))
1356 (,(concat "(python" version "-lib)Module Index" nil ""))
1357 (,(concat "(python" version "-lib)Class-Exception-Object Index"
1358 nil ""))
1359 (,(concat "(python" version "-lib)Function-Method-Variable Index"
1360 nil ""))
1361 (,(concat "(python" version "-lib)Miscellaneous Index" nil "")))
1362 '(("(python-ref)Miscellaneous Index" nil "")
1363 ("(python-ref)Module Index" nil "")
1364 ("(python-ref)Function-Method-Variable Index" nil "")
1365 ("(python-ref)Class-Exception-Object Index" nil "")
1366 ("(python-lib)Module Index" nil "")
1367 ("(python-lib)Class-Exception-Object Index" nil "")
1368 ("(python-lib)Function-Method-Variable Index" nil "")
1369 ("(python-lib)Miscellaneous Index" nil ""))))))
1370 (eval-after-load "info-look" '(python-after-info-look))
1371
1372 ;;;; Miscellancy.
1373
1374 (defcustom python-jython-packages '("java" "javax" "org" "com")
1375 "Packages implying `jython-mode'.
1376 If these are imported near the beginning of the buffer, `python-mode'
1377 actually punts to `jython-mode'."
1378 :type '(repeat string)
1379 :group 'python)
1380
1381 ;; Called from `python-mode', this causes a recursive call of the
1382 ;; mode. See logic there to break out of the recursion.
1383 (defun python-maybe-jython ()
1384 "Invoke `jython-mode' if the buffer appears to contain Jython code.
1385 The criterion is either a match for `jython-mode' via
1386 `interpreter-mode-alist' or an import of a module from the list
1387 `python-jython-packages'."
1388 ;; The logic is taken from python-mode.el.
1389 (save-excursion
1390 (save-restriction
1391 (widen)
1392 (goto-char (point-min))
1393 (let ((interpreter (if (looking-at auto-mode-interpreter-regexp)
1394 (match-string 2))))
1395 (if (and interpreter (eq 'jython-mode
1396 (cdr (assoc (file-name-nondirectory
1397 interpreter)
1398 interpreter-mode-alist))))
1399 (jython-mode)
1400 (if (catch 'done
1401 (while (re-search-forward
1402 (rx (and line-start (or "import" "from") (1+ space)
1403 (group (1+ (not (any " \t\n."))))))
1404 10000 ; Probably not worth customizing.
1405 t)
1406 (if (member (match-string 1) python-jython-packages)
1407 (throw 'done t))))
1408 (jython-mode)))))))
1409
1410 (defun python-fill-paragraph (&optional justify)
1411 "`fill-paragraph-function' handling comments and multi-line strings.
1412 If any of the current line is a comment, fill the comment or the
1413 paragraph of it that point is in, preserving the comment's
1414 indentation and initial comment characters. Similarly if the end
1415 of the current line is in or at the end of a multi-line string.
1416 Otherwise, do nothing."
1417 (interactive "P")
1418 (or (fill-comment-paragraph justify)
1419 ;; The `paragraph-start' and `paragraph-separate' variables
1420 ;; don't allow us to delimit the last paragraph in a multi-line
1421 ;; string properly, so narrow to the string and then fill around
1422 ;; (the end of) the current line.
1423 (save-excursion
1424 (end-of-line)
1425 (let* ((syntax (syntax-ppss))
1426 (orig (point))
1427 (start (nth 8 syntax))
1428 end)
1429 (cond ((eq t (nth 3 syntax)) ; in fenced string
1430 (goto-char (nth 8 syntax)) ; string start
1431 (condition-case () ; for unbalanced quotes
1432 (progn (forward-sexp)
1433 (setq end (point)))
1434 (error (setq end (point-max)))))
1435 ((re-search-backward "\\s|\\s-*\\=" nil t) ; end of fenced
1436 ; string
1437 (forward-char)
1438 (setq end (point))
1439 (condition-case ()
1440 (progn (backward-sexp)
1441 (setq start (point)))
1442 (error nil))))
1443 (when end
1444 (save-restriction
1445 (narrow-to-region start end)
1446 (goto-char orig)
1447 (fill-paragraph justify))))))
1448 t)
1449
1450 (defun python-shift-left (start end &optional count)
1451 "Shift lines in region COUNT (the prefix arg) columns to the left.
1452 COUNT defaults to `python-indent'. If region isn't active, just shift
1453 current line. The region shifted includes the lines in which START and
1454 END lie. It is an error if any lines in the region are indented less than
1455 COUNT columns."
1456 (interactive (if mark-active
1457 (list (region-beginning) (region-end) current-prefix-arg)
1458 (list (point) (point) current-prefix-arg)))
1459 (if count
1460 (setq count (prefix-numeric-value count))
1461 (setq count python-indent))
1462 (when (> count 0)
1463 (save-excursion
1464 (goto-char start)
1465 (while (< (point) end)
1466 (if (and (< (current-indentation) count)
1467 (not (looking-at "[ \t]*$")))
1468 (error "Can't shift all lines enough"))
1469 (forward-line))
1470 (indent-rigidly start end (- count)))))
1471
1472 (add-to-list 'debug-ignored-errors "^Can't shift all lines enough")
1473
1474 (defun python-shift-right (start end &optional count)
1475 "Shift lines in region COUNT (the prefix arg) columns to the right.
1476 COUNT defaults to `python-indent'. If region isn't active, just shift
1477 current line. The region shifted includes the lines in which START and
1478 END lie."
1479 (interactive (if mark-active
1480 (list (region-beginning) (region-end) current-prefix-arg)
1481 (list (point) (point) current-prefix-arg)))
1482 (if count
1483 (setq count (prefix-numeric-value count))
1484 (setq count python-indent))
1485 (indent-rigidly start end count))
1486
1487 (defun python-outline-level ()
1488 "`outline-level' function for Python mode.
1489 The level is the number of `python-indent' steps of indentation
1490 of current line."
1491 (/ (current-indentation) python-indent))
1492
1493 ;; Fixme: Consider top-level assignments, imports, &c.
1494 (defun python-current-defun ()
1495 "`add-log-current-defun-function' for Python."
1496 (save-excursion
1497 ;; Move up the tree of nested `class' and `def' blocks until we
1498 ;; get to zero indentation, accumulating the defined names.
1499 (let ((start t)
1500 accum)
1501 (while (or start (> (current-indentation) 0))
1502 (setq start nil)
1503 (python-beginning-of-block)
1504 (end-of-line)
1505 (beginning-of-defun)
1506 (if (looking-at (rx (and (0+ space) (or "def" "class") (1+ space)
1507 (group (1+ (or word (syntax symbol))))
1508 word-end)))
1509 (push (match-string 1) accum)))
1510 (if accum (mapconcat 'identity accum ".")))))
1511
1512 (defun python-mark-block ()
1513 "Mark the block around point.
1514 Uses `python-beginning-of-block', `python-end-of-block'."
1515 (interactive)
1516 (push-mark)
1517 (python-beginning-of-block)
1518 (push-mark (point) nil t)
1519 (python-end-of-block)
1520 (exchange-point-and-mark))
1521
1522 ;;;; Modes.
1523
1524 (defvar outline-heading-end-regexp)
1525 (defvar eldoc-print-current-symbol-info-function)
1526 (defvar python-mode-running)
1527 ;;;###autoload
1528 (define-derived-mode python-mode fundamental-mode "Python"
1529 "Major mode for editing Python files.
1530 Turns on Font Lock mode unconditionally since it is required for correct
1531 parsing of the source.
1532 See also `jython-mode', which is actually invoked if the buffer appears to
1533 contain Jython code. See also `run-python' and associated Python mode
1534 commands for running Python under Emacs.
1535
1536 The Emacs commands which work with `defun's, e.g. \\[beginning-of-defun], deal
1537 with nested `def' and `class' blocks. They take the innermost one as
1538 current without distinguishing method and class definitions. Used multiple
1539 times, they move over others at the same indentation level until they reach
1540 the end of definitions at that level, when they move up a level.
1541 \\<python-mode-map>
1542 Colon is electric: it outdents the line if appropriate, e.g. for
1543 an else statement. \\[python-backspace] at the beginning of an indented statement
1544 deletes a level of indentation to close the current block; otherwise it
1545 deletes a charcter backward. TAB indents the current line relative to
1546 the preceding code. Successive TABs, with no intervening command, cycle
1547 through the possibilities for indentation on the basis of enclosing blocks.
1548
1549 \\[fill-paragraph] fills comments and multiline strings appropriately, but has no
1550 effect outside them.
1551
1552 Supports Eldoc mode (only for functions, using a Python process),
1553 Info-Look and Imenu. In Outline minor mode, `class' and `def'
1554 lines count as headers.
1555
1556 \\{python-mode-map}"
1557 :group 'python
1558 (set (make-local-variable 'font-lock-defaults)
1559 '(python-font-lock-keywords nil nil ((?_ . "w")) nil
1560 (font-lock-syntactic-keywords
1561 . python-font-lock-syntactic-keywords)
1562 ;;; This probably isn't worth it.
1563 ;;; (font-lock-syntactic-face-function
1564 ;;; . python-font-lock-syntactic-face-function)
1565 ))
1566 (set (make-local-variable 'parse-sexp-lookup-properties) t)
1567 (set (make-local-variable 'comment-start) "# ")
1568 ;; Fixme: define a comment-indent-function?
1569 (set (make-local-variable 'indent-line-function) #'python-indent-line)
1570 (set (make-local-variable 'paragraph-start) "\\s-*$")
1571 (set (make-local-variable 'fill-paragraph-function)
1572 'python-fill-paragraph)
1573 (set (make-local-variable 'require-final-newline) t)
1574 (set (make-local-variable 'add-log-current-defun-function)
1575 #'python-current-defun)
1576 ;; Fixme: Generalize to do all blocks?
1577 (set (make-local-variable 'outline-regexp) "\\s-*\\(def\\|class\\)\\>")
1578 (set (make-local-variable 'outline-heading-end-regexp) ":\\s-*\n")
1579 (set (make-local-variable 'outline-level) #'python-outline-level)
1580 (set (make-local-variable 'open-paren-in-column-0-is-defun-start) nil)
1581 (make-local-variable 'python-saved-check-command)
1582 (set (make-local-variable 'beginning-of-defun-function)
1583 'python-beginning-of-defun)
1584 (set (make-local-variable 'end-of-defun-function) 'python-end-of-defun)
1585 (setq imenu-create-index-function #'python-imenu-create-index)
1586 (set (make-local-variable 'eldoc-print-current-symbol-info-function)
1587 #'python-eldoc-function)
1588 (add-hook 'eldoc-mode-hook
1589 '(lambda () (run-python 0 t)) nil t) ; need it running
1590 (unless font-lock-mode (font-lock-mode 1))
1591 (when python-guess-indent (python-guess-indent))
1592 (set (make-local-variable 'python-command) python-python-command)
1593 (unless (boundp 'python-mode-running) ; kill the recursion from jython-mode
1594 (let ((python-mode-running t))
1595 (python-maybe-jython))))
1596
1597 (custom-add-option 'python-mode-hook 'imenu-add-menubar-index)
1598 (custom-add-option 'python-mode-hook
1599 '(lambda ()
1600 "Turn on Indent Tabs mode."
1601 (set (make-local-variable 'indent-tabs-mode) t)))
1602 (custom-add-option 'python-mode-hook 'turn-on-eldoc-mode)
1603
1604 ;;;###autoload
1605 (define-derived-mode jython-mode python-mode "Jython"
1606 "Major mode for editing Jython files.
1607 Like `python-mode', but sets up parameters for Jython subprocesses.
1608 Runs `jython-mode-hook' after `python-mode-hook'."
1609 :group 'python
1610 (set (make-local-variable 'python-command) python-jython-command))
1611
1612 (provide 'python)
1613 ;; arch-tag: 6fce1d99-a704-4de9-ba19-c6e4912b0554
1614 ;;; python.el ends here