3 |
;; Copyright (C) 2003, 04 Free Software Foundation, Inc. |
;; Copyright (C) 2003, 04 Free Software Foundation, Inc. |
4 |
|
|
5 |
;; Author: Dave Love <fx@gnu.org> |
;; Author: Dave Love <fx@gnu.org> |
6 |
|
;; Maintainer: FSF |
7 |
;; Created: Nov 2003 |
;; Created: Nov 2003 |
8 |
;; Keywords: languages |
;; Keywords: languages |
9 |
|
|
46 |
;; I've installed a minor mode to do the job properly in Emacs 22. |
;; 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 |
;; Other things seem more natural or canonical here, e.g. the |
48 |
;; {beginning,end}-of-defun implementation dealing with nested |
;; {beginning,end}-of-defun implementation dealing with nested |
49 |
;; definitions, and the inferior mode following `cmuscheme'. (The |
;; definitions, and the inferior mode following `cmuscheme'. The |
50 |
;; inferior mode should be able to find the source of errors from |
;; inferior mode can find the source of errors from |
51 |
;; `python-send-region' & al via `compilation-minor-mode', but I can't |
;; `python-send-region' & al via `compilation-minor-mode'. Successive |
52 |
;; make that work with the current (March '04) compile.el.) |
;; TABs cycle between possible indentations for the line. There is |
53 |
;; Successive TABs cycle between possible indentations for the line. |
;; symbol completion using lookup in Python. |
54 |
|
|
55 |
;; Even where it has similar facilities, this is incompatible with |
;; Even where it has similar facilities, this is incompatible with |
56 |
;; python-mode.el in various respects. For instance, various key |
;; python-mode.el in various respects. For instance, various key |
57 |
;; bindings are changed to obey Emacs conventions, and things like |
;; bindings are changed to obey Emacs conventions, and things like |
58 |
;; marking blocks and `beginning-of-defun' behave differently. |
;; marking blocks and `beginning-of-defun' behave differently. |
59 |
|
|
60 |
;; TODO: See various Fixmes below. It should be possible to arrange |
;; TODO: See various Fixmes below. |
|
;; some sort of completion using the inferior interpreter. |
|
61 |
|
|
62 |
;;; Code: |
;;; Code: |
63 |
|
|
66 |
(require 'comint) |
(require 'comint) |
67 |
(eval-when-compile |
(eval-when-compile |
68 |
(require 'compile) |
(require 'compile) |
|
(autoload 'Info-last "info") |
|
|
(autoload 'Info-exit "info") |
|
69 |
(autoload 'info-lookup-maybe-add-help "info-look")) |
(autoload 'info-lookup-maybe-add-help "info-look")) |
70 |
(autoload 'compilation-start "compile") ; spurious compiler warning anyway |
(autoload 'compilation-start "compile") |
71 |
|
|
72 |
(defgroup python nil |
(defgroup python nil |
73 |
"Silly walks in the Python language" |
"Silly walks in the Python language" |
202 |
(define-key map "\C-c\C-z" 'python-switch-to-python) |
(define-key map "\C-c\C-z" 'python-switch-to-python) |
203 |
(define-key map "\C-c\C-m" 'python-load-file) |
(define-key map "\C-c\C-m" 'python-load-file) |
204 |
(define-key map "\C-c\C-l" 'python-load-file) ; a la cmuscheme |
(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. |
;; Fixme: Add :help to menu. |
208 |
(easy-menu-define python-menu map "Python Mode menu" |
(easy-menu-define python-menu map "Python Mode menu" |
209 |
'("Python" |
'("Python" |
262 |
;;;; Utility stuff |
;;;; Utility stuff |
263 |
|
|
264 |
(defsubst python-in-string/comment () |
(defsubst python-in-string/comment () |
265 |
"Return non-nil if point is in a Python literal (a comment or string). |
"Return non-nil if point is in a Python literal (a comment or string)." |
|
Optional argument LIM indicates the beginning of the containing form, |
|
|
i.e. the limit on how far back to scan." |
|
266 |
(syntax-ppss-context (syntax-ppss))) |
(syntax-ppss-context (syntax-ppss))) |
267 |
|
|
268 |
(defconst python-space-backslash-table |
(defconst python-space-backslash-table |
297 |
(syntax-ppss (line-beginning-position))))))) |
(syntax-ppss (line-beginning-position))))))) |
298 |
|
|
299 |
(defun python-comment-line-p () |
(defun python-comment-line-p () |
300 |
"Return non-nil if current line has only a comment or is blank." |
"Return non-nil iff current line has only a comment." |
301 |
(save-excursion |
(save-excursion |
302 |
(back-to-indentation) |
(end-of-line) |
303 |
(looking-at (rx (or (syntax comment-start) line-end))))) |
(when (eq 'comment (syntax-ppss-context (syntax-ppss))) |
304 |
|
(back-to-indentation) |
305 |
|
(looking-at (rx (or (syntax comment-start) line-end)))))) |
306 |
|
|
307 |
(defun python-beginning-of-string () |
(defun python-beginning-of-string () |
308 |
"Go to beginning of string around point. |
"Go to beginning of string around point. |
309 |
Do nothing if not in string." |
Do nothing if not in string." |
310 |
(let ((state (syntax-ppss))) |
(let ((state (syntax-ppss))) |
311 |
(when (nth 3 state) |
(when (eq 'string (syntax-ppss-context state)) |
312 |
(goto-char (nth 8 state))))) |
(goto-char (nth 8 state))))) |
313 |
|
|
314 |
(defun python-open-block-statement-p (&optional bos) |
(defun python-open-block-statement-p (&optional bos) |
323 |
line-end)) |
line-end)) |
324 |
(save-excursion (python-end-of-statement)) |
(save-excursion (python-end-of-statement)) |
325 |
t) |
t) |
326 |
(not (python-in-string/comment))))) |
(not (progn (goto-char (match-beginning 0)) |
327 |
|
(python-in-string/comment)))))) |
328 |
|
|
329 |
(defun python-close-block-statement-p (&optional bos) |
(defun python-close-block-statement-p (&optional bos) |
330 |
"Return non-nil if current line is a statement closing a block. |
"Return non-nil if current line is a statement closing a block. |
385 |
(defcustom python-honour-comment-indentation nil |
(defcustom python-honour-comment-indentation nil |
386 |
"Non-nil means indent relative to preceding comment line. |
"Non-nil means indent relative to preceding comment line. |
387 |
Only do this for comments where the leading comment character is followed |
Only do this for comments where the leading comment character is followed |
388 |
by space." |
by space. This doesn't apply to comment lines, which are always indented |
389 |
|
in lines with preceding comments." |
390 |
:type 'boolean |
:type 'boolean |
391 |
:group 'python) |
:group 'python) |
392 |
|
|
516 |
(- python-indent))) |
(- python-indent))) |
517 |
0))))))))) |
0))))))))) |
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 |
|
|
529 |
;;;; Cycling through the possible indentations with successive TABs. |
;;;; Cycling through the possible indentations with successive TABs. |
530 |
|
|
531 |
;; These don't need to be buffer-local since they're only relevant |
;; These don't need to be buffer-local since they're only relevant |
550 |
(point)))) |
(point)))) |
551 |
|
|
552 |
(defun python-indentation-levels () |
(defun python-indentation-levels () |
553 |
"Return a list of possible indentations for this statement. |
"Return a list of possible indentations for this line. |
554 |
Includes the default indentation and those which would close all |
Includes the default indentation and those which would close all |
555 |
enclosing blocks." |
enclosing blocks. Assumes the line has already been indented per |
556 |
|
`python-indent-line'. Elements of the list are actually pairs: |
557 |
|
\(INDENTATION . TEXT), where TEXT is the initial text of the |
558 |
|
corresponding block opening (or nil)." |
559 |
(save-excursion |
(save-excursion |
560 |
(let ((levels (list (cons (current-indentation) nil)))) |
(let ((levels (list (cons (current-indentation) |
561 |
|
(save-excursion |
562 |
|
(if (python-beginning-of-block) |
563 |
|
(python-initial-text))))))) |
564 |
;; Only one possibility if we immediately follow a block open or |
;; Only one possibility if we immediately follow a block open or |
565 |
;; are in a continuation line. |
;; are in a continuation line. |
566 |
(unless (or (python-continuation-line-p) |
(unless (or (python-continuation-line-p) |
586 |
(if (> (- (point-max) pos) (point)) |
(if (> (- (point-max) pos) (point)) |
587 |
(goto-char (- (point-max) pos)))))) |
(goto-char (- (point-max) pos)))))) |
588 |
|
|
589 |
;; Fixme: Is the arg necessary? |
(defun python-indent-line () |
|
(defun python-indent-line (&optional arg) |
|
590 |
"Indent current line as Python code. |
"Indent current line as Python code. |
591 |
When invoked via `indent-for-tab-command', cycle through possible |
When invoked via `indent-for-tab-command', cycle through possible |
592 |
indentations for current line. The cycle is broken by a command different |
indentations for current line. The cycle is broken by a command different |
603 |
(beginning-of-line) |
(beginning-of-line) |
604 |
(delete-horizontal-space) |
(delete-horizontal-space) |
605 |
(indent-to (car (nth python-indent-index python-indent-list))) |
(indent-to (car (nth python-indent-index python-indent-list))) |
606 |
(let ((text (cdr (nth python-indent-index |
(if (python-block-end-p) |
607 |
python-indent-list)))) |
(let ((text (cdr (nth python-indent-index |
608 |
(if text (message "Closes: %s" text))))) |
python-indent-list)))) |
609 |
|
(if text |
610 |
|
(message "Closes: %s" text)))))) |
611 |
(python-indent-line-1) |
(python-indent-line-1) |
612 |
(setq python-indent-list (python-indentation-levels) |
(setq python-indent-list (python-indentation-levels) |
613 |
python-indent-list-length (length python-indent-list) |
python-indent-list-length (length python-indent-list) |
614 |
python-indent-index (1- python-indent-list-length))))) |
python-indent-index (1- python-indent-list-length))))) |
615 |
|
|
616 |
|
(defun python-block-end-p () |
617 |
|
"Non-nil if this is a line in a statement closing a block, |
618 |
|
or a blank line indented to where it would close a block." |
619 |
|
(and (not (python-comment-line-p)) |
620 |
|
(or (python-close-block-statement-p t) |
621 |
|
(< (current-indentation) |
622 |
|
(save-excursion |
623 |
|
(python-previous-statement) |
624 |
|
(current-indentation)))))) |
625 |
|
|
626 |
|
;; Fixme: Define an indent-region-function. It should probably leave |
627 |
|
;; lines alone if the indentation is already at one of the allowed |
628 |
|
;; levels. Otherwise, M-C-\ typically keeps indenting more deeply |
629 |
|
;; down a function. |
630 |
|
|
631 |
;;;; Movement. |
;;;; Movement. |
632 |
|
|
663 |
"`end-of-defun-function' for Python. |
"`end-of-defun-function' for Python. |
664 |
Finds end of innermost nested class or method definition." |
Finds end of innermost nested class or method definition." |
665 |
(let ((orig (point)) |
(let ((orig (point)) |
666 |
(pattern (rx (and line-start (0+ space) |
(pattern (rx (and line-start (0+ space) (or "def" "class") space)))) |
|
(or "def" "class") space)))) |
|
667 |
;; Go to start of current block and check whether it's at top |
;; Go to start of current block and check whether it's at top |
668 |
;; level. If it is, and not a block start, look forward for |
;; level. If it is, and not a block start, look forward for |
669 |
;; definition statement. |
;; definition statement. |
862 |
Makes nested Imenu menus from nested `class' and `def' statements. |
Makes nested Imenu menus from nested `class' and `def' statements. |
863 |
The nested menus are headed by an item referencing the outer |
The nested menus are headed by an item referencing the outer |
864 |
definition; it has a space prepended to the name so that it sorts |
definition; it has a space prepended to the name so that it sorts |
865 |
first with `imenu--sort-by-name'." |
first with `imenu--sort-by-name' (though, unfortunately, sub-menus |
866 |
|
precede it)." |
867 |
(unless (boundp 'python-recursing) ; dynamically bound below |
(unless (boundp 'python-recursing) ; dynamically bound below |
868 |
(goto-char (point-min))) ; normal call from Imenu |
(goto-char (point-min))) ; normal call from Imenu |
869 |
(let (index-alist ; accumulated value to return |
(let (index-alist ; accumulated value to return |
948 |
(file-name-nondirectory name)))))))) |
(file-name-nondirectory name)))))))) |
949 |
(setq python-saved-check-command command) |
(setq python-saved-check-command command) |
950 |
(save-some-buffers (not compilation-ask-about-save) nil) |
(save-some-buffers (not compilation-ask-about-save) nil) |
951 |
(compilation-start command)) |
(let ((compilation-error-regexp-alist |
952 |
|
(cons '("(\\([^,]+\\), line \\([0-9]+\\))" 1 2) |
953 |
|
compilation-error-regexp-alist))) |
954 |
|
(compilation-start command))) |
955 |
|
|
956 |
;;;; Inferior mode stuff (following cmuscheme). |
;;;; Inferior mode stuff (following cmuscheme). |
957 |
|
|
958 |
|
;; Fixme: Make sure we can work with IPython. |
959 |
|
|
960 |
(defcustom python-python-command "python" |
(defcustom python-python-command "python" |
961 |
"*Shell command to run Python interpreter. |
"*Shell command to run Python interpreter. |
962 |
Any arguments can't contain whitespace." |
Any arguments can't contain whitespace. |
963 |
|
Note that IPython may not work properly; it must at least be used with the |
964 |
|
`-cl' flag, i.e. use `ipython -cl'." |
965 |
:group 'python |
:group 'python |
966 |
:type 'string) |
:type 'string) |
967 |
|
|
978 |
et al.") |
et al.") |
979 |
|
|
980 |
(defvar python-buffer nil |
(defvar python-buffer nil |
981 |
"*The current python process buffer. |
"The current python process buffer." |
982 |
To run multiple Python processes, start the first with \\[run-python]. |
;; Fixme: a single process is currently assumed, so that this doc |
983 |
It will be in a buffer named *Python*. Rename that with |
;; is misleading. |
984 |
\\[rename-buffer]. Now start a new process with \\[run-python]. It |
|
985 |
will be in a new buffer, named *Python*. Switch between the different |
;; "*The current python process buffer. |
986 |
process buffers with \\[switch-to-buffer]. |
;; To run multiple Python processes, start the first with \\[run-python]. |
987 |
|
;; It will be in a buffer named *Python*. Rename that with |
988 |
Commands that send text from source buffers to Python processes have |
;; \\[rename-buffer]. Now start a new process with \\[run-python]. It |
989 |
to choose a process to send to. This is determined by global variable |
;; will be in a new buffer, named *Python*. Switch between the different |
990 |
`python-buffer'. Suppose you have three inferior Pythons running: |
;; process buffers with \\[switch-to-buffer]. |
991 |
Buffer Process |
|
992 |
foo python |
;; Commands that send text from source buffers to Python processes have |
993 |
bar python<2> |
;; to choose a process to send to. This is determined by global variable |
994 |
*Python* python<3> |
;; `python-buffer'. Suppose you have three inferior Pythons running: |
995 |
If you do a \\[python-send-region-and-go] command on some Python source |
;; Buffer Process |
996 |
code, what process does it go to? |
;; foo python |
997 |
|
;; bar python<2> |
998 |
- In a process buffer (foo, bar, or *Python*), send it to that process. |
;; *Python* python<3> |
999 |
- In some other buffer (e.g. a source file), send it to the process |
;; If you do a \\[python-send-region-and-go] command on some Python source |
1000 |
attached to `python-buffer'. |
;; code, what process does it go to? |
1001 |
Process selection is done by function `python-proc'. |
|
1002 |
|
;; - In a process buffer (foo, bar, or *Python*), send it to that process. |
1003 |
Whenever \\[run-python] starts a new process, it resets `python-buffer' |
;; - In some other buffer (e.g. a source file), send it to the process |
1004 |
to be the new process's buffer. If you only run one process, this will |
;; attached to `python-buffer'. |
1005 |
do the right thing. If you run multiple processes, you can change |
;; Process selection is done by function `python-proc'. |
1006 |
`python-buffer' to another process buffer with \\[set-variable].") |
|
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 |
|
) |
1012 |
|
|
1013 |
(defconst python-compilation-regexp-alist |
(defconst python-compilation-regexp-alist |
1014 |
|
;; FIXME: maybe these should move to compilation-error-regexp-alist-alist. |
1015 |
`((,(rx (and line-start (1+ (any " \t")) "File \"" |
`((,(rx (and line-start (1+ (any " \t")) "File \"" |
1016 |
(group (1+ (not (any "\"<")))) ; avoid `<stdin>' &c |
(group (1+ (not (any "\"<")))) ; avoid `<stdin>' &c |
1017 |
"\", line " (group (1+ digit)))) |
"\", line " (group (1+ digit)))) |
1018 |
1 python-compilation-line-number)) |
1 2) |
1019 |
|
(,(rx (and " in file " (group (1+ not-newline)) " on line " |
1020 |
|
(group (1+ digit)))) |
1021 |
|
1 2)) |
1022 |
"`compilation-error-regexp-alist' for inferior Python.") |
"`compilation-error-regexp-alist' for inferior Python.") |
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? |
1041 |
(define-derived-mode inferior-python-mode comint-mode "Inferior Python" |
(define-derived-mode inferior-python-mode comint-mode "Inferior Python" |
1042 |
"Major mode for interacting with an inferior Python process. |
"Major mode for interacting with an inferior Python process. |
1043 |
A Python process can be started with \\[run-python]. |
A Python process can be started with \\[run-python]. |
1058 |
:group 'python |
:group 'python |
1059 |
(set-syntax-table python-mode-syntax-table) |
(set-syntax-table python-mode-syntax-table) |
1060 |
(setq mode-line-process '(":%s")) |
(setq mode-line-process '(":%s")) |
1061 |
;; Fixme: Maybe install some python-mode bindings too. |
(set (make-local-variable 'comint-input-filter) 'python-input-filter) |
|
(define-key inferior-python-mode-map "\C-c\C-l" 'python-load-file) |
|
|
(define-key inferior-python-mode-map "\C-c\C-z" 'python-switch-to-python) |
|
|
(add-hook 'comint-input-filter-functions 'python-input-filter nil t) |
|
1062 |
(add-hook 'comint-preoutput-filter-functions #'python-preoutput-filter |
(add-hook 'comint-preoutput-filter-functions #'python-preoutput-filter |
1063 |
nil t) |
nil t) |
1064 |
;; Still required by `comint-redirect-send-command', for instance: |
;; Still required by `comint-redirect-send-command', for instance |
1065 |
(set (make-local-variable 'comint-prompt-regexp) "^\\([>.]\\{3\\} \\)+") |
;; (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 ">.")) ?\ ))))) |
1068 |
(set (make-local-variable 'compilation-error-regexp-alist) |
(set (make-local-variable 'compilation-error-regexp-alist) |
1069 |
python-compilation-regexp-alist) |
python-compilation-regexp-alist) |
1070 |
(compilation-shell-minor-mode 1)) |
(compilation-shell-minor-mode 1)) |
1075 |
:type 'regexp |
:type 'regexp |
1076 |
:group 'python) |
:group 'python) |
1077 |
|
|
|
(defvar python-orig-start nil |
|
|
"Marker to the start of the region passed to the inferior Python. |
|
|
It can also be a filename.") |
|
|
|
|
1078 |
(defun python-input-filter (str) |
(defun python-input-filter (str) |
1079 |
"`comint-input-filter' function for inferior Python. |
"`comint-input-filter' function for inferior Python. |
1080 |
Don't save anything for STR matching `inferior-python-filter-regexp'. |
Don't save anything for STR matching `inferior-python-filter-regexp'." |
|
Also resets variables for adjusting error messages." |
|
|
(setq python-orig-start nil) |
|
1081 |
(not (string-match inferior-python-filter-regexp str))) |
(not (string-match inferior-python-filter-regexp str))) |
1082 |
|
|
1083 |
;; Fixme: Loses with quoted whitespace. |
;; Fixme: Loses with quoted whitespace. |
1090 |
(t (let ((pos (string-match "[^ \t]" string))) |
(t (let ((pos (string-match "[^ \t]" string))) |
1091 |
(if pos (python-args-to-list (substring string pos)))))))) |
(if pos (python-args-to-list (substring string pos)))))))) |
1092 |
|
|
|
(defun python-compilation-line-number (file col) |
|
|
"Return error descriptor of error found for FILE, column COL. |
|
|
Used as line-number hook function in `python-compilation-regexp-alist'." |
|
|
(let ((line (string-to-number (match-string 2)))) |
|
|
(cons (point-marker) |
|
|
(if (and (markerp python-orig-start) |
|
|
(marker-buffer python-orig-start)) |
|
|
(with-current-buffer (marker-buffer python-orig-start) |
|
|
(goto-char python-orig-start) |
|
|
(forward-line (1- line))) |
|
|
(list (if (stringp python-orig-start) python-orig-start file) |
|
|
line nil))))) |
|
|
|
|
1093 |
(defvar python-preoutput-result nil |
(defvar python-preoutput-result nil |
1094 |
"Data from output line last `_emacs_out' line seen by the preoutput filter.") |
"Data from last `_emacs_out' line seen by the preoutput filter.") |
1095 |
|
|
1096 |
(defvar python-preoutput-continuation nil |
(defvar python-preoutput-continuation nil |
1097 |
"If non-nil, funcall this when `python-preoutput-filter' sees `_emacs_ok'.") |
"If non-nil, funcall this when `python-preoutput-filter' sees `_emacs_ok'.") |
1102 |
;; `python-preoutput-continuation' if we get it. |
;; `python-preoutput-continuation' if we get it. |
1103 |
(defun python-preoutput-filter (s) |
(defun python-preoutput-filter (s) |
1104 |
"`comint-preoutput-filter-functions' function: ignore prompts not at bol." |
"`comint-preoutput-filter-functions' function: ignore prompts not at bol." |
1105 |
(cond ((and (string-match "\\`[.>]\\{3\\} \\'" s) |
(cond ((and (string-match (rx (and string-start (repeat 3 (any ".>")) |
1106 |
|
" " string-end)) |
1107 |
|
s) |
1108 |
(/= (let ((inhibit-field-text-motion t)) |
(/= (let ((inhibit-field-text-motion t)) |
1109 |
(line-beginning-position)) |
(line-beginning-position)) |
1110 |
(point))) |
(point))) |
1125 |
CMD is the Python command to run. NOSHOW non-nil means don't show the |
CMD is the Python command to run. NOSHOW non-nil means don't show the |
1126 |
buffer automatically. |
buffer automatically. |
1127 |
If there is a process already running in `*Python*', switch to |
If there is a process already running in `*Python*', switch to |
1128 |
that buffer. Interactively a prefix arg, allows you to edit the initial |
that buffer. Interactively, a prefix arg allows you to edit the initial |
1129 |
command line (default is the value of `python-command'); `-i' etc. args |
command line (default is `python-command'); `-i' etc. args will be added |
1130 |
will be added to this as appropriate. Runs the hooks |
to this as appropriate. Runs the hook `inferior-python-mode-hook' |
1131 |
`inferior-python-mode-hook' (after the `comint-mode-hook' is run). |
\(after the `comint-mode-hook' is run). |
1132 |
\(Type \\[describe-mode] in the process buffer for a list of commands.)" |
\(Type \\[describe-mode] in the process buffer for a list of commands.)" |
1133 |
(interactive (list (if current-prefix-arg |
(interactive (list (if current-prefix-arg |
1134 |
(read-string "Run Python: " python-command) |
(read-string "Run Python: " python-command) |
1138 |
;; Fixme: Consider making `python-buffer' buffer-local as a buffer |
;; Fixme: Consider making `python-buffer' buffer-local as a buffer |
1139 |
;; (not a name) in Python buffers from which `run-python' &c is |
;; (not a name) in Python buffers from which `run-python' &c is |
1140 |
;; invoked. Would support multiple processes better. |
;; invoked. Would support multiple processes better. |
1141 |
(unless (comint-check-proc "*Python*") |
(unless (comint-check-proc python-buffer) |
1142 |
(let ((cmdlist (append (python-args-to-list cmd) '("-i")))) |
(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))) |
1148 |
(set-buffer (apply 'make-comint "Python" (car cmdlist) nil |
(set-buffer (apply 'make-comint "Python" (car cmdlist) nil |
1149 |
(cdr cmdlist)))) |
(cdr cmdlist))) |
1150 |
|
(setq python-buffer "*Python*")) |
1151 |
(inferior-python-mode) |
(inferior-python-mode) |
1152 |
;; Load function defintions we need. |
;; Load function defintions we need. |
1153 |
;; Before the preoutput function was used, this was done via -c in |
;; Before the preoutput function was used, this was done via -c in |
1154 |
;; cmdlist, but that loses the banner and doesn't run the startup |
;; cmdlist, but that loses the banner and doesn't run the startup |
1155 |
;; file. |
;; file. The code might be inline here, but there's enough that it |
1156 |
(python-send-string "\ |
;; seems worth putting in a separate file, and it's probably cleaner |
1157 |
def _emacs_execfile (file): # execute file and remove it |
;; to put it in a module. |
1158 |
from os import remove |
(python-send-string "import emacs")) |
1159 |
try: execfile (file, globals (), globals ()) |
(unless noshow (pop-to-buffer python-buffer))) |
1160 |
finally: remove (file) |
|
1161 |
|
;; Fixme: We typically lose if the inferior isn't in the normal REPL, |
1162 |
def _emacs_args (name): # get arglist of name for eldoc &c |
;; e.g. prompt is `help> '. Probably raise an error if the form of |
1163 |
import inspect |
;; the prompt is unexpected; actually, it needs to be `>>> ', not |
1164 |
parts = name.split ('.') |
;; `... ', i.e. we're not inputting a block &c. However, this may not |
1165 |
if len (parts) > 1: |
;; be the place to do it, e.g. we might actually want to send commands |
1166 |
try: exec 'import ' + parts[0] |
;; having set up such a state. |
1167 |
except: return None |
|
1168 |
try: exec 'func='+name # lose if name is keyword or undefined |
(defun python-send-command (command) |
1169 |
except: return None |
"Like `python-send-string' but resets `compilation-minor-mode'." |
1170 |
if inspect.isbuiltin (func): |
(goto-char (point-max)) |
1171 |
doc = func.__doc__ |
(let ((end (marker-position (process-mark (python-proc))))) |
1172 |
if doc.find (' ->') != -1: |
(compilation-forget-errors) |
1173 |
print '_emacs_out', doc.split (' ->')[0] |
(python-send-string command) |
1174 |
elif doc.find ('\\n') != -1: |
(set-marker compilation-parsing-end end) |
1175 |
print '_emacs_out', doc.split ('\\n')[0] |
(setq compilation-last-buffer (current-buffer)))) |
|
return None |
|
|
if inspect.ismethod (func): func = func.im_func |
|
|
if not inspect.isfunction (func): |
|
|
return None |
|
|
(args, varargs, varkw, defaults) = inspect.getargspec (func) |
|
|
print '_emacs_out', func.__name__+inspect.formatargspec (args, varargs, varkw, defaults) |
|
|
|
|
|
print '_emacs_ok'")) |
|
|
(unless noshow (pop-to-buffer (setq python-buffer "*Python*")))) |
|
1176 |
|
|
1177 |
(defun python-send-region (start end) |
(defun python-send-region (start end) |
1178 |
"Send the region to the inferior Python process." |
"Send the region to the inferior Python process." |
1179 |
;; The region is evaluated from a temporary file. This avoids |
;; The region is evaluated from a temporary file. This avoids |
1180 |
;; problems with blank lines, which have different semantics |
;; problems with blank lines, which have different semantics |
1181 |
;; interactively and in files. It also saves the inferior process |
;; interactively and in files. It also saves the inferior process |
1182 |
;; buffer filling up with interpreter prompts. We need a function |
;; buffer filling up with interpreter prompts. We need a Python |
1183 |
;; to remove the temporary file when it has been evaluated, which |
;; function to remove the temporary file when it has been evaluated |
1184 |
;; unfortunately means using a not-quite pristine interpreter |
;; (though we could probably do it in Lisp with a Comint output |
1185 |
;; initially. Unfortunately we also get tracebacks which look like: |
;; filter). This function also catches exceptions and truncates |
1186 |
;; |
;; tracebacks not to mention the frame of the function itself. |
|
;; >>> Traceback (most recent call last): |
|
|
;; File "<stdin>", line 1, in ? |
|
|
;; File "<string>", line 4, in _emacs_execfile |
|
|
;; File "/tmp/py7734RSB", line 11 |
|
1187 |
;; |
;; |
1188 |
;; The compilation-minor-mode parsing takes care of relating the |
;; The compilation-minor-mode parsing takes care of relating the |
1189 |
;; reference to the temporary file to the source. Fixme: |
;; reference to the temporary file to the source. |
1190 |
;; comint-filter the first two lines of the traceback? |
;; |
1191 |
|
;; Fixme: Write a `coding' header to the temp file if the region is |
1192 |
|
;; non-ASCII. |
1193 |
(interactive "r") |
(interactive "r") |
1194 |
(let* ((f (make-temp-file "py")) |
(let* ((f (make-temp-file "py")) |
1195 |
(command (format "_emacs_execfile(%S)" f)) |
(command (format "emacs.eexecfile(%S)" f)) |
1196 |
(orig-start (copy-marker start))) |
(orig-start (copy-marker start))) |
1197 |
(if (save-excursion |
(when (save-excursion |
1198 |
(goto-char start) |
(goto-char start) |
1199 |
(/= 0 (current-indentation))) ; need dummy block |
(/= 0 (current-indentation))) ; need dummy block |
1200 |
(write-region "if True:\n" nil f nil 'nomsg)) |
(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)) |
1205 |
(write-region start end f t 'nomsg) |
(write-region start end f t 'nomsg) |
1206 |
(when python-buffer |
(let ((proc (python-proc))) ;Make sure we're running a process. |
1207 |
(with-current-buffer python-buffer |
(with-current-buffer python-buffer |
1208 |
(let ((end (marker-position (process-mark (python-proc))))) |
(python-send-command command) |
1209 |
(set (make-local-variable 'python-orig-start) orig-start) |
;; Tell compile.el to redirect error locations in file `f' to |
1210 |
(set (make-local-variable 'compilation-error-list) nil) |
;; positions past marker `orig-start'. It has to be done *after* |
1211 |
(let ((comint-input-filter-functions |
;; python-send-command's call to compilation-forget-errors. |
1212 |
(delete 'python-input-filter comint-input-filter-functions))) |
(compilation-fake-loc orig-start f))))) |
|
(python-send-string command)) |
|
|
(set-marker compilation-parsing-end end) |
|
|
(setq compilation-last-buffer (current-buffer))))))) |
|
1213 |
|
|
1214 |
(defun python-send-string (string) |
(defun python-send-string (string) |
1215 |
"Evaluate STRING in inferior Python process." |
"Evaluate STRING in inferior Python process." |
1222 |
(interactive) |
(interactive) |
1223 |
(python-send-region (point-min) (point-max))) |
(python-send-region (point-min) (point-max))) |
1224 |
|
|
1225 |
|
;; Fixme: Try to define the function or class within the relevant |
1226 |
|
;; module, not just at top level. |
1227 |
(defun python-send-defun () |
(defun python-send-defun () |
1228 |
"Send the current defun (class or method) to the inferior Python process." |
"Send the current defun (class or method) to the inferior Python process." |
1229 |
(interactive) |
(interactive) |
1270 |
module-qualified names." |
module-qualified names." |
1271 |
(interactive (comint-get-source "Load Python file: " python-prev-dir/file |
(interactive (comint-get-source "Load Python file: " python-prev-dir/file |
1272 |
python-source-modes |
python-source-modes |
1273 |
t)) ; because execfile needs exact name |
t)) ; because execfile needs exact name |
1274 |
(comint-check-source file-name) ; Check to see if buffer needs saved. |
(comint-check-source file-name) ; Check to see if buffer needs saving. |
1275 |
(setq python-prev-dir/file (cons (file-name-directory file-name) |
(setq python-prev-dir/file (cons (file-name-directory file-name) |
1276 |
(file-name-nondirectory file-name))) |
(file-name-nondirectory file-name))) |
1277 |
(when python-buffer |
(let ((proc (python-proc))) ;Make sure we have a process. |
1278 |
(with-current-buffer python-buffer |
(with-current-buffer python-buffer |
1279 |
(let ((end (marker-position (process-mark (python-proc))))) |
;; Fixme: I'm not convinced by this logic from python-mode.el. |
1280 |
(set (make-local-variable 'compilation-error-list) nil) |
(python-send-command |
1281 |
;; (set (make-local-variable 'compilation-old-error-list) nil) |
(if (string-match "\\.py\\'" file-name) |
1282 |
(let ((comint-input-filter-functions |
(let ((module (file-name-sans-extension |
1283 |
(delete 'python-input-filter comint-input-filter-functions))) |
(file-name-nondirectory file-name)))) |
1284 |
(python-send-string |
(format "emacs.eimport(%S,%S)" |
1285 |
(if (string-match "\\.py\\'" file-name) |
module (file-name-directory file-name))) |
1286 |
;; Fixme: make sure the directory is in the path list |
(format "execfile(%S)" file-name))) |
1287 |
(let ((module (file-name-sans-extension |
(message "%s loaded" file-name)))) |
|
(file-name-nondirectory file-name)))) |
|
|
(set (make-local-variable 'python-orig-start) nil) |
|
|
(format "\ |
|
|
if globals().has_key(%S): reload(%s) |
|
|
else: import %s |
|
|
" module module module)) |
|
|
(set (make-local-variable 'python-orig-start) file-name) |
|
|
(format "execfile('%s')" file-name)))) |
|
|
(set-marker compilation-parsing-end end) |
|
|
(setq compilation-last-buffer (current-buffer)))))) |
|
1288 |
|
|
1289 |
;; Fixme: Should this start a process if there isn't one? (Unlike cmuscheme.) |
;; Fixme: If we need to start the process, wait until we've got the OK |
1290 |
|
;; from the startup. |
1291 |
(defun python-proc () |
(defun python-proc () |
1292 |
"Return the current Python process. See variable `python-buffer'." |
"Return the current Python process. |
1293 |
(let ((proc (get-buffer-process (if (eq major-mode 'inferior-python-mode) |
See variable `python-buffer'. Starts a new process if necessary." |
1294 |
(current-buffer) |
(or (if python-buffer |
1295 |
python-buffer)))) |
(get-buffer-process (if (eq major-mode 'inferior-python-mode) |
1296 |
(or proc (error "No current process. See variable `python-buffer'")))) |
(current-buffer) |
1297 |
|
python-buffer))) |
1298 |
|
(progn (run-python nil t) |
1299 |
|
(python-proc)))) |
1300 |
|
|
1301 |
;;;; Context-sensitive help. |
;;;; Context-sensitive help. |
1302 |
|
|
1308 |
"Syntax table giving `.' symbol syntax. |
"Syntax table giving `.' symbol syntax. |
1309 |
Otherwise inherits from `python-mode-syntax-table'.") |
Otherwise inherits from `python-mode-syntax-table'.") |
1310 |
|
|
1311 |
|
(defvar view-return-to-alist) |
1312 |
|
(eval-when-compile (autoload 'help-buffer "help-fns")) |
1313 |
|
|
1314 |
;; Fixme: Should this actually be used instead of info-look, i.e. be |
;; Fixme: Should this actually be used instead of info-look, i.e. be |
1315 |
;; bound to C-h S? |
;; bound to C-h S? Can we use other pydoc stuff before python 2.2? |
1316 |
(defun python-describe-symbol (symbol) |
(defun python-describe-symbol (symbol) |
1317 |
"Get help on SYMBOL using `pydoc'. |
"Get help on SYMBOL using `help'. |
1318 |
Interactively, prompt for symbol." |
Interactively, prompt for symbol. |
1319 |
;; Note that we do this in the inferior process, not a separate one to |
|
1320 |
|
Symbol may be anything recognized by the interpreter's `help' command -- |
1321 |
|
e.g. `CALLS' -- not just variables in scope. |
1322 |
|
This only works for Python version 2.2 or newer since earlier interpreters |
1323 |
|
don't support `help'." |
1324 |
|
;; Note that we do this in the inferior process, not a separate one, to |
1325 |
;; ensure the environment is appropriate. |
;; ensure the environment is appropriate. |
1326 |
(interactive |
(interactive |
1327 |
(let ((symbol (with-syntax-table python-dotty-syntax-table |
(let ((symbol (with-syntax-table python-dotty-syntax-table |
1328 |
(current-word))) |
(current-word))) |
1329 |
(enable-recursive-minibuffers t) |
(enable-recursive-minibuffers t)) |
1330 |
val) |
(list (read-string (if symbol |
1331 |
(setq val (read-string (if symbol |
(format "Describe symbol (default %s): " symbol) |
1332 |
(format "Describe symbol (default %s): " |
"Describe symbol: ") |
1333 |
symbol) |
nil nil symbol)))) |
|
"Describe symbol: ") |
|
|
nil nil symbol)) |
|
|
(list (or val symbol)))) |
|
1334 |
(if (equal symbol "") (error "No symbol")) |
(if (equal symbol "") (error "No symbol")) |
1335 |
(let* ((func `(lambda () |
(let* ((func `(lambda () |
1336 |
(comint-redirect-send-command (format "help(%S)\n" ,symbol) |
(comint-redirect-send-command (format "emacs.ehelp(%S)\n" |
1337 |
|
,symbol) |
1338 |
"*Help*" nil)))) |
"*Help*" nil)))) |
1339 |
;; Ensure we have a suitable help buffer. |
;; Ensure we have a suitable help buffer. |
1340 |
(let (temp-buffer-show-hook) ; avoid xref stuff |
;; Fixme: Maybe process `Related help topics' a la help xrefs and |
1341 |
(with-output-to-temp-buffer "*Help*" |
;; 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) |
1349 |
(with-current-buffer standard-output |
(with-current-buffer standard-output |
1350 |
(set (make-local-variable 'comint-redirect-subvert-readonly) t)))) |
(set (make-local-variable 'comint-redirect-subvert-readonly) t) |
1351 |
|
(print-help-return-message)))) |
1352 |
(if (and python-buffer (get-buffer python-buffer)) |
(if (and python-buffer (get-buffer python-buffer)) |
1353 |
(with-current-buffer python-buffer |
(with-current-buffer python-buffer |
1354 |
(funcall func)) |
(funcall func)) |
1357 |
|
|
1358 |
(add-to-list 'debug-ignored-errors "^No symbol") |
(add-to-list 'debug-ignored-errors "^No symbol") |
1359 |
|
|
1360 |
|
(defun python-send-receive (string) |
1361 |
|
"Send STRING to inferior Python (if any) and return result. |
1362 |
|
The result is what follows `_emacs_out' in the output (or nil)." |
1363 |
|
(let ((proc (python-proc))) |
1364 |
|
(python-send-string string) |
1365 |
|
(setq python-preoutput-result nil) |
1366 |
|
(accept-process-output proc 5) |
1367 |
|
python-preoutput-result)) |
1368 |
|
|
1369 |
;; Fixme: try to make it work with point in the arglist. Also, is |
;; Fixme: try to make it work with point in the arglist. Also, is |
1370 |
;; there anything reasonable we can do with random methods? |
;; there anything reasonable we can do with random methods? |
1371 |
;; (Currently only works with functions.) |
;; (Currently only works with functions.) |
1374 |
Only works when point is in a function name, not its arglist, for instance. |
Only works when point is in a function name, not its arglist, for instance. |
1375 |
Assumes an inferior Python is running." |
Assumes an inferior Python is running." |
1376 |
(let ((symbol (with-syntax-table python-dotty-syntax-table |
(let ((symbol (with-syntax-table python-dotty-syntax-table |
1377 |
(current-word))) |
(current-word)))) |
1378 |
(proc (and python-buffer (python-proc)))) |
(when symbol |
1379 |
(when (and proc symbol) |
(python-send-receive (format "emacs.eargs(%S)" symbol))))) |
|
(python-send-string |
|
|
(format "_emacs_args(%S)" symbol)) |
|
|
(setq python-preoutput-result nil) |
|
|
(accept-process-output proc 1) |
|
|
python-preoutput-result))) |
|
1380 |
|
|
1381 |
;;;; Info-look functionality. |
;;;; Info-look functionality. |
1382 |
|
|
1390 |
;; Whether info files have a Python version suffix, e.g. in Debian. |
;; Whether info files have a Python version suffix, e.g. in Debian. |
1391 |
(versioned |
(versioned |
1392 |
(with-temp-buffer |
(with-temp-buffer |
1393 |
(Info-mode) |
(with-no-warnings (Info-mode)) |
1394 |
(condition-case () |
(condition-case () |
1395 |
;; Don't use `info' because it would pop-up a *info* buffer. |
;; Don't use `info' because it would pop-up a *info* buffer. |
1396 |
(Info-goto-node (format "(python%s-lib)Miscellaneous Index" |
(with-no-warnings |
1397 |
version)) |
(Info-goto-node (format "(python%s-lib)Miscellaneous Index" |
1398 |
|
version)) |
1399 |
|
t) |
1400 |
(error nil))))) |
(error nil))))) |
1401 |
(info-lookup-maybe-add-help |
(info-lookup-maybe-add-help |
1402 |
:mode 'python-mode |
:mode 'python-mode |
1462 |
(while (re-search-forward |
(while (re-search-forward |
1463 |
(rx (and line-start (or "import" "from") (1+ space) |
(rx (and line-start (or "import" "from") (1+ space) |
1464 |
(group (1+ (not (any " \t\n.")))))) |
(group (1+ (not (any " \t\n.")))))) |
1465 |
10000 ; Probably not worth customizing. |
(+ (point-min) 10000) ; Probably not worth customizing. |
1466 |
t) |
t) |
1467 |
(if (member (match-string 1) python-jython-packages) |
(if (member (match-string 1) python-jython-packages) |
1468 |
(throw 'done t)))) |
(throw 'done t)))) |
1580 |
(python-end-of-block) |
(python-end-of-block) |
1581 |
(exchange-point-and-mark)) |
(exchange-point-and-mark)) |
1582 |
|
|
1583 |
|
;;;; Completion. |
1584 |
|
|
1585 |
|
(defun python-symbol-completions (symbol) |
1586 |
|
"Return a list of completions of the string SYMBOL from Python process. |
1587 |
|
The list is sorted." |
1588 |
|
(when symbol |
1589 |
|
(let ((completions |
1590 |
|
(condition-case () |
1591 |
|
(car (read-from-string (python-send-receive |
1592 |
|
(format "emacs.complete(%S)" symbol)))) |
1593 |
|
(error nil)))) |
1594 |
|
(sort |
1595 |
|
;; We can get duplicates from the above -- don't know why. |
1596 |
|
(delete-dups completions) |
1597 |
|
#'string<)))) |
1598 |
|
|
1599 |
|
(defun python-partial-symbol () |
1600 |
|
"Return the partial symbol before point (for completion)." |
1601 |
|
(let ((end (point)) |
1602 |
|
(start (save-excursion |
1603 |
|
(and (re-search-backward |
1604 |
|
(rx (and (or buffer-start (regexp "[^[:alnum:]._]")) |
1605 |
|
(group (1+ (regexp "[[:alnum:]._]"))) |
1606 |
|
point)) |
1607 |
|
nil t) |
1608 |
|
(match-beginning 1))))) |
1609 |
|
(if start (buffer-substring-no-properties start end)))) |
1610 |
|
|
1611 |
|
;; Fixme: We should have an abstraction of this sort of thing in the |
1612 |
|
;; core. |
1613 |
|
(defun python-complete-symbol () |
1614 |
|
"Perform completion on the Python symbol preceding point. |
1615 |
|
Repeating the command scrolls the completion window." |
1616 |
|
(interactive) |
1617 |
|
(let ((window (get-buffer-window "*Completions*"))) |
1618 |
|
(if (and (eq last-command this-command) |
1619 |
|
window (window-live-p window) (window-buffer window) |
1620 |
|
(buffer-name (window-buffer window))) |
1621 |
|
(with-current-buffer (window-buffer window) |
1622 |
|
(if (pos-visible-in-window-p (point-max) window) |
1623 |
|
(set-window-start window (point-min)) |
1624 |
|
(save-selected-window |
1625 |
|
(select-window window) |
1626 |
|
(scroll-up)))) |
1627 |
|
;; Do completion. |
1628 |
|
(let* ((end (point)) |
1629 |
|
(symbol (python-partial-symbol)) |
1630 |
|
(completions (python-symbol-completions symbol)) |
1631 |
|
(completion (if completions |
1632 |
|
(try-completion symbol completions)))) |
1633 |
|
(when symbol |
1634 |
|
(cond ((eq completion t)) |
1635 |
|
((null completion) |
1636 |
|
(message "Can't find completion for \"%s\"" symbol) |
1637 |
|
(ding)) |
1638 |
|
((not (string= symbol completion)) |
1639 |
|
(delete-region (- end (length symbol)) end) |
1640 |
|
(insert completion)) |
1641 |
|
(t |
1642 |
|
(message "Making completion list...") |
1643 |
|
(with-output-to-temp-buffer "*Completions*" |
1644 |
|
(display-completion-list completions)) |
1645 |
|
(message "Making completion list...%s" "done")))))))) |
1646 |
|
|
1647 |
|
(eval-when-compile (require 'hippie-exp)) |
1648 |
|
|
1649 |
|
(defun python-try-complete (old) |
1650 |
|
"Completion function for Python for use with `hippie-expand'." |
1651 |
|
(when (eq major-mode 'python-mode) ; though we only add it locally |
1652 |
|
(unless old |
1653 |
|
(let ((symbol (python-partial-symbol))) |
1654 |
|
(he-init-string (- (point) (length symbol)) (point)) |
1655 |
|
(if (not (he-string-member he-search-string he-tried-table)) |
1656 |
|
(push he-search-string he-tried-table)) |
1657 |
|
(setq he-expand-list |
1658 |
|
(and symbol (python-symbol-completions symbol))))) |
1659 |
|
(while (and he-expand-list |
1660 |
|
(he-string-member (car he-expand-list) he-tried-table)) |
1661 |
|
(pop he-expand-list)) |
1662 |
|
(if he-expand-list |
1663 |
|
(progn |
1664 |
|
(he-substitute-string (pop he-expand-list)) |
1665 |
|
t) |
1666 |
|
(if old (he-reset-string)) |
1667 |
|
nil))) |
1668 |
|
|
1669 |
;;;; Modes. |
;;;; Modes. |
1670 |
|
|
1671 |
(defvar outline-heading-end-regexp) |
(defvar outline-heading-end-regexp) |
1672 |
(defvar eldoc-print-current-symbol-info-function) |
(defvar eldoc-print-current-symbol-info-function) |
1673 |
(defvar python-mode-running) |
|
1674 |
;;;###autoload |
;;;###autoload |
1675 |
(define-derived-mode python-mode fundamental-mode "Python" |
(define-derived-mode python-mode fundamental-mode "Python" |
1676 |
"Major mode for editing Python files. |
"Major mode for editing Python files. |
1712 |
)) |
)) |
1713 |
(set (make-local-variable 'parse-sexp-lookup-properties) t) |
(set (make-local-variable 'parse-sexp-lookup-properties) t) |
1714 |
(set (make-local-variable 'comment-start) "# ") |
(set (make-local-variable 'comment-start) "# ") |
1715 |
;; Fixme: define a comment-indent-function? |
(set (make-local-variable 'comment-indent-function) #'python-comment-indent) |
1716 |
(set (make-local-variable 'indent-line-function) #'python-indent-line) |
(set (make-local-variable 'indent-line-function) #'python-indent-line) |
1717 |
(set (make-local-variable 'paragraph-start) "\\s-*$") |
(set (make-local-variable 'paragraph-start) "\\s-*$") |
1718 |
(set (make-local-variable 'fill-paragraph-function) |
(set (make-local-variable 'fill-paragraph-function) 'python-fill-paragraph) |
|
'python-fill-paragraph) |
|
1719 |
(set (make-local-variable 'require-final-newline) t) |
(set (make-local-variable 'require-final-newline) t) |
1720 |
(set (make-local-variable 'add-log-current-defun-function) |
(set (make-local-variable 'add-log-current-defun-function) |
1721 |
#'python-current-defun) |
#'python-current-defun) |
1733 |
#'python-eldoc-function) |
#'python-eldoc-function) |
1734 |
(add-hook 'eldoc-mode-hook |
(add-hook 'eldoc-mode-hook |
1735 |
'(lambda () (run-python 0 t)) nil t) ; need it running |
'(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))) |
1739 |
(unless font-lock-mode (font-lock-mode 1)) |
(unless font-lock-mode (font-lock-mode 1)) |
1740 |
(when python-guess-indent (python-guess-indent)) |
(when python-guess-indent (python-guess-indent)) |
1741 |
(set (make-local-variable 'python-command) python-python-command) |
(set (make-local-variable 'python-command) python-python-command) |