aboutsummaryrefslogtreecommitdiffstats
path: root/lisp
diff options
context:
space:
mode:
authorChong Yidong2008-02-21 17:03:47 +0000
committerChong Yidong2008-02-21 17:03:47 +0000
commit2bcda1d5ac8c029e29619eedd94ccff4ea91a310 (patch)
tree873ea5c447c9ccd0f9c29cff8b2507c00303dbd0 /lisp
parente21766aa6370c6bcd5c1c5f1f7de972408e1e971 (diff)
downloademacs-2bcda1d5ac8c029e29619eedd94ccff4ea91a310.tar.gz
emacs-2bcda1d5ac8c029e29619eedd94ccff4ea91a310.zip
Merge from Dave Love's 2008-01-20 version.
Require sym-comp. Add Python buffer to same-window-buffer-names. Fixup whitespaces. (python-font-lock-keywords): Add highlighting for Python builtins. (python-font-lock-syntactic-keywords): Rewrite. (python-quote-syntax): Use syntax-ppss-context instead of parsing ppss directly. (python-mode-map): Add binding for python-find-function. (python-calculate-indentation): Clean up the logic. (python-beginning-of-defun): Explicitly set return value. (python-beginning-of-statement): Stop looping if we get stuck going backwards. (python-next-statement): Stop looping if we somehow end up inside a string while advancing. (python-preoutput-continuation, python-version-checked): New vars. (python-check-version): New function. (run-python): Set default command to python-command instead of python-python-command. (run-python): Use python-check-version. Give PYTHONPATH precedence over data-directory in the process environment. Load function definitions in python process after. (python-check-comint-prompt): New function. (python-send-command, python-send-receive): Use it. (python-complete-symbol, python-try-complete): Functions deleted. Use symbol-complete instead of python-complete-symbol throughout. (python-fill-paragraph): Further refine the fenced-string regexp. (def-python-skeleton): Expand to the original abbrev instead if in a comment or string. Tweak skeletons for `if', `while', `for', `try/except', `try/finally', `name'. (python-pea-hook, python-abbrev-pc-hook): New functions. (python-abbrev-syntax-table): New var. (python-mode): Add python-pea-hook to pre-abbrev-expand-hook. Use symbol-completion-try-complete for hippie expansion. Turn on font lock unconditionally. (python-mode-hook): Defcustom it. No need to use make-local variable on indent-tabs-mode in "Turn off Indent Tabs mode" option, since it's buffer-local.
Diffstat (limited to 'lisp')
-rw-r--r--lisp/progmodes/python.el592
1 files changed, 355 insertions, 237 deletions
diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el
index 11662c8e46a..9057e51e439 100644
--- a/lisp/progmodes/python.el
+++ b/lisp/progmodes/python.el
@@ -62,6 +62,8 @@
62 62
63;; TODO: See various Fixmes below. 63;; TODO: See various Fixmes below.
64 64
65;; Fixme: This doesn't support (the nascent) Python 3 .
66
65;;; Code: 67;;; Code:
66 68
67(require 'comint) 69(require 'comint)
@@ -70,6 +72,7 @@
70 (require 'compile) 72 (require 'compile)
71 (require 'hippie-exp)) 73 (require 'hippie-exp))
72 74
75(require 'sym-comp)
73(autoload 'comint-mode "comint") 76(autoload 'comint-mode "comint")
74 77
75(defgroup python nil 78(defgroup python nil
@@ -84,6 +87,7 @@
84(add-to-list 'interpreter-mode-alist '("python" . python-mode)) 87(add-to-list 'interpreter-mode-alist '("python" . python-mode))
85;;;###autoload 88;;;###autoload
86(add-to-list 'auto-mode-alist '("\\.py\\'" . python-mode)) 89(add-to-list 'auto-mode-alist '("\\.py\\'" . python-mode))
90(add-to-list 'same-window-buffer-names "*Python*")
87 91
88;;;; Font lock 92;;;; Font lock
89 93
@@ -98,7 +102,7 @@
98 ;; Not real keywords, but close enough to be fontified as such 102 ;; Not real keywords, but close enough to be fontified as such
99 "self" "True" "False") 103 "self" "True" "False")
100 symbol-end) 104 symbol-end)
101 (,(rx symbol-start "None" symbol-end) ; See § Keywords in 2.5 manual. 105 (,(rx symbol-start "None" symbol-end) ; see § Keywords in 2.5 manual
102 . font-lock-constant-face) 106 . font-lock-constant-face)
103 ;; Definitions 107 ;; Definitions
104 (,(rx symbol-start (group "class") (1+ space) (group (1+ (or word ?_)))) 108 (,(rx symbol-start (group "class") (1+ space) (group (1+ (or word ?_))))
@@ -108,15 +112,63 @@
108 ;; Top-level assignments are worth highlighting. 112 ;; Top-level assignments are worth highlighting.
109 (,(rx line-start (group (1+ (or word ?_))) (0+ space) "=") 113 (,(rx line-start (group (1+ (or word ?_))) (0+ space) "=")
110 (1 font-lock-variable-name-face)) 114 (1 font-lock-variable-name-face))
111 (,(rx "@" (1+ (or word ?_))) ; decorators 115 (,(rx line-start (* (any " \t")) (group "@" (1+ (or word ?_)))) ; decorators
112 (0 font-lock-preprocessor-face)))) 116 (1 font-lock-type-face))
117 ;; Built-ins. (The next three blocks are from
118 ;; `__builtin__.__dict__.keys()' in Python 2.5.1.) These patterns
119 ;; are debateable, but they at least help to spot possible
120 ;; shadowing of builtins.
121 (,(rx symbol-start (or
122 ;; exceptions
123 "ArithmeticError" "AssertionError" "AttributeError"
124 "BaseException" "DeprecationWarning" "EOFError"
125 "EnvironmentError" "Exception" "FloatingPointError"
126 "FutureWarning" "GeneratorExit" "IOError" "ImportError"
127 "ImportWarning" "IndentationError" "IndexError" "KeyError"
128 "KeyboardInterrupt" "LookupError" "MemoryError" "NameError"
129 "NotImplemented" "NotImplementedError" "OSError"
130 "OverflowError" "PendingDeprecationWarning" "ReferenceError"
131 "RuntimeError" "RuntimeWarning" "StandardError"
132 "StopIteration" "SyntaxError" "SyntaxWarning" "SystemError"
133 "SystemExit" "TabError" "TypeError" "UnboundLocalError"
134 "UnicodeDecodeError" "UnicodeEncodeError" "UnicodeError"
135 "UnicodeTranslateError" "UnicodeWarning" "UserWarning"
136 "ValueError" "Warning" "ZeroDivisionError") symbol-end)
137 . font-lock-type-face)
138 (,(rx (or line-start (not (any ". \t"))) (* (any " \t")) symbol-start
139 (group (or
140 ;; callable built-ins, fontified when not appearing as
141 ;; object attributes
142 "abs" "all" "any" "apply" "basestring" "bool" "buffer" "callable"
143 "chr" "classmethod" "cmp" "coerce" "compile" "complex"
144 "copyright" "credits" "delattr" "dict" "dir" "divmod"
145 "enumerate" "eval" "execfile" "exit" "file" "filter" "float"
146 "frozenset" "getattr" "globals" "hasattr" "hash" "help"
147 "hex" "id" "input" "int" "intern" "isinstance" "issubclass"
148 "iter" "len" "license" "list" "locals" "long" "map" "max"
149 "min" "object" "oct" "open" "ord" "pow" "property" "quit"
150 "range" "raw_input" "reduce" "reload" "repr" "reversed"
151 "round" "set" "setattr" "slice" "sorted" "staticmethod"
152 "str" "sum" "super" "tuple" "type" "unichr" "unicode" "vars"
153 "xrange" "zip")) symbol-end)
154 (1 font-lock-builtin-face))
155 (,(rx symbol-start (or
156 ;; other built-ins
157 "True" "False" "None" "Ellipsis"
158 "_" "__debug__" "__doc__" "__import__" "__name__") symbol-end)
159 . font-lock-builtin-face)))
113 160
114(defconst python-font-lock-syntactic-keywords 161(defconst python-font-lock-syntactic-keywords
115 ;; Make outer chars of matching triple-quote sequences into generic 162 ;; Make outer chars of matching triple-quote sequences into generic
116 ;; string delimiters. Fixme: Is there a better way? 163 ;; string delimiters. Fixme: Is there a better way?
117 `((,(rx (or line-start buffer-start 164 ;; First avoid a sequence preceded by an odd number of backslashes.
118 (not (syntax escape))) ; avoid escaped leading quote 165 `((,(rx (not (any ?\\))
119 (group (optional (any "uUrR"))) ; prefix gets syntax property 166 ?\\ (* (and ?\\ ?\\))
167 (group (syntax string-quote))
168 (backref 1)
169 (group (backref 1)))
170 (2 ,(string-to-syntax "\""))) ; dummy
171 (,(rx (group (optional (any "uUrR"))) ; prefix gets syntax property
120 (optional (any "rR")) ; possible second prefix 172 (optional (any "rR")) ; possible second prefix
121 (group (syntax string-quote)) ; maybe gets property 173 (group (syntax string-quote)) ; maybe gets property
122 (backref 2) ; per first quote 174 (backref 2) ; per first quote
@@ -144,8 +196,6 @@ Used for syntactic keywords. N is the match number (1, 2 or 3)."
144 ;; x = ''' """ ' a 196 ;; x = ''' """ ' a
145 ;; ''' 197 ;; '''
146 ;; x '"""' x """ \"""" x 198 ;; x '"""' x """ \"""" x
147 ;; Fixme: """""" goes wrong (due to syntax-ppss not getting the string
148 ;; fence context).
149 (save-excursion 199 (save-excursion
150 (goto-char (match-beginning 0)) 200 (goto-char (match-beginning 0))
151 (cond 201 (cond
@@ -165,8 +215,8 @@ Used for syntactic keywords. N is the match number (1, 2 or 3)."
165 (and (= n 1) ; prefix 215 (and (= n 1) ; prefix
166 (/= (match-beginning 1) (match-end 1)))) ; non-empty 216 (/= (match-beginning 1) (match-end 1)))) ; non-empty
167 (let ((font-lock-syntactic-keywords nil)) 217 (let ((font-lock-syntactic-keywords nil))
168 (unless (nth 3 (syntax-ppss)) 218 (unless (eq 'string (syntax-ppss-context (syntax-ppss)))
169 (eval-when-compile (string-to-syntax "|"))))) 219 (eval-when-compile (string-to-syntax "|")))))
170 ;; Otherwise (we're in a non-matching string) the property is 220 ;; Otherwise (we're in a non-matching string) the property is
171 ;; nil, which is OK. 221 ;; nil, which is OK.
172 ))) 222 )))
@@ -217,7 +267,7 @@ Used for syntactic keywords. N is the match number (1, 2 or 3)."
217 (define-key map "\C-c\C-z" 'python-switch-to-python) 267 (define-key map "\C-c\C-z" 'python-switch-to-python)
218 (define-key map "\C-c\C-m" 'python-load-file) 268 (define-key map "\C-c\C-m" 'python-load-file)
219 (define-key map "\C-c\C-l" 'python-load-file) ; a la cmuscheme 269 (define-key map "\C-c\C-l" 'python-load-file) ; a la cmuscheme
220 (substitute-key-definition 'complete-symbol 'python-complete-symbol 270 (substitute-key-definition 'complete-symbol 'symbol-complete
221 map global-map) 271 map global-map)
222 (define-key map "\C-c\C-i" 'python-find-imports) 272 (define-key map "\C-c\C-i" 'python-find-imports)
223 (define-key map "\C-c\C-t" 'python-expand-template) 273 (define-key map "\C-c\C-t" 'python-expand-template)
@@ -270,8 +320,10 @@ Used for syntactic keywords. N is the match number (1, 2 or 3)."
270 "-" 320 "-"
271 ["Help on symbol" python-describe-symbol 321 ["Help on symbol" python-describe-symbol
272 :help "Use pydoc on symbol at point"] 322 :help "Use pydoc on symbol at point"]
273 ["Complete symbol" python-complete-symbol 323 ["Complete symbol" symbol-complete
274 :help "Complete (qualified) symbol before point"] 324 :help "Complete (qualified) symbol before point"]
325 ["Find function" python-find-function
326 :help "Try to find source definition of function at point"]
275 ["Update imports" python-find-imports 327 ["Update imports" python-find-imports
276 :help "Update list of top-level imports for completion"])) 328 :help "Update list of top-level imports for completion"]))
277 map)) 329 map))
@@ -630,39 +682,38 @@ Set `python-indent' locally to the value guessed."
630 ((looking-at (rx (0+ space) (syntax comment-start) 682 ((looking-at (rx (0+ space) (syntax comment-start)
631 (not (any " \t\n")))) ; non-indentable comment 683 (not (any " \t\n")))) ; non-indentable comment
632 (current-indentation)) 684 (current-indentation))
633 (t (if python-honour-comment-indentation 685 ((and python-honour-comment-indentation
634 ;; Back over whitespace, newlines, non-indentable comments. 686 ;; Back over whitespace, newlines, non-indentable comments.
635 (catch 'done 687 (catch 'done
636 (while t 688 (while (cond ((bobp) nil)
637 (if (cond ((bobp)) 689 ((not (forward-comment -1))
638 ;; not at comment start 690 nil) ; not at comment start
639 ((not (forward-comment -1)) 691 ;; Now at start of comment -- trailing one?
640 (python-beginning-of-statement) 692 ((/= (current-column) (current-indentation))
641 t) 693 nil)
642 ;; trailing comment 694 ;; Indentable comment, like python-mode.el?
643 ((/= (current-column) (current-indentation)) 695 ((and (looking-at (rx (syntax comment-start)
644 (python-beginning-of-statement) 696 (or space line-end)))
645 t) 697 (/= 0 (current-column)))
646 ;; indentable comment like python-mode.el 698 (throw 'done (current-column)))
647 ((and (looking-at (rx (syntax comment-start) 699 ;; Else skip it (loop).
648 (or space line-end))) 700 (t))))))
649 (/= 0 (current-column))))) 701 (t
650 (throw 'done t))))) 702 (python-indentation-levels)
651 (python-indentation-levels) 703 ;; Prefer to indent comments with an immediately-following
652 ;; Prefer to indent comments with an immediately-following 704 ;; statement, e.g.
653 ;; statement, e.g. 705 ;; ...
654 ;; ... 706 ;; # ...
655 ;; # ... 707 ;; def ...
656 ;; def ... 708 (when (and (> python-indent-list-length 1)
657 (when (and (> python-indent-list-length 1) 709 (python-comment-line-p))
658 (python-comment-line-p)) 710 (forward-line)
659 (forward-line) 711 (unless (python-comment-line-p)
660 (unless (python-comment-line-p) 712 (let ((elt (assq (current-indentation) python-indent-list)))
661 (let ((elt (assq (current-indentation) python-indent-list))) 713 (setq python-indent-list
662 (setq python-indent-list 714 (nconc (delete elt python-indent-list)
663 (nconc (delete elt python-indent-list) 715 (list elt))))))
664 (list elt)))))) 716 (caar (last python-indent-list)))))))
665 (caar (last python-indent-list)))))))
666 717
667;;;; Cycling through the possible indentations with successive TABs. 718;;;; Cycling through the possible indentations with successive TABs.
668 719
@@ -855,11 +906,12 @@ reached start of buffer."
855 ;; Not sure why it was like this -- fails in case of 906 ;; Not sure why it was like this -- fails in case of
856 ;; last internal function followed by first 907 ;; last internal function followed by first
857 ;; non-def statement of the main body. 908 ;; non-def statement of the main body.
858 ;;(and def-line (= in ci)) 909;; (and def-line (= in ci))
859 (= in ci) 910 (= in ci)
860 (< in ci))) 911 (< in ci)))
861 (not (python-in-string/comment))) 912 (not (python-in-string/comment)))
862 (setq found t))))) 913 (setq found t)))
914 found))
863 915
864(defun python-end-of-defun () 916(defun python-end-of-defun ()
865 "`end-of-defun-function' for Python. 917 "`end-of-defun-function' for Python.
@@ -913,15 +965,17 @@ Accounts for continuation lines, multi-line strings, and
913multi-line bracketed expressions." 965multi-line bracketed expressions."
914 (beginning-of-line) 966 (beginning-of-line)
915 (python-beginning-of-string) 967 (python-beginning-of-string)
916 (while (python-continuation-line-p) 968 (let ((point (point)))
917 (beginning-of-line) 969 (while (and (python-continuation-line-p)
918 (if (python-backslash-continuation-line-p) 970 (> point (setq point (point))))
919 (progn 971 (beginning-of-line)
920 (forward-line -1) 972 (if (python-backslash-continuation-line-p)
921 (while (python-backslash-continuation-line-p) 973 (progn
922 (forward-line -1))) 974 (forward-line -1)
923 (python-beginning-of-string) 975 (while (python-backslash-continuation-line-p)
924 (python-skip-out))) 976 (forward-line -1)))
977 (python-beginning-of-string)
978 (python-skip-out))))
925 (back-to-indentation)) 979 (back-to-indentation))
926 980
927(defun python-skip-out (&optional forward syntax) 981(defun python-skip-out (&optional forward syntax)
@@ -999,11 +1053,14 @@ Return count of statements left to move."
999 (if (< count 0) 1053 (if (< count 0)
1000 (python-previous-statement (- count)) 1054 (python-previous-statement (- count))
1001 (beginning-of-line) 1055 (beginning-of-line)
1002 (while (and (> count 0) (not (eobp))) 1056 (let (bogus)
1003 (python-end-of-statement) 1057 (while (and (> count 0) (not (eobp)) (not bogus))
1004 (python-skip-comments/blanks) 1058 (python-end-of-statement)
1005 (unless (eobp) 1059 (python-skip-comments/blanks)
1006 (setq count (1- count)))) 1060 (if (eq 'string (syntax-ppss-context (syntax-ppss)))
1061 (setq bogus t)
1062 (unless (eobp)
1063 (setq count (1- count))))))
1007 count)) 1064 count))
1008 1065
1009(defun python-beginning-of-block (&optional arg) 1066(defun python-beginning-of-block (&optional arg)
@@ -1066,7 +1123,7 @@ don't move and return nil. Otherwise return t."
1066 (if (and (zerop ci) (not open)) 1123 (if (and (zerop ci) (not open))
1067 (not (goto-char point)) 1124 (not (goto-char point))
1068 (catch 'done 1125 (catch 'done
1069 (while (zerop (python-next-statement)) 1126 (while (zerop (python-next-statement))
1070 (when (or (and open (<= (current-indentation) ci)) 1127 (when (or (and open (<= (current-indentation) ci))
1071 (< (current-indentation) ci)) 1128 (< (current-indentation) ci))
1072 (python-skip-comments/blanks t) 1129 (python-skip-comments/blanks t)
@@ -1083,9 +1140,21 @@ don't move and return nil. Otherwise return t."
1083 (set-text-properties 0 (length function-name) nil function-name) 1140 (set-text-properties 0 (length function-name) nil function-name)
1084 function-name)) 1141 function-name))
1085 1142
1086 1143
1087;;;; Imenu. 1144;;;; Imenu.
1088 1145
1146;; For possibily speeding this up, here's the top of the ELP profile
1147;; for rescanning pydoc.py (2.2k lines, 90kb):
1148;; Function Name Call Count Elapsed Time Average Time
1149;; ==================================== ========== ============= ============
1150;; python-imenu-create-index 156 2.430906 0.0155827307
1151;; python-end-of-defun 155 1.2718260000 0.0082053290
1152;; python-end-of-block 155 1.1898689999 0.0076765741
1153;; python-next-statement 2970 1.024717 0.0003450225
1154;; python-end-of-statement 2970 0.4332190000 0.0001458649
1155;; python-beginning-of-defun 265 0.0918479999 0.0003465962
1156;; python-skip-comments/blanks 3125 0.0753319999 2.410...e-05
1157
1089(defvar python-recursing) 1158(defvar python-recursing)
1090(defun python-imenu-create-index () 1159(defun python-imenu-create-index ()
1091 "`imenu-create-index-function' for Python. 1160 "`imenu-create-index-function' for Python.
@@ -1361,11 +1430,16 @@ Don't save anything for STR matching `inferior-python-filter-regexp'."
1361(defvar python-preoutput-result nil 1430(defvar python-preoutput-result nil
1362 "Data from last `_emacs_out' line seen by the preoutput filter.") 1431 "Data from last `_emacs_out' line seen by the preoutput filter.")
1363 1432
1433(defvar python-preoutput-continuation nil
1434 "If non-nil, funcall this when `python-preoutput-filter' sees `_emacs_ok'.")
1435
1364(defvar python-preoutput-leftover nil) 1436(defvar python-preoutput-leftover nil)
1365(defvar python-preoutput-skip-next-prompt nil) 1437(defvar python-preoutput-skip-next-prompt nil)
1366 1438
1367;; Using this stops us getting lines in the buffer like 1439;; Using this stops us getting lines in the buffer like
1368;; >>> ... ... >>> 1440;; >>> ... ... >>>
1441;; Also look for (and delete) an `_emacs_ok' string and call
1442;; `python-preoutput-continuation' if we get it.
1369(defun python-preoutput-filter (s) 1443(defun python-preoutput-filter (s)
1370 "`comint-preoutput-filter-functions' function: ignore prompts not at bol." 1444 "`comint-preoutput-filter-functions' function: ignore prompts not at bol."
1371 (when python-preoutput-leftover 1445 (when python-preoutput-leftover
@@ -1415,6 +1489,23 @@ Don't save anything for STR matching `inferior-python-filter-regexp'."
1415 1489
1416(autoload 'comint-check-proc "comint") 1490(autoload 'comint-check-proc "comint")
1417 1491
1492(defvar python-version-checked nil)
1493(defun python-check-version (cmd)
1494 "Check that CMD runs a suitable version of Python."
1495 ;; Fixme: Check on Jython.
1496 (unless (or python-version-checked
1497 (equal 0 (string-match (regexp-quote python-python-command)
1498 cmd)))
1499 (unless (shell-command-to-string cmd)
1500 (error "Can't run Python command `%s'" cmd))
1501 (let* ((res (shell-command-to-string (concat cmd " --version"))))
1502 (string-match "Python \\([0-9]\\)\\.\\([0-9]\\)" res)
1503 (unless (and (equal "2" (match-string 1 res))
1504 (match-beginning 2)
1505 (>= (string-to-number (match-string 2 res)) 2))
1506 (error "Only Python versions >= 2.2 and < 3.0 supported")))
1507 (setq python-version-checked t)))
1508
1418;;;###autoload 1509;;;###autoload
1419(defun run-python (&optional cmd noshow new) 1510(defun run-python (&optional cmd noshow new)
1420 "Run an inferior Python process, input and output via buffer *Python*. 1511 "Run an inferior Python process, input and output via buffer *Python*.
@@ -1435,22 +1526,26 @@ buffer for a list of commands.)"
1435 (interactive (if current-prefix-arg 1526 (interactive (if current-prefix-arg
1436 (list (read-string "Run Python: " python-command) nil t) 1527 (list (read-string "Run Python: " python-command) nil t)
1437 (list python-command))) 1528 (list python-command)))
1438 (unless cmd (setq cmd python-python-command)) 1529 (unless cmd (setq cmd python-command))
1530 (python-check-version cmd)
1439 (setq python-command cmd) 1531 (setq python-command cmd)
1440 ;; Fixme: Consider making `python-buffer' buffer-local as a buffer 1532 ;; Fixme: Consider making `python-buffer' buffer-local as a buffer
1441 ;; (not a name) in Python buffers from which `run-python' &c is 1533 ;; (not a name) in Python buffers from which `run-python' &c is
1442 ;; invoked. Would support multiple processes better. 1534 ;; invoked. Would support multiple processes better.
1443 (when (or new (not (comint-check-proc python-buffer))) 1535 (when (or new (not (comint-check-proc python-buffer)))
1444 (with-current-buffer 1536 (with-current-buffer
1445 (let* ((cmdlist (append (python-args-to-list cmd) '("-i"))) 1537 (let* ((cmdlist (append (python-args-to-list cmd) '("-i")))
1446 (path (getenv "PYTHONPATH")) 1538 (path (getenv "PYTHONPATH"))
1447 (process-environment ; to import emacs.py 1539 (process-environment ; to import emacs.py
1448 (cons (concat "PYTHONPATH=" data-directory 1540 (cons (concat "PYTHONPATH="
1449 (if path (concat path-separator path))) 1541 (if path (concat path path-separator))
1450 process-environment))) 1542 data-directory)
1451 (apply 'make-comint-in-buffer "Python" 1543 process-environment))
1452 (if new (generate-new-buffer "*Python*") "*Python*") 1544 ;; Suppress use of pager for help output:
1453 (car cmdlist) nil (cdr cmdlist))) 1545 (process-connection-type nil))
1546 (apply 'make-comint-in-buffer "Python"
1547 (generate-new-buffer "*Python*")
1548 (car cmdlist) nil (cdr cmdlist)))
1454 (setq-default python-buffer (current-buffer)) 1549 (setq-default python-buffer (current-buffer))
1455 (setq python-buffer (current-buffer)) 1550 (setq python-buffer (current-buffer))
1456 (accept-process-output (get-buffer-process python-buffer) 5) 1551 (accept-process-output (get-buffer-process python-buffer) 5)
@@ -1462,7 +1557,13 @@ buffer for a list of commands.)"
1462 ;; seems worth putting in a separate file, and it's probably cleaner 1557 ;; seems worth putting in a separate file, and it's probably cleaner
1463 ;; to put it in a module. 1558 ;; to put it in a module.
1464 ;; Ensure we're at a prompt before doing anything else. 1559 ;; Ensure we're at a prompt before doing anything else.
1465 (python-send-string "import emacs"))) 1560 (python-send-string "import emacs")
1561 ;; The following line was meant to ensure that we're at a prompt
1562 ;; before doing anything else. However, this can cause Emacs to
1563 ;; hang waiting for a response, if that Python function fails
1564 ;; (i.e. raises an exception).
1565 ;; (python-send-receive "print '_emacs_out ()'")
1566 ))
1466 (if (derived-mode-p 'python-mode) 1567 (if (derived-mode-p 'python-mode)
1467 (setq python-buffer (default-value 'python-buffer))) ; buffer-local 1568 (setq python-buffer (default-value 'python-buffer))) ; buffer-local
1468 ;; Without this, help output goes into the inferior python buffer if 1569 ;; Without this, help output goes into the inferior python buffer if
@@ -1470,30 +1571,14 @@ buffer for a list of commands.)"
1470 (sit-for 1 t) ;Should we use accept-process-output instead? --Stef 1571 (sit-for 1 t) ;Should we use accept-process-output instead? --Stef
1471 (unless noshow (pop-to-buffer python-buffer t))) 1572 (unless noshow (pop-to-buffer python-buffer t)))
1472 1573
1473;; Fixme: We typically lose if the inferior isn't in the normal REPL,
1474;; e.g. prompt is `help> '. Probably raise an error if the form of
1475;; the prompt is unexpected. Actually, it needs to be `>>> ', not
1476;; `... ', i.e. we're not inputting a block &c. However, this may not
1477;; be the place to check it, e.g. we might actually want to send
1478;; commands having set up such a state.
1479
1480(defun python-send-command (command) 1574(defun python-send-command (command)
1481 "Like `python-send-string' but resets `compilation-shell-minor-mode'. 1575 "Like `python-send-string' but resets `compilation-shell-minor-mode'."
1482COMMAND should be a single statement." 1576 (when (python-check-comint-prompt)
1483 ;; (assert (not (string-match "\n" command))) 1577 (with-current-buffer (process-buffer (python-proc))
1484 ;; (let ((end (marker-position (process-mark (python-proc))))) 1578 (goto-char (point-max))
1485 (with-current-buffer (process-buffer (python-proc)) 1579 (compilation-forget-errors)
1486 (goto-char (point-max)) 1580 (python-send-string command)
1487 (compilation-forget-errors) 1581 (setq compilation-last-buffer (current-buffer)))))
1488 (python-send-string command)
1489 (setq compilation-last-buffer (current-buffer)))
1490 ;; No idea what this is for but it breaks the call to
1491 ;; compilation-fake-loc in python-send-region. -- Stef
1492 ;; Must wait until this has completed before re-setting variables below.
1493 ;; (python-send-receive "print '_emacs_out ()'")
1494 ;; (with-current-buffer python-buffer
1495 ;; (set-marker compilation-parsing-end end))
1496 ) ;;)
1497 1582
1498(defun python-send-region (start end) 1583(defun python-send-region (start end)
1499 "Send the region to the inferior Python process." 1584 "Send the region to the inferior Python process."
@@ -1617,8 +1702,8 @@ See variable `python-buffer'. Starts a new process if necessary."
1617 (unless (comint-check-proc python-buffer) 1702 (unless (comint-check-proc python-buffer)
1618 (run-python nil t)) 1703 (run-python nil t))
1619 (get-buffer-process (if (derived-mode-p 'inferior-python-mode) 1704 (get-buffer-process (if (derived-mode-p 'inferior-python-mode)
1620 (current-buffer) 1705 (current-buffer)
1621 python-buffer))) 1706 python-buffer)))
1622 1707
1623(defun python-set-proc () 1708(defun python-set-proc ()
1624 "Set the default value of `python-buffer' to correspond to this buffer. 1709 "Set the default value of `python-buffer' to correspond to this buffer.
@@ -1693,16 +1778,27 @@ will."
1693 1778
1694(defun python-send-receive (string) 1779(defun python-send-receive (string)
1695 "Send STRING to inferior Python (if any) and return result. 1780 "Send STRING to inferior Python (if any) and return result.
1696The result is what follows `_emacs_out' in the output." 1781The result is what follows `_emacs_out' in the output.
1782This is a no-op if `python-check-comint-prompt' returns nil."
1697 (python-send-string string) 1783 (python-send-string string)
1698 (let ((proc (python-proc))) 1784 (let ((proc (python-proc)))
1699 (with-current-buffer (process-buffer proc) 1785 (with-current-buffer (process-buffer proc)
1700 (set (make-local-variable 'python-preoutput-result) nil) 1786 (when (python-check-comint-prompt proc)
1701 (while (progn 1787 (set (make-local-variable 'python-preoutput-result) nil)
1702 (accept-process-output proc 5) 1788 (while (progn
1703 (null python-preoutput-result))) 1789 (accept-process-output proc 5)
1704 (prog1 python-preoutput-result 1790 (null python-preoutput-result)))
1705 (kill-local-variable 'python-preoutput-result))))) 1791 (prog1 python-preoutput-result
1792 (kill-local-variable 'python-preoutput-result))))))
1793
1794(defun python-check-comint-prompt (&optional proc)
1795 "Return non-nil iff there's a normal prompt in the inferior buffer.
1796If there isn't, it's probably not appropriate to send input to return
1797Eldoc information etc. If PROC is non-nil, check the buffer for that
1798process."
1799 (with-current-buffer (process-buffer (or proc (python-proc)))
1800 (save-excursion
1801 (save-match-data (re-search-backward ">>> \\=" nil t)))))
1706 1802
1707;; Fixme: Is there anything reasonable we can do with random methods? 1803;; Fixme: Is there anything reasonable we can do with random methods?
1708;; (Currently only works with functions.) 1804;; (Currently only works with functions.)
@@ -1716,22 +1812,22 @@ instance. Assumes an inferior Python is running."
1716 (with-local-quit 1812 (with-local-quit
1717 ;; First try the symbol we're on. 1813 ;; First try the symbol we're on.
1718 (or (and symbol 1814 (or (and symbol
1719 (python-send-receive (format "emacs.eargs(%S, %s)" 1815 (python-send-receive (format "emacs.eargs(%S, %s)"
1720 symbol python-imports))) 1816 symbol python-imports)))
1721 ;; Try moving to symbol before enclosing parens. 1817 ;; Try moving to symbol before enclosing parens.
1722 (let ((s (syntax-ppss))) 1818 (let ((s (syntax-ppss)))
1723 (unless (zerop (car s)) 1819 (unless (zerop (car s))
1724 (when (eq ?\( (char-after (nth 1 s))) 1820 (when (eq ?\( (char-after (nth 1 s)))
1725 (save-excursion 1821 (save-excursion
1726 (goto-char (nth 1 s)) 1822 (goto-char (nth 1 s))
1727 (skip-syntax-backward "-") 1823 (skip-syntax-backward "-")
1728 (let ((point (point))) 1824 (let ((point (point)))
1729 (skip-chars-backward "a-zA-Z._") 1825 (skip-chars-backward "a-zA-Z._")
1730 (if (< (point) point) 1826 (if (< (point) point)
1731 (python-send-receive 1827 (python-send-receive
1732 (format "emacs.eargs(%S, %s)" 1828 (format "emacs.eargs(%S, %s)"
1733 (buffer-substring-no-properties (point) point) 1829 (buffer-substring-no-properties (point) point)
1734 python-imports)))))))))))) 1830 python-imports))))))))))))
1735 1831
1736;;;; Info-look functionality. 1832;;;; Info-look functionality.
1737 1833
@@ -1751,9 +1847,9 @@ Used with `eval-after-load'."
1751 (condition-case () 1847 (condition-case ()
1752 ;; Don't use `info' because it would pop-up a *info* buffer. 1848 ;; Don't use `info' because it would pop-up a *info* buffer.
1753 (with-no-warnings 1849 (with-no-warnings
1754 (Info-goto-node (format "(python%s-lib)Miscellaneous Index" 1850 (Info-goto-node (format "(python%s-lib)Miscellaneous Index"
1755 version)) 1851 version))
1756 t) 1852 t)
1757 (error nil))))) 1853 (error nil)))))
1758 (info-lookup-maybe-add-help 1854 (info-lookup-maybe-add-help
1759 :mode 'python-mode 1855 :mode 'python-mode
@@ -1829,7 +1925,7 @@ The criterion is either a match for `jython-mode' via
1829 "`fill-paragraph-function' handling multi-line strings and possibly comments. 1925 "`fill-paragraph-function' handling multi-line strings and possibly comments.
1830If any of the current line is in or at the end of a multi-line string, 1926If any of the current line is in or at the end of a multi-line string,
1831fill the string or the paragraph of it that point is in, preserving 1927fill the string or the paragraph of it that point is in, preserving
1832the strings's indentation." 1928the string's indentation."
1833 (interactive "P") 1929 (interactive "P")
1834 (or (fill-comment-paragraph justify) 1930 (or (fill-comment-paragraph justify)
1835 (save-excursion 1931 (save-excursion
@@ -1845,7 +1941,7 @@ the strings's indentation."
1845 ;; paragraph in a multi-line string properly, so narrow 1941 ;; paragraph in a multi-line string properly, so narrow
1846 ;; to the string and then fill around (the end of) the 1942 ;; to the string and then fill around (the end of) the
1847 ;; current line. 1943 ;; current line.
1848 ((eq t (nth 3 syntax)) ; in fenced string 1944 ((eq t (nth 3 syntax)) ; in fenced string
1849 (goto-char (nth 8 syntax)) ; string start 1945 (goto-char (nth 8 syntax)) ; string start
1850 (setq start (line-beginning-position)) 1946 (setq start (line-beginning-position))
1851 (setq end (condition-case () ; for unbalanced quotes 1947 (setq end (condition-case () ; for unbalanced quotes
@@ -1868,14 +1964,25 @@ the strings's indentation."
1868 ;; """ 1964 ;; """
1869 ;; ... 1965 ;; ...
1870 ;; """ 1966 ;; """
1871 (let* ((paragraph-separate 1967 (let ((paragraph-separate
1872 (concat ".*\\s|\"\"$" ; newline after opening quotes 1968 ;; Note that the string could be part of an
1873 "\\|\\(?:" paragraph-separate "\\)")) 1969 ;; expression, so it can have preceding and
1874 (paragraph-start 1970 ;; trailing non-whitespace.
1875 (concat ".*\\s|\"\"[ \t]*[^ \t].*" ; not newline after 1971 (concat
1876 ; opening quotes 1972 (rx (or
1877 "\\|\\(?:" paragraph-separate "\\)")) 1973 ;; Opening triple quote without following text.
1878 (fill-paragraph-function)) 1974 (and (* nonl)
1975 (group (syntax string-delimiter))
1976 (repeat 2 (backref 1))
1977 ;; Fixme: Not sure about including
1978 ;; trailing whitespace.
1979 (* (any " \t"))
1980 eol)
1981 ;; Closing trailing quote without preceding text.
1982 (and (group (any ?\" ?')) (backref 2)
1983 (syntax string-delimiter))))
1984 "\\(?:" paragraph-separate "\\)"))
1985 fill-paragraph-function)
1879 (fill-paragraph justify))))))) t) 1986 (fill-paragraph justify))))))) t)
1880 1987
1881(defun python-shift-left (start end &optional count) 1988(defun python-shift-left (start end &optional count)
@@ -1988,7 +2095,8 @@ Uses `python-beginning-of-block', `python-end-of-block'."
1988 (let ((start (line-beginning-position))) 2095 (let ((start (line-beginning-position)))
1989 ;; Skip over continued lines. 2096 ;; Skip over continued lines.
1990 (while (and (eq ?\\ (char-before (line-end-position))) 2097 (while (and (eq ?\\ (char-before (line-end-position)))
1991 (= 0 (forward-line 1)))) 2098 (= 0 (forward-line 1)))
2099 t)
1992 (push (buffer-substring start (line-beginning-position 2)) 2100 (push (buffer-substring start (line-beginning-position 2))
1993 lines)))) 2101 lines))))
1994 (setq python-imports 2102 (setq python-imports
@@ -2041,60 +2149,6 @@ Uses `python-imports' to load modules against which to complete."
2041 nil t) 2149 nil t)
2042 (match-beginning 1))))) 2150 (match-beginning 1)))))
2043 (if start (buffer-substring-no-properties start end)))) 2151 (if start (buffer-substring-no-properties start end))))
2044
2045(defun python-complete-symbol ()
2046 "Perform completion on the Python symbol preceding point.
2047Repeating the command scrolls the completion window."
2048 (interactive)
2049 (let ((window (get-buffer-window "*Completions*")))
2050 (if (and (eq last-command this-command)
2051 (window-live-p window) (window-buffer window)
2052 (buffer-name (window-buffer window)))
2053 (with-current-buffer (window-buffer window)
2054 (if (pos-visible-in-window-p (point-max) window)
2055 (set-window-start window (point-min))
2056 (save-selected-window
2057 (select-window window)
2058 (scroll-up))))
2059 ;; Do completion.
2060 (let* ((end (point))
2061 (symbol (python-partial-symbol))
2062 (completions (python-symbol-completions symbol))
2063 (completion (if completions
2064 (try-completion symbol completions))))
2065 (when symbol
2066 (cond ((eq completion t))
2067 ((null completion)
2068 (message "Can't find completion for \"%s\"" symbol)
2069 (ding))
2070 ((not (string= symbol completion))
2071 (delete-region (- end (length symbol)) end)
2072 (insert completion))
2073 (t
2074 (message "Making completion list...")
2075 (with-output-to-temp-buffer "*Completions*"
2076 (display-completion-list completions symbol))
2077 (message "Making completion list...%s" "done"))))))))
2078
2079(defun python-try-complete (old)
2080 "Completion function for Python for use with `hippie-expand'."
2081 (when (derived-mode-p 'python-mode) ; though we only add it locally
2082 (unless old
2083 (let ((symbol (python-partial-symbol)))
2084 (he-init-string (- (point) (length symbol)) (point))
2085 (if (not (he-string-member he-search-string he-tried-table))
2086 (push he-search-string he-tried-table))
2087 (setq he-expand-list
2088 (and symbol (python-symbol-completions symbol)))))
2089 (while (and he-expand-list
2090 (he-string-member (car he-expand-list) he-tried-table))
2091 (pop he-expand-list))
2092 (if he-expand-list
2093 (progn
2094 (he-substitute-string (pop he-expand-list))
2095 t)
2096 (if old (he-reset-string))
2097 nil)))
2098 2152
2099;;;; FFAP support 2153;;;; FFAP support
2100 2154
@@ -2105,6 +2159,33 @@ Repeating the command scrolls the completion window."
2105(eval-after-load "ffap" 2159(eval-after-load "ffap"
2106 '(push '(python-mode . python-module-path) ffap-alist)) 2160 '(push '(python-mode . python-module-path) ffap-alist))
2107 2161
2162;;;; Find-function support
2163
2164;; Fixme: key binding?
2165
2166(defun python-find-function (name)
2167 "Find source of definition of function NAME.
2168Interactively, prompt for name."
2169 (interactive
2170 (let ((symbol (with-syntax-table python-dotty-syntax-table
2171 (current-word)))
2172 (enable-recursive-minibuffers t))
2173 (list (read-string (if symbol
2174 (format "Find location of (default %s): " symbol)
2175 "Find location of: ")
2176 nil nil symbol))))
2177 (unless python-imports
2178 (error "Not called from buffer visiting Python file"))
2179 (let* ((loc (python-send-receive (format "emacs.location_of (%S, %s)"
2180 name python-imports)))
2181 (loc (car (read-from-string loc)))
2182 (file (car loc))
2183 (line (cdr loc)))
2184 (unless file (error "Don't know where `%s' is defined" name))
2185 (pop-to-buffer (find-file-noselect file))
2186 (when (integerp line)
2187 (goto-line line))))
2188
2108;;;; Skeletons 2189;;;; Skeletons
2109 2190
2110(defcustom python-use-skeletons nil 2191(defcustom python-use-skeletons nil
@@ -2132,24 +2213,31 @@ The default contents correspond to the elements of `python-skeletons'."
2132 (function (intern (concat "python-insert-" name)))) 2213 (function (intern (concat "python-insert-" name))))
2133 `(progn 2214 `(progn
2134 (add-to-list 'python-skeletons ',(cons name function)) 2215 (add-to-list 'python-skeletons ',(cons name function))
2135 (define-abbrev python-mode-abbrev-table ,name "" ',function 2216 ;; Usual technique for inserting a skeleton, but expand
2136 :system t :case-fixed t 2217 ;; to the original abbrev instead if in a comment or string.
2137 :enable-function (lambda () python-use-skeletons)) 2218 (define-abbrev python-mode-abbrev-table ,name ""
2219 ;; Quote this to give a readable abbrev table.
2220 '(lambda ()
2221 (if (python-in-string/comment)
2222 (insert ,name)
2223 (,function)))
2224 nil t) ; system abbrev
2138 (define-skeleton ,function 2225 (define-skeleton ,function
2139 ,(format "Insert Python \"%s\" template." name) 2226 ,(format "Insert Python \"%s\" template." name)
2140 ,@elements))))) 2227 ,@elements)))))
2141(put 'def-python-skeleton 'lisp-indent-function 2) 2228(put 'def-python-skeleton 'lisp-indent-function 2)
2142 2229
2143;; From `skeleton-further-elements': 2230;; From `skeleton-further-elements' set below:
2144;; `<': outdent a level; 2231;; `<': outdent a level;
2145;; `^': delete indentation on current line and also previous newline. 2232;; `^': delete indentation on current line and also previous newline.
2146;; Not quote like `delete-indentation'. Assumes point is at 2233;; Not quite like `delete-indentation'. Assumes point is at
2147;; beginning of indentation. 2234;; beginning of indentation.
2148 2235
2149(def-python-skeleton if 2236(def-python-skeleton if
2150 "Condition: " 2237 "Condition: "
2151 "if " str ":" \n 2238 "if " str ":" \n
2152 > _ \n 2239 > -1 ; Fixme: I don't understand the spurious space this removes.
2240 _ \n
2153 ("other condition, %s: " 2241 ("other condition, %s: "
2154 < ; Avoid wrong indentation after block opening. 2242 < ; Avoid wrong indentation after block opening.
2155 "elif " str ":" \n 2243 "elif " str ":" \n
@@ -2167,19 +2255,19 @@ The default contents correspond to the elements of `python-skeletons'."
2167(def-python-skeleton while 2255(def-python-skeleton while
2168 "Condition: " 2256 "Condition: "
2169 "while " str ":" \n 2257 "while " str ":" \n
2170 > _ \n 2258 > -1 _ \n
2171 '(python-else) | ^) 2259 '(python-else) | ^)
2172 2260
2173(def-python-skeleton for 2261(def-python-skeleton for
2174 "Target, %s: " 2262 "Target, %s: "
2175 "for " str " in " (skeleton-read "Expression, %s: ") ":" \n 2263 "for " str " in " (skeleton-read "Expression, %s: ") ":" \n
2176 > _ \n 2264 > -1 _ \n
2177 '(python-else) | ^) 2265 '(python-else) | ^)
2178 2266
2179(def-python-skeleton try/except 2267(def-python-skeleton try/except
2180 nil 2268 nil
2181 "try:" \n 2269 "try:" \n
2182 > _ \n 2270 > -1 _ \n
2183 ("Exception, %s: " 2271 ("Exception, %s: "
2184 < "except " str '(python-target) ":" \n 2272 < "except " str '(python-target) ":" \n
2185 > _ \n nil) 2273 > _ \n nil)
@@ -2194,7 +2282,7 @@ The default contents correspond to the elements of `python-skeletons'."
2194(def-python-skeleton try/finally 2282(def-python-skeleton try/finally
2195 nil 2283 nil
2196 "try:" \n 2284 "try:" \n
2197 > _ \n 2285 > -1 _ \n
2198 < "finally:" \n 2286 < "finally:" \n
2199 > _ \n) 2287 > _ \n)
2200 2288
@@ -2202,7 +2290,7 @@ The default contents correspond to the elements of `python-skeletons'."
2202 "Name: " 2290 "Name: "
2203 "def " str " (" ("Parameter, %s: " (unless (equal ?\( (char-before)) ", ") 2291 "def " str " (" ("Parameter, %s: " (unless (equal ?\( (char-before)) ", ")
2204 str) "):" \n 2292 str) "):" \n
2205 "\"\"\"" @ " \"\"\"" \n ; Fixme: syntaxification wrong for """""" 2293 "\"\"\"" - "\"\"\"" \n ; Fixme: extra space inserted -- why?).
2206 > _ \n) 2294 > _ \n)
2207 2295
2208(def-python-skeleton class 2296(def-python-skeleton class
@@ -2212,7 +2300,7 @@ The default contents correspond to the elements of `python-skeletons'."
2212 str) 2300 str)
2213 & ")" | -2 ; close list or remove opening 2301 & ")" | -2 ; close list or remove opening
2214 ":" \n 2302 ":" \n
2215 "\"\"\"" @ " \"\"\"" \n 2303 "\"\"\"" - "\"\"\"" \n
2216 > _ \n) 2304 > _ \n)
2217 2305
2218(defvar python-default-template "if" 2306(defvar python-default-template "if"
@@ -2255,35 +2343,35 @@ without confirmation."
2255 (pymacs-load "bikeemacs" "brm-") ; first line of normal recipe 2343 (pymacs-load "bikeemacs" "brm-") ; first line of normal recipe
2256 (let ((py-mode-map (make-sparse-keymap)) ; it assumes this 2344 (let ((py-mode-map (make-sparse-keymap)) ; it assumes this
2257 (features (cons 'python-mode features))) ; and requires this 2345 (features (cons 'python-mode features))) ; and requires this
2258 (brm-init)) ; second line of normal recipe 2346 (brm-init) ; second line of normal recipe
2259 (remove-hook 'python-mode-hook ; undo this from `brm-init' 2347 (remove-hook 'python-mode-hook ; undo this from `brm-init'
2260 '(lambda () (easy-menu-add brm-menu))) 2348 '(lambda () (easy-menu-add brm-menu)))
2261 (easy-menu-define 2349 (easy-menu-define
2262 python-brm-menu python-mode-map 2350 python-brm-menu python-mode-map
2263 "Bicycle Repair Man" 2351 "Bicycle Repair Man"
2264 '("BicycleRepairMan" 2352 '("BicycleRepairMan"
2265 :help "Interface to navigation and refactoring tool" 2353 :help "Interface to navigation and refactoring tool"
2266 "Queries" 2354 "Queries"
2267 ["Find References" brm-find-references 2355 ["Find References" brm-find-references
2268 :help "Find references to name at point in compilation buffer"] 2356 :help "Find references to name at point in compilation buffer"]
2269 ["Find Definition" brm-find-definition 2357 ["Find Definition" brm-find-definition
2270 :help "Find definition of name at point"] 2358 :help "Find definition of name at point"]
2271 "-" 2359 "-"
2272 "Refactoring" 2360 "Refactoring"
2273 ["Rename" brm-rename 2361 ["Rename" brm-rename
2274 :help "Replace name at point with a new name everywhere"] 2362 :help "Replace name at point with a new name everywhere"]
2275 ["Extract Method" brm-extract-method 2363 ["Extract Method" brm-extract-method
2276 :active (and mark-active (not buffer-read-only)) 2364 :active (and mark-active (not buffer-read-only))
2277 :help "Replace statements in region with a method"] 2365 :help "Replace statements in region with a method"]
2278 ["Extract Local Variable" brm-extract-local-variable 2366 ["Extract Local Variable" brm-extract-local-variable
2279 :active (and mark-active (not buffer-read-only)) 2367 :active (and mark-active (not buffer-read-only))
2280 :help "Replace expression in region with an assignment"] 2368 :help "Replace expression in region with an assignment"]
2281 ["Inline Local Variable" brm-inline-local-variable 2369 ["Inline Local Variable" brm-inline-local-variable
2282 :help 2370 :help
2283 "Substitute uses of variable at point with its definition"] 2371 "Substitute uses of variable at point with its definition"]
2284 ;; Fixme: Should check for anything to revert. 2372 ;; Fixme: Should check for anything to revert.
2285 ["Undo Last Refactoring" brm-undo :help ""]))) 2373 ["Undo Last Refactoring" brm-undo :help ""]))))
2286 (error (error "Bicyclerepairman setup failed: %s" data)))) 2374 (error (error "BicycleRepairMan setup failed: %s" data))))
2287 2375
2288;;;; Modes. 2376;;;; Modes.
2289 2377
@@ -2291,10 +2379,27 @@ without confirmation."
2291(defvar eldoc-documentation-function) 2379(defvar eldoc-documentation-function)
2292(defvar python-mode-running) ;Dynamically scoped var. 2380(defvar python-mode-running) ;Dynamically scoped var.
2293 2381
2382;; Stuff to allow expanding abbrevs with non-word constituents.
2383(defun python-abbrev-pc-hook ()
2384 "Reset the syntax table after possibly expanding abbrevs."
2385 (remove-hook 'post-command-hook 'python-abbrev-pc-hook t)
2386 (set-syntax-table python-mode-syntax-table))
2387
2388(defvar python-abbrev-syntax-table
2389 (copy-syntax-table python-mode-syntax-table)
2390 "Syntax table used when expanding abbrevs.")
2391
2392(defun python-pea-hook ()
2393 "Set the syntax table before possibly expanding abbrevs."
2394 (set-syntax-table python-abbrev-syntax-table)
2395 (add-hook 'post-command-hook 'python-abbrev-pc-hook nil t))
2396(modify-syntax-entry ?/ "w" python-abbrev-syntax-table)
2397
2294;;;###autoload 2398;;;###autoload
2295(define-derived-mode python-mode fundamental-mode "Python" 2399(define-derived-mode python-mode fundamental-mode "Python"
2296 "Major mode for editing Python files. 2400 "Major mode for editing Python files.
2297Font Lock mode is currently required for correct parsing of the source. 2401Turns on Font Lock mode unconditionally since it is currently required
2402for correct parsing of the source.
2298See also `jython-mode', which is actually invoked if the buffer appears to 2403See also `jython-mode', which is actually invoked if the buffer appears to
2299contain Jython code. See also `run-python' and associated Python mode 2404contain Jython code. See also `run-python' and associated Python mode
2300commands for running Python under Emacs. 2405commands for running Python under Emacs.
@@ -2363,24 +2468,31 @@ with skeleton expansions for compound statement templates.
2363 (add-hook 'eldoc-mode-hook 2468 (add-hook 'eldoc-mode-hook
2364 (lambda () (run-python nil t)) ; need it running 2469 (lambda () (run-python nil t)) ; need it running
2365 nil t) 2470 nil t)
2471 (set (make-local-variable 'symbol-completion-symbol-function)
2472 'python-partial-symbol)
2473 (set (make-local-variable 'symbol-completion-completions-function)
2474 'python-symbol-completions)
2366 ;; Fixme: should be in hideshow. This seems to be of limited use 2475 ;; Fixme: should be in hideshow. This seems to be of limited use
2367 ;; since it isn't (can't be) indentation-based. Also hide-level 2476 ;; since it isn't (can't be) indentation-based. Also hide-level
2368 ;; doesn't seem to work properly. 2477 ;; doesn't seem to work properly.
2369 (add-to-list 'hs-special-modes-alist 2478 (add-to-list 'hs-special-modes-alist
2370 `(python-mode "^\\s-*\\(?:def\\|class\\)\\>" nil "#" 2479 `(python-mode "^\\s-*\\(?:def\\|class\\)\\>" nil "#"
2371 ,(lambda (arg) 2480 ,(lambda (arg)
2372 (python-end-of-defun) 2481 (python-end-of-defun)
2373 (skip-chars-backward " \t\n")) 2482 (skip-chars-backward " \t\n"))
2374 nil)) 2483 nil))
2375 (set (make-local-variable 'skeleton-further-elements) 2484 (set (make-local-variable 'skeleton-further-elements)
2376 '((< '(backward-delete-char-untabify (min python-indent 2485 '((< '(backward-delete-char-untabify (min python-indent
2377 (current-column)))) 2486 (current-column))))
2378 (^ '(- (1+ (current-indentation)))))) 2487 (^ '(- (1+ (current-indentation))))))
2488 (add-hook 'pre-abbrev-expand-hook 'python-pea-hook nil t)
2379 (if (featurep 'hippie-exp) 2489 (if (featurep 'hippie-exp)
2380 (set (make-local-variable 'hippie-expand-try-functions-list) 2490 (set (make-local-variable 'hippie-expand-try-functions-list)
2381 (cons 'python-try-complete hippie-expand-try-functions-list))) 2491 (cons 'symbol-completion-try-complete
2492 hippie-expand-try-functions-list)))
2382 ;; Python defines TABs as being 8-char wide. 2493 ;; Python defines TABs as being 8-char wide.
2383 (set (make-local-variable 'tab-width) 8) 2494 (set (make-local-variable 'tab-width) 8)
2495 (unless font-lock-mode (font-lock-mode 1))
2384 (when python-guess-indent (python-guess-indent)) 2496 (when python-guess-indent (python-guess-indent))
2385 ;; Let's make it harder for the user to shoot himself in the foot. 2497 ;; Let's make it harder for the user to shoot himself in the foot.
2386 (unless (= tab-width python-indent) 2498 (unless (= tab-width python-indent)
@@ -2391,11 +2503,16 @@ with skeleton expansions for compound statement templates.
2391 (let ((python-mode-running t)) 2503 (let ((python-mode-running t))
2392 (python-maybe-jython)))) 2504 (python-maybe-jython))))
2393 2505
2506;; Not done automatically in Emacs 21 or 22.
2507(defcustom python-mode-hook nil
2508 "Hook run when entering Python mode."
2509 :group 'python
2510 :type 'hook)
2394(custom-add-option 'python-mode-hook 'imenu-add-menubar-index) 2511(custom-add-option 'python-mode-hook 'imenu-add-menubar-index)
2395(custom-add-option 'python-mode-hook 2512(custom-add-option 'python-mode-hook
2396 (lambda () 2513 (lambda ()
2397 "Turn off Indent Tabs mode." 2514 "Turn off Indent Tabs mode."
2398 (set (make-local-variable 'indent-tabs-mode) nil))) 2515 (setq indent-tabs-mode nil)))
2399(custom-add-option 'python-mode-hook 'turn-on-eldoc-mode) 2516(custom-add-option 'python-mode-hook 'turn-on-eldoc-mode)
2400(custom-add-option 'python-mode-hook 'abbrev-mode) 2517(custom-add-option 'python-mode-hook 'abbrev-mode)
2401(custom-add-option 'python-mode-hook 'python-setup-brm) 2518(custom-add-option 'python-mode-hook 'python-setup-brm)
@@ -2776,5 +2893,6 @@ filter."
2776 2893
2777(provide 'python) 2894(provide 'python)
2778(provide 'python-21) 2895(provide 'python-21)
2896
2779;; arch-tag: 6fce1d99-a704-4de9-ba19-c6e4912b0554 2897;; arch-tag: 6fce1d99-a704-4de9-ba19-c6e4912b0554
2780;;; python.el ends here 2898;;; python.el ends here