aboutsummaryrefslogtreecommitdiffstats
path: root/lisp/progmodes/python.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/progmodes/python.el')
-rw-r--r--lisp/progmodes/python.el454
1 files changed, 295 insertions, 159 deletions
diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el
index 9eaba9027b8..0fdaf652e50 100644
--- a/lisp/progmodes/python.el
+++ b/lisp/progmodes/python.el
@@ -46,19 +46,18 @@
46;; 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.
47;; Other things seem more natural or canonical here, e.g. the 47;; Other things seem more natural or canonical here, e.g. the
48;; {beginning,end}-of-defun implementation dealing with nested 48;; {beginning,end}-of-defun implementation dealing with nested
49;; definitions, and the inferior mode following `cmuscheme'. (The 49;; definitions, and the inferior mode following `cmuscheme'. The
50;; inferior mode should be able to find the source of errors from 50;; inferior mode can find the source of errors from
51;; `python-send-region' & al via `compilation-minor-mode', but I can't 51;; `python-send-region' & al via `compilation-minor-mode'. Successive
52;; make that work with the current (March '04) compile.el.) 52;; TABs cycle between possible indentations for the line. There is
53;; Successive TABs cycle between possible indentations for the line. 53;; symbol completion using lookup in Python.
54 54
55;; Even where it has similar facilities, this is incompatible with 55;; Even where it has similar facilities, this is incompatible with
56;; python-mode.el in various respects. For instance, various key 56;; python-mode.el in various respects. For instance, various key
57;; bindings are changed to obey Emacs conventions, and things like 57;; bindings are changed to obey Emacs conventions, and things like
58;; marking blocks and `beginning-of-defun' behave differently. 58;; marking blocks and `beginning-of-defun' behave differently.
59 59
60;; TODO: See various Fixmes below. It should be possible to arrange 60;; TODO: See various Fixmes below.
61;; some sort of completion using the inferior interpreter.
62 61
63;;; Code: 62;;; Code:
64 63
@@ -203,6 +202,8 @@ Used for syntactic keywords. N is the match number (1, 2 or 3)."
203 (define-key map "\C-c\C-z" 'python-switch-to-python) 202 (define-key map "\C-c\C-z" 'python-switch-to-python)
204 (define-key map "\C-c\C-m" 'python-load-file) 203 (define-key map "\C-c\C-m" 'python-load-file)
205 (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)
206 ;; Fixme: Add :help to menu. 207 ;; Fixme: Add :help to menu.
207 (easy-menu-define python-menu map "Python Mode menu" 208 (easy-menu-define python-menu map "Python Mode menu"
208 '("Python" 209 '("Python"
@@ -261,9 +262,7 @@ Used for syntactic keywords. N is the match number (1, 2 or 3)."
261;;;; Utility stuff 262;;;; Utility stuff
262 263
263(defsubst python-in-string/comment () 264(defsubst python-in-string/comment ()
264 "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)."
265Optional argument LIM indicates the beginning of the containing form,
266i.e. the limit on how far back to scan."
267 (syntax-ppss-context (syntax-ppss))) 266 (syntax-ppss-context (syntax-ppss)))
268 267
269(defconst python-space-backslash-table 268(defconst python-space-backslash-table
@@ -300,14 +299,17 @@ comments and strings, or that the bracket/paren nesting depth is nonzero."
300(defun python-comment-line-p () 299(defun python-comment-line-p ()
301 "Return non-nil if current line has only a comment or is blank." 300 "Return non-nil if current line has only a comment or is blank."
302 (save-excursion 301 (save-excursion
303 (back-to-indentation) 302 (end-of-line)
304 (looking-at (rx (or (syntax comment-start) line-end))))) 303 ;; FIXME: This looks wrong because it returns nil for empty lines. --Stef
304 (when (eq 'comment (syntax-ppss-context (syntax-ppss)))
305 (back-to-indentation)
306 (looking-at (rx (or (syntax comment-start) line-end))))))
305 307
306(defun python-beginning-of-string () 308(defun python-beginning-of-string ()
307 "Go to beginning of string around point. 309 "Go to beginning of string around point.
308Do nothing if not in string." 310Do nothing if not in string."
309 (let ((state (syntax-ppss))) 311 (let ((state (syntax-ppss)))
310 (when (nth 3 state) 312 (when (eq 'string (syntax-ppss-context state))
311 (goto-char (nth 8 state))))) 313 (goto-char (nth 8 state)))))
312 314
313(defun python-open-block-statement-p (&optional bos) 315(defun python-open-block-statement-p (&optional bos)
@@ -383,7 +385,8 @@ Otherwise indent them to column zero."
383(defcustom python-honour-comment-indentation nil 385(defcustom python-honour-comment-indentation nil
384 "Non-nil means indent relative to preceding comment line. 386 "Non-nil means indent relative to preceding comment line.
385Only do this for comments where the leading comment character is followed 387Only do this for comments where the leading comment character is followed
386by space." 388by space. This doesn't apply to comment lines, which are always indented
389in lines with preceding comments."
387 :type 'boolean 390 :type 'boolean
388 :group 'python) 391 :group 'python)
389 392
@@ -513,6 +516,16 @@ Set `python-indent' locally to the value guessed."
513 (- python-indent))) 516 (- python-indent)))
514 0))))))))) 517 0)))))))))
515 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
516;;;; Cycling through the possible indentations with successive TABs. 529;;;; Cycling through the possible indentations with successive TABs.
517 530
518;; 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
@@ -537,11 +550,17 @@ Set `python-indent' locally to the value guessed."
537 (point)))) 550 (point))))
538 551
539(defun python-indentation-levels () 552(defun python-indentation-levels ()
540 "Return a list of possible indentations for this statement. 553 "Return a list of possible indentations for this line.
541Includes the default indentation and those which would close all 554Includes the default indentation and those which would close all
542enclosing 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)."
543 (save-excursion 559 (save-excursion
544 (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)))))))
545 ;; Only one possibility if we immediately follow a block open or 564 ;; Only one possibility if we immediately follow a block open or
546 ;; are in a continuation line. 565 ;; are in a continuation line.
547 (unless (or (python-continuation-line-p) 566 (unless (or (python-continuation-line-p)
@@ -567,8 +586,7 @@ enclosing blocks."
567 (if (> (- (point-max) pos) (point)) 586 (if (> (- (point-max) pos) (point))
568 (goto-char (- (point-max) pos)))))) 587 (goto-char (- (point-max) pos))))))
569 588
570;; Fixme: Is the arg necessary? 589(defun python-indent-line ()
571(defun python-indent-line (&optional arg)
572 "Indent current line as Python code. 590 "Indent current line as Python code.
573When invoked via `indent-for-tab-command', cycle through possible 591When invoked via `indent-for-tab-command', cycle through possible
574indentations for current line. The cycle is broken by a command different 592indentations for current line. The cycle is broken by a command different
@@ -585,13 +603,30 @@ from `indent-for-tab-command', i.e. successive TABs do the cycling."
585 (beginning-of-line) 603 (beginning-of-line)
586 (delete-horizontal-space) 604 (delete-horizontal-space)
587 (indent-to (car (nth python-indent-index python-indent-list))) 605 (indent-to (car (nth python-indent-index python-indent-list)))
588 (let ((text (cdr (nth python-indent-index 606 (if (python-block-end-p)
589 python-indent-list)))) 607 (let ((text (cdr (nth python-indent-index
590 (if text (message "Closes: %s" text))))) 608 python-indent-list))))
609 (if text
610 (message "Closes: %s" text))))))
591 (python-indent-line-1) 611 (python-indent-line-1)
592 (setq python-indent-list (python-indentation-levels) 612 (setq python-indent-list (python-indentation-levels)
593 python-indent-list-length (length python-indent-list) 613 python-indent-list-length (length python-indent-list)
594 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.
595 630
596;;;; Movement. 631;;;; Movement.
597 632
@@ -628,8 +663,7 @@ start of buffer."
628 "`end-of-defun-function' for Python. 663 "`end-of-defun-function' for Python.
629Finds end of innermost nested class or method definition." 664Finds end of innermost nested class or method definition."
630 (let ((orig (point)) 665 (let ((orig (point))
631 (pattern (rx (and line-start (0+ space) 666 (pattern (rx (and line-start (0+ space) (or "def" "class") space))))
632 (or "def" "class") space))))
633 ;; 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
634 ;; 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
635 ;; definition statement. 669 ;; definition statement.
@@ -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
@@ -970,12 +1011,31 @@ et al.")
970 ) 1011 )
971 1012
972(defconst python-compilation-regexp-alist 1013(defconst python-compilation-regexp-alist
1014 ;; FIXME: maybe these should move to compilation-error-regexp-alist-alist.
973 `((,(rx (and line-start (1+ (any " \t")) "File \"" 1015 `((,(rx (and line-start (1+ (any " \t")) "File \""
974 (group (1+ (not (any "\"<")))) ; avoid `<stdin>' &c 1016 (group (1+ (not (any "\"<")))) ; avoid `<stdin>' &c
975 "\", line " (group (1+ digit)))) 1017 "\", line " (group (1+ digit))))
976 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))
977 "`compilation-error-regexp-alist' for inferior Python.") 1022 "`compilation-error-regexp-alist' for inferior Python.")
978 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-z" 'python-switch-to-python) ;What for? --Stef
1029 (define-key map "\C-c\C-v" 'python-check)
1030 ;; Note that we _can_ still use these commands which send to the
1031 ;; Python process even at the prompt iff we have a normal prompt,
1032 ;; i.e. '>>> ' and not '... '. See the comment before
1033 ;; python-send-region. Fixme: uncomment these if we address that.
1034
1035 ;; (define-key map [(meta ?\t)] 'python-complete-symbol)
1036 ;; (define-key map "\C-c\C-f" 'python-describe-symbol)
1037 map))
1038
979;; Fixme: This should inherit some stuff from python-mode, but I'm not 1039;; Fixme: This should inherit some stuff from python-mode, but I'm not
980;; sure how much: at least some keybindings, like C-c C-f; syntax?; 1040;; sure how much: at least some keybindings, like C-c C-f; syntax?;
981;; font-locking, e.g. for triple-quoted strings? 1041;; font-locking, e.g. for triple-quoted strings?
@@ -999,15 +1059,13 @@ For running multiple processes in multiple buffers, see `python-buffer'.
999 :group 'python 1059 :group 'python
1000 (set-syntax-table python-mode-syntax-table) 1060 (set-syntax-table python-mode-syntax-table)
1001 (setq mode-line-process '(":%s")) 1061 (setq mode-line-process '(":%s"))
1002 ;; Fixme: Maybe install some python-mode bindings too. 1062 (set (make-local-variable 'comint-input-filter) 'python-input-filter)
1003 (define-key inferior-python-mode-map "\C-c\C-l" 'python-load-file)
1004 (define-key inferior-python-mode-map "\C-c\C-z" 'python-switch-to-python)
1005 (add-hook 'comint-input-filter-functions 'python-input-filter nil t)
1006 (add-hook 'comint-preoutput-filter-functions #'python-preoutput-filter 1063 (add-hook 'comint-preoutput-filter-functions #'python-preoutput-filter
1007 nil t) 1064 nil t)
1008 ;; Still required by `comint-redirect-send-command', for instance 1065 ;; Still required by `comint-redirect-send-command', for instance
1009 ;; (and we need to match things like `>>> ... >>> '): 1066 ;; (and we need to match things like `>>> ... >>> '):
1010 (set (make-local-variable 'comint-prompt-regexp) "^\\([>.]\\{3\\} \\)+") 1067 (set (make-local-variable 'comint-prompt-regexp)
1068 (rx (and line-start (1+ (and (repeat 3 (any ">.")) ?\ )))))
1011 (set (make-local-variable 'compilation-error-regexp-alist) 1069 (set (make-local-variable 'compilation-error-regexp-alist)
1012 python-compilation-regexp-alist) 1070 python-compilation-regexp-alist)
1013 (compilation-shell-minor-mode 1)) 1071 (compilation-shell-minor-mode 1))
@@ -1018,15 +1076,9 @@ Default ignores all inputs of 0, 1, or 2 non-blank characters."
1018 :type 'regexp 1076 :type 'regexp
1019 :group 'python) 1077 :group 'python)
1020 1078
1021(defvar python-orig-start nil
1022 "Marker to the start of the region passed to the inferior Python.
1023It can also be a filename.")
1024
1025(defun python-input-filter (str) 1079(defun python-input-filter (str)
1026 "`comint-input-filter' function for inferior Python. 1080 "`comint-input-filter' function for inferior Python.
1027Don't save anything for STR matching `inferior-python-filter-regexp'. 1081Don't save anything for STR matching `inferior-python-filter-regexp'."
1028Also resets variables for adjusting error messages."
1029 (setq python-orig-start nil)
1030 (not (string-match inferior-python-filter-regexp str))) 1082 (not (string-match inferior-python-filter-regexp str)))
1031 1083
1032;; Fixme: Loses with quoted whitespace. 1084;; Fixme: Loses with quoted whitespace.
@@ -1039,25 +1091,8 @@ Also resets variables for adjusting error messages."
1039 (t (let ((pos (string-match "[^ \t]" string))) 1091 (t (let ((pos (string-match "[^ \t]" string)))
1040 (if pos (python-args-to-list (substring string pos)))))))) 1092 (if pos (python-args-to-list (substring string pos))))))))
1041 1093
1042(defun python-compilation-line-number (file col)
1043 "Return error descriptor of error found for FILE, column COL.
1044Used as line-number hook function in `python-compilation-regexp-alist'."
1045 (let ((line (string-to-number (match-string 2))))
1046 (cons (point-marker)
1047 (if (and (markerp python-orig-start)
1048 (marker-buffer python-orig-start))
1049 (let ((start python-orig-start))
1050 (with-current-buffer (marker-buffer python-orig-start)
1051 (goto-char start)
1052 (forward-line (1- line))
1053 (point-marker)))
1054 (list (if (stringp python-orig-start)
1055 (list python-orig-start default-directory)
1056 file)
1057 line col)))))
1058
1059(defvar python-preoutput-result nil 1094(defvar python-preoutput-result nil
1060 "Data from output line last `_emacs_out' line seen by the preoutput filter.") 1095 "Data from last `_emacs_out' line seen by the preoutput filter.")
1061 1096
1062(defvar python-preoutput-continuation nil 1097(defvar python-preoutput-continuation nil
1063 "If non-nil, funcall this when `python-preoutput-filter' sees `_emacs_ok'.") 1098 "If non-nil, funcall this when `python-preoutput-filter' sees `_emacs_ok'.")
@@ -1068,7 +1103,9 @@ Used as line-number hook function in `python-compilation-regexp-alist'."
1068;; `python-preoutput-continuation' if we get it. 1103;; `python-preoutput-continuation' if we get it.
1069(defun python-preoutput-filter (s) 1104(defun python-preoutput-filter (s)
1070 "`comint-preoutput-filter-functions' function: ignore prompts not at bol." 1105 "`comint-preoutput-filter-functions' function: ignore prompts not at bol."
1071 (cond ((and (string-match "\\`[.>]\\{3\\} \\'" s) 1106 (cond ((and (string-match (rx (and string-start (repeat 3 (any ".>"))
1107 " " string-end))
1108 s)
1072 (/= (let ((inhibit-field-text-motion t)) 1109 (/= (let ((inhibit-field-text-motion t))
1073 (line-beginning-position)) 1110 (line-beginning-position))
1074 (point))) 1111 (point)))
@@ -1089,10 +1126,10 @@ Used as line-number hook function in `python-compilation-regexp-alist'."
1089CMD is the Python command to run. NOSHOW non-nil means don't show the 1126CMD is the Python command to run. NOSHOW non-nil means don't show the
1090buffer automatically. 1127buffer automatically.
1091If there is a process already running in `*Python*', switch to 1128If there is a process already running in `*Python*', switch to
1092that buffer. Interactively a prefix arg, allows you to edit the initial 1129that buffer. Interactively, a prefix arg allows you to edit the initial
1093command line (default is the value of `python-command'); `-i' etc. args 1130command line (default is `python-command'); `-i' etc. args will be added
1094will be added to this as appropriate. Runs the hooks 1131to this as appropriate. Runs the hook `inferior-python-mode-hook'
1095`inferior-python-mode-hook' (after the `comint-mode-hook' is run). 1132\(after the `comint-mode-hook' is run).
1096\(Type \\[describe-mode] in the process buffer for a list of commands.)" 1133\(Type \\[describe-mode] in the process buffer for a list of commands.)"
1097 (interactive (list (if current-prefix-arg 1134 (interactive (list (if current-prefix-arg
1098 (read-string "Run Python: " python-command) 1135 (read-string "Run Python: " python-command)
@@ -1102,47 +1139,34 @@ will be added to this as appropriate. Runs the hooks
1102 ;; Fixme: Consider making `python-buffer' buffer-local as a buffer 1139 ;; Fixme: Consider making `python-buffer' buffer-local as a buffer
1103 ;; (not a name) in Python buffers from which `run-python' &c is 1140 ;; (not a name) in Python buffers from which `run-python' &c is
1104 ;; invoked. Would support multiple processes better. 1141 ;; invoked. Would support multiple processes better.
1105 (unless (comint-check-proc "*Python*") 1142 (unless (comint-check-proc python-buffer)
1106 (let ((cmdlist (append (python-args-to-list cmd) '("-i")))) 1143 (let ((cmdlist (append (python-args-to-list cmd) '("-i")))
1144 (process-environment ; to import emacs.py
1145 (push (concat "PYTHONPATH=" data-directory)
1146 process-environment)))
1107 (set-buffer (apply 'make-comint "Python" (car cmdlist) nil 1147 (set-buffer (apply 'make-comint "Python" (car cmdlist) nil
1108 (cdr cmdlist)))) 1148 (cdr cmdlist)))
1149 (setq python-buffer "*Python*"))
1109 (inferior-python-mode) 1150 (inferior-python-mode)
1110 ;; Load function defintions we need. 1151 ;; Load function defintions we need.
1111 ;; Before the preoutput function was used, this was done via -c in 1152 ;; Before the preoutput function was used, this was done via -c in
1112 ;; cmdlist, but that loses the banner and doesn't run the startup 1153 ;; cmdlist, but that loses the banner and doesn't run the startup
1113 ;; file. 1154 ;; file. The code might be inline here, but there's enough that it
1114 (python-send-string "\ 1155 ;; seems worth putting in a separate file, and it's probably cleaner
1115def _emacs_execfile (file): # execute file and remove it 1156 ;; to put it in a module.
1116 from os import remove 1157 (python-send-string "import emacs"))
1117 try: execfile (file, globals (), globals ()) 1158 (unless noshow (pop-to-buffer python-buffer)))
1118 finally: remove (file) 1159
1119 1160;; Fixme: We typically lose if the inferior isn't in the normal REPL,
1120def _emacs_args (name): # get arglist of name for eldoc &c 1161;; e.g. prompt is `help> '. Probably raise an error if the form of
1121 import inspect 1162;; the prompt is unexpected; actually, it needs to be `>>> ', not
1122 parts = name.split ('.') 1163;; `... ', i.e. we're not inputting a block &c. However, this may not
1123 if len (parts) > 1: 1164;; be the place to do it, e.g. we might actually want to send commands
1124 try: exec 'import ' + parts[0] 1165;; having set up such a state.
1125 except: return None
1126 try: exec 'func='+name # lose if name is keyword or undefined
1127 except: return None
1128 if inspect.isbuiltin (func):
1129 doc = func.__doc__
1130 if doc.find (' ->') != -1:
1131 print '_emacs_out', doc.split (' ->')[0]
1132 elif doc.find ('\\n') != -1:
1133 print '_emacs_out', doc.split ('\\n')[0]
1134 return None
1135 if inspect.ismethod (func): func = func.im_func
1136 if not inspect.isfunction (func):
1137 return None
1138 (args, varargs, varkw, defaults) = inspect.getargspec (func)
1139 print '_emacs_out', func.__name__+inspect.formatargspec (args, varargs, varkw, defaults)
1140
1141print '_emacs_ok'"))
1142 (unless noshow (pop-to-buffer (setq python-buffer "*Python*"))))
1143 1166
1144(defun python-send-command (command) 1167(defun python-send-command (command)
1145 "Like `python-send-string' but resets `compilation-minor-mode'." 1168 "Like `python-send-string' but resets `compilation-minor-mode'."
1169 (goto-char (point-max))
1146 (let ((end (marker-position (process-mark (python-proc))))) 1170 (let ((end (marker-position (process-mark (python-proc)))))
1147 (compilation-forget-errors) 1171 (compilation-forget-errors)
1148 (python-send-string command) 1172 (python-send-string command)
@@ -1154,35 +1178,37 @@ print '_emacs_ok'"))
1154 ;; The region is evaluated from a temporary file. This avoids 1178 ;; The region is evaluated from a temporary file. This avoids
1155 ;; problems with blank lines, which have different semantics 1179 ;; problems with blank lines, which have different semantics
1156 ;; interactively and in files. It also saves the inferior process 1180 ;; interactively and in files. It also saves the inferior process
1157 ;; buffer filling up with interpreter prompts. We need a function 1181 ;; buffer filling up with interpreter prompts. We need a Python
1158 ;; to remove the temporary file when it has been evaluated, which 1182 ;; function to remove the temporary file when it has been evaluated
1159 ;; unfortunately means using a not-quite pristine interpreter 1183 ;; (though we could probably do it in Lisp with a Comint output
1160 ;; initially. Unfortunately we also get tracebacks which look like: 1184 ;; filter). This function also catches exceptions and truncates
1161 ;; 1185 ;; tracebacks not to mention the frame of the function itself.
1162 ;; >>> Traceback (most recent call last):
1163 ;; File "<stdin>", line 1, in ?
1164 ;; File "<string>", line 4, in _emacs_execfile
1165 ;; File "/tmp/py7734RSB", line 11
1166 ;; 1186 ;;
1167 ;; The compilation-minor-mode parsing takes care of relating the 1187 ;; The compilation-minor-mode parsing takes care of relating the
1168 ;; reference to the temporary file to the source. Fixme: 1188 ;; reference to the temporary file to the source.
1169 ;; comint-filter the first two lines of the traceback? 1189 ;;
1190 ;; Fixme: Write a `coding' header to the temp file if the region is
1191 ;; non-ASCII.
1170 (interactive "r") 1192 (interactive "r")
1171 (let* ((f (make-temp-file "py")) 1193 (let* ((f (make-temp-file "py"))
1172 (command (format "_emacs_execfile(%S)" f)) 1194 (command (format "emacs.eexecfile(%S)" f))
1173 (orig-start (copy-marker start))) 1195 (orig-start (copy-marker start)))
1174 (if (save-excursion 1196 (when (save-excursion
1175 (goto-char start) 1197 (goto-char start)
1176 (/= 0 (current-indentation))) ; need dummy block 1198 (/= 0 (current-indentation))) ; need dummy block
1177 (write-region "if True:\n" nil f nil 'nomsg)) 1199 (save-excursion
1200 (goto-char orig-start)
1201 ;; Wrong if we had indented code at buffer start.
1202 (set-marker orig-start (line-beginning-position 0)))
1203 (write-region "if True:\n" nil f nil 'nomsg))
1178 (write-region start end f t 'nomsg) 1204 (write-region start end f t 'nomsg)
1179 (when python-buffer 1205 (let ((proc (python-proc))) ;Make sure we're running a process.
1180 (with-current-buffer python-buffer 1206 (with-current-buffer python-buffer
1181 (set (make-local-variable 'python-orig-start) orig-start) 1207 (python-send-command command)
1182 (let ((comint-input-filter-functions 1208 ;; Tell compile.el to redirect error locations in file `f' to
1183 ;; Don't reset python-orig-start. 1209 ;; positions past marker `orig-start'. It has to be done *after*
1184 (remq 'python-input-filter comint-input-filter-functions))) 1210 ;; python-send-command's call to compilation-forget-errors.
1185 (python-send-command command)))))) 1211 (compilation-fake-loc orig-start f)))))
1186 1212
1187(defun python-send-string (string) 1213(defun python-send-string (string)
1188 "Evaluate STRING in inferior Python process." 1214 "Evaluate STRING in inferior Python process."
@@ -1195,6 +1221,8 @@ print '_emacs_ok'"))
1195 (interactive) 1221 (interactive)
1196 (python-send-region (point-min) (point-max))) 1222 (python-send-region (point-min) (point-max)))
1197 1223
1224;; Fixme: Try to define the function or class within the relevant
1225;; module, not just at top level.
1198(defun python-send-defun () 1226(defun python-send-defun ()
1199 "Send the current defun (class or method) to the inferior Python process." 1227 "Send the current defun (class or method) to the inferior Python process."
1200 (interactive) 1228 (interactive)
@@ -1241,11 +1269,11 @@ function location information for debugging, and supports users of
1241module-qualified names." 1269module-qualified names."
1242 (interactive (comint-get-source "Load Python file: " python-prev-dir/file 1270 (interactive (comint-get-source "Load Python file: " python-prev-dir/file
1243 python-source-modes 1271 python-source-modes
1244 t)) ; because execfile needs exact name 1272 t)) ; because execfile needs exact name
1245 (comint-check-source file-name) ; Check to see if buffer needs saved. 1273 (comint-check-source file-name) ; Check to see if buffer needs saving.
1246 (setq python-prev-dir/file (cons (file-name-directory file-name) 1274 (setq python-prev-dir/file (cons (file-name-directory file-name)
1247 (file-name-nondirectory file-name))) 1275 (file-name-nondirectory file-name)))
1248 (when python-buffer 1276 (let ((proc (python-proc))) ;Make sure we have a process.
1249 (with-current-buffer python-buffer 1277 (with-current-buffer python-buffer
1250 ;; Fixme: I'm not convinced by this logic from python-mode.el. 1278 ;; Fixme: I'm not convinced by this logic from python-mode.el.
1251 (python-send-command 1279 (python-send-command
@@ -1253,19 +1281,22 @@ module-qualified names."
1253 ;; Fixme: make sure the directory is in the path list 1281 ;; Fixme: make sure the directory is in the path list
1254 (let ((module (file-name-sans-extension 1282 (let ((module (file-name-sans-extension
1255 (file-name-nondirectory file-name)))) 1283 (file-name-nondirectory file-name))))
1256 (format "\ 1284 (format "emacs.eimport(%S,%S)"
1257if globals().has_key(%S): reload(%s) 1285 module (file-name-directory file-name)))
1258else: import %s 1286 (format "execfile(%S)" file-name)))
1259" module module module)) 1287 (message "%s loaded" file-name))))
1260 (format "execfile('%s')" file-name))))))
1261 1288
1262;; Fixme: Should this start a process if there isn't one? (Unlike cmuscheme.) 1289;; Fixme: If we need to start the process, wait until we've got the OK
1290;; from the startup.
1263(defun python-proc () 1291(defun python-proc ()
1264 "Return the current Python process. See variable `python-buffer'." 1292 "Return the current Python process.
1265 (let ((proc (get-buffer-process (if (eq major-mode 'inferior-python-mode) 1293See variable `python-buffer'. Starts a new process if necessary."
1266 (current-buffer) 1294 (or (if python-buffer
1267 python-buffer)))) 1295 (get-buffer-process (if (eq major-mode 'inferior-python-mode)
1268 (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))))
1269 1300
1270;;;; Context-sensitive help. 1301;;;; Context-sensitive help.
1271 1302
@@ -1277,33 +1308,46 @@ else: import %s
1277 "Syntax table giving `.' symbol syntax. 1308 "Syntax table giving `.' symbol syntax.
1278Otherwise inherits from `python-mode-syntax-table'.") 1309Otherwise inherits from `python-mode-syntax-table'.")
1279 1310
1311(defvar view-return-to-alist)
1312
1280;; Fixme: Should this actually be used instead of info-look, i.e. be 1313;; Fixme: Should this actually be used instead of info-look, i.e. be
1281;; bound to C-h S? 1314;; bound to C-h S? Can we use other pydoc stuff before python 2.2?
1282(defun python-describe-symbol (symbol) 1315(defun python-describe-symbol (symbol)
1283 "Get help on SYMBOL using `pydoc'. 1316 "Get help on SYMBOL using `help'.
1284Interactively, prompt for symbol." 1317Interactively, prompt for symbol.
1285 ;; Note that we do this in the inferior process, not a separate one to 1318
1319Symbol may be anything recognized by the interpreter's `help' command --
1320e.g. `CALLS' -- not just variables in scope.
1321This only works for Python version 2.2 or newer since earlier interpreters
1322don't support `help'."
1323 ;; Note that we do this in the inferior process, not a separate one, to
1286 ;; ensure the environment is appropriate. 1324 ;; ensure the environment is appropriate.
1287 (interactive 1325 (interactive
1288 (let ((symbol (with-syntax-table python-dotty-syntax-table 1326 (let ((symbol (with-syntax-table python-dotty-syntax-table
1289 (current-word))) 1327 (current-word)))
1290 (enable-recursive-minibuffers t) 1328 (enable-recursive-minibuffers t))
1291 val) 1329 (list (read-string (if symbol
1292 (setq val (read-string (if symbol 1330 (format "Describe symbol (default %s): " symbol)
1293 (format "Describe symbol (default %s): " 1331 "Describe symbol: ")
1294 symbol) 1332 nil nil symbol))))
1295 "Describe symbol: ")
1296 nil nil symbol))
1297 (list (or val symbol))))
1298 (if (equal symbol "") (error "No symbol")) 1333 (if (equal symbol "") (error "No symbol"))
1299 (let* ((func `(lambda () 1334 (let* ((func `(lambda ()
1300 (comint-redirect-send-command (format "help(%S)\n" ,symbol) 1335 (comint-redirect-send-command (format "emacs.ehelp(%S)\n"
1336 ,symbol)
1301 "*Help*" nil)))) 1337 "*Help*" nil))))
1302 ;; Ensure we have a suitable help buffer. 1338 ;; Ensure we have a suitable help buffer.
1303 (let (temp-buffer-show-hook) ; avoid xref stuff 1339 ;; Fixme: Maybe process `Related help topics' a la help xrefs and
1304 (with-output-to-temp-buffer "*Help*" 1340 ;; allow C-c C-f in help buffer.
1341 (let ((temp-buffer-show-hook ; avoid xref stuff
1342 (lambda ()
1343 (toggle-read-only 1)
1344 (setq view-return-to-alist
1345 (list (cons (selected-window) help-return-method))))))
1346 (help-setup-xref (list 'python-describe-symbol symbol))
1347 (with-output-to-temp-buffer (help-buffer)
1305 (with-current-buffer standard-output 1348 (with-current-buffer standard-output
1306 (set (make-local-variable 'comint-redirect-subvert-readonly) t)))) 1349 (set (make-local-variable 'comint-redirect-subvert-readonly) t)
1350 (print-help-return-message))))
1307 (if (and python-buffer (get-buffer python-buffer)) 1351 (if (and python-buffer (get-buffer python-buffer))
1308 (with-current-buffer python-buffer 1352 (with-current-buffer python-buffer
1309 (funcall func)) 1353 (funcall func))
@@ -1312,6 +1356,15 @@ Interactively, prompt for symbol."
1312 1356
1313(add-to-list 'debug-ignored-errors "^No symbol") 1357(add-to-list 'debug-ignored-errors "^No symbol")
1314 1358
1359(defun python-send-receive (string)
1360 "Send STRING to inferior Python (if any) and return result.
1361The result is what follows `_emacs_out' in the output (or nil)."
1362 (let ((proc (python-proc)))
1363 (python-send-string string)
1364 (setq python-preoutput-result nil)
1365 (accept-process-output proc 5)
1366 python-preoutput-result))
1367
1315;; Fixme: try to make it work with point in the arglist. Also, is 1368;; Fixme: try to make it work with point in the arglist. Also, is
1316;; there anything reasonable we can do with random methods? 1369;; there anything reasonable we can do with random methods?
1317;; (Currently only works with functions.) 1370;; (Currently only works with functions.)
@@ -1320,14 +1373,9 @@ Interactively, prompt for symbol."
1320Only works when point is in a function name, not its arglist, for instance. 1373Only works when point is in a function name, not its arglist, for instance.
1321Assumes an inferior Python is running." 1374Assumes an inferior Python is running."
1322 (let ((symbol (with-syntax-table python-dotty-syntax-table 1375 (let ((symbol (with-syntax-table python-dotty-syntax-table
1323 (current-word))) 1376 (current-word))))
1324 (proc (and python-buffer (python-proc)))) 1377 (when symbol
1325 (when (and proc symbol) 1378 (python-send-receive (format "emacs.eargs(%S)" symbol)))))
1326 (python-send-string
1327 (format "_emacs_args(%S)" symbol))
1328 (setq python-preoutput-result nil)
1329 (accept-process-output proc 1)
1330 python-preoutput-result)))
1331 1379
1332;;;; Info-look functionality. 1380;;;; Info-look functionality.
1333 1381
@@ -1530,11 +1578,97 @@ Uses `python-beginning-of-block', `python-end-of-block'."
1530 (python-end-of-block) 1578 (python-end-of-block)
1531 (exchange-point-and-mark)) 1579 (exchange-point-and-mark))
1532 1580
1581;;;; Completion.
1582
1583(defun python-symbol-completions (symbol)
1584 "Return a list of completions of the string SYMBOL from Python process.
1585The list is sorted."
1586 (when symbol
1587 (let ((completions
1588 (condition-case ()
1589 (car (read-from-string (python-send-receive
1590 (format "emacs.complete(%S)" symbol))))
1591 (error nil))))
1592 (sort
1593 ;; We can get duplicates from the above -- don't know why.
1594 (delete-dups completions)
1595 #'string<))))
1596
1597(defun python-partial-symbol ()
1598 "Return the partial symbol before point (for completion)."
1599 (let ((end (point))
1600 (start (save-excursion
1601 (and (re-search-backward
1602 (rx (and (or buffer-start (regexp "[^[:alnum:]._]"))
1603 (group (1+ (regexp "[[:alnum:]._]")))
1604 point))
1605 nil t)
1606 (match-beginning 1)))))
1607 (if start (buffer-substring-no-properties start end))))
1608
1609;; Fixme: We should have an abstraction of this sort of thing in the
1610;; core.
1611(defun python-complete-symbol ()
1612 "Perform completion on the Python symbol preceding point.
1613Repeating the command scrolls the completion window."
1614 (interactive)
1615 (let ((window (get-buffer-window "*Completions*")))
1616 (if (and (eq last-command this-command)
1617 window (window-live-p window) (window-buffer window)
1618 (buffer-name (window-buffer window)))
1619 (with-current-buffer (window-buffer window)
1620 (if (pos-visible-in-window-p (point-max) window)
1621 (set-window-start window (point-min))
1622 (save-selected-window
1623 (select-window window)
1624 (scroll-up))))
1625 ;; Do completion.
1626 (let* ((end (point))
1627 (symbol (python-partial-symbol))
1628 (completions (python-symbol-completions symbol))
1629 (completion (if completions
1630 (try-completion symbol completions))))
1631 (when symbol
1632 (cond ((eq completion t))
1633 ((null completion)
1634 (message "Can't find completion for \"%s\"" symbol)
1635 (ding))
1636 ((not (string= symbol completion))
1637 (delete-region (- end (length symbol)) end)
1638 (insert completion))
1639 (t
1640 (message "Making completion list...")
1641 (with-output-to-temp-buffer "*Completions*"
1642 (display-completion-list completions))
1643 (message "Making completion list...%s" "done"))))))))
1644
1645(eval-when-compile (require 'hippie-exp))
1646
1647(defun python-try-complete (old)
1648 "Completion function for Python for use with `hippie-expand'."
1649 (when (eq major-mode 'python-mode) ; though we only add it locally
1650 (unless old
1651 (let ((symbol (python-partial-symbol)))
1652 (he-init-string (- (point) (length symbol)) (point))
1653 (if (not (he-string-member he-search-string he-tried-table))
1654 (push he-search-string he-tried-table))
1655 (setq he-expand-list
1656 (and symbol (python-symbol-completions symbol)))))
1657 (while (and he-expand-list
1658 (he-string-member (car he-expand-list) he-tried-table))
1659 (pop he-expand-list))
1660 (if he-expand-list
1661 (progn
1662 (he-substitute-string (pop he-expand-list))
1663 t)
1664 (if old (he-reset-string))
1665 nil)))
1666
1533;;;; Modes. 1667;;;; Modes.
1534 1668
1535(defvar outline-heading-end-regexp) 1669(defvar outline-heading-end-regexp)
1536(defvar eldoc-print-current-symbol-info-function) 1670(defvar eldoc-print-current-symbol-info-function)
1537(defvar python-mode-running) 1671
1538;;;###autoload 1672;;;###autoload
1539(define-derived-mode python-mode fundamental-mode "Python" 1673(define-derived-mode python-mode fundamental-mode "Python"
1540 "Major mode for editing Python files. 1674 "Major mode for editing Python files.
@@ -1576,11 +1710,10 @@ lines count as headers.
1576 )) 1710 ))
1577 (set (make-local-variable 'parse-sexp-lookup-properties) t) 1711 (set (make-local-variable 'parse-sexp-lookup-properties) t)
1578 (set (make-local-variable 'comment-start) "# ") 1712 (set (make-local-variable 'comment-start) "# ")
1579 ;; Fixme: define a comment-indent-function? 1713 (set (make-local-variable 'comment-indent-function) #'python-comment-indent)
1580 (set (make-local-variable 'indent-line-function) #'python-indent-line) 1714 (set (make-local-variable 'indent-line-function) #'python-indent-line)
1581 (set (make-local-variable 'paragraph-start) "\\s-*$") 1715 (set (make-local-variable 'paragraph-start) "\\s-*$")
1582 (set (make-local-variable 'fill-paragraph-function) 1716 (set (make-local-variable 'fill-paragraph-function) 'python-fill-paragraph)
1583 'python-fill-paragraph)
1584 (set (make-local-variable 'require-final-newline) t) 1717 (set (make-local-variable 'require-final-newline) t)
1585 (set (make-local-variable 'add-log-current-defun-function) 1718 (set (make-local-variable 'add-log-current-defun-function)
1586 #'python-current-defun) 1719 #'python-current-defun)
@@ -1598,6 +1731,9 @@ lines count as headers.
1598 #'python-eldoc-function) 1731 #'python-eldoc-function)
1599 (add-hook 'eldoc-mode-hook 1732 (add-hook 'eldoc-mode-hook
1600 '(lambda () (run-python 0 t)) nil t) ; need it running 1733 '(lambda () (run-python 0 t)) nil t) ; need it running
1734 (if (featurep 'hippie-exp)
1735 (set (make-local-variable 'hippie-expand-try-functions-list)
1736 (cons 'python-try-complete hippie-expand-try-functions-list)))
1601 (unless font-lock-mode (font-lock-mode 1)) 1737 (unless font-lock-mode (font-lock-mode 1))
1602 (when python-guess-indent (python-guess-indent)) 1738 (when python-guess-indent (python-guess-indent))
1603 (set (make-local-variable 'python-command) python-python-command) 1739 (set (make-local-variable 'python-command) python-python-command)