comparison lisp/progmodes/python.el @ 89943:4c90ffeb71c5

Revision: miles@gnu.org--gnu-2004/emacs--unicode--0--patch-15 Merge from emacs--cvs-trunk--0 Patches applied: * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-218 - miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-220 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-221 Restore deleted tagline in etc/TUTORIAL.ru * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-222 - miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-228 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-229 Remove TeX output files from the archive * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-230 - miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-247 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-248 src/lisp.h (CYCLE_CHECK): Macro moved from xfaces.c * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-249 - miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-256 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-258 - miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-263 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-264 Update from CVS: lispref/display.texi: emacs -> Emacs. * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-265 - miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-274 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-275 Update from CVS: man/makefile.w32-in: Revert last change * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-276 - miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-295 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-296 Allow restarting an existing debugger session that's exited * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-297 - miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-299 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-300 - miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-327 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-328 Update from CVS: src/.gdbinit (xsymbol): Fix last change. * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-329 - miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-344 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-345 Tweak source regexps so that building in place won't cause problems * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-346 - miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-351 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-352 Update from CVS: lisp/flymake.el: New file. * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-353 - miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-361 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-362 Support " [...]" style defaults in minibuffer-electric-default-mode * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-363 (read-number): Use canonical format for default in prompt. * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-364 - miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-367 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-368 Improve display-supports-face-attributes-p on non-ttys * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-369 Rewrite face-differs-from-default-p * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-370 Move `display-supports-face-attributes-p' entirely into C code * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-371 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-372 Simplify face-differs-from-default-p; don't consider :stipple. * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-373 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-374 (tty_supports_face_attributes_p): Ensure attributes differ from default * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-375 - miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-376 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-377 (Fdisplay_supports_face_attributes_p): Work around bootstrapping problem * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-378 - miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-380 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-381 Face merging cleanups * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-382 - miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-384 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-385 src/xfaces.c (push_named_merge_point): Return 0 if a cycle is detected * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-386 - miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-395 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-396 Tweak arch tagging to make build/install-in-place less annoying * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-397 Work around vc-arch problems when building eshell * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-398 Tweak permissions * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-399 Tweak directory permissions * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-400 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-401 More build-in-place tweaking of arch tagging * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-402 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-403 Yet more build-in-place tweaking of arch tagging * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-404 - miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-409 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-410 Make sure image types are initialized for lookup too * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-411 - miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-416 Update from CVS
author Miles Bader <miles@gnu.org>
date Mon, 28 Jun 2004 07:56:49 +0000
parents 68c22ea6027c 0cecb3d4d566
children 6f6e9fe4658b
comparison
equal deleted inserted replaced
89942:9cb747ae49af 89943:4c90ffeb71c5
1 ;;; python.el --- silly walks for Python 1 ;;; python.el --- silly walks for Python
2 2
3 ;; Copyright (C) 2003, 04 Free Software Foundation, Inc. 3 ;; Copyright (C) 2003, 04 Free Software Foundation, Inc.
4 4
5 ;; Author: Dave Love <fx@gnu.org> 5 ;; Author: Dave Love <fx@gnu.org>
6 ;; Maintainer: FSF
6 ;; Created: Nov 2003 7 ;; Created: Nov 2003
7 ;; Keywords: languages 8 ;; Keywords: languages
8 9
9 ;; This file is part of GNU Emacs. 10 ;; This file is part of GNU Emacs.
10 11
43 ;; don't seem appropriate. For instance, `forward-into-nomenclature' 44 ;; don't seem appropriate. For instance, `forward-into-nomenclature'
44 ;; should be done separately, since it's not specific to Python, and 45 ;; 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 ;; 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 ;; Other things seem more natural or canonical here, e.g. the
47 ;; {beginning,end}-of-defun implementation dealing with nested 48 ;; {beginning,end}-of-defun implementation dealing with nested
48 ;; definitions, and the inferior mode following `cmuscheme'. (The 49 ;; definitions, and the inferior mode following `cmuscheme'. The
49 ;; inferior mode should be able to find the source of errors from 50 ;; inferior mode can find the source of errors from
50 ;; `python-send-region' & al via `compilation-minor-mode', but I can't 51 ;; `python-send-region' & al via `compilation-minor-mode'. Successive
51 ;; make that work with the current (March '04) compile.el.) 52 ;; TABs cycle between possible indentations for the line. There is
52 ;; Successive TABs cycle between possible indentations for the line. 53 ;; symbol completion using lookup in Python.
53 54
54 ;; Even where it has similar facilities, this is incompatible with 55 ;; Even where it has similar facilities, this is incompatible with
55 ;; python-mode.el in various respects. For instance, various key 56 ;; python-mode.el in various respects. For instance, various key
56 ;; bindings are changed to obey Emacs conventions, and things like 57 ;; bindings are changed to obey Emacs conventions, and things like
57 ;; marking blocks and `beginning-of-defun' behave differently. 58 ;; marking blocks and `beginning-of-defun' behave differently.
58 59
59 ;; TODO: See various Fixmes below. It should be possible to arrange 60 ;; TODO: See various Fixmes below.
60 ;; some sort of completion using the inferior interpreter.
61 61
62 ;;; Code: 62 ;;; Code:
63 63
64 ;; It's messy to autoload the relevant comint functions so that comint 64 ;; It's messy to autoload the relevant comint functions so that comint
65 ;; is only required when inferior Python is used. 65 ;; is only required when inferior Python is used.
66 (require 'comint) 66 (require 'comint)
67 (eval-when-compile 67 (eval-when-compile
68 (require 'compile) 68 (require 'compile)
69 (autoload 'Info-last "info")
70 (autoload 'Info-exit "info")
71 (autoload 'info-lookup-maybe-add-help "info-look")) 69 (autoload 'info-lookup-maybe-add-help "info-look"))
72 (autoload 'compilation-start "compile") ; spurious compiler warning anyway 70 (autoload 'compilation-start "compile")
73 71
74 (defgroup python nil 72 (defgroup python nil
75 "Silly walks in the Python language" 73 "Silly walks in the Python language"
76 :group 'languages 74 :group 'languages
77 :version "21.4" 75 :version "21.4"
202 (define-key map "\C-c\M-r" 'python-send-region-and-go) 200 (define-key map "\C-c\M-r" 'python-send-region-and-go)
203 (define-key map "\C-c\C-c" 'python-send-buffer) 201 (define-key map "\C-c\C-c" 'python-send-buffer)
204 (define-key map "\C-c\C-z" 'python-switch-to-python) 202 (define-key map "\C-c\C-z" 'python-switch-to-python)
205 (define-key map "\C-c\C-m" 'python-load-file) 203 (define-key map "\C-c\C-m" 'python-load-file)
206 (define-key map "\C-c\C-l" 'python-load-file) ; a la cmuscheme 204 (define-key map "\C-c\C-l" 'python-load-file) ; a la cmuscheme
205 (substitute-key-definition 'complete-symbol 'python-complete-symbol
206 map global-map)
207 ;; Fixme: Add :help to menu. 207 ;; Fixme: Add :help to menu.
208 (easy-menu-define python-menu map "Python Mode menu" 208 (easy-menu-define python-menu map "Python Mode menu"
209 '("Python" 209 '("Python"
210 ["Shift region left" python-shift-left :active mark-active] 210 ["Shift region left" python-shift-left :active mark-active]
211 ["Shift region right" python-shift-right :active mark-active] 211 ["Shift region right" python-shift-right :active mark-active]
260 table)) 260 table))
261 261
262 ;;;; Utility stuff 262 ;;;; Utility stuff
263 263
264 (defsubst python-in-string/comment () 264 (defsubst python-in-string/comment ()
265 "Return non-nil if point is in a Python literal (a comment or string). 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))) 266 (syntax-ppss-context (syntax-ppss)))
269 267
270 (defconst python-space-backslash-table 268 (defconst python-space-backslash-table
271 (let ((table (copy-syntax-table python-mode-syntax-table))) 269 (let ((table (copy-syntax-table python-mode-syntax-table)))
272 (modify-syntax-entry ?\\ " " table) 270 (modify-syntax-entry ?\\ " " table)
297 (/= 0 (syntax-ppss-depth 295 (/= 0 (syntax-ppss-depth
298 (save-excursion ; syntax-ppss with arg changes point 296 (save-excursion ; syntax-ppss with arg changes point
299 (syntax-ppss (line-beginning-position))))))) 297 (syntax-ppss (line-beginning-position)))))))
300 298
301 (defun python-comment-line-p () 299 (defun python-comment-line-p ()
302 "Return non-nil if current line has only a comment or is blank." 300 "Return non-nil iff current line has only a comment."
303 (save-excursion 301 (save-excursion
304 (back-to-indentation) 302 (end-of-line)
305 (looking-at (rx (or (syntax comment-start) line-end))))) 303 (when (eq 'comment (syntax-ppss-context (syntax-ppss)))
304 (back-to-indentation)
305 (looking-at (rx (or (syntax comment-start) line-end))))))
306 306
307 (defun python-beginning-of-string () 307 (defun python-beginning-of-string ()
308 "Go to beginning of string around point. 308 "Go to beginning of string around point.
309 Do nothing if not in string." 309 Do nothing if not in string."
310 (let ((state (syntax-ppss))) 310 (let ((state (syntax-ppss)))
311 (when (nth 3 state) 311 (when (eq 'string (syntax-ppss-context state))
312 (goto-char (nth 8 state))))) 312 (goto-char (nth 8 state)))))
313 313
314 (defun python-open-block-statement-p (&optional bos) 314 (defun python-open-block-statement-p (&optional bos)
315 "Return non-nil if statement at point opens a block. 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." 316 BOS non-nil means point is known to be at beginning of statement."
321 (optional (and (syntax comment-start) 321 (optional (and (syntax comment-start)
322 (0+ not-newline))) 322 (0+ not-newline)))
323 line-end)) 323 line-end))
324 (save-excursion (python-end-of-statement)) 324 (save-excursion (python-end-of-statement))
325 t) 325 t)
326 (not (python-in-string/comment))))) 326 (not (progn (goto-char (match-beginning 0))
327 (python-in-string/comment))))))
327 328
328 (defun python-close-block-statement-p (&optional bos) 329 (defun python-close-block-statement-p (&optional bos)
329 "Return non-nil if current line is a statement closing a block. 330 "Return non-nil if current line is a statement closing a block.
330 BOS non-nil means point is at beginning of statement. 331 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 The criteria are that the line isn't a comment or in string and starts with
382 :group 'python) 383 :group 'python)
383 384
384 (defcustom python-honour-comment-indentation nil 385 (defcustom python-honour-comment-indentation nil
385 "Non-nil means indent relative to preceding comment line. 386 "Non-nil means indent relative to preceding comment line.
386 Only do this for comments where the leading comment character is followed 387 Only do this for comments where the leading comment character is followed
387 by space." 388 by space. This doesn't apply to comment lines, which are always indented
389 in lines with preceding comments."
388 :type 'boolean 390 :type 'boolean
389 :group 'python) 391 :group 'python)
390 392
391 (defcustom python-continuation-offset 4 393 (defcustom python-continuation-offset 4
392 "*Number of columns of additional indentation for continuation lines. 394 "*Number of columns of additional indentation for continuation lines.
512 (progn (goto-char point) 514 (progn (goto-char point)
513 (if (python-outdent-p) 515 (if (python-outdent-p)
514 (- python-indent))) 516 (- python-indent)))
515 0))))))))) 517 0)))))))))
516 518
519 (defun python-comment-indent ()
520 "`comment-indent-function' for Python."
521 ;; If previous non-blank line was a comment, use its indentation.
522 ;; FIXME: This seems unnecessary since the default code delegates to
523 ;; indent-according-to-mode. --Stef
524 (unless (bobp)
525 (save-excursion
526 (forward-comment -1)
527 (if (eq ?# (char-after)) (current-column)))))
528
517 ;;;; Cycling through the possible indentations with successive TABs. 529 ;;;; Cycling through the possible indentations with successive TABs.
518 530
519 ;; These don't need to be buffer-local since they're only relevant 531 ;; These don't need to be buffer-local since they're only relevant
520 ;; during a cycle. 532 ;; during a cycle.
521 533
536 (end-of-line) 548 (end-of-line)
537 (forward-comment -1) 549 (forward-comment -1)
538 (point)))) 550 (point))))
539 551
540 (defun python-indentation-levels () 552 (defun python-indentation-levels ()
541 "Return a list of possible indentations for this statement. 553 "Return a list of possible indentations for this line.
542 Includes the default indentation and those which would close all 554 Includes the default indentation and those which would close all
543 enclosing blocks." 555 enclosing blocks. Assumes the line has already been indented per
556 `python-indent-line'. Elements of the list are actually pairs:
557 \(INDENTATION . TEXT), where TEXT is the initial text of the
558 corresponding block opening (or nil)."
544 (save-excursion 559 (save-excursion
545 (let ((levels (list (cons (current-indentation) nil)))) 560 (let ((levels (list (cons (current-indentation)
561 (save-excursion
562 (if (python-beginning-of-block)
563 (python-initial-text)))))))
546 ;; Only one possibility if we immediately follow a block open or 564 ;; Only one possibility if we immediately follow a block open or
547 ;; are in a continuation line. 565 ;; are in a continuation line.
548 (unless (or (python-continuation-line-p) 566 (unless (or (python-continuation-line-p)
549 (save-excursion (and (python-previous-statement) 567 (save-excursion (and (python-previous-statement)
550 (python-open-block-statement-p t)))) 568 (python-open-block-statement-p t))))
566 (delete-horizontal-space) 584 (delete-horizontal-space)
567 (indent-to target) 585 (indent-to target)
568 (if (> (- (point-max) pos) (point)) 586 (if (> (- (point-max) pos) (point))
569 (goto-char (- (point-max) pos)))))) 587 (goto-char (- (point-max) pos))))))
570 588
571 ;; Fixme: Is the arg necessary? 589 (defun python-indent-line ()
572 (defun python-indent-line (&optional arg)
573 "Indent current line as Python code. 590 "Indent current line as Python code.
574 When invoked via `indent-for-tab-command', cycle through possible 591 When invoked via `indent-for-tab-command', cycle through possible
575 indentations for current line. The cycle is broken by a command different 592 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." 593 from `indent-for-tab-command', i.e. successive TABs do the cycling."
577 (interactive) 594 (interactive)
584 (progn (setq python-indent-index (% (1+ python-indent-index) 601 (progn (setq python-indent-index (% (1+ python-indent-index)
585 python-indent-list-length)) 602 python-indent-list-length))
586 (beginning-of-line) 603 (beginning-of-line)
587 (delete-horizontal-space) 604 (delete-horizontal-space)
588 (indent-to (car (nth python-indent-index python-indent-list))) 605 (indent-to (car (nth python-indent-index python-indent-list)))
589 (let ((text (cdr (nth python-indent-index 606 (if (python-block-end-p)
590 python-indent-list)))) 607 (let ((text (cdr (nth python-indent-index
591 (if text (message "Closes: %s" text))))) 608 python-indent-list))))
609 (if text
610 (message "Closes: %s" text))))))
592 (python-indent-line-1) 611 (python-indent-line-1)
593 (setq python-indent-list (python-indentation-levels) 612 (setq python-indent-list (python-indentation-levels)
594 python-indent-list-length (length python-indent-list) 613 python-indent-list-length (length python-indent-list)
595 python-indent-index (1- python-indent-list-length))))) 614 python-indent-index (1- python-indent-list-length)))))
615
616 (defun python-block-end-p ()
617 "Non-nil if this is a line in a statement closing a block,
618 or a blank line indented to where it would close a block."
619 (and (not (python-comment-line-p))
620 (or (python-close-block-statement-p t)
621 (< (current-indentation)
622 (save-excursion
623 (python-previous-statement)
624 (current-indentation))))))
625
626 ;; Fixme: Define an indent-region-function. It should probably leave
627 ;; lines alone if the indentation is already at one of the allowed
628 ;; levels. Otherwise, M-C-\ typically keeps indenting more deeply
629 ;; down a function.
596 630
597 ;;;; Movement. 631 ;;;; Movement.
598 632
599 (defun python-beginning-of-defun () 633 (defun python-beginning-of-defun ()
600 "`beginning-of-defun-function' for Python. 634 "`beginning-of-defun-function' for Python.
627 661
628 (defun python-end-of-defun () 662 (defun python-end-of-defun ()
629 "`end-of-defun-function' for Python. 663 "`end-of-defun-function' for Python.
630 Finds end of innermost nested class or method definition." 664 Finds end of innermost nested class or method definition."
631 (let ((orig (point)) 665 (let ((orig (point))
632 (pattern (rx (and line-start (0+ space) 666 (pattern (rx (and line-start (0+ space) (or "def" "class") space))))
633 (or "def" "class") space))))
634 ;; Go to start of current block and check whether it's at top 667 ;; 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 668 ;; level. If it is, and not a block start, look forward for
636 ;; definition statement. 669 ;; definition statement.
637 (when (python-comment-line-p) 670 (when (python-comment-line-p)
638 (end-of-line) 671 (end-of-line)
827 "`imenu-create-index-function' for Python. 860 "`imenu-create-index-function' for Python.
828 861
829 Makes nested Imenu menus from nested `class' and `def' statements. 862 Makes nested Imenu menus from nested `class' and `def' statements.
830 The nested menus are headed by an item referencing the outer 863 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 864 definition; it has a space prepended to the name so that it sorts
832 first with `imenu--sort-by-name'." 865 first with `imenu--sort-by-name' (though, unfortunately, sub-menus
866 precede it)."
833 (unless (boundp 'python-recursing) ; dynamically bound below 867 (unless (boundp 'python-recursing) ; dynamically bound below
834 (goto-char (point-min))) ; normal call from Imenu 868 (goto-char (point-min))) ; normal call from Imenu
835 (let (index-alist ; accumulated value to return 869 (let (index-alist ; accumulated value to return
836 name) 870 name)
837 (while (re-search-forward 871 (while (re-search-forward
912 (let ((name (buffer-file-name))) 946 (let ((name (buffer-file-name)))
913 (if name 947 (if name
914 (file-name-nondirectory name)))))))) 948 (file-name-nondirectory name))))))))
915 (setq python-saved-check-command command) 949 (setq python-saved-check-command command)
916 (save-some-buffers (not compilation-ask-about-save) nil) 950 (save-some-buffers (not compilation-ask-about-save) nil)
917 (compilation-start command)) 951 (let ((compilation-error-regexp-alist
952 (cons '("(\\([^,]+\\), line \\([0-9]+\\))" 1 2)
953 compilation-error-regexp-alist)))
954 (compilation-start command)))
918 955
919 ;;;; Inferior mode stuff (following cmuscheme). 956 ;;;; Inferior mode stuff (following cmuscheme).
920 957
958 ;; Fixme: Make sure we can work with IPython.
959
921 (defcustom python-python-command "python" 960 (defcustom python-python-command "python"
922 "*Shell command to run Python interpreter. 961 "*Shell command to run Python interpreter.
923 Any arguments can't contain whitespace." 962 Any arguments can't contain whitespace.
963 Note that IPython may not work properly; it must at least be used with the
964 `-cl' flag, i.e. use `ipython -cl'."
924 :group 'python 965 :group 'python
925 :type 'string) 966 :type 'string)
926 967
927 (defcustom python-jython-command "jython" 968 (defcustom python-jython-command "jython"
928 "*Shell command to run Jython interpreter. 969 "*Shell command to run Jython interpreter.
935 May be `python-python-command' or `python-jython-command'. 976 May be `python-python-command' or `python-jython-command'.
936 Additional arguments are added when the command is used by `run-python' 977 Additional arguments are added when the command is used by `run-python'
937 et al.") 978 et al.")
938 979
939 (defvar python-buffer nil 980 (defvar python-buffer nil
940 "*The current python process buffer. 981 "The current python process buffer."
941 To run multiple Python processes, start the first with \\[run-python]. 982 ;; Fixme: a single process is currently assumed, so that this doc
942 It will be in a buffer named *Python*. Rename that with 983 ;; is misleading.
943 \\[rename-buffer]. Now start a new process with \\[run-python]. It 984
944 will be in a new buffer, named *Python*. Switch between the different 985 ;; "*The current python process buffer.
945 process buffers with \\[switch-to-buffer]. 986 ;; To run multiple Python processes, start the first with \\[run-python].
946 987 ;; It will be in a buffer named *Python*. Rename that with
947 Commands that send text from source buffers to Python processes have 988 ;; \\[rename-buffer]. Now start a new process with \\[run-python]. It
948 to choose a process to send to. This is determined by global variable 989 ;; will be in a new buffer, named *Python*. Switch between the different
949 `python-buffer'. Suppose you have three inferior Pythons running: 990 ;; process buffers with \\[switch-to-buffer].
950 Buffer Process 991
951 foo python 992 ;; Commands that send text from source buffers to Python processes have
952 bar python<2> 993 ;; to choose a process to send to. This is determined by global variable
953 *Python* python<3> 994 ;; `python-buffer'. Suppose you have three inferior Pythons running:
954 If you do a \\[python-send-region-and-go] command on some Python source 995 ;; Buffer Process
955 code, what process does it go to? 996 ;; foo python
956 997 ;; bar python<2>
957 - In a process buffer (foo, bar, or *Python*), send it to that process. 998 ;; *Python* python<3>
958 - In some other buffer (e.g. a source file), send it to the process 999 ;; If you do a \\[python-send-region-and-go] command on some Python source
959 attached to `python-buffer'. 1000 ;; code, what process does it go to?
960 Process selection is done by function `python-proc'. 1001
961 1002 ;; - In a process buffer (foo, bar, or *Python*), send it to that process.
962 Whenever \\[run-python] starts a new process, it resets `python-buffer' 1003 ;; - In some other buffer (e.g. a source file), send it to the process
963 to be the new process's buffer. If you only run one process, this will 1004 ;; attached to `python-buffer'.
964 do the right thing. If you run multiple processes, you can change 1005 ;; Process selection is done by function `python-proc'.
965 `python-buffer' to another process buffer with \\[set-variable].") 1006
1007 ;; Whenever \\[run-python] starts a new process, it resets `python-buffer'
1008 ;; to be the new process's buffer. If you only run one process, this will
1009 ;; do the right thing. If you run multiple processes, you can change
1010 ;; `python-buffer' to another process buffer with \\[set-variable]."
1011 )
966 1012
967 (defconst python-compilation-regexp-alist 1013 (defconst python-compilation-regexp-alist
1014 ;; FIXME: maybe these should move to compilation-error-regexp-alist-alist.
968 `((,(rx (and line-start (1+ (any " \t")) "File \"" 1015 `((,(rx (and line-start (1+ (any " \t")) "File \""
969 (group (1+ (not (any "\"<")))) ; avoid `<stdin>' &c 1016 (group (1+ (not (any "\"<")))) ; avoid `<stdin>' &c
970 "\", line " (group (1+ digit)))) 1017 "\", line " (group (1+ digit))))
971 1 python-compilation-line-number)) 1018 1 2)
1019 (,(rx (and " in file " (group (1+ not-newline)) " on line "
1020 (group (1+ digit))))
1021 1 2))
972 "`compilation-error-regexp-alist' for inferior Python.") 1022 "`compilation-error-regexp-alist' for inferior Python.")
973 1023
1024 (defvar inferior-python-mode-map
1025 (let ((map (make-sparse-keymap)))
1026 ;; This will inherit from comint-mode-map.
1027 (define-key map "\C-c\C-l" 'python-load-file)
1028 (define-key map "\C-c\C-v" 'python-check)
1029 ;; Note that we _can_ still use these commands which send to the
1030 ;; Python process even at the prompt iff we have a normal prompt,
1031 ;; i.e. '>>> ' and not '... '. See the comment before
1032 ;; python-send-region. Fixme: uncomment these if we address that.
1033
1034 ;; (define-key map [(meta ?\t)] 'python-complete-symbol)
1035 ;; (define-key map "\C-c\C-f" 'python-describe-symbol)
1036 map))
1037
1038 ;; Fixme: This should inherit some stuff from python-mode, but I'm not
1039 ;; sure how much: at least some keybindings, like C-c C-f; syntax?;
1040 ;; font-locking, e.g. for triple-quoted strings?
974 (define-derived-mode inferior-python-mode comint-mode "Inferior Python" 1041 (define-derived-mode inferior-python-mode comint-mode "Inferior Python"
975 "Major mode for interacting with an inferior Python process. 1042 "Major mode for interacting with an inferior Python process.
976 A Python process can be started with \\[run-python]. 1043 A Python process can be started with \\[run-python].
977 1044
978 Hooks `comint-mode-hook' and `inferior-python-mode-hook' are run in 1045 Hooks `comint-mode-hook' and `inferior-python-mode-hook' are run in
989 1056
990 \\{inferior-python-mode-map}" 1057 \\{inferior-python-mode-map}"
991 :group 'python 1058 :group 'python
992 (set-syntax-table python-mode-syntax-table) 1059 (set-syntax-table python-mode-syntax-table)
993 (setq mode-line-process '(":%s")) 1060 (setq mode-line-process '(":%s"))
994 ;; Fixme: Maybe install some python-mode bindings too. 1061 (set (make-local-variable 'comint-input-filter) 'python-input-filter)
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 1062 (add-hook 'comint-preoutput-filter-functions #'python-preoutput-filter
999 nil t) 1063 nil t)
1000 ;; Still required by `comint-redirect-send-command', for instance: 1064 ;; Still required by `comint-redirect-send-command', for instance
1001 (set (make-local-variable 'comint-prompt-regexp) "^\\([>.]\\{3\\} \\)+") 1065 ;; (and we need to match things like `>>> ... >>> '):
1066 (set (make-local-variable 'comint-prompt-regexp)
1067 (rx (and line-start (1+ (and (repeat 3 (any ">.")) ?\ )))))
1002 (set (make-local-variable 'compilation-error-regexp-alist) 1068 (set (make-local-variable 'compilation-error-regexp-alist)
1003 python-compilation-regexp-alist) 1069 python-compilation-regexp-alist)
1004 (compilation-shell-minor-mode 1)) 1070 (compilation-shell-minor-mode 1))
1005 1071
1006 (defcustom inferior-python-filter-regexp "\\`\\s-*\\S-?\\S-?\\s-*\\'" 1072 (defcustom inferior-python-filter-regexp "\\`\\s-*\\S-?\\S-?\\s-*\\'"
1007 "*Input matching this regexp is not saved on the history list. 1073 "*Input matching this regexp is not saved on the history list.
1008 Default ignores all inputs of 0, 1, or 2 non-blank characters." 1074 Default ignores all inputs of 0, 1, or 2 non-blank characters."
1009 :type 'regexp 1075 :type 'regexp
1010 :group 'python) 1076 :group 'python)
1011 1077
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) 1078 (defun python-input-filter (str)
1017 "`comint-input-filter' function for inferior Python. 1079 "`comint-input-filter' function for inferior Python.
1018 Don't save anything for STR matching `inferior-python-filter-regexp'. 1080 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))) 1081 (not (string-match inferior-python-filter-regexp str)))
1022 1082
1023 ;; Fixme: Loses with quoted whitespace. 1083 ;; Fixme: Loses with quoted whitespace.
1024 (defun python-args-to-list (string) 1084 (defun python-args-to-list (string)
1025 (let ((where (string-match "[ \t]" string))) 1085 (let ((where (string-match "[ \t]" string)))
1028 (cons (substring string 0 where) 1088 (cons (substring string 0 where)
1029 (python-args-to-list (substring string (+ 1 where))))) 1089 (python-args-to-list (substring string (+ 1 where)))))
1030 (t (let ((pos (string-match "[^ \t]" string))) 1090 (t (let ((pos (string-match "[^ \t]" string)))
1031 (if pos (python-args-to-list (substring string pos)))))))) 1091 (if pos (python-args-to-list (substring string pos))))))))
1032 1092
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 1093 (defvar python-preoutput-result nil
1047 "Data from output line last `_emacs_out' line seen by the preoutput filter.") 1094 "Data from last `_emacs_out' line seen by the preoutput filter.")
1048 1095
1049 (defvar python-preoutput-continuation nil 1096 (defvar python-preoutput-continuation nil
1050 "If non-nil, funcall this when `python-preoutput-filter' sees `_emacs_ok'.") 1097 "If non-nil, funcall this when `python-preoutput-filter' sees `_emacs_ok'.")
1051 1098
1052 ;; Using this stops us getting lines in the buffer like 1099 ;; Using this stops us getting lines in the buffer like
1053 ;; >>> ... ... >>> 1100 ;; >>> ... ... >>>
1054 ;; Also look for (and delete) an `_emacs_ok' string and call 1101 ;; Also look for (and delete) an `_emacs_ok' string and call
1055 ;; `python-preoutput-continuation' if we get it. 1102 ;; `python-preoutput-continuation' if we get it.
1056 (defun python-preoutput-filter (s) 1103 (defun python-preoutput-filter (s)
1057 "`comint-preoutput-filter-functions' function: ignore prompts not at bol." 1104 "`comint-preoutput-filter-functions' function: ignore prompts not at bol."
1058 (cond ((and (string-match "\\`[.>]\\{3\\} \\'" s) 1105 (cond ((and (string-match (rx (and string-start (repeat 3 (any ".>"))
1106 " " string-end))
1107 s)
1059 (/= (let ((inhibit-field-text-motion t)) 1108 (/= (let ((inhibit-field-text-motion t))
1060 (line-beginning-position)) 1109 (line-beginning-position))
1061 (point))) 1110 (point)))
1062 "") 1111 "")
1063 ((string= s "_emacs_ok\n") 1112 ((string= s "_emacs_ok\n")
1074 (defun run-python (&optional cmd noshow) 1123 (defun run-python (&optional cmd noshow)
1075 "Run an inferior Python process, input and output via buffer *Python*. 1124 "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 1125 CMD is the Python command to run. NOSHOW non-nil means don't show the
1077 buffer automatically. 1126 buffer automatically.
1078 If there is a process already running in `*Python*', switch to 1127 If there is a process already running in `*Python*', switch to
1079 that buffer. Interactively a prefix arg, allows you to edit the initial 1128 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 1129 command line (default is `python-command'); `-i' etc. args will be added
1081 will be added to this as appropriate. Runs the hooks 1130 to this as appropriate. Runs the hook `inferior-python-mode-hook'
1082 `inferior-python-mode-hook' (after the `comint-mode-hook' is run). 1131 \(after the `comint-mode-hook' is run).
1083 \(Type \\[describe-mode] in the process buffer for a list of commands.)" 1132 \(Type \\[describe-mode] in the process buffer for a list of commands.)"
1084 (interactive (list (if current-prefix-arg 1133 (interactive (list (if current-prefix-arg
1085 (read-string "Run Python: " python-command) 1134 (read-string "Run Python: " python-command)
1086 python-command))) 1135 python-command)))
1087 (unless cmd (setq cmd python-python-command)) 1136 (unless cmd (setq cmd python-python-command))
1088 (setq python-command cmd) 1137 (setq python-command cmd)
1089 ;; Fixme: Consider making `python-buffer' buffer-local as a buffer 1138 ;; Fixme: Consider making `python-buffer' buffer-local as a buffer
1090 ;; (not a name) in Python buffers from which `run-python' &c is 1139 ;; (not a name) in Python buffers from which `run-python' &c is
1091 ;; invoked. Would support multiple processes better. 1140 ;; invoked. Would support multiple processes better.
1092 (unless (comint-check-proc "*Python*") 1141 (unless (comint-check-proc python-buffer)
1093 (let ((cmdlist (append (python-args-to-list cmd) '("-i")))) 1142 (let* ((cmdlist (append (python-args-to-list cmd) '("-i")))
1143 (path (getenv "PYTHONPATH"))
1144 (process-environment ; to import emacs.py
1145 (push (concat "PYTHONPATH=" data-directory
1146 (if path (concat ":" path)))
1147 process-environment)))
1094 (set-buffer (apply 'make-comint "Python" (car cmdlist) nil 1148 (set-buffer (apply 'make-comint "Python" (car cmdlist) nil
1095 (cdr cmdlist)))) 1149 (cdr cmdlist)))
1150 (setq python-buffer "*Python*"))
1096 (inferior-python-mode) 1151 (inferior-python-mode)
1097 ;; Load function defintions we need. 1152 ;; Load function defintions we need.
1098 ;; Before the preoutput function was used, this was done via -c in 1153 ;; 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 1154 ;; cmdlist, but that loses the banner and doesn't run the startup
1100 ;; file. 1155 ;; file. The code might be inline here, but there's enough that it
1101 (python-send-string "\ 1156 ;; seems worth putting in a separate file, and it's probably cleaner
1102 def _emacs_execfile (file): # execute file and remove it 1157 ;; to put it in a module.
1103 from os import remove 1158 (python-send-string "import emacs"))
1104 try: execfile (file, globals (), globals ()) 1159 (unless noshow (pop-to-buffer python-buffer)))
1105 finally: remove (file) 1160
1106 1161 ;; Fixme: We typically lose if the inferior isn't in the normal REPL,
1107 def _emacs_args (name): # get arglist of name for eldoc &c 1162 ;; e.g. prompt is `help> '. Probably raise an error if the form of
1108 import inspect 1163 ;; the prompt is unexpected; actually, it needs to be `>>> ', not
1109 parts = name.split ('.') 1164 ;; `... ', i.e. we're not inputting a block &c. However, this may not
1110 if len (parts) > 1: 1165 ;; be the place to do it, e.g. we might actually want to send commands
1111 try: exec 'import ' + parts[0] 1166 ;; having set up such a state.
1112 except: return None 1167
1113 try: exec 'func='+name # lose if name is keyword or undefined 1168 (defun python-send-command (command)
1114 except: return None 1169 "Like `python-send-string' but resets `compilation-minor-mode'."
1115 if inspect.isbuiltin (func): 1170 (goto-char (point-max))
1116 doc = func.__doc__ 1171 (let ((end (marker-position (process-mark (python-proc)))))
1117 if doc.find (' ->') != -1: 1172 (compilation-forget-errors)
1118 print '_emacs_out', doc.split (' ->')[0] 1173 (python-send-string command)
1119 elif doc.find ('\\n') != -1: 1174 (set-marker compilation-parsing-end end)
1120 print '_emacs_out', doc.split ('\\n')[0] 1175 (setq compilation-last-buffer (current-buffer))))
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 1176
1131 (defun python-send-region (start end) 1177 (defun python-send-region (start end)
1132 "Send the region to the inferior Python process." 1178 "Send the region to the inferior Python process."
1133 ;; The region is evaluated from a temporary file. This avoids 1179 ;; The region is evaluated from a temporary file. This avoids
1134 ;; problems with blank lines, which have different semantics 1180 ;; problems with blank lines, which have different semantics
1135 ;; interactively and in files. It also saves the inferior process 1181 ;; interactively and in files. It also saves the inferior process
1136 ;; buffer filling up with interpreter prompts. We need a function 1182 ;; buffer filling up with interpreter prompts. We need a Python
1137 ;; to remove the temporary file when it has been evaluated, which 1183 ;; function to remove the temporary file when it has been evaluated
1138 ;; unfortunately means using a not-quite pristine interpreter 1184 ;; (though we could probably do it in Lisp with a Comint output
1139 ;; initially. Unfortunately we also get tracebacks which look like: 1185 ;; filter). This function also catches exceptions and truncates
1140 ;; 1186 ;; tracebacks not to mention the frame of the function itself.
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 ;; 1187 ;;
1146 ;; The compilation-minor-mode parsing takes care of relating the 1188 ;; The compilation-minor-mode parsing takes care of relating the
1147 ;; reference to the temporary file to the source. Fixme: 1189 ;; reference to the temporary file to the source.
1148 ;; comint-filter the first two lines of the traceback? 1190 ;;
1191 ;; Fixme: Write a `coding' header to the temp file if the region is
1192 ;; non-ASCII.
1149 (interactive "r") 1193 (interactive "r")
1150 (let* ((f (make-temp-file "py")) 1194 (let* ((f (make-temp-file "py"))
1151 (command (format "_emacs_execfile(%S)" f)) 1195 (command (format "emacs.eexecfile(%S)" f))
1152 (orig-start (copy-marker start))) 1196 (orig-start (copy-marker start)))
1153 (if (save-excursion 1197 (when (save-excursion
1154 (goto-char start) 1198 (goto-char start)
1155 (/= 0 (current-indentation))) ; need dummy block 1199 (/= 0 (current-indentation))) ; need dummy block
1156 (write-region "if True:\n" nil f nil 'nomsg)) 1200 (save-excursion
1201 (goto-char orig-start)
1202 ;; Wrong if we had indented code at buffer start.
1203 (set-marker orig-start (line-beginning-position 0)))
1204 (write-region "if True:\n" nil f nil 'nomsg))
1157 (write-region start end f t 'nomsg) 1205 (write-region start end f t 'nomsg)
1158 (when python-buffer 1206 (let ((proc (python-proc))) ;Make sure we're running a process.
1159 (with-current-buffer python-buffer 1207 (with-current-buffer python-buffer
1160 (let ((end (marker-position (process-mark (python-proc))))) 1208 (python-send-command command)
1161 (set (make-local-variable 'python-orig-start) orig-start) 1209 ;; Tell compile.el to redirect error locations in file `f' to
1162 (set (make-local-variable 'compilation-error-list) nil) 1210 ;; positions past marker `orig-start'. It has to be done *after*
1163 (let ((comint-input-filter-functions 1211 ;; python-send-command's call to compilation-forget-errors.
1164 (delete 'python-input-filter comint-input-filter-functions))) 1212 (compilation-fake-loc orig-start f)))))
1165 (python-send-string command))
1166 (set-marker compilation-parsing-end end)
1167 (setq compilation-last-buffer (current-buffer)))))))
1168 1213
1169 (defun python-send-string (string) 1214 (defun python-send-string (string)
1170 "Evaluate STRING in inferior Python process." 1215 "Evaluate STRING in inferior Python process."
1171 (interactive "sPython command: ") 1216 (interactive "sPython command: ")
1172 (comint-send-string (python-proc) string) 1217 (comint-send-string (python-proc) string)
1175 (defun python-send-buffer () 1220 (defun python-send-buffer ()
1176 "Send the current buffer to the inferior Python process." 1221 "Send the current buffer to the inferior Python process."
1177 (interactive) 1222 (interactive)
1178 (python-send-region (point-min) (point-max))) 1223 (python-send-region (point-min) (point-max)))
1179 1224
1225 ;; Fixme: Try to define the function or class within the relevant
1226 ;; module, not just at top level.
1180 (defun python-send-defun () 1227 (defun python-send-defun ()
1181 "Send the current defun (class or method) to the inferior Python process." 1228 "Send the current defun (class or method) to the inferior Python process."
1182 (interactive) 1229 (interactive)
1183 (save-excursion (python-send-region (progn (beginning-of-defun) (point)) 1230 (save-excursion (python-send-region (progn (beginning-of-defun) (point))
1184 (progn (end-of-defun) (point))))) 1231 (progn (end-of-defun) (point)))))
1221 Treating it as a module keeps the global namespace clean, provides 1268 Treating it as a module keeps the global namespace clean, provides
1222 function location information for debugging, and supports users of 1269 function location information for debugging, and supports users of
1223 module-qualified names." 1270 module-qualified names."
1224 (interactive (comint-get-source "Load Python file: " python-prev-dir/file 1271 (interactive (comint-get-source "Load Python file: " python-prev-dir/file
1225 python-source-modes 1272 python-source-modes
1226 t)) ; because execfile needs exact name 1273 t)) ; because execfile needs exact name
1227 (comint-check-source file-name) ; Check to see if buffer needs saved. 1274 (comint-check-source file-name) ; Check to see if buffer needs saving.
1228 (setq python-prev-dir/file (cons (file-name-directory file-name) 1275 (setq python-prev-dir/file (cons (file-name-directory file-name)
1229 (file-name-nondirectory file-name))) 1276 (file-name-nondirectory file-name)))
1230 (when python-buffer 1277 (let ((proc (python-proc))) ;Make sure we have a process.
1231 (with-current-buffer python-buffer 1278 (with-current-buffer python-buffer
1232 (let ((end (marker-position (process-mark (python-proc))))) 1279 ;; Fixme: I'm not convinced by this logic from python-mode.el.
1233 (set (make-local-variable 'compilation-error-list) nil) 1280 (python-send-command
1234 ;; (set (make-local-variable 'compilation-old-error-list) nil) 1281 (if (string-match "\\.py\\'" file-name)
1235 (let ((comint-input-filter-functions 1282 (let ((module (file-name-sans-extension
1236 (delete 'python-input-filter comint-input-filter-functions))) 1283 (file-name-nondirectory file-name))))
1237 (python-send-string 1284 (format "emacs.eimport(%S,%S)"
1238 (if (string-match "\\.py\\'" file-name) 1285 module (file-name-directory file-name)))
1239 ;; Fixme: make sure the directory is in the path list 1286 (format "execfile(%S)" file-name)))
1240 (let ((module (file-name-sans-extension 1287 (message "%s loaded" file-name))))
1241 (file-name-nondirectory file-name)))) 1288
1242 (set (make-local-variable 'python-orig-start) nil) 1289 ;; Fixme: If we need to start the process, wait until we've got the OK
1243 (format "\ 1290 ;; from the startup.
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 () 1291 (defun python-proc ()
1254 "Return the current Python process. See variable `python-buffer'." 1292 "Return the current Python process.
1255 (let ((proc (get-buffer-process (if (eq major-mode 'inferior-python-mode) 1293 See variable `python-buffer'. Starts a new process if necessary."
1256 (current-buffer) 1294 (or (if python-buffer
1257 python-buffer)))) 1295 (get-buffer-process (if (eq major-mode 'inferior-python-mode)
1258 (or proc (error "No current process. See variable `python-buffer'")))) 1296 (current-buffer)
1297 python-buffer)))
1298 (progn (run-python nil t)
1299 (python-proc))))
1259 1300
1260 ;;;; Context-sensitive help. 1301 ;;;; Context-sensitive help.
1261 1302
1262 (defconst python-dotty-syntax-table 1303 (defconst python-dotty-syntax-table
1263 (let ((table (make-syntax-table))) 1304 (let ((table (make-syntax-table)))
1265 (modify-syntax-entry ?. "_" table) 1306 (modify-syntax-entry ?. "_" table)
1266 table) 1307 table)
1267 "Syntax table giving `.' symbol syntax. 1308 "Syntax table giving `.' symbol syntax.
1268 Otherwise inherits from `python-mode-syntax-table'.") 1309 Otherwise inherits from `python-mode-syntax-table'.")
1269 1310
1311 (defvar view-return-to-alist)
1312 (eval-when-compile (autoload 'help-buffer "help-fns"))
1313
1270 ;; Fixme: Should this actually be used instead of info-look, i.e. be 1314 ;; Fixme: Should this actually be used instead of info-look, i.e. be
1271 ;; bound to C-h S? 1315 ;; bound to C-h S? Can we use other pydoc stuff before python 2.2?
1272 (defun python-describe-symbol (symbol) 1316 (defun python-describe-symbol (symbol)
1273 "Get help on SYMBOL using `pydoc'. 1317 "Get help on SYMBOL using `help'.
1274 Interactively, prompt for symbol." 1318 Interactively, prompt for symbol.
1275 ;; Note that we do this in the inferior process, not a separate one to 1319
1320 Symbol may be anything recognized by the interpreter's `help' command --
1321 e.g. `CALLS' -- not just variables in scope.
1322 This only works for Python version 2.2 or newer since earlier interpreters
1323 don't support `help'."
1324 ;; Note that we do this in the inferior process, not a separate one, to
1276 ;; ensure the environment is appropriate. 1325 ;; ensure the environment is appropriate.
1277 (interactive 1326 (interactive
1278 (let ((symbol (with-syntax-table python-dotty-syntax-table 1327 (let ((symbol (with-syntax-table python-dotty-syntax-table
1279 (current-word))) 1328 (current-word)))
1280 (enable-recursive-minibuffers t) 1329 (enable-recursive-minibuffers t))
1281 val) 1330 (list (read-string (if symbol
1282 (setq val (read-string (if symbol 1331 (format "Describe symbol (default %s): " symbol)
1283 (format "Describe symbol (default %s): " 1332 "Describe symbol: ")
1284 symbol) 1333 nil nil symbol))))
1285 "Describe symbol: ")
1286 nil nil symbol))
1287 (list (or val symbol))))
1288 (if (equal symbol "") (error "No symbol")) 1334 (if (equal symbol "") (error "No symbol"))
1289 (let* ((func `(lambda () 1335 (let* ((func `(lambda ()
1290 (comint-redirect-send-command (format "help(%S)\n" ,symbol) 1336 (comint-redirect-send-command (format "emacs.ehelp(%S)\n"
1337 ,symbol)
1291 "*Help*" nil)))) 1338 "*Help*" nil))))
1292 ;; Ensure we have a suitable help buffer. 1339 ;; Ensure we have a suitable help buffer.
1293 (let (temp-buffer-show-hook) ; avoid xref stuff 1340 ;; Fixme: Maybe process `Related help topics' a la help xrefs and
1294 (with-output-to-temp-buffer "*Help*" 1341 ;; allow C-c C-f in help buffer.
1342 (let ((temp-buffer-show-hook ; avoid xref stuff
1343 (lambda ()
1344 (toggle-read-only 1)
1345 (setq view-return-to-alist
1346 (list (cons (selected-window) help-return-method))))))
1347 (help-setup-xref (list 'python-describe-symbol symbol) (interactive-p))
1348 (with-output-to-temp-buffer (help-buffer)
1295 (with-current-buffer standard-output 1349 (with-current-buffer standard-output
1296 (set (make-local-variable 'comint-redirect-subvert-readonly) t)))) 1350 (set (make-local-variable 'comint-redirect-subvert-readonly) t)
1351 (print-help-return-message))))
1297 (if (and python-buffer (get-buffer python-buffer)) 1352 (if (and python-buffer (get-buffer python-buffer))
1298 (with-current-buffer python-buffer 1353 (with-current-buffer python-buffer
1299 (funcall func)) 1354 (funcall func))
1300 (setq python-preoutput-continuation func) 1355 (setq python-preoutput-continuation func)
1301 (run-python nil t)))) 1356 (run-python nil t))))
1302 1357
1303 (add-to-list 'debug-ignored-errors "^No symbol") 1358 (add-to-list 'debug-ignored-errors "^No symbol")
1359
1360 (defun python-send-receive (string)
1361 "Send STRING to inferior Python (if any) and return result.
1362 The result is what follows `_emacs_out' in the output (or nil)."
1363 (let ((proc (python-proc)))
1364 (python-send-string string)
1365 (setq python-preoutput-result nil)
1366 (accept-process-output proc 5)
1367 python-preoutput-result))
1304 1368
1305 ;; Fixme: try to make it work with point in the arglist. Also, is 1369 ;; Fixme: try to make it work with point in the arglist. Also, is
1306 ;; there anything reasonable we can do with random methods? 1370 ;; there anything reasonable we can do with random methods?
1307 ;; (Currently only works with functions.) 1371 ;; (Currently only works with functions.)
1308 (defun python-eldoc-function () 1372 (defun python-eldoc-function ()
1309 "`eldoc-print-current-symbol-info' for Python. 1373 "`eldoc-print-current-symbol-info' for Python.
1310 Only works when point is in a function name, not its arglist, for instance. 1374 Only works when point is in a function name, not its arglist, for instance.
1311 Assumes an inferior Python is running." 1375 Assumes an inferior Python is running."
1312 (let ((symbol (with-syntax-table python-dotty-syntax-table 1376 (let ((symbol (with-syntax-table python-dotty-syntax-table
1313 (current-word))) 1377 (current-word))))
1314 (proc (and python-buffer (python-proc)))) 1378 (when symbol
1315 (when (and proc symbol) 1379 (python-send-receive (format "emacs.eargs(%S)" 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 1380
1322 ;;;; Info-look functionality. 1381 ;;;; Info-look functionality.
1323 1382
1324 (defun python-after-info-look () 1383 (defun python-after-info-look ()
1325 "Set up info-look for Python. 1384 "Set up info-look for Python.
1329 (string-match "^Python \\([0-9]+\\.[0-9]+\\>\\)" s) 1388 (string-match "^Python \\([0-9]+\\.[0-9]+\\>\\)" s)
1330 (match-string 1 s))) 1389 (match-string 1 s)))
1331 ;; Whether info files have a Python version suffix, e.g. in Debian. 1390 ;; Whether info files have a Python version suffix, e.g. in Debian.
1332 (versioned 1391 (versioned
1333 (with-temp-buffer 1392 (with-temp-buffer
1334 (Info-mode) 1393 (with-no-warnings (Info-mode))
1335 (condition-case () 1394 (condition-case ()
1336 ;; Don't use `info' because it would pop-up a *info* buffer. 1395 ;; Don't use `info' because it would pop-up a *info* buffer.
1337 (Info-goto-node (format "(python%s-lib)Miscellaneous Index" 1396 (with-no-warnings
1338 version)) 1397 (Info-goto-node (format "(python%s-lib)Miscellaneous Index"
1398 version))
1399 t)
1339 (error nil))))) 1400 (error nil)))))
1340 (info-lookup-maybe-add-help 1401 (info-lookup-maybe-add-help
1341 :mode 'python-mode 1402 :mode 'python-mode
1342 :regexp "[[:alnum:]_]+" 1403 :regexp "[[:alnum:]_]+"
1343 :doc-spec 1404 :doc-spec
1399 (jython-mode) 1460 (jython-mode)
1400 (if (catch 'done 1461 (if (catch 'done
1401 (while (re-search-forward 1462 (while (re-search-forward
1402 (rx (and line-start (or "import" "from") (1+ space) 1463 (rx (and line-start (or "import" "from") (1+ space)
1403 (group (1+ (not (any " \t\n.")))))) 1464 (group (1+ (not (any " \t\n."))))))
1404 10000 ; Probably not worth customizing. 1465 (+ (point-min) 10000) ; Probably not worth customizing.
1405 t) 1466 t)
1406 (if (member (match-string 1) python-jython-packages) 1467 (if (member (match-string 1) python-jython-packages)
1407 (throw 'done t)))) 1468 (throw 'done t))))
1408 (jython-mode))))))) 1469 (jython-mode)))))))
1409 1470
1517 (python-beginning-of-block) 1578 (python-beginning-of-block)
1518 (push-mark (point) nil t) 1579 (push-mark (point) nil t)
1519 (python-end-of-block) 1580 (python-end-of-block)
1520 (exchange-point-and-mark)) 1581 (exchange-point-and-mark))
1521 1582
1583 ;;;; Completion.
1584
1585 (defun python-symbol-completions (symbol)
1586 "Return a list of completions of the string SYMBOL from Python process.
1587 The list is sorted."
1588 (when symbol
1589 (let ((completions
1590 (condition-case ()
1591 (car (read-from-string (python-send-receive
1592 (format "emacs.complete(%S)" symbol))))
1593 (error nil))))
1594 (sort
1595 ;; We can get duplicates from the above -- don't know why.
1596 (delete-dups completions)
1597 #'string<))))
1598
1599 (defun python-partial-symbol ()
1600 "Return the partial symbol before point (for completion)."
1601 (let ((end (point))
1602 (start (save-excursion
1603 (and (re-search-backward
1604 (rx (and (or buffer-start (regexp "[^[:alnum:]._]"))
1605 (group (1+ (regexp "[[:alnum:]._]")))
1606 point))
1607 nil t)
1608 (match-beginning 1)))))
1609 (if start (buffer-substring-no-properties start end))))
1610
1611 ;; Fixme: We should have an abstraction of this sort of thing in the
1612 ;; core.
1613 (defun python-complete-symbol ()
1614 "Perform completion on the Python symbol preceding point.
1615 Repeating the command scrolls the completion window."
1616 (interactive)
1617 (let ((window (get-buffer-window "*Completions*")))
1618 (if (and (eq last-command this-command)
1619 window (window-live-p window) (window-buffer window)
1620 (buffer-name (window-buffer window)))
1621 (with-current-buffer (window-buffer window)
1622 (if (pos-visible-in-window-p (point-max) window)
1623 (set-window-start window (point-min))
1624 (save-selected-window
1625 (select-window window)
1626 (scroll-up))))
1627 ;; Do completion.
1628 (let* ((end (point))
1629 (symbol (python-partial-symbol))
1630 (completions (python-symbol-completions symbol))
1631 (completion (if completions
1632 (try-completion symbol completions))))
1633 (when symbol
1634 (cond ((eq completion t))
1635 ((null completion)
1636 (message "Can't find completion for \"%s\"" symbol)
1637 (ding))
1638 ((not (string= symbol completion))
1639 (delete-region (- end (length symbol)) end)
1640 (insert completion))
1641 (t
1642 (message "Making completion list...")
1643 (with-output-to-temp-buffer "*Completions*"
1644 (display-completion-list completions))
1645 (message "Making completion list...%s" "done"))))))))
1646
1647 (eval-when-compile (require 'hippie-exp))
1648
1649 (defun python-try-complete (old)
1650 "Completion function for Python for use with `hippie-expand'."
1651 (when (eq major-mode 'python-mode) ; though we only add it locally
1652 (unless old
1653 (let ((symbol (python-partial-symbol)))
1654 (he-init-string (- (point) (length symbol)) (point))
1655 (if (not (he-string-member he-search-string he-tried-table))
1656 (push he-search-string he-tried-table))
1657 (setq he-expand-list
1658 (and symbol (python-symbol-completions symbol)))))
1659 (while (and he-expand-list
1660 (he-string-member (car he-expand-list) he-tried-table))
1661 (pop he-expand-list))
1662 (if he-expand-list
1663 (progn
1664 (he-substitute-string (pop he-expand-list))
1665 t)
1666 (if old (he-reset-string))
1667 nil)))
1668
1522 ;;;; Modes. 1669 ;;;; Modes.
1523 1670
1524 (defvar outline-heading-end-regexp) 1671 (defvar outline-heading-end-regexp)
1525 (defvar eldoc-print-current-symbol-info-function) 1672 (defvar eldoc-print-current-symbol-info-function)
1526 (defvar python-mode-running) 1673
1527 ;;;###autoload 1674 ;;;###autoload
1528 (define-derived-mode python-mode fundamental-mode "Python" 1675 (define-derived-mode python-mode fundamental-mode "Python"
1529 "Major mode for editing Python files. 1676 "Major mode for editing Python files.
1530 Turns on Font Lock mode unconditionally since it is required for correct 1677 Turns on Font Lock mode unconditionally since it is required for correct
1531 parsing of the source. 1678 parsing of the source.
1563 ;;; (font-lock-syntactic-face-function 1710 ;;; (font-lock-syntactic-face-function
1564 ;;; . python-font-lock-syntactic-face-function) 1711 ;;; . python-font-lock-syntactic-face-function)
1565 )) 1712 ))
1566 (set (make-local-variable 'parse-sexp-lookup-properties) t) 1713 (set (make-local-variable 'parse-sexp-lookup-properties) t)
1567 (set (make-local-variable 'comment-start) "# ") 1714 (set (make-local-variable 'comment-start) "# ")
1568 ;; Fixme: define a comment-indent-function? 1715 (set (make-local-variable 'comment-indent-function) #'python-comment-indent)
1569 (set (make-local-variable 'indent-line-function) #'python-indent-line) 1716 (set (make-local-variable 'indent-line-function) #'python-indent-line)
1570 (set (make-local-variable 'paragraph-start) "\\s-*$") 1717 (set (make-local-variable 'paragraph-start) "\\s-*$")
1571 (set (make-local-variable 'fill-paragraph-function) 1718 (set (make-local-variable 'fill-paragraph-function) 'python-fill-paragraph)
1572 'python-fill-paragraph)
1573 (set (make-local-variable 'require-final-newline) t) 1719 (set (make-local-variable 'require-final-newline) t)
1574 (set (make-local-variable 'add-log-current-defun-function) 1720 (set (make-local-variable 'add-log-current-defun-function)
1575 #'python-current-defun) 1721 #'python-current-defun)
1576 ;; Fixme: Generalize to do all blocks? 1722 ;; Fixme: Generalize to do all blocks?
1577 (set (make-local-variable 'outline-regexp) "\\s-*\\(def\\|class\\)\\>") 1723 (set (make-local-variable 'outline-regexp) "\\s-*\\(def\\|class\\)\\>")
1585 (setq imenu-create-index-function #'python-imenu-create-index) 1731 (setq imenu-create-index-function #'python-imenu-create-index)
1586 (set (make-local-variable 'eldoc-print-current-symbol-info-function) 1732 (set (make-local-variable 'eldoc-print-current-symbol-info-function)
1587 #'python-eldoc-function) 1733 #'python-eldoc-function)
1588 (add-hook 'eldoc-mode-hook 1734 (add-hook 'eldoc-mode-hook
1589 '(lambda () (run-python 0 t)) nil t) ; need it running 1735 '(lambda () (run-python 0 t)) nil t) ; need it running
1736 (if (featurep 'hippie-exp)
1737 (set (make-local-variable 'hippie-expand-try-functions-list)
1738 (cons 'python-try-complete hippie-expand-try-functions-list)))
1590 (unless font-lock-mode (font-lock-mode 1)) 1739 (unless font-lock-mode (font-lock-mode 1))
1591 (when python-guess-indent (python-guess-indent)) 1740 (when python-guess-indent (python-guess-indent))
1592 (set (make-local-variable 'python-command) python-python-command) 1741 (set (make-local-variable 'python-command) python-python-command)
1593 (unless (boundp 'python-mode-running) ; kill the recursion from jython-mode 1742 (unless (boundp 'python-mode-running) ; kill the recursion from jython-mode
1594 (let ((python-mode-running t)) 1743 (let ((python-mode-running t))