diff options
| author | Stefan Monnier | 2004-04-13 18:02:03 +0000 |
|---|---|---|
| committer | Stefan Monnier | 2004-04-13 18:02:03 +0000 |
| commit | 0578dead3a18ccc5419db3d1d5bb4db43165bd44 (patch) | |
| tree | 688e4ee2ba1e5c447e38332db3994e8f2fbc5d17 /lisp/progmodes/python.el | |
| parent | 40899d7b7522cd518bb37ac635d1263c9f0d2236 (diff) | |
| download | emacs-0578dead3a18ccc5419db3d1d5bb4db43165bd44.tar.gz emacs-0578dead3a18ccc5419db3d1d5bb4db43165bd44.zip | |
Doc fixes. Changes for compiler warnings.
(syntax): Don't require.
(python) <defgroup>: Add :version.
(python-quote-syntax): Re-written.
(inferior-python-mode): Move stuff here from run-python and add
some more.
(python-preoutput-continuation, python-preoutput-result)
(python-dotty-syntax-table): New.
(python-describe-symbol): Use them.
(run-python): Move stuff to inferior-python-mode. Modify code
loaded into Python.
(python-send-region): Use python-proc, python-send-string.
(python-send-string): Send newlines too. Callers changed.
(python-load-file): Re-written.
(python-eldoc-function): New.
(info-look): Don't require.
(python-after-info-look): New. A modified version of former
top-level code for use with eval-after-load.
(python-maybe-jython, python-guess-indent): Use widened buffer.
(python-fill-paragraph): Re-written.
(python-mode): Fix outline-regexp. Set outline-heading-end-regexp,
eldoc-print-current-symbol-info-function. Add to eldoc-mode-hook.
Diffstat (limited to 'lisp/progmodes/python.el')
| -rw-r--r-- | lisp/progmodes/python.el | 558 |
1 files changed, 361 insertions, 197 deletions
diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el index ee752f78352..36dc832347c 100644 --- a/lisp/progmodes/python.el +++ b/lisp/progmodes/python.el | |||
| @@ -38,7 +38,7 @@ | |||
| 38 | 38 | ||
| 39 | ;; This doesn't implement all the facilities of python-mode.el. Some | 39 | ;; This doesn't implement all the facilities of python-mode.el. Some |
| 40 | ;; just need doing, e.g. catching exceptions in the inferior Python | 40 | ;; just need doing, e.g. catching exceptions in the inferior Python |
| 41 | ;; buffer (but see M-x pdb for debugging). [Atually, the use of | 41 | ;; buffer (but see M-x pdb for debugging). [Actually, the use of |
| 42 | ;; `compilation-minor-mode' now is probably enough for that.] Others | 42 | ;; `compilation-minor-mode' now is probably enough for that.] Others |
| 43 | ;; don't seem appropriate. For instance, `forward-into-nomenclature' | 43 | ;; don't seem appropriate. For instance, `forward-into-nomenclature' |
| 44 | ;; should be done separately, since it's not specific to Python, and | 44 | ;; should be done separately, since it's not specific to Python, and |
| @@ -56,16 +56,25 @@ | |||
| 56 | ;; bindings are changed to obey Emacs conventions, and things like | 56 | ;; bindings are changed to obey Emacs conventions, and things like |
| 57 | ;; marking blocks and `beginning-of-defun' behave differently. | 57 | ;; marking blocks and `beginning-of-defun' behave differently. |
| 58 | 58 | ||
| 59 | ;; TODO: See various Fixmes below. It should be possible to arrange | ||
| 60 | ;; some sort of completion using the inferior interpreter. | ||
| 61 | |||
| 59 | ;;; Code: | 62 | ;;; Code: |
| 60 | 63 | ||
| 61 | (require 'syntax) ; ensure appropriate version | ||
| 62 | ;; It's messy to autoload the relevant comint functions so that comint | 64 | ;; It's messy to autoload the relevant comint functions so that comint |
| 63 | ;; is only required when inferior Python is used. | 65 | ;; is only required when inferior Python is used. |
| 64 | (require 'comint) | 66 | (require 'comint) |
| 67 | (eval-when-compile | ||
| 68 | (require 'compile) | ||
| 69 | (autoload 'Info-last "info") | ||
| 70 | (autoload 'Info-exit "info") | ||
| 71 | (autoload 'info-lookup-maybe-add-help "info-look")) | ||
| 72 | (autoload 'compilation-start "compile") ; spurious compiler warning anyway | ||
| 65 | 73 | ||
| 66 | (defgroup python nil | 74 | (defgroup python nil |
| 67 | "Silly walks in the Python language" | 75 | "Silly walks in the Python language" |
| 68 | :group 'languages | 76 | :group 'languages |
| 77 | :version "21.4" | ||
| 69 | :link '(emacs-commentary-link "python")) | 78 | :link '(emacs-commentary-link "python")) |
| 70 | 79 | ||
| 71 | ;;;###autoload | 80 | ;;;###autoload |
| @@ -101,7 +110,8 @@ | |||
| 101 | (group (syntax string-quote)) ; maybe gets property | 110 | (group (syntax string-quote)) ; maybe gets property |
| 102 | (backref 2) ; per first quote | 111 | (backref 2) ; per first quote |
| 103 | (group (backref 2)))) ; maybe gets property | 112 | (group (backref 2)))) ; maybe gets property |
| 104 | (1 (python-quote-syntax 1)) (2 (python-quote-syntax 2)) | 113 | (1 (python-quote-syntax 1)) |
| 114 | (2 (python-quote-syntax 2)) | ||
| 105 | (3 (python-quote-syntax 3))) | 115 | (3 (python-quote-syntax 3))) |
| 106 | ;; This doesn't really help. | 116 | ;; This doesn't really help. |
| 107 | ;;; (,(rx (and ?\\ (group ?\n))) (1 " ")) | 117 | ;;; (,(rx (and ?\\ (group ?\n))) (1 " ")) |
| @@ -110,40 +120,43 @@ | |||
| 110 | (defun python-quote-syntax (n) | 120 | (defun python-quote-syntax (n) |
| 111 | "Put `syntax-table' property correctly on triple quote. | 121 | "Put `syntax-table' property correctly on triple quote. |
| 112 | Used for syntactic keywords. N is the match number (1, 2 or 3)." | 122 | Used for syntactic keywords. N is the match number (1, 2 or 3)." |
| 113 | ;; Given a triple quote, we have to look backwards for a previous | 123 | ;; Given a triple quote, we have to check the context to know |
| 114 | ;; occurrence of the sequence to know whether this is an opening or | 124 | ;; whether this is an opening or closing triple or whether it's |
| 115 | ;; closing triple. We also have to sort out a possible prefix -- | 125 | ;; quoted anyhow, and should be ignored. (For that we need to do |
| 116 | ;; well, we don't _have_ to, but I think it should be treated as | 126 | ;; the same job as `syntax-ppss' to be correct and it seems to be OK |
| 117 | ;; part of the string. | 127 | ;; to use it here despite initial worries.) We also have to sort |
| 118 | (let ((tag (save-excursion | 128 | ;; out a possible prefix -- well, we don't _have_ to, but I think it |
| 119 | (goto-char (match-beginning 0)) | 129 | ;; should be treated as part of the string. |
| 120 | (unless (eq ?\\ (char-before)) | 130 | |
| 121 | (cond | 131 | ;; Test cases: |
| 122 | ;; Look for a previous string fence. | 132 | ;; ur"""ar""" x='"' # """ |
| 123 | ((or (zerop (skip-syntax-backward "^|")) | 133 | ;; x = ''' """ ' a |
| 124 | (bobp)) | 134 | ;; ''' |
| 125 | 'start) ; no previous string fence | 135 | ;; x '"""' x |
| 126 | ;; Check fence on a matching quote. | 136 | (save-excursion |
| 127 | ((eq (char-before) (char-after (match-beginning 2))) | 137 | (goto-char (match-beginning 0)) |
| 128 | (if (eq (char-before) (char-after)) | 138 | (unless (eq ?\\ (char-before)) |
| 129 | 'end ; fence ended string | 139 | (cond |
| 130 | 'start)) ; began string | 140 | ;; Consider property for the last char if in a fenced string. |
| 131 | ;; Check for matching prefixed string. | 141 | ((= n 3) |
| 132 | ((and (memq (char-before) '(?u ?U ?r ?R)) | 142 | (let ((syntax (syntax-ppss))) |
| 133 | (skip-chars-forward "rR")) | 143 | (when (eq t (nth 3 syntax)) ; after unclosed fence |
| 134 | (if (eq (char-after) (char-after (match-beginning 2))) | 144 | (goto-char (nth 8 syntax)) ; fence position |
| 135 | 'end)) ; else non-matching: return nil | 145 | ;; Skip any prefix. |
| 136 | ;; For non-matching quote, start new string. | 146 | (if (memq (char-after) '(?u ?U ?R ?r)) |
| 137 | ((/= (char-before) (char-after)) | 147 | (skip-chars-forward "uUrR")) |
| 138 | 'start)))))) | 148 | ;; Is it a matching sequence? |
| 139 | (if (if (eq tag 'start) ; Maybe starts a new string. | 149 | (if (eq (char-after) (char-after (match-beginning 2))) |
| 140 | ;; Initial property if this is the prefix (empty or not) or | 150 | (eval-when-compile (string-to-syntax "|")))))) |
| 141 | ;; isn't the prefix and the prefix is empty. | 151 | ;; Consider property for initial char, accounting for prefixes. |
| 142 | (or (= n 1) (and (= n 2) (= (match-beginning 1) (match-end 1)))) | 152 | ((or (and (= n 2) ; not prefix |
| 143 | (and (eq tag 'end) ; Maybe ends existing string. | 153 | (= (match-beginning 1) (match-end 1))) ; prefix is null |
| 144 | (= n 3))) ; Match is at end. | 154 | (and (= n 1) ; prefix |
| 145 | (eval-when-compile (string-to-syntax "|")) | 155 | (/= (match-beginning 1) (match-end 1)))) ; non-empty |
| 146 | ;; Otherwise the property is nil, which is OK. | 156 | (unless (eq 'string (syntax-ppss-context (syntax-ppss))) |
| 157 | (eval-when-compile (string-to-syntax "|"))))) | ||
| 158 | ;; Otherwise (we're in a non-matching string) the property is | ||
| 159 | ;; nil, which is OK. | ||
| 147 | ))) | 160 | ))) |
| 148 | 161 | ||
| 149 | ;; This isn't currently in `font-lock-defaults' as probably not worth | 162 | ;; This isn't currently in `font-lock-defaults' as probably not worth |
| @@ -386,27 +399,29 @@ Continuation lines follow a backslash-terminated line starting a statement." | |||
| 386 | Set `python-indent' locally to the value guessed." | 399 | Set `python-indent' locally to the value guessed." |
| 387 | (interactive) | 400 | (interactive) |
| 388 | (save-excursion | 401 | (save-excursion |
| 389 | (goto-char (point-min)) | 402 | (save-restriction |
| 390 | (let (done indent) | 403 | (widen) |
| 391 | (while (and (not done) (not (eobp))) | 404 | (goto-char (point-min)) |
| 392 | (when (and (re-search-forward (rx (and ?: (0+ space) | 405 | (let (done indent) |
| 393 | (or (syntax comment-start) | 406 | (while (and (not done) (not (eobp))) |
| 394 | line-end))) | 407 | (when (and (re-search-forward (rx (and ?: (0+ space) |
| 395 | nil 'move) | 408 | (or (syntax comment-start) |
| 396 | (python-open-block-statement-p)) | 409 | line-end))) |
| 397 | (save-excursion | 410 | nil 'move) |
| 398 | (python-beginning-of-statement) | 411 | (python-open-block-statement-p)) |
| 399 | (let ((initial (current-indentation))) | 412 | (save-excursion |
| 400 | (if (zerop (python-next-statement)) | 413 | (python-beginning-of-statement) |
| 401 | (setq indent (- (current-indentation) initial))) | 414 | (let ((initial (current-indentation))) |
| 402 | (if (and (>= indent 2) (<= indent 8)) ; sanity check | 415 | (if (zerop (python-next-statement)) |
| 403 | (setq done t)))))) | 416 | (setq indent (- (current-indentation) initial))) |
| 404 | (when done | 417 | (if (and (>= indent 2) (<= indent 8)) ; sanity check |
| 405 | (when (/= indent (default-value 'python-indent)) | 418 | (setq done t)))))) |
| 406 | (set (make-local-variable 'python-indent) indent) | 419 | (when done |
| 407 | (unless (= tab-width python-indent) | 420 | (when (/= indent (default-value 'python-indent)) |
| 408 | (setq indent-tabs-mode nil))) | 421 | (set (make-local-variable 'python-indent) indent) |
| 409 | indent)))) | 422 | (unless (= tab-width python-indent) |
| 423 | (setq indent-tabs-mode nil))) | ||
| 424 | indent))))) | ||
| 410 | 425 | ||
| 411 | (defun python-calculate-indentation () | 426 | (defun python-calculate-indentation () |
| 412 | "Calculate Python indentation for line at point." | 427 | "Calculate Python indentation for line at point." |
| @@ -884,8 +899,6 @@ If not at the end of line's indentation, or on a comment line, just call | |||
| 884 | (defvar python-saved-check-command nil | 899 | (defvar python-saved-check-command nil |
| 885 | "Internal use.") | 900 | "Internal use.") |
| 886 | 901 | ||
| 887 | (autoload 'compilation-start "compile") | ||
| 888 | |||
| 889 | ;; After `sgml-validate-command'. | 902 | ;; After `sgml-validate-command'. |
| 890 | (defun python-check (command) | 903 | (defun python-check (command) |
| 891 | "Check a Python file (default current buffer's file). | 904 | "Check a Python file (default current buffer's file). |
| @@ -950,6 +963,13 @@ to be the new process's buffer. If you only run one process, this will | |||
| 950 | do the right thing. If you run multiple processes, you can change | 963 | do the right thing. If you run multiple processes, you can change |
| 951 | `python-buffer' to another process buffer with \\[set-variable].") | 964 | `python-buffer' to another process buffer with \\[set-variable].") |
| 952 | 965 | ||
| 966 | (defconst python-compilation-regexp-alist | ||
| 967 | `((,(rx (and line-start (1+ (any " \t")) "File \"" | ||
| 968 | (group (1+ (not (any "\"<")))) ; avoid `<stdin>' &c | ||
| 969 | "\", line " (group (1+ digit)))) | ||
| 970 | 1 python-compilation-line-number)) | ||
| 971 | "`compilation-error-regexp-alist' for inferior Python.") | ||
| 972 | |||
| 953 | (define-derived-mode inferior-python-mode comint-mode "Inferior Python" | 973 | (define-derived-mode inferior-python-mode comint-mode "Inferior Python" |
| 954 | "Major mode for interacting with an inferior Python process. | 974 | "Major mode for interacting with an inferior Python process. |
| 955 | A Python process can be started with \\[run-python]. | 975 | A Python process can be started with \\[run-python]. |
| @@ -973,7 +993,14 @@ For running multiple processes in multiple buffers, see `python-buffer'. | |||
| 973 | ;; Fixme: Maybe install some python-mode bindings too. | 993 | ;; Fixme: Maybe install some python-mode bindings too. |
| 974 | (define-key inferior-python-mode-map "\C-c\C-l" 'python-load-file) | 994 | (define-key inferior-python-mode-map "\C-c\C-l" 'python-load-file) |
| 975 | (define-key inferior-python-mode-map "\C-c\C-z" 'python-switch-to-python) | 995 | (define-key inferior-python-mode-map "\C-c\C-z" 'python-switch-to-python) |
| 976 | (setq comint-input-filter #'python-input-filter)) | 996 | (add-hook 'comint-input-filter-functions 'python-input-filter nil t) |
| 997 | (add-hook 'comint-preoutput-filter-functions #'python-preoutput-filter | ||
| 998 | nil t) | ||
| 999 | ;; Still required by `comint-redirect-send-command', for instance: | ||
| 1000 | (set (make-local-variable 'comint-prompt-regexp) "^\\([>.]\\{3\\} \\)+") | ||
| 1001 | (set (make-local-variable 'compilation-error-regexp-alist) | ||
| 1002 | python-compilation-regexp-alist) | ||
| 1003 | (compilation-shell-minor-mode 1)) | ||
| 977 | 1004 | ||
| 978 | (defcustom inferior-python-filter-regexp "\\`\\s-*\\S-?\\S-?\\s-*\\'" | 1005 | (defcustom inferior-python-filter-regexp "\\`\\s-*\\S-?\\S-?\\s-*\\'" |
| 979 | "*Input matching this regexp is not saved on the history list. | 1006 | "*Input matching this regexp is not saved on the history list. |
| @@ -989,7 +1016,7 @@ Default ignores all inputs of 0, 1, or 2 non-blank characters." | |||
| 989 | 1016 | ||
| 990 | (defun python-input-filter (str) | 1017 | (defun python-input-filter (str) |
| 991 | "`comint-input-filter' function for inferior Python. | 1018 | "`comint-input-filter' function for inferior Python. |
| 992 | Don't save anything matching `inferior-python-filter-regexp'. | 1019 | Don't save anything for STR matching `inferior-python-filter-regexp'. |
| 993 | Also resets variables for adjusting error messages." | 1020 | Also resets variables for adjusting error messages." |
| 994 | (setq python-orig-file nil | 1021 | (setq python-orig-file nil |
| 995 | python-orig-start-line 1) | 1022 | python-orig-start-line 1) |
| @@ -1005,17 +1032,6 @@ Also resets variables for adjusting error messages." | |||
| 1005 | (t (let ((pos (string-match "[^ \t]" string))) | 1032 | (t (let ((pos (string-match "[^ \t]" string))) |
| 1006 | (if pos (python-args-to-list (substring string pos)))))))) | 1033 | (if pos (python-args-to-list (substring string pos)))))))) |
| 1007 | 1034 | ||
| 1008 | (defvar compilation-minor-mode-map) | ||
| 1009 | (defvar compilation-error-list) | ||
| 1010 | (defvar compilation-parsing-end) | ||
| 1011 | |||
| 1012 | (defconst python-compilation-regexp-alist | ||
| 1013 | `((,(rx (and line-start (1+ (any " \t")) "File \"" | ||
| 1014 | (group (1+ (not (any "\"<")))) ; avoid `<stdin>' &c | ||
| 1015 | "\", line " (group (1+ digit)))) | ||
| 1016 | 1 python-compilation-line-number)) | ||
| 1017 | "`compilation-error-regexp-alist' for inferior Python.") | ||
| 1018 | |||
| 1019 | (defun python-compilation-line-number (file col) | 1035 | (defun python-compilation-line-number (file col) |
| 1020 | "Return error descriptor of error found for FILE, column COL. | 1036 | "Return error descriptor of error found for FILE, column COL. |
| 1021 | Used as line-number hook function in `python-compilation-regexp-alist'." | 1037 | Used as line-number hook function in `python-compilation-regexp-alist'." |
| @@ -1028,44 +1044,90 @@ Used as line-number hook function in `python-compilation-regexp-alist'." | |||
| 1028 | (+ line (1- python-orig-start-line)) | 1044 | (+ line (1- python-orig-start-line)) |
| 1029 | nil))) | 1045 | nil))) |
| 1030 | 1046 | ||
| 1047 | (defvar python-preoutput-result nil | ||
| 1048 | "Data from output line last `_emacs_out' line seen by the preoutput filter.") | ||
| 1049 | |||
| 1050 | (defvar python-preoutput-continuation nil | ||
| 1051 | "If non-nil, funcall this when `python-preoutput-filter' sees `_emacs_ok'.") | ||
| 1052 | |||
| 1053 | ;; Using this stops us getting lines in the buffer like | ||
| 1054 | ;; >>> ... ... >>> | ||
| 1055 | ;; Also look for (and delete) an `_emacs_ok' string and call | ||
| 1056 | ;; `python-preoutput-continuation' if we get it. | ||
| 1057 | (defun python-preoutput-filter (s) | ||
| 1058 | "`comint-preoutput-filter-functions' function: ignore prompts not at bol." | ||
| 1059 | (cond ((and (string-match "\\`[.>]\\{3\\} \\'" s) | ||
| 1060 | (/= (let ((inhibit-field-text-motion t)) | ||
| 1061 | (line-beginning-position)) | ||
| 1062 | (point))) | ||
| 1063 | "") | ||
| 1064 | ((string= s "_emacs_ok\n") | ||
| 1065 | (when python-preoutput-continuation | ||
| 1066 | (funcall python-preoutput-continuation) | ||
| 1067 | (setq python-preoutput-continuation nil)) | ||
| 1068 | "") | ||
| 1069 | ((string-match "_emacs_out \\(.*\\)\n" s) | ||
| 1070 | (setq python-preoutput-result (match-string 1 s)) | ||
| 1071 | "") | ||
| 1072 | (t s))) | ||
| 1073 | |||
| 1031 | ;;;###autoload | 1074 | ;;;###autoload |
| 1032 | (defun run-python (cmd) | 1075 | (defun run-python (&optional cmd noshow) |
| 1033 | "Run an inferior Python process, input and output via buffer *Python*. | 1076 | "Run an inferior Python process, input and output via buffer *Python*. |
| 1034 | CMD is the Python command to run. | 1077 | CMD is the Python command to run. NOSHOW non-nil means don't show the |
| 1078 | buffer automatically. | ||
| 1035 | If there is a process already running in `*Python*', switch to | 1079 | If there is a process already running in `*Python*', switch to |
| 1036 | that buffer. With argument, allows you to edit the initial | 1080 | that buffer. Interactively a prefix arg, allows you to edit the initial |
| 1037 | command line (default is the value of `python-command'); `-i' and | 1081 | command line (default is the value of `python-command'); `-i' etc. args |
| 1038 | `-c' args will be added to this to support evaluations in the | 1082 | will be added to this as appropriate. Runs the hooks |
| 1039 | REPL. Runs the hooks `inferior-python-mode-hook' \(after the | 1083 | `inferior-python-mode-hook' (after the `comint-mode-hook' is run). |
| 1040 | `comint-mode-hook' is run). \(Type \\[describe-mode] in the | 1084 | \(Type \\[describe-mode] in the process buffer for a list of commands.)" |
| 1041 | process buffer for a list of commands.)" | ||
| 1042 | (interactive (list (if current-prefix-arg | 1085 | (interactive (list (if current-prefix-arg |
| 1043 | (read-string "Run Python: " python-command) | 1086 | (read-string "Run Python: " python-command) |
| 1044 | python-command))) | 1087 | python-command))) |
| 1088 | (unless cmd (setq cmd python-python-command)) | ||
| 1089 | (setq python-command cmd) | ||
| 1045 | ;; Fixme: Consider making `python-buffer' buffer-local as a buffer | 1090 | ;; Fixme: Consider making `python-buffer' buffer-local as a buffer |
| 1046 | ;; (not a name) in Python buffers from which `run-python' &c is | 1091 | ;; (not a name) in Python buffers from which `run-python' &c is |
| 1047 | ;; invoked. Would support multiple processes better. | 1092 | ;; invoked. Would support multiple processes better. |
| 1048 | (if (not (comint-check-proc "*Python*")) | 1093 | (unless (comint-check-proc "*Python*") |
| 1049 | (let ((cmdlist (append (python-args-to-list cmd) | 1094 | (let ((cmdlist (append (python-args-to-list cmd) '("-i")))) |
| 1050 | '("-i" "-c" "\ | 1095 | (set-buffer (apply 'make-comint "Python" (car cmdlist) nil |
| 1051 | from os import remove as _emacs_rem | 1096 | (cdr cmdlist)))) |
| 1052 | def _emacs_execfile (file): | 1097 | (inferior-python-mode) |
| 1053 | try: | 1098 | ;; Load function defintions we need. |
| 1054 | execfile (file) | 1099 | ;; Before the preoutput function was used, this was done via -c in |
| 1055 | finally: | 1100 | ;; cmdlist, but that loses the banner and doesn't run the startup |
| 1056 | _emacs_rem (file) | 1101 | ;; file. |
| 1057 | ")))) | 1102 | (python-send-string "\ |
| 1058 | (set-buffer (apply 'make-comint "Python" (car cmdlist) nil | 1103 | def _emacs_execfile (file): # execute file and remove it |
| 1059 | (cdr cmdlist))) | 1104 | from os import remove |
| 1060 | (inferior-python-mode) | 1105 | try: execfile (file, globals (), globals ()) |
| 1061 | (setq comint-output-filter-functions nil))) | 1106 | finally: remove (file) |
| 1062 | (setq python-command cmd) | 1107 | |
| 1063 | (setq python-buffer "*Python*") | 1108 | def _emacs_args (name): # get arglist of name for eldoc &c |
| 1064 | (pop-to-buffer "*Python*") | 1109 | import inspect |
| 1065 | (set (make-local-variable 'compilation-error-regexp-alist) | 1110 | parts = name.split ('.') |
| 1066 | python-compilation-regexp-alist) | 1111 | if len (parts) > 1: |
| 1067 | (compilation-shell-minor-mode 1) | 1112 | try: exec 'import ' + parts[0] |
| 1068 | (add-hook 'comint-input-filter-functions 'python-input-filter nil t)) | 1113 | except: return None |
| 1114 | try: exec 'func='+name # lose if name is keyword or undefined | ||
| 1115 | except: return None | ||
| 1116 | if inspect.isbuiltin (func): | ||
| 1117 | doc = func.__doc__ | ||
| 1118 | if doc.find (' ->') != -1: | ||
| 1119 | print '_emacs_out', doc.split (' ->')[0] | ||
| 1120 | elif doc.find ('\n') != -1: | ||
| 1121 | print '_emacs_out', doc.split ('\n')[0] | ||
| 1122 | return None | ||
| 1123 | if inspect.ismethod (func): func = func.im_func | ||
| 1124 | if not inspect.isfunction (func): | ||
| 1125 | return None | ||
| 1126 | (args, varargs, varkw, defaults) = inspect.getargspec (func) | ||
| 1127 | print '_emacs_out', func.__name__+inspect.formatargspec (args, varargs, varkw, defaults) | ||
| 1128 | |||
| 1129 | print '_emacs_ok'")) | ||
| 1130 | (unless noshow (pop-to-buffer (setq python-buffer "*Python*")))) | ||
| 1069 | 1131 | ||
| 1070 | (defun python-mouse-2-command (event) | 1132 | (defun python-mouse-2-command (event) |
| 1071 | "Command bound to `mouse-2' in inferior Python buffer. | 1133 | "Command bound to `mouse-2' in inferior Python buffer. |
| @@ -1114,7 +1176,7 @@ Selects Comint or Compilation mode command as appropriate." | |||
| 1114 | ;; comint-filter the first two lines of the traceback? | 1176 | ;; comint-filter the first two lines of the traceback? |
| 1115 | (interactive "r") | 1177 | (interactive "r") |
| 1116 | (let* ((f (make-temp-file "py")) | 1178 | (let* ((f (make-temp-file "py")) |
| 1117 | (command (format "_emacs_execfile(%S)\n" f)) | 1179 | (command (format "_emacs_execfile(%S)" f)) |
| 1118 | (orig-file (buffer-file-name)) | 1180 | (orig-file (buffer-file-name)) |
| 1119 | (orig-line (save-restriction | 1181 | (orig-line (save-restriction |
| 1120 | (widen) | 1182 | (widen) |
| @@ -1126,22 +1188,21 @@ Selects Comint or Compilation mode command as appropriate." | |||
| 1126 | (write-region start end f t 'nomsg) | 1188 | (write-region start end f t 'nomsg) |
| 1127 | (when python-buffer | 1189 | (when python-buffer |
| 1128 | (with-current-buffer python-buffer | 1190 | (with-current-buffer python-buffer |
| 1129 | (let ((end (marker-position (process-mark | 1191 | (let ((end (marker-position (process-mark (python-proc))))) |
| 1130 | (get-buffer-process python-buffer))))) | ||
| 1131 | (set (make-local-variable 'python-orig-file) orig-file) | 1192 | (set (make-local-variable 'python-orig-file) orig-file) |
| 1132 | (set (make-local-variable 'python-orig-start-line) orig-line) | 1193 | (set (make-local-variable 'python-orig-start-line) orig-line) |
| 1133 | (set (make-local-variable 'compilation-error-list) nil) | 1194 | (set (make-local-variable 'compilation-error-list) nil) |
| 1134 | ;; (set (make-local-variable 'compilation-old-error-list) nil) | ||
| 1135 | (let ((comint-input-filter-functions | 1195 | (let ((comint-input-filter-functions |
| 1136 | (delete 'python-input-filter comint-input-filter-functions))) | 1196 | (delete 'python-input-filter comint-input-filter-functions))) |
| 1137 | (comint-send-string (python-proc) command)) | 1197 | (python-send-string command)) |
| 1138 | (set-marker compilation-parsing-end end) | 1198 | (set-marker compilation-parsing-end end) |
| 1139 | (setq compilation-last-buffer (current-buffer))))))) | 1199 | (setq compilation-last-buffer (current-buffer))))))) |
| 1140 | 1200 | ||
| 1141 | (defun python-send-string (string) | 1201 | (defun python-send-string (string) |
| 1142 | "Evaluate STRING in inferior Python process." | 1202 | "Evaluate STRING in inferior Python process." |
| 1143 | (interactive "sPython command: ") | 1203 | (interactive "sPython command: ") |
| 1144 | (comint-send-string (python-proc) string)) | 1204 | (comint-send-string (python-proc) string) |
| 1205 | (comint-send-string (python-proc) "\n\n")) | ||
| 1145 | 1206 | ||
| 1146 | (defun python-send-buffer () | 1207 | (defun python-send-buffer () |
| 1147 | "Send the current buffer to the inferior Python process." | 1208 | "Send the current buffer to the inferior Python process." |
| @@ -1198,19 +1259,31 @@ module-qualified names." | |||
| 1198 | (comint-check-source file-name) ; Check to see if buffer needs saved. | 1259 | (comint-check-source file-name) ; Check to see if buffer needs saved. |
| 1199 | (setq python-prev-dir/file (cons (file-name-directory file-name) | 1260 | (setq python-prev-dir/file (cons (file-name-directory file-name) |
| 1200 | (file-name-nondirectory file-name))) | 1261 | (file-name-nondirectory file-name))) |
| 1201 | (comint-send-string | 1262 | (when python-buffer |
| 1202 | (python-proc) | 1263 | (with-current-buffer python-buffer |
| 1203 | (if (string-match "\\.py\\'" file-name) | 1264 | (let ((end (marker-position (process-mark (python-proc))))) |
| 1204 | ;; Fixme: make sure the directory is in the path list | 1265 | (set (make-local-variable 'compilation-error-list) nil) |
| 1205 | (let ((module (file-name-sans-extension | 1266 | ;; (set (make-local-variable 'compilation-old-error-list) nil) |
| 1206 | (file-name-nondirectory file-name)))) | 1267 | (let ((comint-input-filter-functions |
| 1207 | (format "\ | 1268 | (delete 'python-input-filter comint-input-filter-functions))) |
| 1208 | if globals().has_key('%s'): | 1269 | (python-send-string |
| 1209 | reload(%s) | 1270 | (if (string-match "\\.py\\'" file-name) |
| 1210 | else: | 1271 | ;; Fixme: make sure the directory is in the path list |
| 1211 | import %s | 1272 | (let ((module (file-name-sans-extension |
| 1273 | (file-name-nondirectory file-name)))) | ||
| 1274 | (set (make-local-variable 'python-orig-file) nil) | ||
| 1275 | (set (make-local-variable 'python-orig-start-line) nil) | ||
| 1276 | (format "\ | ||
| 1277 | try: | ||
| 1278 | if globals().has_key(%S): reload(%s) | ||
| 1279 | else: import %s | ||
| 1280 | except: None | ||
| 1212 | " module module module)) | 1281 | " module module module)) |
| 1213 | (format "execfile('%s')\n" filename)))) | 1282 | (set (make-local-variable 'python-orig-file) file-name) |
| 1283 | (set (make-local-variable 'python-orig-start-line) 1) | ||
| 1284 | (format "execfile('%s')" file-name)))) | ||
| 1285 | (set-marker compilation-parsing-end end) | ||
| 1286 | (setq compilation-last-buffer (current-buffer)))))) | ||
| 1214 | 1287 | ||
| 1215 | ;; Fixme: Should this start a process if there isn't one? (Unlike cmuscheme.) | 1288 | ;; Fixme: Should this start a process if there isn't one? (Unlike cmuscheme.) |
| 1216 | (defun python-proc () | 1289 | (defun python-proc () |
| @@ -1222,74 +1295,114 @@ else: | |||
| 1222 | 1295 | ||
| 1223 | ;;;; Context-sensitive help. | 1296 | ;;;; Context-sensitive help. |
| 1224 | 1297 | ||
| 1225 | ;; Fixme: Investigate adapting this to eldoc. | 1298 | (defconst python-dotty-syntax-table |
| 1299 | (let ((table (make-syntax-table))) | ||
| 1300 | (set-char-table-parent table python-mode-syntax-table) | ||
| 1301 | (modify-syntax-entry ?. "_" table) | ||
| 1302 | table) | ||
| 1303 | "Syntax table giving `.' symbol syntax. | ||
| 1304 | Otherwise inherits from `python-mode-syntax-table'.") | ||
| 1226 | 1305 | ||
| 1306 | ;; Fixme: Should this actually be used instead of info-look, i.e. be | ||
| 1307 | ;; bound to C-h S? | ||
| 1227 | (defun python-describe-symbol (symbol) | 1308 | (defun python-describe-symbol (symbol) |
| 1228 | "Get help on SYMBOL using `pydoc'. | 1309 | "Get help on SYMBOL using `pydoc'. |
| 1229 | Interactively, prompt for symbol." | 1310 | Interactively, prompt for symbol." |
| 1311 | ;; Note that we do this in the inferior process, not a separate one to | ||
| 1312 | ;; ensure the environment is appropriate. | ||
| 1230 | (interactive | 1313 | (interactive |
| 1231 | (let ((symbol (current-word)) | 1314 | (let ((symbol (with-syntax-table python-dotty-syntax-table |
| 1315 | (current-word))) | ||
| 1232 | (enable-recursive-minibuffers t) | 1316 | (enable-recursive-minibuffers t) |
| 1233 | val) | 1317 | val) |
| 1234 | (setq val (read-string (if symbol | 1318 | (setq val (read-string (if symbol |
| 1235 | (format "Describe variable (default %s): " | 1319 | (format "Describe variable (default %s): " |
| 1236 | symbol) | 1320 | symbol) |
| 1237 | "Describe variable: ") | 1321 | "Describe symbol: ") |
| 1238 | nil nil symbol)) | 1322 | nil nil symbol)) |
| 1239 | (list (or val symbol)))) | 1323 | (list (or val symbol)))) |
| 1240 | (if (equal symbol "") (error "No symbol")) | 1324 | (if (equal symbol "") (error "No symbol")) |
| 1241 | (let* ((mod (if (string-match "\\(\\.[^.]+\\)\\'" symbol) | 1325 | (let* ((func `(lambda () |
| 1242 | (substring symbol 0 (match-beginning 1)))) | 1326 | (comint-redirect-send-command (format "help(%S)\n" ,symbol) |
| 1243 | (import (when mod (concat "import " mod "\n")))) | 1327 | "*Help*" nil)))) |
| 1244 | (with-output-to-temp-buffer "*Python Output*" | 1328 | ;; Ensure we have a suitable help buffer. |
| 1245 | (princ (shell-command-to-string | 1329 | (let (temp-buffer-show-hook) ; avoid xref stuff |
| 1246 | (format "%s -c 'import pydoc %s | 1330 | (with-output-to-temp-buffer "*Help*" |
| 1247 | try: pydoc.help(%S) | 1331 | (with-current-buffer standard-output |
| 1248 | except: print \"No help available on:\", %S'" | 1332 | (set (make-local-variable 'comint-redirect-subvert-readonly) t)))) |
| 1249 | ;; Fixme: Is this necessarily right? | 1333 | (if (and python-buffer (get-buffer python-buffer)) |
| 1250 | (car (split-string python-command)) | 1334 | (with-current-buffer python-buffer |
| 1251 | (or import "") symbol symbol)))))) | 1335 | (funcall func)) |
| 1336 | (setq python-preoutput-continuation func) | ||
| 1337 | (run-python nil t)))) | ||
| 1252 | 1338 | ||
| 1253 | (add-to-list 'debug-ignored-errors "^No symbol") | 1339 | (add-to-list 'debug-ignored-errors "^No symbol") |
| 1340 | |||
| 1341 | ;; Fixme: try to make it work with point in the arglist. Also, is | ||
| 1342 | ;; there anything reasonable we can do with random methods? | ||
| 1343 | ;; (Currently only works with functions.) | ||
| 1344 | (defun python-eldoc-function () | ||
| 1345 | "`eldoc-print-current-symbol-info' for Python. | ||
| 1346 | Only works when point is in a function name, not its arglist, for instance. | ||
| 1347 | Assumes an inferior Python is running." | ||
| 1348 | (let ((symbol (with-syntax-table python-dotty-syntax-table | ||
| 1349 | (current-word))) | ||
| 1350 | (proc (and python-buffer (python-proc)))) | ||
| 1351 | (when (and proc symbol) | ||
| 1352 | (python-send-string | ||
| 1353 | (format "_emacs_args(%S)" symbol)) | ||
| 1354 | (setq python-preoutput-result nil) | ||
| 1355 | (accept-process-output proc 1) | ||
| 1356 | python-preoutput-result))) | ||
| 1254 | 1357 | ||
| 1255 | ;;;; Info-look functionality. | 1358 | ;;;; Info-look functionality. |
| 1256 | 1359 | ||
| 1257 | (require 'info-look) | 1360 | (defun python-after-info-look () |
| 1258 | ;; We should be able to add info-lookup specs without loading the file first. | 1361 | "Set up info-look for Python. |
| 1259 | ;; E.g. by setting a buffer-local var or something like that. --Stef | 1362 | Used with `eval-after-load'." |
| 1260 | (let ((version (let ((s (shell-command-to-string (concat python-command | 1363 | (let* ((version (let ((s (shell-command-to-string (concat python-command |
| 1261 | " -V")))) | 1364 | " -V")))) |
| 1262 | (string-match "^Python \\([0-9]+\\.[0-9]+\\>\\)" s) | 1365 | (string-match "^Python \\([0-9]+\\.[0-9]+\\>\\)" s) |
| 1263 | (match-string 1 s))) | 1366 | (match-string 1 s))) |
| 1264 | ;; Whether info files have a Python version suffix, e.g. in Debian. | 1367 | ;; Whether info files have a Python version suffix, e.g. in Debian. |
| 1265 | (versioned (save-window-excursion | 1368 | (versioned |
| 1266 | (condition-case () | 1369 | (with-temp-buffer |
| 1267 | ;; The call to `info' might create a new frame if | 1370 | (Info-mode) |
| 1268 | ;; pop-up-frames or special-display-buffers are used. | 1371 | (condition-case () |
| 1269 | ;; So I disabled it until we find a better way | 1372 | (Info-goto-node (format "(python%s-lib)Miscellaneous Index" |
| 1270 | ;; to handle this situation. Maybe Debian should just | 1373 | version)) |
| 1271 | ;; fix their install somehow. --Stef | 1374 | (error nil))))) |
| 1272 | ;; (progn (info "(python2.3-lib)Miscellaneous Index") | 1375 | (info-lookup-maybe-add-help |
| 1273 | ;; (Info-last) | 1376 | :mode 'python-mode |
| 1274 | ;; (Info-exit) | 1377 | :regexp "[[:alnum:]_]+" |
| 1275 | ;; t) | 1378 | :doc-spec |
| 1276 | nil | 1379 | ;; Fixme: Can this reasonably be made specific to indices with |
| 1277 | (error nil))))) | 1380 | ;; different rules? Is the order of indices optimal? |
| 1278 | (info-lookup-maybe-add-help | 1381 | ;; (Miscellaneous in -ref first prefers lookup of keywords, for |
| 1279 | :mode 'python-mode | 1382 | ;; instance.) |
| 1280 | :regexp "[[:alnum:]_]+" | 1383 | (if versioned |
| 1281 | :doc-spec | 1384 | ;; The empty prefix just gets us highlighted terms. |
| 1282 | ;; Fixme: Add python-ref? Can this reasonably be made specific | 1385 | `((,(concat "(python" version "-ref)Miscellaneous Index") nil "") |
| 1283 | ;; to indices with different rules? | 1386 | (,(concat "(python" version "-ref)Module Index" nil "")) |
| 1284 | (if versioned | 1387 | (,(concat "(python" version "-ref)Function-Method-Variable Index" |
| 1285 | '((,(concat "(python" version "-lib)Module Index")) | 1388 | nil "")) |
| 1286 | (,(concat "(python" version "-lib)Class-Exception-Object Index")) | 1389 | (,(concat "(python" version "-ref)Class-Exception-Object Index" |
| 1287 | (,(concat "(python" version "-lib)Function-Method-Variable Index")) | 1390 | nil "")) |
| 1288 | (,(concat "(python" version "-lib)Miscellaneous Index"))) | 1391 | (,(concat "(python" version "-lib)Module Index" nil "")) |
| 1289 | '(("(python-lib)Module Index") | 1392 | (,(concat "(python" version "-lib)Class-Exception-Object Index" |
| 1290 | ("(python-lib)Class-Exception-Object Index") | 1393 | nil "")) |
| 1291 | ("(python-lib)Function-Method-Variable Index") | 1394 | (,(concat "(python" version "-lib)Function-Method-Variable Index" |
| 1292 | ("(python-lib)Miscellaneous Index"))))) | 1395 | nil "")) |
| 1396 | (,(concat "(python" version "-lib)Miscellaneous Index" nil ""))) | ||
| 1397 | '(("(python-ref)Miscellaneous Index" nil "") | ||
| 1398 | ("(python-ref)Module Index" nil "") | ||
| 1399 | ("(python-ref)Function-Method-Variable Index" nil "") | ||
| 1400 | ("(python-ref)Class-Exception-Object Index" nil "") | ||
| 1401 | ("(python-lib)Module Index" nil "") | ||
| 1402 | ("(python-lib)Class-Exception-Object Index" nil "") | ||
| 1403 | ("(python-lib)Function-Method-Variable Index" nil "") | ||
| 1404 | ("(python-lib)Miscellaneous Index" nil "")))))) | ||
| 1405 | (eval-after-load "info-look" '(python-after-info-look)) | ||
| 1293 | 1406 | ||
| 1294 | ;;;; Miscellancy. | 1407 | ;;;; Miscellancy. |
| 1295 | 1408 | ||
| @@ -1309,34 +1422,65 @@ The criterion is either a match for `jython-mode' via | |||
| 1309 | `python-jython-packages'." | 1422 | `python-jython-packages'." |
| 1310 | ;; The logic is taken from python-mode.el. | 1423 | ;; The logic is taken from python-mode.el. |
| 1311 | (save-excursion | 1424 | (save-excursion |
| 1312 | (goto-char (point-min)) | 1425 | (save-restriction |
| 1313 | (let ((interpreter (if (looking-at auto-mode-interpreter-regexp) | 1426 | (widen) |
| 1314 | (match-string 2)))) | 1427 | (goto-char (point-min)) |
| 1315 | (if (and interpreter (eq 'jython-mode | 1428 | (let ((interpreter (if (looking-at auto-mode-interpreter-regexp) |
| 1316 | (cdr (assoc (file-name-nondirectory interpreter) | 1429 | (match-string 2)))) |
| 1317 | interpreter-mode-alist)))) | 1430 | (if (and interpreter (eq 'jython-mode |
| 1318 | (jython-mode) | 1431 | (cdr (assoc (file-name-nondirectory |
| 1319 | (if (catch 'done | 1432 | interpreter) |
| 1320 | (while (re-search-forward | 1433 | interpreter-mode-alist)))) |
| 1321 | (rx (and line-start (or "import" "from") (1+ space) | 1434 | (jython-mode) |
| 1322 | (group (1+ (not (any " \t\n.")))))) | 1435 | (if (catch 'done |
| 1323 | (+ (point) 10000) ; Probably not worth customizing. | 1436 | (while (re-search-forward |
| 1324 | t) | 1437 | (rx (and line-start (or "import" "from") (1+ space) |
| 1325 | (if (member (match-string 1) python-jython-packages) | 1438 | (group (1+ (not (any " \t\n.")))))) |
| 1326 | (throw 'done t)))) | 1439 | 10000 ; Probably not worth customizing. |
| 1327 | (jython-mode)))))) | 1440 | t) |
| 1441 | (if (member (match-string 1) python-jython-packages) | ||
| 1442 | (throw 'done t)))) | ||
| 1443 | (jython-mode))))))) | ||
| 1328 | 1444 | ||
| 1329 | (defun python-fill-paragraph (&optional justify) | 1445 | (defun python-fill-paragraph (&optional justify) |
| 1330 | "Like \\[fill-paragraph], but handle comments and multi-line strings. | 1446 | "`fill-paragraph-function' handling comments and multi-line strings. |
| 1331 | If any of the current line is a comment, fill the comment or the | 1447 | If any of the current line is a comment, fill the comment or the |
| 1332 | paragraph of it that point is in, preserving the comment's indentation | 1448 | paragraph of it that point is in, preserving the comment's |
| 1333 | and initial comment characters." | 1449 | indentation and initial comment characters. Similarly if the end |
| 1450 | of the current line is in or at the end of a multi-line string. | ||
| 1451 | Otherwise, do nothing." | ||
| 1334 | (interactive "P") | 1452 | (interactive "P") |
| 1335 | (or (fill-comment-paragraph justify) | 1453 | (or (fill-comment-paragraph justify) |
| 1336 | (let ((paragraph-start (concat paragraph-start | 1454 | ;; The `paragraph-start' and `paragraph-separate' variables |
| 1337 | "\\|\\s-*\\(:?#\\s\"\\|\\s|\\|#"))) | 1455 | ;; don't allow us to delimit the last paragraph in a multi-line |
| 1338 | (fill-paragraph justify)) | 1456 | ;; string properly, so narrow to the string and then fill around |
| 1339 | t)) | 1457 | ;; (the end of) the current line. |
| 1458 | (save-excursion | ||
| 1459 | (end-of-line) | ||
| 1460 | (let* ((syntax (syntax-ppss)) | ||
| 1461 | (orig (point)) | ||
| 1462 | (start (nth 8 syntax)) | ||
| 1463 | end) | ||
| 1464 | (cond ((eq t (nth 3 syntax)) ; in fenced string | ||
| 1465 | (goto-char (nth 8 syntax)) ; string start | ||
| 1466 | (condition-case () ; for unbalanced quotes | ||
| 1467 | (progn (forward-sexp) | ||
| 1468 | (setq end (point))) | ||
| 1469 | (error (setq end (point-max))))) | ||
| 1470 | ((re-search-backward "\\s|\\s-*\\=" nil t) ; end of fenced | ||
| 1471 | ; string | ||
| 1472 | (forward-char) | ||
| 1473 | (setq end (point)) | ||
| 1474 | (condition-case () | ||
| 1475 | (progn (backward-sexp) | ||
| 1476 | (setq start (point))) | ||
| 1477 | (error nil)))) | ||
| 1478 | (when end | ||
| 1479 | (save-restriction | ||
| 1480 | (narrow-to-region start end) | ||
| 1481 | (goto-char orig) | ||
| 1482 | (fill-paragraph justify)))))) | ||
| 1483 | t) | ||
| 1340 | 1484 | ||
| 1341 | (defun python-shift-left (start end &optional count) | 1485 | (defun python-shift-left (start end &optional count) |
| 1342 | "Shift lines in region COUNT (the prefix arg) columns to the left. | 1486 | "Shift lines in region COUNT (the prefix arg) columns to the left. |
| @@ -1377,7 +1521,8 @@ END lie." | |||
| 1377 | 1521 | ||
| 1378 | (defun python-outline-level () | 1522 | (defun python-outline-level () |
| 1379 | "`outline-level' function for Python mode. | 1523 | "`outline-level' function for Python mode. |
| 1380 | The level is the number of `python-indent' steps of indentation." | 1524 | The level is the number of `python-indent' steps of indentation |
| 1525 | of current line." | ||
| 1381 | (/ (current-indentation) python-indent)) | 1526 | (/ (current-indentation) python-indent)) |
| 1382 | 1527 | ||
| 1383 | ;; Fixme: Consider top-level assignments, imports, &c. | 1528 | ;; Fixme: Consider top-level assignments, imports, &c. |
| @@ -1411,17 +1556,23 @@ Uses `python-beginning-of-block', `python-end-of-block'." | |||
| 1411 | 1556 | ||
| 1412 | ;;;; Modes. | 1557 | ;;;; Modes. |
| 1413 | 1558 | ||
| 1559 | (defvar outline-heading-end-regexp) | ||
| 1560 | (defvar eldoc-print-current-symbol-info-function) | ||
| 1561 | |||
| 1414 | ;;;###autoload | 1562 | ;;;###autoload |
| 1415 | (define-derived-mode python-mode fundamental-mode "Python" | 1563 | (define-derived-mode python-mode fundamental-mode "Python" |
| 1416 | "Major mode for editing Python files. | 1564 | "Major mode for editing Python files. |
| 1417 | Turns on Font Lock mode unconditionally since it is required for correct | 1565 | Turns on Font Lock mode unconditionally since it is required for correct |
| 1418 | parsing of the source. | 1566 | parsing of the source. |
| 1419 | See also `jython-mode', which is actually invoked if the buffer appears to | 1567 | See also `jython-mode', which is actually invoked if the buffer appears to |
| 1420 | contain Jython code. | 1568 | contain Jython code. See also `run-python' and associated Python mode |
| 1569 | commands for running Python under Emacs. | ||
| 1421 | 1570 | ||
| 1422 | The Emacs commands which work with `defun's, e.g. \\[beginning-of-defun], deal | 1571 | The Emacs commands which work with `defun's, e.g. \\[beginning-of-defun], deal |
| 1423 | with nested `def' and `class' blocks. They take the innermost one as | 1572 | with nested `def' and `class' blocks. They take the innermost one as |
| 1424 | current without distinguishing method and class definitions. | 1573 | current without distinguishing method and class definitions. Used multiple |
| 1574 | times, they move over others at the same indentation level until they reach | ||
| 1575 | the end of definitions at that level, when they move up a level. | ||
| 1425 | \\<python-mode-map> | 1576 | \\<python-mode-map> |
| 1426 | Colon is electric: it outdents the line if appropriate, e.g. for | 1577 | Colon is electric: it outdents the line if appropriate, e.g. for |
| 1427 | an else statement. \\[python-backspace] at the beginning of an indented statement | 1578 | an else statement. \\[python-backspace] at the beginning of an indented statement |
| @@ -1430,6 +1581,13 @@ deletes a charcter backward. TAB indents the current line relative to | |||
| 1430 | the preceding code. Successive TABs, with no intervening command, cycle | 1581 | the preceding code. Successive TABs, with no intervening command, cycle |
| 1431 | through the possibilities for indentation on the basis of enclosing blocks. | 1582 | through the possibilities for indentation on the basis of enclosing blocks. |
| 1432 | 1583 | ||
| 1584 | \\[fill-paragraph] fills comments and multiline strings appropriately, but has no | ||
| 1585 | effect outside them. | ||
| 1586 | |||
| 1587 | Supports Eldoc mode (only for functions, using a Python process), | ||
| 1588 | Info-Look and Imenu. In Outline minor mode, `class' and `def' | ||
| 1589 | lines count as headers. | ||
| 1590 | |||
| 1433 | \\{python-mode-map}" | 1591 | \\{python-mode-map}" |
| 1434 | :group 'python | 1592 | :group 'python |
| 1435 | (set (make-local-variable 'font-lock-defaults) | 1593 | (set (make-local-variable 'font-lock-defaults) |
| @@ -1451,7 +1609,8 @@ through the possibilities for indentation on the basis of enclosing blocks. | |||
| 1451 | (set (make-local-variable 'add-log-current-defun-function) | 1609 | (set (make-local-variable 'add-log-current-defun-function) |
| 1452 | #'python-current-defun) | 1610 | #'python-current-defun) |
| 1453 | ;; Fixme: Generalize to do all blocks? | 1611 | ;; Fixme: Generalize to do all blocks? |
| 1454 | (set (make-local-variable 'outline-regexp) "\\s-+\\(def\\|class\\)\\>") | 1612 | (set (make-local-variable 'outline-regexp) "\\s-*\\(def\\|class\\)\\>") |
| 1613 | (set (make-local-variable 'outline-heading-end-regexp) ":\\s-*\n") | ||
| 1455 | (set (make-local-variable 'outline-level) #'python-outline-level) | 1614 | (set (make-local-variable 'outline-level) #'python-outline-level) |
| 1456 | (set (make-local-variable 'open-paren-in-column-0-is-defun-start) nil) | 1615 | (set (make-local-variable 'open-paren-in-column-0-is-defun-start) nil) |
| 1457 | (make-local-variable 'python-saved-check-command) | 1616 | (make-local-variable 'python-saved-check-command) |
| @@ -1459,6 +1618,10 @@ through the possibilities for indentation on the basis of enclosing blocks. | |||
| 1459 | 'python-beginning-of-defun) | 1618 | 'python-beginning-of-defun) |
| 1460 | (set (make-local-variable 'end-of-defun-function) 'python-end-of-defun) | 1619 | (set (make-local-variable 'end-of-defun-function) 'python-end-of-defun) |
| 1461 | (setq imenu-create-index-function #'python-imenu-create-index) | 1620 | (setq imenu-create-index-function #'python-imenu-create-index) |
| 1621 | (set (make-local-variable 'eldoc-print-current-symbol-info-function) | ||
| 1622 | #'python-eldoc-function) | ||
| 1623 | (add-hook 'eldoc-mode-hook | ||
| 1624 | '(lambda () (run-python 0 t)) nil t) ; need it running | ||
| 1462 | (unless font-lock-mode (font-lock-mode 1)) | 1625 | (unless font-lock-mode (font-lock-mode 1)) |
| 1463 | (when python-guess-indent (python-guess-indent)) | 1626 | (when python-guess-indent (python-guess-indent)) |
| 1464 | (set (make-local-variable 'python-command) python-python-command) | 1627 | (set (make-local-variable 'python-command) python-python-command) |
| @@ -1471,6 +1634,7 @@ through the possibilities for indentation on the basis of enclosing blocks. | |||
| 1471 | '(lambda () | 1634 | '(lambda () |
| 1472 | "Turn on Indent Tabs mode." | 1635 | "Turn on Indent Tabs mode." |
| 1473 | (set (make-local-variable 'indent-tabs-mode) t))) | 1636 | (set (make-local-variable 'indent-tabs-mode) t))) |
| 1637 | (custom-add-option 'python-mode-hook 'turn-on-eldoc-mode) | ||
| 1474 | 1638 | ||
| 1475 | ;;;###autoload | 1639 | ;;;###autoload |
| 1476 | (define-derived-mode jython-mode python-mode "Jython" | 1640 | (define-derived-mode jython-mode python-mode "Jython" |