aboutsummaryrefslogtreecommitdiffstats
path: root/lisp/progmodes/python.el
diff options
context:
space:
mode:
authorMiles Bader2004-06-28 07:56:49 +0000
committerMiles Bader2004-06-28 07:56:49 +0000
commit327719ee8a3fcdb36ed6acaf6d8cb5fbdf0bd801 (patch)
tree21de188e13b5e41a79bb50040933072ae0235217 /lisp/progmodes/python.el
parent852f73b7fa7b71910282eacb6263b3ecfd4ee783 (diff)
parent376de73927383d6062483db10b8a82448505f52b (diff)
downloademacs-327719ee8a3fcdb36ed6acaf6d8cb5fbdf0bd801.tar.gz
emacs-327719ee8a3fcdb36ed6acaf6d8cb5fbdf0bd801.zip
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
Diffstat (limited to 'lisp/progmodes/python.el')
-rw-r--r--lisp/progmodes/python.el569
1 files changed, 359 insertions, 210 deletions
diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el
index bfa507b851a..274480a36de 100644
--- a/lisp/progmodes/python.el
+++ b/lisp/progmodes/python.el
@@ -3,6 +3,7 @@
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
@@ -45,19 +46,18 @@
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
@@ -66,10 +66,8 @@
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"
@@ -204,6 +202,8 @@ Used for syntactic keywords. N is the match number (1, 2 or 3)."
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"
@@ -262,9 +262,7 @@ Used for syntactic keywords. N is the match number (1, 2 or 3)."
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)."
266Optional argument LIM indicates the beginning of the containing form,
267i.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
@@ -299,16 +297,18 @@ comments and strings, or that the bracket/paren nesting depth is nonzero."
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.
309Do nothing if not in string." 309Do 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)
@@ -323,7 +323,8 @@ BOS non-nil means point is known to be at beginning of statement."
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.
@@ -384,7 +385,8 @@ Otherwise indent them to column zero."
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.
386Only do this for comments where the leading comment character is followed 387Only do this for comments where the leading comment character is followed
387by space." 388by space. This doesn't apply to comment lines, which are always indented
389in lines with preceding comments."
388 :type 'boolean 390 :type 'boolean
389 :group 'python) 391 :group 'python)
390 392
@@ -514,6 +516,16 @@ Set `python-indent' locally to the value guessed."
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
@@ -538,11 +550,17 @@ Set `python-indent' locally to the value guessed."
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.
542Includes the default indentation and those which would close all 554Includes the default indentation and those which would close all
543enclosing blocks." 555enclosing 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
558corresponding 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)
@@ -568,8 +586,7 @@ enclosing blocks."
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.
574When invoked via `indent-for-tab-command', cycle through possible 591When invoked via `indent-for-tab-command', cycle through possible
575indentations for current line. The cycle is broken by a command different 592indentations for current line. The cycle is broken by a command different
@@ -586,13 +603,30 @@ from `indent-for-tab-command', i.e. successive TABs do the cycling."
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,
618or 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
@@ -629,8 +663,7 @@ start of buffer."
629 "`end-of-defun-function' for Python. 663 "`end-of-defun-function' for Python.
630Finds end of innermost nested class or method definition." 664Finds 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.
@@ -829,7 +862,8 @@ move and return nil. Otherwise return t."
829Makes nested Imenu menus from nested `class' and `def' statements. 862Makes nested Imenu menus from nested `class' and `def' statements.
830The nested menus are headed by an item referencing the outer 863The nested menus are headed by an item referencing the outer
831definition; it has a space prepended to the name so that it sorts 864definition; it has a space prepended to the name so that it sorts
832first with `imenu--sort-by-name'." 865first with `imenu--sort-by-name' (though, unfortunately, sub-menus
866precede 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
@@ -914,13 +948,20 @@ See `python-check-command' for the default."
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.
923Any arguments can't contain whitespace." 962Any arguments can't contain whitespace.
963Note 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
@@ -937,40 +978,66 @@ Additional arguments are added when the command is used by `run-python'
937et al.") 978et 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."
941To run multiple Python processes, start the first with \\[run-python]. 982 ;; Fixme: a single process is currently assumed, so that this doc
942It 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
944will be in a new buffer, named *Python*. Switch between the different 985;; "*The current python process buffer.
945process 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
947Commands that send text from source buffers to Python processes have 988;; \\[rename-buffer]. Now start a new process with \\[run-python]. It
948to 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:
954If you do a \\[python-send-region-and-go] command on some Python source 995;; Buffer Process
955code, 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?
960Process selection is done by function `python-proc'. 1001
961 1002;; - In a process buffer (foo, bar, or *Python*), send it to that process.
962Whenever \\[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
963to be the new process's buffer. If you only run one process, this will 1004;; attached to `python-buffer'.
964do 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.
976A Python process can be started with \\[run-python]. 1043A Python process can be started with \\[run-python].
@@ -991,14 +1058,13 @@ For running multiple processes in multiple buffers, see `python-buffer'.
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))
@@ -1009,15 +1075,9 @@ 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.
1014It 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.
1018Don't save anything for STR matching `inferior-python-filter-regexp'. 1080Don't save anything for STR matching `inferior-python-filter-regexp'."
1019Also 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.
@@ -1030,21 +1090,8 @@ Also resets variables for adjusting error messages."
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.
1035Used 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'.")
@@ -1055,7 +1102,9 @@ Used as line-number hook function in `python-compilation-regexp-alist'."
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)))
@@ -1076,10 +1125,10 @@ Used as line-number hook function in `python-compilation-regexp-alist'."
1076CMD is the Python command to run. NOSHOW non-nil means don't show the 1125CMD is the Python command to run. NOSHOW non-nil means don't show the
1077buffer automatically. 1126buffer automatically.
1078If there is a process already running in `*Python*', switch to 1127If there is a process already running in `*Python*', switch to
1079that buffer. Interactively a prefix arg, allows you to edit the initial 1128that buffer. Interactively, a prefix arg allows you to edit the initial
1080command line (default is the value of `python-command'); `-i' etc. args 1129command line (default is `python-command'); `-i' etc. args will be added
1081will be added to this as appropriate. Runs the hooks 1130to 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)
@@ -1089,82 +1138,78 @@ will be added to this as appropriate. Runs the hooks
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
1102def _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,
1107def _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
1128print '_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."
@@ -1177,6 +1222,8 @@ print '_emacs_ok'"))
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)
@@ -1223,39 +1270,33 @@ function location information for debugging, and supports users of
1223module-qualified names." 1270module-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.
1244if globals().has_key(%S): reload(%s)
1245else: 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) 1293See 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
@@ -1267,33 +1308,47 @@ else: import %s
1267 "Syntax table giving `.' symbol syntax. 1308 "Syntax table giving `.' symbol syntax.
1268Otherwise inherits from `python-mode-syntax-table'.") 1309Otherwise 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'.
1274Interactively, prompt for symbol." 1318Interactively, prompt for symbol.
1275 ;; Note that we do this in the inferior process, not a separate one to 1319
1320Symbol may be anything recognized by the interpreter's `help' command --
1321e.g. `CALLS' -- not just variables in scope.
1322This only works for Python version 2.2 or newer since earlier interpreters
1323don'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))
@@ -1302,6 +1357,15 @@ Interactively, prompt for symbol."
1302 1357
1303(add-to-list 'debug-ignored-errors "^No symbol") 1358(add-to-list 'debug-ignored-errors "^No symbol")
1304 1359
1360(defun python-send-receive (string)
1361 "Send STRING to inferior Python (if any) and return result.
1362The 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))
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.)
@@ -1310,14 +1374,9 @@ Interactively, prompt for symbol."
1310Only works when point is in a function name, not its arglist, for instance. 1374Only works when point is in a function name, not its arglist, for instance.
1311Assumes an inferior Python is running." 1375Assumes 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
@@ -1331,11 +1390,13 @@ Used with `eval-after-load'."
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
@@ -1401,7 +1462,7 @@ The criterion is either a match for `jython-mode' via
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))))
@@ -1519,11 +1580,97 @@ Uses `python-beginning-of-block', `python-end-of-block'."
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.
1587The 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.
1615Repeating 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.
@@ -1565,11 +1712,10 @@ lines count as headers.
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)
@@ -1587,6 +1733,9 @@ lines count as headers.
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)