aboutsummaryrefslogtreecommitdiffstats
path: root/lisp/progmodes/python.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/progmodes/python.el')
-rw-r--r--lisp/progmodes/python.el5164
1 files changed, 2662 insertions, 2502 deletions
diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el
index 620ea8cd519..e0a58d1523e 100644
--- a/lisp/progmodes/python.el
+++ b/lisp/progmodes/python.el
@@ -1,181 +1,472 @@
1;;; python.el --- silly walks for Python -*- coding: iso-8859-1 -*- 1;;; python.el --- Python's flying circus support for Emacs -*- coding: utf-8 -*-
2 2
3;; Copyright (C) 2003-2012 Free Software Foundation, Inc. 3;; Copyright (C) 2003-2012 Free Software Foundation, Inc.
4 4
5;; Author: Dave Love <fx@gnu.org> 5;; Author: Fabián E. Gallina <fabian@anue.biz>
6;; URL: https://github.com/fgallina/python.el
7;; Version: 0.24.2
6;; Maintainer: FSF 8;; Maintainer: FSF
7;; Created: Nov 2003 9;; Created: Jul 2010
8;; Keywords: languages 10;; Keywords: languages
9 11
10;; This file is part of GNU Emacs. 12;; This file is part of GNU Emacs.
11 13
12;; GNU Emacs is free software: you can redistribute it and/or modify 14;; GNU Emacs is free software: you can redistribute it and/or modify
13;; it under the terms of the GNU General Public License as published by 15;; it under the terms of the GNU General Public License as published
14;; the Free Software Foundation, either version 3 of the License, or 16;; by the Free Software Foundation, either version 3 of the License,
15;; (at your option) any later version. 17;; or (at your option) any later version.
16 18
17;; GNU Emacs is distributed in the hope that it will be useful, 19;; GNU Emacs is distributed in the hope that it will be useful, but
18;; but WITHOUT ANY WARRANTY; without even the implied warranty of 20;; WITHOUT ANY WARRANTY; without even the implied warranty of
19;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20;; GNU General Public License for more details. 22;; General Public License for more details.
21 23
22;; You should have received a copy of the GNU General Public License 24;; You should have received a copy of the GNU General Public License
23;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. 25;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
24 26
25;;; Commentary: 27;;; Commentary:
26 28
27;; Major mode for editing Python, with support for inferior processes. 29;; Major mode for editing Python files with some fontification and
28 30;; indentation bits extracted from original Dave Love's python.el
29;; There is another Python mode, python-mode.el: 31;; found in GNU/Emacs.
30;; http://launchpad.net/python-mode 32
31;; used by XEmacs, and originally maintained with Python. 33;; Implements Syntax highlighting, Indentation, Movement, Shell
32;; That isn't covered by an FSF copyright assignment (?), unlike this 34;; interaction, Shell completion, Shell virtualenv support, Pdb
33;; code, and seems not to be well-maintained for Emacs (though I've 35;; tracking, Symbol completion, Skeletons, FFAP, Code Check, Eldoc,
34;; submitted fixes). This mode is rather simpler and is better in 36;; imenu.
35;; other ways. In particular, using the syntax functions with text 37
36;; properties maintained by font-lock makes it more correct with 38;; Syntax highlighting: Fontification of code is provided and supports
37;; arbitrary string and comment contents. 39;; python's triple quoted strings properly.
38 40
39;; This doesn't implement all the facilities of python-mode.el. Some 41;; Indentation: Automatic indentation with indentation cycling is
40;; just need doing, e.g. catching exceptions in the inferior Python 42;; provided, it allows you to navigate different available levels of
41;; buffer (but see M-x pdb for debugging). [Actually, the use of 43;; indentation by hitting <tab> several times. Also when inserting a
42;; `compilation-shell-minor-mode' now is probably enough for that.] 44;; colon the `python-indent-electric-colon' command is invoked and
43;; Others don't seem appropriate. For instance, 45;; causes the current line to be dedented automatically if needed.
44;; `forward-into-nomenclature' should be done separately, since it's 46
45;; not specific to Python, and I've installed a minor mode to do the 47;; Movement: `beginning-of-defun' and `end-of-defun' functions are
46;; job properly in Emacs 23. [CC mode 5.31 contains an incompatible 48;; properly implemented. There are also specialized
47;; feature, `subword-mode' which is intended to have a similar 49;; `forward-sentence' and `backward-sentence' replacements called
48;; effect, but actually only affects word-oriented keybindings.] 50;; `python-nav-forward-block', `python-nav-backward-block'
49 51;; respectively which navigate between beginning of blocks of code.
50;; Other things seem more natural or canonical here, e.g. the 52;; Extra functions `python-nav-forward-statement',
51;; {beginning,end}-of-defun implementation dealing with nested 53;; `python-nav-backward-statement', `python-nav-statement-start',
52;; definitions, and the inferior mode following `cmuscheme'. (The 54;; `python-nav-statement-end', `python-nav-block-start' and
53;; inferior mode can find the source of errors from 55;; `python-nav-block-end' are included but no bound to any key.
54;; `python-send-region' & al via `compilation-shell-minor-mode'.) 56
55;; There is (limited) symbol completion using lookup in Python and 57;; Shell interaction: is provided and allows you to execute easily any
56;; Eldoc support also using the inferior process. Successive TABs 58;; block of code of your current buffer in an inferior Python process.
57;; cycle between possible indentations for the line. 59
58 60;; Shell completion: hitting tab will try to complete the current
59;; Even where it has similar facilities, this mode is incompatible 61;; word. Shell completion is implemented in a manner that if you
60;; with python-mode.el in some respects. For instance, various key 62;; change the `python-shell-interpreter' to any other (for example
61;; bindings are changed to obey Emacs conventions. 63;; IPython) it should be easy to integrate another way to calculate
62 64;; completions. You just need to specify your custom
63;; TODO: See various Fixmes below. 65;; `python-shell-completion-setup-code' and
64 66;; `python-shell-completion-string-code'.
65;; Fixme: This doesn't support (the nascent) Python 3 . 67
68;; Here is a complete example of the settings you would use for
69;; iPython 0.11:
70
71;; (setq
72;; python-shell-interpreter "ipython"
73;; python-shell-interpreter-args ""
74;; python-shell-prompt-regexp "In \\[[0-9]+\\]: "
75;; python-shell-prompt-output-regexp "Out\\[[0-9]+\\]: "
76;; python-shell-completion-setup-code
77;; "from IPython.core.completerlib import module_completion"
78;; python-shell-completion-module-string-code
79;; "';'.join(module_completion('''%s'''))\n"
80;; python-shell-completion-string-code
81;; "';'.join(get_ipython().Completer.all_completions('''%s'''))\n")
82
83;; For iPython 0.10 everything would be the same except for
84;; `python-shell-completion-string-code' and
85;; `python-shell-completion-module-string-code':
86
87;; (setq python-shell-completion-string-code
88;; "';'.join(__IP.complete('''%s'''))\n"
89;; python-shell-completion-module-string-code "")
90
91;; Unfortunately running iPython on Windows needs some more tweaking.
92;; The way you must set `python-shell-interpreter' and
93;; `python-shell-interpreter-args' is as follows:
94
95;; (setq
96;; python-shell-interpreter "C:\\Python27\\python.exe"
97;; python-shell-interpreter-args
98;; "-i C:\\Python27\\Scripts\\ipython-script.py")
99
100;; That will spawn the iPython process correctly (Of course you need
101;; to modify the paths according to your system).
102
103;; Please note that the default completion system depends on the
104;; readline module, so if you are using some Operating System that
105;; bundles Python without it (like Windows) just install the
106;; pyreadline from http://ipython.scipy.org/moin/PyReadline/Intro and
107;; you should be good to go.
108
109;; Shell virtualenv support: The shell also contains support for
110;; virtualenvs and other special environment modifications thanks to
111;; `python-shell-process-environment' and `python-shell-exec-path'.
112;; These two variables allows you to modify execution paths and
113;; environment variables to make easy for you to setup virtualenv rules
114;; or behavior modifications when running shells. Here is an example
115;; of how to make shell processes to be run using the /path/to/env/
116;; virtualenv:
117
118;; (setq python-shell-process-environment
119;; (list
120;; (format "PATH=%s" (mapconcat
121;; 'identity
122;; (reverse
123;; (cons (getenv "PATH")
124;; '("/path/to/env/bin/")))
125;; ":"))
126;; "VIRTUAL_ENV=/path/to/env/"))
127;; (python-shell-exec-path . ("/path/to/env/bin/"))
128
129;; Since the above is cumbersome and can be programmatically
130;; calculated, the variable `python-shell-virtualenv-path' is
131;; provided. When this variable is set with the path of the
132;; virtualenv to use, `process-environment' and `exec-path' get proper
133;; values in order to run shells inside the specified virtualenv. So
134;; the following will achieve the same as the previous example:
135
136;; (setq python-shell-virtualenv-path "/path/to/env/")
137
138;; Also the `python-shell-extra-pythonpaths' variable have been
139;; introduced as simple way of adding paths to the PYTHONPATH without
140;; affecting existing values.
141
142;; Pdb tracking: when you execute a block of code that contains some
143;; call to pdb (or ipdb) it will prompt the block of code and will
144;; follow the execution of pdb marking the current line with an arrow.
145
146;; Symbol completion: you can complete the symbol at point. It uses
147;; the shell completion in background so you should run
148;; `python-shell-send-buffer' from time to time to get better results.
149
150;; Skeletons: 6 skeletons are provided for simple inserting of class,
151;; def, for, if, try and while. These skeletons are integrated with
152;; dabbrev. If you have `dabbrev-mode' activated and
153;; `python-skeleton-autoinsert' is set to t, then whenever you type
154;; the name of any of those defined and hit SPC, they will be
155;; automatically expanded.
156
157;; FFAP: You can find the filename for a given module when using ffap
158;; out of the box. This feature needs an inferior python shell
159;; running.
160
161;; Code check: Check the current file for errors with `python-check'
162;; using the program defined in `python-check-command'.
163
164;; Eldoc: returns documentation for object at point by using the
165;; inferior python subprocess to inspect its documentation. As you
166;; might guessed you should run `python-shell-send-buffer' from time
167;; to time to get better results too.
168
169;; imenu: This mode supports imenu in its most basic form, letting it
170;; build the necessary alist via `imenu-default-create-index-function'
171;; by having set `imenu-extract-index-name-function' to
172;; `python-info-current-defun'.
173
174;; If you used python-mode.el you probably will miss auto-indentation
175;; when inserting newlines. To achieve the same behavior you have
176;; two options:
177
178;; 1) Use GNU/Emacs' standard binding for `newline-and-indent': C-j.
179
180;; 2) Add the following hook in your .emacs:
181
182;; (add-hook 'python-mode-hook
183;; #'(lambda ()
184;; (define-key python-mode-map "\C-m" 'newline-and-indent)))
185
186;; I'd recommend the first one since you'll get the same behavior for
187;; all modes out-of-the-box.
188
189;;; Installation:
190
191;; Add this to your .emacs:
192
193;; (add-to-list 'load-path "/folder/containing/file")
194;; (require 'python)
195
196;;; TODO:
66 197
67;;; Code: 198;;; Code:
68 199
69(require 'comint)
70(require 'ansi-color) 200(require 'ansi-color)
201(require 'comint)
202
203(eval-when-compile
204 (require 'cl)
205 ;; Avoid compiler warnings
206 (defvar view-return-to-alist)
207 (defvar compilation-error-regexp-alist)
208 (defvar outline-heading-end-regexp))
71 209
72(eval-when-compile (require 'compile)) 210(autoload 'comint-mode "comint")
211
212;;;###autoload
213(add-to-list 'auto-mode-alist (cons (purecopy "\\.py\\'") 'python-mode))
214;;;###autoload
215(add-to-list 'interpreter-mode-alist (cons (purecopy "python") 'python-mode))
73 216
74(defgroup python nil 217(defgroup python nil
75 "Silly walks in the Python language." 218 "Python Language's flying circus support for Emacs."
76 :group 'languages 219 :group 'languages
77 :version "22.1" 220 :version "23.2"
78 :link '(emacs-commentary-link "python")) 221 :link '(emacs-commentary-link "python"))
222
79 223
80;;;###autoload 224;;; Bindings
81(add-to-list 'interpreter-mode-alist (cons (purecopy "jython") 'jython-mode)) 225
82;;;###autoload 226(defvar python-mode-map
83(add-to-list 'interpreter-mode-alist (cons (purecopy "python") 'python-mode)) 227 (let ((map (make-sparse-keymap)))
84;;;###autoload 228 ;; Movement
85(add-to-list 'auto-mode-alist (cons (purecopy "\\.py\\'") 'python-mode)) 229 (substitute-key-definition 'backward-sentence
230 'python-nav-backward-block
231 map global-map)
232 (substitute-key-definition 'forward-sentence
233 'python-nav-forward-block
234 map global-map)
235 (define-key map "\C-c\C-j" 'imenu)
236 ;; Indent specific
237 (define-key map "\177" 'python-indent-dedent-line-backspace)
238 (define-key map (kbd "<backtab>") 'python-indent-dedent-line)
239 (define-key map "\C-c<" 'python-indent-shift-left)
240 (define-key map "\C-c>" 'python-indent-shift-right)
241 (define-key map ":" 'python-indent-electric-colon)
242 ;; Skeletons
243 (define-key map "\C-c\C-tc" 'python-skeleton-class)
244 (define-key map "\C-c\C-td" 'python-skeleton-def)
245 (define-key map "\C-c\C-tf" 'python-skeleton-for)
246 (define-key map "\C-c\C-ti" 'python-skeleton-if)
247 (define-key map "\C-c\C-tt" 'python-skeleton-try)
248 (define-key map "\C-c\C-tw" 'python-skeleton-while)
249 ;; Shell interaction
250 (define-key map "\C-c\C-s" 'python-shell-send-string)
251 (define-key map "\C-c\C-r" 'python-shell-send-region)
252 (define-key map "\C-\M-x" 'python-shell-send-defun)
253 (define-key map "\C-c\C-c" 'python-shell-send-buffer)
254 (define-key map "\C-c\C-l" 'python-shell-send-file)
255 (define-key map "\C-c\C-z" 'python-shell-switch-to-shell)
256 ;; Some util commands
257 (define-key map "\C-c\C-v" 'python-check)
258 (define-key map "\C-c\C-f" 'python-eldoc-at-point)
259 ;; Utilities
260 (substitute-key-definition 'complete-symbol 'completion-at-point
261 map global-map)
262 (easy-menu-define python-menu map "Python Mode menu"
263 `("Python"
264 :help "Python-specific Features"
265 ["Shift region left" python-indent-shift-left :active mark-active
266 :help "Shift region left by a single indentation step"]
267 ["Shift region right" python-indent-shift-right :active mark-active
268 :help "Shift region right by a single indentation step"]
269 "-"
270 ["Start of def/class" beginning-of-defun
271 :help "Go to start of outermost definition around point"]
272 ["End of def/class" end-of-defun
273 :help "Go to end of definition around point"]
274 ["Mark def/class" mark-defun
275 :help "Mark outermost definition around point"]
276 ["Jump to def/class" imenu
277 :help "Jump to a class or function definition"]
278 "--"
279 ("Skeletons")
280 "---"
281 ["Start interpreter" run-python
282 :help "Run inferior Python process in a separate buffer"]
283 ["Switch to shell" python-shell-switch-to-shell
284 :help "Switch to running inferior Python process"]
285 ["Eval string" python-shell-send-string
286 :help "Eval string in inferior Python session"]
287 ["Eval buffer" python-shell-send-buffer
288 :help "Eval buffer in inferior Python session"]
289 ["Eval region" python-shell-send-region
290 :help "Eval region in inferior Python session"]
291 ["Eval defun" python-shell-send-defun
292 :help "Eval defun in inferior Python session"]
293 ["Eval file" python-shell-send-file
294 :help "Eval file in inferior Python session"]
295 ["Debugger" pdb :help "Run pdb under GUD"]
296 "----"
297 ["Check file" python-check
298 :help "Check file for errors"]
299 ["Help on symbol" python-eldoc-at-point
300 :help "Get help on symbol at point"]
301 ["Complete symbol" completion-at-point
302 :help "Complete symbol before point"]))
303 map)
304 "Keymap for `python-mode'.")
305
86 306
87;;;; Font lock 307;;; Python specialized rx
308
309(eval-when-compile
310 (defconst python-rx-constituents
311 `((block-start . ,(rx symbol-start
312 (or "def" "class" "if" "elif" "else" "try"
313 "except" "finally" "for" "while" "with")
314 symbol-end))
315 (decorator . ,(rx line-start (* space) ?@ (any letter ?_)
316 (* (any word ?_))))
317 (defun . ,(rx symbol-start (or "def" "class") symbol-end))
318 (if-name-main . ,(rx line-start "if" (+ space) "__name__"
319 (+ space) "==" (+ space)
320 (any ?' ?\") "__main__" (any ?' ?\")
321 (* space) ?:))
322 (symbol-name . ,(rx (any letter ?_) (* (any word ?_))))
323 (open-paren . ,(rx (or "{" "[" "(")))
324 (close-paren . ,(rx (or "}" "]" ")")))
325 (simple-operator . ,(rx (any ?+ ?- ?/ ?& ?^ ?~ ?| ?* ?< ?> ?= ?%)))
326 ;; FIXME: rx should support (not simple-operator).
327 (not-simple-operator . ,(rx
328 (not
329 (any ?+ ?- ?/ ?& ?^ ?~ ?| ?* ?< ?> ?= ?%))))
330 ;; FIXME: Use regexp-opt.
331 (operator . ,(rx (or "+" "-" "/" "&" "^" "~" "|" "*" "<" ">"
332 "=" "%" "**" "//" "<<" ">>" "<=" "!="
333 "==" ">=" "is" "not")))
334 ;; FIXME: Use regexp-opt.
335 (assignment-operator . ,(rx (or "=" "+=" "-=" "*=" "/=" "//=" "%=" "**="
336 ">>=" "<<=" "&=" "^=" "|="))))
337 "Additional Python specific sexps for `python-rx'"))
338
339(defmacro python-rx (&rest regexps)
340 "Python mode specialized rx macro.
341This variant of `rx' supports common python named REGEXPS."
342 (let ((rx-constituents (append python-rx-constituents rx-constituents)))
343 (cond ((null regexps)
344 (error "No regexp"))
345 ((cdr regexps)
346 (rx-to-string `(and ,@regexps) t))
347 (t
348 (rx-to-string (car regexps) t)))))
88 349
350
351;;; Font-lock and syntax
89(defvar python-font-lock-keywords 352(defvar python-font-lock-keywords
353 ;; Keywords
90 `(,(rx symbol-start 354 `(,(rx symbol-start
91 ;; From v 2.7 reference, § keywords. 355 (or
92 ;; def and class dealt with separately below 356 "and" "del" "from" "not" "while" "as" "elif" "global" "or" "with"
93 (or "and" "as" "assert" "break" "continue" "del" "elif" "else" 357 "assert" "else" "if" "pass" "yield" "break" "except" "import" "class"
94 "except" "exec" "finally" "for" "from" "global" "if" 358 "in" "raise" "continue" "finally" "is" "return" "def" "for" "lambda"
95 "import" "in" "is" "lambda" "not" "or" "pass" "print" 359 "try"
96 "raise" "return" "try" "while" "with" "yield" 360 ;; Python 2:
97 ;; Not real keywords, but close enough to be fontified as such 361 "print" "exec"
98 "self" "True" "False" 362 ;; Python 3:
99 ;; Python 3 363 ;; False, None, and True are listed as keywords on the Python 3
100 "nonlocal") 364 ;; documentation, but since they also qualify as constants they are
101 symbol-end) 365 ;; fontified like that in order to keep font-lock consistent between
102 (,(rx symbol-start "None" symbol-end) ; see § Keywords in 2.7 manual 366 ;; Python versions.
103 . font-lock-constant-face) 367 "nonlocal"
104 ;; Definitions 368 ;; Extra:
105 (,(rx symbol-start (group "class") (1+ space) (group (1+ (or word ?_)))) 369 "self")
106 (1 font-lock-keyword-face) (2 font-lock-type-face)) 370 symbol-end)
107 (,(rx symbol-start (group "def") (1+ space) (group (1+ (or word ?_)))) 371 ;; functions
108 (1 font-lock-keyword-face) (2 font-lock-function-name-face)) 372 (,(rx symbol-start "def" (1+ space) (group (1+ (or word ?_))))
109 ;; Top-level assignments are worth highlighting. 373 (1 font-lock-function-name-face))
110 (,(rx line-start (group (1+ (or word ?_))) (0+ space) 374 ;; classes
111 (opt (or "+" "-" "*" "**" "/" "//" "&" "%" "|" "^" "<<" ">>")) "=") 375 (,(rx symbol-start "class" (1+ space) (group (1+ (or word ?_))))
112 (1 font-lock-variable-name-face)) 376 (1 font-lock-type-face))
377 ;; Constants
378 (,(rx symbol-start
379 (or
380 "Ellipsis" "False" "None" "NotImplemented" "True" "__debug__"
381 ;; copyright, license, credits, quit and exit are added by the site
382 ;; module and they are not intended to be used in programs
383 "copyright" "credits" "exit" "license" "quit")
384 symbol-end) . font-lock-constant-face)
113 ;; Decorators. 385 ;; Decorators.
114 (,(rx line-start (* (any " \t")) (group "@" (1+ (or word ?_)) 386 (,(rx line-start (* (any " \t")) (group "@" (1+ (or word ?_))
115 (0+ "." (1+ (or word ?_))))) 387 (0+ "." (1+ (or word ?_)))))
116 (1 font-lock-type-face)) 388 (1 font-lock-type-face))
117 ;; Built-ins. (The next three blocks are from 389 ;; Builtin Exceptions
118 ;; `__builtin__.__dict__.keys()' in Python 2.7) These patterns 390 (,(rx symbol-start
119 ;; are debatable, but they at least help to spot possible 391 (or
120 ;; shadowing of builtins. 392 "ArithmeticError" "AssertionError" "AttributeError" "BaseException"
121 (,(rx symbol-start (or 393 "DeprecationWarning" "EOFError" "EnvironmentError" "Exception"
122 ;; exceptions 394 "FloatingPointError" "FutureWarning" "GeneratorExit" "IOError"
123 "ArithmeticError" "AssertionError" "AttributeError" 395 "ImportError" "ImportWarning" "IndexError" "KeyError"
124 "BaseException" "DeprecationWarning" "EOFError" 396 "KeyboardInterrupt" "LookupError" "MemoryError" "NameError"
125 "EnvironmentError" "Exception" "FloatingPointError" 397 "NotImplementedError" "OSError" "OverflowError"
126 "FutureWarning" "GeneratorExit" "IOError" "ImportError" 398 "PendingDeprecationWarning" "ReferenceError" "RuntimeError"
127 "ImportWarning" "IndentationError" "IndexError" "KeyError" 399 "RuntimeWarning" "StopIteration" "SyntaxError" "SyntaxWarning"
128 "KeyboardInterrupt" "LookupError" "MemoryError" "NameError" 400 "SystemError" "SystemExit" "TypeError" "UnboundLocalError"
129 "NotImplemented" "NotImplementedError" "OSError" 401 "UnicodeDecodeError" "UnicodeEncodeError" "UnicodeError"
130 "OverflowError" "PendingDeprecationWarning" "ReferenceError" 402 "UnicodeTranslateError" "UnicodeWarning" "UserWarning" "VMSError"
131 "RuntimeError" "RuntimeWarning" "StandardError" 403 "ValueError" "Warning" "WindowsError" "ZeroDivisionError"
132 "StopIteration" "SyntaxError" "SyntaxWarning" "SystemError" 404 ;; Python 2:
133 "SystemExit" "TabError" "TypeError" "UnboundLocalError" 405 "StandardError"
134 "UnicodeDecodeError" "UnicodeEncodeError" "UnicodeError" 406 ;; Python 3:
135 "UnicodeTranslateError" "UnicodeWarning" "UserWarning" 407 "BufferError" "BytesWarning" "IndentationError" "ResourceWarning"
136 "ValueError" "Warning" "ZeroDivisionError" 408 "TabError")
137 ;; Python 2.7 409 symbol-end) . font-lock-type-face)
138 "BufferError" "BytesWarning" "WindowsError") symbol-end) 410 ;; Builtins
139 . font-lock-type-face) 411 (,(rx symbol-start
140 (,(rx (or line-start (not (any ". \t"))) (* (any " \t")) symbol-start 412 (or
141 (group (or 413 "abs" "all" "any" "bin" "bool" "callable" "chr" "classmethod"
142 ;; callable built-ins, fontified when not appearing as 414 "compile" "complex" "delattr" "dict" "dir" "divmod" "enumerate"
143 ;; object attributes 415 "eval" "filter" "float" "format" "frozenset" "getattr" "globals"
144 "abs" "all" "any" "apply" "basestring" "bool" "buffer" "callable" 416 "hasattr" "hash" "help" "hex" "id" "input" "int" "isinstance"
145 "chr" "classmethod" "cmp" "coerce" "compile" "complex" 417 "issubclass" "iter" "len" "list" "locals" "map" "max" "memoryview"
146 "copyright" "credits" "delattr" "dict" "dir" "divmod" 418 "min" "next" "object" "oct" "open" "ord" "pow" "print" "property"
147 "enumerate" "eval" "execfile" "exit" "file" "filter" "float" 419 "range" "repr" "reversed" "round" "set" "setattr" "slice" "sorted"
148 "frozenset" "getattr" "globals" "hasattr" "hash" "help" 420 "staticmethod" "str" "sum" "super" "tuple" "type" "vars" "zip"
149 "hex" "id" "input" "int" "intern" "isinstance" "issubclass" 421 "__import__"
150 "iter" "len" "license" "list" "locals" "long" "map" "max" 422 ;; Python 2:
151 "min" "object" "oct" "open" "ord" "pow" "property" "quit" 423 "basestring" "cmp" "execfile" "file" "long" "raw_input" "reduce"
152 "range" "raw_input" "reduce" "reload" "repr" "reversed" 424 "reload" "unichr" "unicode" "xrange" "apply" "buffer" "coerce"
153 "round" "set" "setattr" "slice" "sorted" "staticmethod" 425 "intern"
154 "str" "sum" "super" "tuple" "type" "unichr" "unicode" "vars" 426 ;; Python 3:
155 "xrange" "zip" 427 "ascii" "bytearray" "bytes" "exec"
156 ;; Python 2.7. 428 ;; Extra:
157 "bin" "bytearray" "bytes" "format" "memoryview" "next" "print" 429 "__all__" "__doc__" "__name__" "__package__")
158 )) symbol-end) 430 symbol-end) . font-lock-builtin-face)
159 (1 font-lock-builtin-face)) 431 ;; assignments
160 (,(rx symbol-start (or 432 ;; support for a = b = c = 5
161 ;; other built-ins 433 (,(lambda (limit)
162 "True" "False" "None" "Ellipsis" 434 (let ((re (python-rx (group (+ (any word ?. ?_)))
163 "_" "__debug__" "__doc__" "__import__" "__name__" "__package__") 435 (? ?\[ (+ (not (any ?\]))) ?\]) (* space)
164 symbol-end) 436 assignment-operator)))
165 . font-lock-builtin-face))) 437 (when (re-search-forward re limit t)
438 (while (and (python-info-ppss-context 'paren)
439 (re-search-forward re limit t)))
440 (if (and (not (python-info-ppss-context 'paren))
441 (not (equal (char-after (point-marker)) ?=)))
442 t
443 (set-match-data nil)))))
444 (1 font-lock-variable-name-face nil nil))
445 ;; support for a, b, c = (1, 2, 3)
446 (,(lambda (limit)
447 (let ((re (python-rx (group (+ (any word ?. ?_))) (* space)
448 (* ?, (* space) (+ (any word ?. ?_)) (* space))
449 ?, (* space) (+ (any word ?. ?_)) (* space)
450 assignment-operator)))
451 (when (and (re-search-forward re limit t)
452 (goto-char (nth 3 (match-data))))
453 (while (and (python-info-ppss-context 'paren)
454 (re-search-forward re limit t))
455 (goto-char (nth 3 (match-data))))
456 (if (not (python-info-ppss-context 'paren))
457 t
458 (set-match-data nil)))))
459 (1 font-lock-variable-name-face nil nil))))
166 460
167(defconst python-syntax-propertize-function 461(defconst python-syntax-propertize-function
168 ;; Make outer chars of matching triple-quote sequences into generic 462 ;; Make outer chars of matching triple-quote sequences into generic
169 ;; string delimiters. Fixme: Is there a better way? 463 ;; string delimiters. Fixme: Is there a better way?
170 ;; First avoid a sequence preceded by an odd number of backslashes. 464 ;; First avoid a sequence preceded by an odd number of backslashes.
171 (syntax-propertize-rules 465 (syntax-propertize-rules
172 (;; ¡Backrefs don't work in syntax-propertize-rules! 466 (;; ¡Backrefs don't work in syntax-propertize-rules!
173 (concat "\\(?:\\([RUru]\\)[Rr]?\\|^\\|[^\\]\\(?:\\\\.\\)*\\)" ;Prefix. 467 (concat "\\(?:\\([RUru]\\)[Rr]?\\|^\\|[^\\]\\(?:\\\\.\\)*\\)" ;Prefix.
174 "\\(?:\\('\\)'\\('\\)\\|\\(?2:\"\\)\"\\(?3:\"\\)\\)") 468 "\\(?:\\('\\)'\\('\\)\\|\\(?2:\"\\)\"\\(?3:\"\\)\\)")
175 (3 (ignore (python-quote-syntax)))) 469 (3 (ignore (python-quote-syntax))))))
176 ;; This doesn't really help.
177 ;;((rx (and ?\\ (group ?\n))) (1 " "))
178 ))
179 470
180(defun python-quote-syntax () 471(defun python-quote-syntax ()
181 "Put `syntax-table' property correctly on triple quote. 472 "Put `syntax-table' property correctly on triple quote.
@@ -199,8 +490,8 @@ Used for syntactic keywords. N is the match number (1, 2 or 3)."
199 (cond 490 (cond
200 ((eq t (nth 3 syntax)) ; after unclosed fence 491 ((eq t (nth 3 syntax)) ; after unclosed fence
201 ;; Consider property for the last char if in a fenced string. 492 ;; Consider property for the last char if in a fenced string.
202 (goto-char (nth 8 syntax)) ; fence position 493 (goto-char (nth 8 syntax)) ; fence position
203 (skip-chars-forward "uUrR") ; skip any prefix 494 (skip-chars-forward "uUrR") ; skip any prefix
204 ;; Is it a matching sequence? 495 ;; Is it a matching sequence?
205 (if (eq (char-after) (char-after (match-beginning 2))) 496 (if (eq (char-after) (char-after (match-beginning 2)))
206 (put-text-property (match-beginning 3) (match-end 3) 497 (put-text-property (match-beginning 3) (match-end 3)
@@ -215,125 +506,16 @@ Used for syntactic keywords. N is the match number (1, 2 or 3)."
215 'syntax-table (string-to-syntax "|")))) 506 'syntax-table (string-to-syntax "|"))))
216 ))) 507 )))
217 508
218;; This isn't currently in `font-lock-defaults' as probably not worth
219;; it -- we basically only mess with a few normally-symbol characters.
220
221;; (defun python-font-lock-syntactic-face-function (state)
222;; "`font-lock-syntactic-face-function' for Python mode.
223;; Returns the string or comment face as usual, with side effect of putting
224;; a `syntax-table' property on the inside of the string or comment which is
225;; the standard syntax table."
226;; (if (nth 3 state)
227;; (save-excursion
228;; (goto-char (nth 8 state))
229;; (condition-case nil
230;; (forward-sexp)
231;; (error nil))
232;; (put-text-property (1+ (nth 8 state)) (1- (point))
233;; 'syntax-table (standard-syntax-table))
234;; 'font-lock-string-face)
235;; (put-text-property (1+ (nth 8 state)) (line-end-position)
236;; 'syntax-table (standard-syntax-table))
237;; 'font-lock-comment-face))
238
239;;;; Keymap and syntax
240
241(defvar python-mode-map
242 (let ((map (make-sparse-keymap)))
243 ;; Mostly taken from python-mode.el.
244 (define-key map ":" 'python-electric-colon)
245 (define-key map "\177" 'python-backspace)
246 (define-key map "\C-c<" 'python-shift-left)
247 (define-key map "\C-c>" 'python-shift-right)
248 (define-key map "\C-c\C-k" 'python-mark-block)
249 (define-key map "\C-c\C-d" 'python-pdbtrack-toggle-stack-tracking)
250 (define-key map "\C-c\C-n" 'python-next-statement)
251 (define-key map "\C-c\C-p" 'python-previous-statement)
252 (define-key map "\C-c\C-u" 'python-beginning-of-block)
253 (define-key map "\C-c\C-f" 'python-describe-symbol)
254 (define-key map "\C-c\C-w" 'python-check)
255 (define-key map "\C-c\C-v" 'python-check) ; a la sgml-mode
256 (define-key map "\C-c\C-s" 'python-send-string)
257 (define-key map [?\C-\M-x] 'python-send-defun)
258 (define-key map "\C-c\C-r" 'python-send-region)
259 (define-key map "\C-c\M-r" 'python-send-region-and-go)
260 (define-key map "\C-c\C-c" 'python-send-buffer)
261 (define-key map "\C-c\C-z" 'python-switch-to-python)
262 (define-key map "\C-c\C-m" 'python-load-file)
263 (define-key map "\C-c\C-l" 'python-load-file) ; a la cmuscheme
264 (substitute-key-definition 'complete-symbol 'completion-at-point
265 map global-map)
266 (define-key map "\C-c\C-i" 'python-find-imports)
267 (define-key map "\C-c\C-t" 'python-expand-template)
268 (easy-menu-define python-menu map "Python Mode menu"
269 `("Python"
270 :help "Python-specific Features"
271 ["Shift region left" python-shift-left :active mark-active
272 :help "Shift by a single indentation step"]
273 ["Shift region right" python-shift-right :active mark-active
274 :help "Shift by a single indentation step"]
275 "-"
276 ["Mark block" python-mark-block
277 :help "Mark innermost block around point"]
278 ["Mark def/class" mark-defun
279 :help "Mark innermost definition around point"]
280 "-"
281 ["Start of block" python-beginning-of-block
282 :help "Go to start of innermost definition around point"]
283 ["End of block" python-end-of-block
284 :help "Go to end of innermost definition around point"]
285 ["Start of def/class" beginning-of-defun
286 :help "Go to start of innermost definition around point"]
287 ["End of def/class" end-of-defun
288 :help "Go to end of innermost definition around point"]
289 "-"
290 ("Templates..."
291 :help "Expand templates for compound statements"
292 :filter (lambda (&rest junk)
293 (abbrev-table-menu python-mode-abbrev-table)))
294 "-"
295 ["Start interpreter" run-python
296 :help "Run `inferior' Python in separate buffer"]
297 ["Import/reload file" python-load-file
298 :help "Load into inferior Python session"]
299 ["Eval buffer" python-send-buffer
300 :help "Evaluate buffer en bloc in inferior Python session"]
301 ["Eval region" python-send-region :active mark-active
302 :help "Evaluate region en bloc in inferior Python session"]
303 ["Eval def/class" python-send-defun
304 :help "Evaluate current definition in inferior Python session"]
305 ["Switch to interpreter" python-switch-to-python
306 :help "Switch to inferior Python buffer"]
307 ["Set default process" python-set-proc
308 :help "Make buffer's inferior process the default"
309 :active (buffer-live-p python-buffer)]
310 ["Check file" python-check :help "Run pychecker"]
311 ["Debugger" pdb :help "Run pdb under GUD"]
312 "-"
313 ["Help on symbol" python-describe-symbol
314 :help "Use pydoc on symbol at point"]
315 ["Complete symbol" completion-at-point
316 :help "Complete (qualified) symbol before point"]
317 ["Find function" python-find-function
318 :help "Try to find source definition of function at point"]
319 ["Update imports" python-find-imports
320 :help "Update list of top-level imports for completion"]))
321 map))
322;; Fixme: add toolbar stuff for useful things like symbol help, send
323;; region, at least. (Shouldn't be specific to Python, obviously.)
324;; eric has items including: (un)indent, (un)comment, restart script,
325;; run script, debug script; also things for profiling, unit testing.
326
327(defvar python-mode-syntax-table 509(defvar python-mode-syntax-table
328 (let ((table (make-syntax-table))) 510 (let ((table (make-syntax-table)))
329 ;; Give punctuation syntax to ASCII that normally has symbol 511 ;; Give punctuation syntax to ASCII that normally has symbol
330 ;; syntax or has word syntax and isn't a letter. 512 ;; syntax or has word syntax and isn't a letter.
331 (let ((symbol (string-to-syntax "_")) 513 (let ((symbol (string-to-syntax "_"))
332 (sst (standard-syntax-table))) 514 (sst (standard-syntax-table)))
333 (dotimes (i 128) 515 (dotimes (i 128)
334 (unless (= i ?_) 516 (unless (= i ?_)
335 (if (equal symbol (aref sst i)) 517 (if (equal symbol (aref sst i))
336 (modify-syntax-entry i "." table))))) 518 (modify-syntax-entry i "." table)))))
337 (modify-syntax-entry ?$ "." table) 519 (modify-syntax-entry ?$ "." table)
338 (modify-syntax-entry ?% "." table) 520 (modify-syntax-entry ?% "." table)
339 ;; exceptions 521 ;; exceptions
@@ -341,1875 +523,1715 @@ Used for syntactic keywords. N is the match number (1, 2 or 3)."
341 (modify-syntax-entry ?\n ">" table) 523 (modify-syntax-entry ?\n ">" table)
342 (modify-syntax-entry ?' "\"" table) 524 (modify-syntax-entry ?' "\"" table)
343 (modify-syntax-entry ?` "$" table) 525 (modify-syntax-entry ?` "$" table)
344 table))
345
346;;;; Utility stuff
347
348(defsubst python-in-string/comment ()
349 "Return non-nil if point is in a Python literal (a comment or string)."
350 ;; We don't need to save the match data.
351 (nth 8 (syntax-ppss)))
352
353(defconst python-space-backslash-table
354 (let ((table (copy-syntax-table python-mode-syntax-table)))
355 (modify-syntax-entry ?\\ " " table)
356 table) 526 table)
357 "`python-mode-syntax-table' with backslash given whitespace syntax.") 527 "Syntax table for Python files.")
358
359(defun python-skip-comments/blanks (&optional backward)
360 "Skip comments and blank lines.
361BACKWARD non-nil means go backwards, otherwise go forwards.
362Backslash is treated as whitespace so that continued blank lines
363are skipped. Doesn't move out of comments -- should be outside
364or at end of line."
365 (let ((arg (if backward
366 ;; If we're in a comment (including on the trailing
367 ;; newline), forward-comment doesn't move backwards out
368 ;; of it. Don't set the syntax table round this bit!
369 (let ((syntax (syntax-ppss)))
370 (if (nth 4 syntax)
371 (goto-char (nth 8 syntax)))
372 (- (point-max)))
373 (point-max))))
374 (with-syntax-table python-space-backslash-table
375 (forward-comment arg))))
376
377(defun python-backslash-continuation-line-p ()
378 "Non-nil if preceding line ends with backslash that is not in a comment."
379 (and (eq ?\\ (char-before (line-end-position 0)))
380 (not (syntax-ppss-context (syntax-ppss)))))
381
382(defun python-continuation-line-p ()
383 "Return non-nil if current line continues a previous one.
384The criteria are that the previous line ends in a backslash outside
385comments and strings, or that point is within brackets/parens."
386 (or (python-backslash-continuation-line-p)
387 (let ((depth (syntax-ppss-depth
388 (save-excursion ; syntax-ppss with arg changes point
389 (syntax-ppss (line-beginning-position))))))
390 (or (> depth 0)
391 (if (< depth 0) ; Unbalanced brackets -- act locally
392 (save-excursion
393 (condition-case ()
394 (progn (backward-up-list) t) ; actually within brackets
395 (error nil))))))))
396
397(defun python-comment-line-p ()
398 "Return non-nil if and only if current line has only a comment."
399 (save-excursion
400 (end-of-line)
401 (when (eq 'comment (syntax-ppss-context (syntax-ppss)))
402 (back-to-indentation)
403 (looking-at (rx (or (syntax comment-start) line-end))))))
404 528
405(defun python-blank-line-p () 529(defvar python-dotty-syntax-table
406 "Return non-nil if and only if current line is blank." 530 (let ((table (make-syntax-table python-mode-syntax-table)))
407 (save-excursion 531 (modify-syntax-entry ?. "w" table)
408 (beginning-of-line) 532 (modify-syntax-entry ?_ "w" table)
409 (looking-at "\\s-*$"))) 533 table)
410 534 "Dotty syntax table for Python files.
411(defun python-beginning-of-string () 535It makes underscores and dots word constituent chars.")
412 "Go to beginning of string around point.
413Do nothing if not in string."
414 (let ((state (syntax-ppss)))
415 (when (eq 'string (syntax-ppss-context state))
416 (goto-char (nth 8 state)))))
417
418(defun python-open-block-statement-p (&optional bos)
419 "Return non-nil if statement at point opens a block.
420BOS non-nil means point is known to be at beginning of statement."
421 (save-excursion
422 (unless bos (python-beginning-of-statement))
423 (looking-at (rx (and (or "if" "else" "elif" "while" "for" "def"
424 "class" "try" "except" "finally" "with")
425 symbol-end)))))
426
427(defun python-close-block-statement-p (&optional bos)
428 "Return non-nil if current line is a statement closing a block.
429BOS non-nil means point is at beginning of statement.
430The criteria are that the line isn't a comment or in string and
431 starts with keyword `raise', `break', `continue' or `pass'."
432 (save-excursion
433 (unless bos (python-beginning-of-statement))
434 (back-to-indentation)
435 (looking-at (rx (or "return" "raise" "break" "continue" "pass")
436 symbol-end))))
437 536
438(defun python-outdent-p ()
439 "Return non-nil if current line should outdent a level."
440 (save-excursion
441 (back-to-indentation)
442 (and (looking-at (rx (and (or "else" "finally" "except" "elif")
443 symbol-end)))
444 (not (python-in-string/comment))
445 ;; Ensure there's a previous statement and move to it.
446 (zerop (python-previous-statement))
447 (not (python-close-block-statement-p t))
448 ;; Fixme: check this
449 (not (python-open-block-statement-p)))))
450 537
451;;;; Indentation. 538;;; Indentation
452 539
453(defcustom python-indent 4 540(defcustom python-indent-offset 4
454 "Number of columns for a unit of indentation in Python mode. 541 "Default indentation offset for Python."
455See also `\\[python-guess-indent]'"
456 :group 'python 542 :group 'python
457 :type 'integer) 543 :type 'integer
458(put 'python-indent 'safe-local-variable 'integerp) 544 :safe 'integerp)
459
460(defcustom python-guess-indent t
461 "Non-nil means Python mode guesses `python-indent' for the buffer."
462 :type 'boolean
463 :group 'python)
464
465(defcustom python-indent-string-contents t
466 "Non-nil means indent contents of multi-line strings together.
467This means indent them the same as the preceding non-blank line.
468Otherwise preserve their indentation.
469
470This only applies to `doc' strings, i.e. those that form statements;
471the indentation is preserved in others."
472 :type '(choice (const :tag "Align with preceding" t)
473 (const :tag "Preserve indentation" nil))
474 :group 'python)
475 545
476(defcustom python-honour-comment-indentation nil 546(defcustom python-indent-guess-indent-offset t
477 "Non-nil means indent relative to preceding comment line. 547 "Non-nil tells Python mode to guess `python-indent-offset' value."
478Only do this for comments where the leading comment character is
479followed by space. This doesn't apply to comment lines, which
480are always indented in lines with preceding comments."
481 :type 'boolean 548 :type 'boolean
482 :group 'python)
483
484(defcustom python-continuation-offset 4
485 "Number of columns of additional indentation for continuation lines.
486Continuation lines follow a backslash-terminated line starting a
487statement."
488 :group 'python 549 :group 'python
489 :type 'integer) 550 :safe 'booleanp)
490 551
552(define-obsolete-variable-alias
553 'python-indent 'python-indent-offset "24.2")
491 554
492(defcustom python-pdbtrack-do-tracking-p t 555(define-obsolete-variable-alias
493 "Controls whether the pdbtrack feature is enabled or not. 556 'python-guess-indent 'python-indent-guess-indent-offset "24.2")
494 557
495When non-nil, pdbtrack is enabled in all comint-based buffers, 558(defvar python-indent-current-level 0
496e.g. shell interaction buffers and the *Python* buffer. 559 "Current indentation level `python-indent-line-function' is using.")
497 560
498When using pdb to debug a Python program, pdbtrack notices the 561(defvar python-indent-levels '(0)
499pdb prompt and presents the line in the source file where the 562 "Levels of indentation available for `python-indent-line-function'.")
500program is stopped in a pop-up buffer. It's similar to what
501gud-mode does for debugging C programs with gdb, but without
502having to restart the program."
503 :type 'boolean
504 :group 'python)
505(make-variable-buffer-local 'python-pdbtrack-do-tracking-p)
506 563
507(defcustom python-pdbtrack-minor-mode-string " PDB" 564(defvar python-indent-dedenters '("else" "elif" "except" "finally")
508 "Minor-mode sign to be displayed when pdbtrack is active." 565 "List of words that should be dedented.
509 :type 'string 566These make `python-indent-calculate-indentation' subtract the value of
510 :group 'python) 567`python-indent-offset'.")
511 568
512;; Add a designator to the minor mode strings 569(defun python-indent-guess-indent-offset ()
513(or (assq 'python-pdbtrack-is-tracking-p minor-mode-alist) 570 "Guess and set `python-indent-offset' for the current buffer."
514 (push '(python-pdbtrack-is-tracking-p python-pdbtrack-minor-mode-string)
515 minor-mode-alist))
516
517(defcustom python-shell-prompt-alist
518 '(("ipython" . "^In \\[[0-9]+\\]: *")
519 (t . "^>>> "))
520 "Alist of Python input prompts.
521Each element has the form (PROGRAM . REGEXP), where PROGRAM is
522the value of `python-python-command' for the python process and
523REGEXP is a regular expression matching the Python prompt.
524PROGRAM can also be t, which specifies the default when no other
525element matches `python-python-command'."
526 :type 'string
527 :group 'python
528 :version "24.1")
529
530(defcustom python-shell-continuation-prompt-alist
531 '(("ipython" . "^ [.][.][.]+: *")
532 (t . "^[.][.][.] "))
533 "Alist of Python continued-line prompts.
534Each element has the form (PROGRAM . REGEXP), where PROGRAM is
535the value of `python-python-command' for the python process and
536REGEXP is a regular expression matching the Python prompt for
537continued lines.
538PROGRAM can also be t, which specifies the default when no other
539element matches `python-python-command'."
540 :type 'string
541 :group 'python
542 :version "24.1")
543
544(defvar python-pdbtrack-is-tracking-p nil)
545
546(defconst python-pdbtrack-stack-entry-regexp
547 "^> \\(.*\\)(\\([0-9]+\\))\\([?a-zA-Z0-9_<>]+\\)()"
548 "Regular expression pdbtrack uses to find a stack trace entry.")
549
550(defconst python-pdbtrack-input-prompt "\n[(<]*[Ii]?[Pp]db[>)]+ "
551 "Regular expression pdbtrack uses to recognize a pdb prompt.")
552
553(defconst python-pdbtrack-track-range 10000
554 "Max number of characters from end of buffer to search for stack entry.")
555
556(defun python-guess-indent ()
557 "Guess step for indentation of current buffer.
558Set `python-indent' locally to the value guessed."
559 (interactive) 571 (interactive)
560 (save-excursion 572 (save-excursion
561 (save-restriction 573 (save-restriction
562 (widen) 574 (widen)
563 (goto-char (point-min)) 575 (goto-char (point-min))
564 (let (done indent) 576 (let ((block-end))
565 (while (and (not done) (not (eobp))) 577 (while (and (not block-end)
566 (when (and (re-search-forward (rx ?: (0+ space) 578 (re-search-forward
567 (or (syntax comment-start) 579 (python-rx line-start block-start) nil t))
568 line-end)) 580 (when (and
569 nil 'move) 581 (not (python-info-ppss-context-type))
570 (python-open-block-statement-p)) 582 (progn
571 (save-excursion 583 (goto-char (line-end-position))
572 (python-beginning-of-statement) 584 (python-util-forward-comment -1)
573 (let ((initial (current-indentation))) 585 (if (equal (char-before) ?:)
574 (if (zerop (python-next-statement)) 586 t
575 (setq indent (- (current-indentation) initial))) 587 (forward-line 1)
576 (if (and indent (>= indent 2) (<= indent 8)) ; sanity check 588 (when (python-info-block-continuation-line-p)
577 (setq done t)))))) 589 (while (and (python-info-continuation-line-p)
578 (when done 590 (not (eobp)))
579 (when (/= indent (default-value 'python-indent)) 591 (forward-line 1))
580 (set (make-local-variable 'python-indent) indent) 592 (python-util-forward-comment -1)
581 (unless (= tab-width python-indent) 593 (when (equal (char-before) ?:)
582 (setq indent-tabs-mode nil))) 594 t)))))
583 indent))))) 595 (setq block-end (point-marker))))
584 596 (let ((indentation
585;; Alist of possible indentations and start of statement they would 597 (when block-end
586;; close. Used in indentation cycling (below). 598 (goto-char block-end)
587(defvar python-indent-list nil 599 (python-util-forward-comment)
588 "Internal use.") 600 (current-indentation))))
589;; Length of the above 601 (if indentation
590(defvar python-indent-list-length nil 602 (setq python-indent-offset indentation)
591 "Internal use.") 603 (message "Can't guess python-indent-offset, using defaults: %s"
592;; Current index into the alist. 604 python-indent-offset)))))))
593(defvar python-indent-index nil 605
594 "Internal use.") 606(defun python-indent-context ()
595 607 "Get information on indentation context.
596(defun python-calculate-indentation () 608Context information is returned with a cons with the form:
597 "Calculate Python indentation for line at point." 609 \(STATUS . START)
598 (setq python-indent-list nil 610
599 python-indent-list-length 1) 611Where status can be any of the following symbols:
600 (save-excursion 612 * inside-paren: If point in between (), {} or []
601 (beginning-of-line) 613 * inside-string: If point is inside a string
602 (let ((syntax (syntax-ppss)) 614 * after-backslash: Previous line ends in a backslash
603 start) 615 * after-beginning-of-block: Point is after beginning of block
604 (cond 616 * after-line: Point is after normal line
605 ((eq 'string (syntax-ppss-context syntax)) ; multi-line string 617 * no-indent: Point is at beginning of buffer or other special case
606 (if (not python-indent-string-contents) 618START is the buffer position where the sexp starts."
607 (current-indentation) 619 (save-restriction
608 ;; Only respect `python-indent-string-contents' in doc 620 (widen)
609 ;; strings (defined as those which form statements). 621 (let ((ppss (save-excursion (beginning-of-line) (syntax-ppss)))
610 (if (not (save-excursion 622 (start))
611 (python-beginning-of-statement) 623 (cons
612 (looking-at (rx (or (syntax string-delimiter) 624 (cond
613 (syntax string-quote)))))) 625 ;; Beginning of buffer
614 (current-indentation) 626 ((save-excursion
615 ;; Find indentation of preceding non-blank line within string. 627 (goto-char (line-beginning-position))
616 (setq start (nth 8 syntax)) 628 (bobp))
617 (forward-line -1) 629 'no-indent)
618 (while (and (< start (point)) (looking-at "\\s-*$")) 630 ;; Inside a paren
619 (forward-line -1)) 631 ((setq start (python-info-ppss-context 'paren ppss))
620 (current-indentation)))) 632 'inside-paren)
621 ((python-continuation-line-p) ; after backslash, or bracketed 633 ;; Inside string
622 (let ((point (point)) 634 ((setq start (python-info-ppss-context 'string ppss))
623 (open-start (cadr syntax)) 635 'inside-string)
624 (backslash (python-backslash-continuation-line-p)) 636 ;; After backslash
625 (colon (eq ?: (char-before (1- (line-beginning-position)))))) 637 ((setq start (when (not (or (python-info-ppss-context 'string ppss)
626 (if open-start 638 (python-info-ppss-context 'comment ppss)))
627 ;; Inside bracketed expression. 639 (let ((line-beg-pos (line-beginning-position)))
628 (progn 640 (when (python-info-line-ends-backslash-p
629 (goto-char (1+ open-start)) 641 (1- line-beg-pos))
630 ;; Look for first item in list (preceding point) and 642 (- line-beg-pos 2)))))
631 ;; align with it, if found. 643 'after-backslash)
632 (if (with-syntax-table python-space-backslash-table 644 ;; After beginning of block
633 (let ((parse-sexp-ignore-comments t)) 645 ((setq start (save-excursion
634 (condition-case () 646 (when (progn
635 (progn (forward-sexp) 647 (back-to-indentation)
636 (backward-sexp) 648 (python-util-forward-comment -1)
637 (< (point) point)) 649 (equal (char-before) ?:))
638 (error nil)))) 650 ;; Move to the first block start that's not in within
639 ;; Extra level if we're backslash-continued or 651 ;; a string, comment or paren and that's not a
640 ;; following a key. 652 ;; continuation line.
641 (if (or backslash colon) 653 (while (and (re-search-backward
642 (+ python-indent (current-column)) 654 (python-rx block-start) nil t)
643 (current-column)) 655 (or
644 ;; Otherwise indent relative to statement start, one 656 (python-info-ppss-context 'string)
645 ;; level per bracketing level. 657 (python-info-ppss-context 'comment)
646 (goto-char (1+ open-start)) 658 (python-info-ppss-context 'paren)
647 (python-beginning-of-statement) 659 (python-info-continuation-line-p))))
648 (+ (current-indentation) (* (car syntax) python-indent)))) 660 (when (looking-at (python-rx block-start))
649 ;; Otherwise backslash-continued. 661 (point-marker)))))
650 (forward-line -1) 662 'after-beginning-of-block)
651 (if (python-continuation-line-p) 663 ;; After normal line
652 ;; We're past first continuation line. Align with 664 ((setq start (save-excursion
653 ;; previous line. 665 (back-to-indentation)
654 (current-indentation) 666 (python-util-forward-comment -1)
655 ;; First continuation line. Indent one step, with an 667 (python-nav-statement-start)
656 ;; extra one if statement opens a block. 668 (point-marker)))
657 (python-beginning-of-statement) 669 'after-line)
658 (+ (current-indentation) python-continuation-offset 670 ;; Do not indent
659 (if (python-open-block-statement-p t) 671 (t 'no-indent))
660 python-indent 672 start))))
661 0)))))) 673
662 ((bobp) 0) 674(defun python-indent-calculate-indentation ()
663 ;; Fixme: Like python-mode.el; not convinced by this. 675 "Calculate correct indentation offset for the current line."
664 ((looking-at (rx (0+ space) (syntax comment-start) 676 (let* ((indentation-context (python-indent-context))
665 (not (any " \t\n")))) ; non-indentable comment 677 (context-status (car indentation-context))
666 (current-indentation)) 678 (context-start (cdr indentation-context)))
667 ((and python-honour-comment-indentation 679 (save-restriction
668 ;; Back over whitespace, newlines, non-indentable comments. 680 (widen)
669 (catch 'done 681 (save-excursion
670 (while (cond ((bobp) nil) 682 (case context-status
671 ((not (forward-comment -1)) 683 ('no-indent 0)
672 nil) ; not at comment start 684 ;; When point is after beginning of block just add one level
673 ;; Now at start of comment -- trailing one? 685 ;; of indentation relative to the context-start
674 ((/= (current-column) (current-indentation)) 686 ('after-beginning-of-block
675 nil) 687 (goto-char context-start)
676 ;; Indentable comment, like python-mode.el? 688 (+ (current-indentation) python-indent-offset))
677 ((and (looking-at (rx (syntax comment-start) 689 ;; When after a simple line just use previous line
678 (or space line-end))) 690 ;; indentation, in the case current line starts with a
679 (/= 0 (current-column))) 691 ;; `python-indent-dedenters' de-indent one level.
680 (throw 'done (current-column))) 692 ('after-line
681 ;; Else skip it (loop). 693 (-
682 (t)))))) 694 (save-excursion
683 (t 695 (goto-char context-start)
684 (python-indentation-levels) 696 (current-indentation))
685 ;; Prefer to indent comments with an immediately-following 697 (if (progn
686 ;; statement, e.g. 698 (back-to-indentation)
687 ;; ... 699 (looking-at (regexp-opt python-indent-dedenters)))
688 ;; # ... 700 python-indent-offset
689 ;; def ... 701 0)))
690 (when (and (> python-indent-list-length 1) 702 ;; When inside of a string, do nothing. just use the current
691 (python-comment-line-p)) 703 ;; indentation. XXX: perhaps it would be a good idea to
692 (forward-line) 704 ;; invoke standard text indentation here
693 (unless (python-comment-line-p) 705 ('inside-string
694 (let ((elt (assq (current-indentation) python-indent-list))) 706 (goto-char context-start)
695 (setq python-indent-list 707 (current-indentation))
696 (nconc (delete elt python-indent-list) 708 ;; After backslash we have several possibilities.
697 (list elt)))))) 709 ('after-backslash
698 (caar (last python-indent-list))))))) 710 (cond
699 711 ;; Check if current line is a dot continuation. For this
700;;;; Cycling through the possible indentations with successive TABs. 712 ;; the current line must start with a dot and previous
701 713 ;; line must contain a dot too.
702;; These don't need to be buffer-local since they're only relevant 714 ((save-excursion
703;; during a cycle. 715 (back-to-indentation)
704 716 (when (looking-at "\\.")
705(defun python-initial-text () 717 ;; If after moving one line back point is inside a paren it
706 "Text of line following indentation and ignoring any trailing comment." 718 ;; needs to move back until it's not anymore
707 (save-excursion 719 (while (prog2
708 (buffer-substring (progn 720 (forward-line -1)
709 (back-to-indentation) 721 (and (not (bobp))
710 (point)) 722 (python-info-ppss-context 'paren))))
711 (progn 723 (goto-char (line-end-position))
712 (end-of-line) 724 (while (and (re-search-backward
713 (forward-comment -1) 725 "\\." (line-beginning-position) t)
714 (point))))) 726 (or (python-info-ppss-context 'comment)
715 727 (python-info-ppss-context 'string)
716(defconst python-block-pairs 728 (python-info-ppss-context 'paren))))
717 '(("else" "if" "elif" "while" "for" "try" "except") 729 (if (and (looking-at "\\.")
718 ("elif" "if" "elif") 730 (not (or (python-info-ppss-context 'comment)
719 ("except" "try" "except") 731 (python-info-ppss-context 'string)
720 ("finally" "else" "try" "except")) 732 (python-info-ppss-context 'paren))))
721 "Alist of keyword matches. 733 ;; The indentation is the same column of the
722The car of an element is a keyword introducing a statement which 734 ;; first matching dot that's not inside a
723can close a block opened by a keyword in the cdr.") 735 ;; comment, a string or a paren
724 736 (current-column)
725(defun python-first-word () 737 ;; No dot found on previous line, just add another
726 "Return first word (actually symbol) on the line." 738 ;; indentation level.
727 (save-excursion 739 (+ (current-indentation) python-indent-offset)))))
728 (back-to-indentation) 740 ;; Check if prev line is a block continuation
729 (current-word t))) 741 ((let ((block-continuation-start
730 742 (python-info-block-continuation-line-p)))
731(defun python-indentation-levels () 743 (when block-continuation-start
732 "Return a list of possible indentations for this line. 744 ;; If block-continuation-start is set jump to that
733It is assumed not to be a continuation line or in a multi-line string. 745 ;; marker and use first column after the block start
734Includes the default indentation and those which would close all 746 ;; as indentation value.
735enclosing blocks. Elements of the list are actually pairs: 747 (goto-char block-continuation-start)
736\(INDENTATION . TEXT), where TEXT is the initial text of the 748 (re-search-forward
737corresponding block opening (or nil)." 749 (python-rx block-start (* space))
738 (save-excursion 750 (line-end-position) t)
739 (let ((initial "") 751 (current-column))))
740 levels indent) 752 ;; Check if current line is an assignment continuation
741 ;; Only one possibility immediately following a block open 753 ((let ((assignment-continuation-start
742 ;; statement, assuming it doesn't have a `suite' on the same line. 754 (python-info-assignment-continuation-line-p)))
743 (cond 755 (when assignment-continuation-start
744 ((save-excursion (and (python-previous-statement) 756 ;; If assignment-continuation is set jump to that
745 (python-open-block-statement-p t) 757 ;; marker and use first column after the assignment
746 (setq indent (current-indentation)) 758 ;; operator as indentation value.
747 ;; Check we don't have something like: 759 (goto-char assignment-continuation-start)
748 ;; if ...: ... 760 (current-column))))
749 (if (progn (python-end-of-statement) 761 (t
750 (python-skip-comments/blanks t) 762 (forward-line -1)
751 (eq ?: (char-before))) 763 (goto-char (python-info-beginning-of-backslash))
752 (setq indent (+ python-indent indent))))) 764 (if (save-excursion
753 (push (cons indent initial) levels)) 765 (and
754 ;; Only one possibility for comment line immediately following 766 (forward-line -1)
755 ;; another. 767 (goto-char
756 ((save-excursion 768 (or (python-info-beginning-of-backslash) (point)))
757 (when (python-comment-line-p) 769 (python-info-line-ends-backslash-p)))
758 (forward-line -1) 770 ;; The two previous lines ended in a backslash so we must
759 (if (python-comment-line-p) 771 ;; respect previous line indentation.
760 (push (cons (current-indentation) initial) levels))))) 772 (current-indentation)
761 ;; Fixme: Maybe have a case here which indents (only) first 773 ;; What happens here is that we are dealing with the second
762 ;; line after a lambda. 774 ;; line of a backslash continuation, in that case we just going
763 (t 775 ;; to add one indentation level.
764 (let ((start (car (assoc (python-first-word) python-block-pairs)))) 776 (+ (current-indentation) python-indent-offset)))))
765 (python-previous-statement) 777 ;; When inside a paren there's a need to handle nesting
766 ;; Is this a valid indentation for the line of interest? 778 ;; correctly
767 (unless (or (if start ; potentially only outdentable 779 ('inside-paren
768 ;; Check for things like: 780 (cond
769 ;; if ...: ... 781 ;; If current line closes the outermost open paren use the
770 ;; else ...: 782 ;; current indentation of the context-start line.
771 ;; where the second line need not be outdented. 783 ((save-excursion
772 (not (member (python-first-word) 784 (skip-syntax-forward "\s" (line-end-position))
773 (cdr (assoc start 785 (when (and (looking-at (regexp-opt '(")" "]" "}")))
774 python-block-pairs))))) 786 (progn
775 ;; Not sensible to indent to the same level as 787 (forward-char 1)
776 ;; previous `return' &c. 788 (not (python-info-ppss-context 'paren))))
777 (python-close-block-statement-p)) 789 (goto-char context-start)
778 (push (cons (current-indentation) (python-initial-text)) 790 (current-indentation))))
779 levels)) 791 ;; If open paren is contained on a line by itself add another
780 (while (python-beginning-of-block) 792 ;; indentation level, else look for the first word after the
781 (when (or (not start) 793 ;; opening paren and use it's column position as indentation
782 (member (python-first-word) 794 ;; level.
783 (cdr (assoc start python-block-pairs)))) 795 ((let* ((content-starts-in-newline)
784 (push (cons (current-indentation) (python-initial-text)) 796 (indent
785 levels)))))) 797 (save-excursion
786 (prog1 (or levels (setq levels '((0 . "")))) 798 (if (setq content-starts-in-newline
787 (setq python-indent-list levels 799 (progn
788 python-indent-list-length (length python-indent-list)))))) 800 (goto-char context-start)
789 801 (forward-char)
790;; This is basically what `python-indent-line' would be if we didn't 802 (save-restriction
791;; do the cycling. 803 (narrow-to-region
792(defun python-indent-line-1 (&optional leave) 804 (line-beginning-position)
793 "Subroutine of `python-indent-line'. 805 (line-end-position))
794Does non-repeated indentation. LEAVE non-nil means leave 806 (python-util-forward-comment))
795indentation if it is valid, i.e. one of the positions returned by 807 (looking-at "$")))
796`python-calculate-indentation'." 808 (+ (current-indentation) python-indent-offset)
797 (let ((target (python-calculate-indentation)) 809 (current-column)))))
798 (pos (- (point-max) (point)))) 810 ;; Adjustments
799 (if (or (= target (current-indentation)) 811 (cond
800 ;; Maybe keep a valid indentation. 812 ;; If current line closes a nested open paren de-indent one
801 (and leave python-indent-list 813 ;; level.
802 (assq (current-indentation) python-indent-list))) 814 ((progn
803 (if (< (current-column) (current-indentation)) 815 (back-to-indentation)
804 (back-to-indentation)) 816 (looking-at (regexp-opt '(")" "]" "}"))))
805 (beginning-of-line) 817 (- indent python-indent-offset))
806 (delete-horizontal-space) 818 ;; If the line of the opening paren that wraps the current
807 (indent-to target) 819 ;; line starts a block add another level of indentation to
808 (if (> (- (point-max) pos) (point)) 820 ;; follow new pep8 recommendation. See: http://ur1.ca/5rojx
809 (goto-char (- (point-max) pos)))))) 821 ((save-excursion
810 822 (when (and content-starts-in-newline
811(defun python-indent-line () 823 (progn
812 "Indent current line as Python code. 824 (goto-char context-start)
813When invoked via `indent-for-tab-command', cycle through possible 825 (back-to-indentation)
814indentations for current line. The cycle is broken by a command 826 (looking-at (python-rx block-start))))
815different from `indent-for-tab-command', i.e. successive TABs do 827 (+ indent python-indent-offset))))
816the cycling." 828 (t indent)))))))))))
817 (interactive) 829
818 (if (and (eq this-command 'indent-for-tab-command) 830(defun python-indent-calculate-levels ()
819 (eq last-command this-command)) 831 "Calculate `python-indent-levels' and reset `python-indent-current-level'."
820 (if (= 1 python-indent-list-length) 832 (let* ((indentation (python-indent-calculate-indentation))
821 (message "Sole indentation") 833 (remainder (% indentation python-indent-offset))
822 (progn (setq python-indent-index 834 (steps (/ (- indentation remainder) python-indent-offset)))
823 (% (1+ python-indent-index) python-indent-list-length)) 835 (setq python-indent-levels (list 0))
824 (beginning-of-line) 836 (dotimes (step steps)
825 (delete-horizontal-space) 837 (push (* python-indent-offset (1+ step)) python-indent-levels))
826 (indent-to (car (nth python-indent-index python-indent-list))) 838 (when (not (eq 0 remainder))
827 (if (python-block-end-p) 839 (push (+ (* python-indent-offset steps) remainder) python-indent-levels))
828 (let ((text (cdr (nth python-indent-index 840 (setq python-indent-levels (nreverse python-indent-levels))
829 python-indent-list)))) 841 (setq python-indent-current-level (1- (length python-indent-levels)))))
830 (if text 842
831 (message "Closes: %s" text)))))) 843(defun python-indent-toggle-levels ()
832 (python-indent-line-1) 844 "Toggle `python-indent-current-level' over `python-indent-levels'."
833 (setq python-indent-index (1- python-indent-list-length)))) 845 (setq python-indent-current-level (1- python-indent-current-level))
846 (when (< python-indent-current-level 0)
847 (setq python-indent-current-level (1- (length python-indent-levels)))))
848
849(defun python-indent-line (&optional force-toggle)
850 "Internal implementation of `python-indent-line-function'.
851Uses the offset calculated in
852`python-indent-calculate-indentation' and available levels
853indicated by the variable `python-indent-levels' to set the
854current indentation.
855
856When the variable `last-command' is equal to
857`indent-for-tab-command' or FORCE-TOGGLE is non-nil it cycles
858levels indicated in the variable `python-indent-levels' by
859setting the current level in the variable
860`python-indent-current-level'.
861
862When the variable `last-command' is not equal to
863`indent-for-tab-command' and FORCE-TOGGLE is nil it calculates
864possible indentation levels and saves it in the variable
865`python-indent-levels'. Afterwards it sets the variable
866`python-indent-current-level' correctly so offset is equal
867to (`nth' `python-indent-current-level' `python-indent-levels')"
868 (if (or (and (eq this-command 'indent-for-tab-command)
869 (eq last-command this-command))
870 force-toggle)
871 (if (not (equal python-indent-levels '(0)))
872 (python-indent-toggle-levels)
873 (python-indent-calculate-levels))
874 (python-indent-calculate-levels))
875 (beginning-of-line)
876 (delete-horizontal-space)
877 (indent-to (nth python-indent-current-level python-indent-levels))
878 (python-info-closing-block-message))
879
880(defun python-indent-line-function ()
881 "`indent-line-function' for Python mode.
882See `python-indent-line' for details."
883 (python-indent-line))
884
885(defun python-indent-dedent-line ()
886 "De-indent current line."
887 (interactive "*")
888 (when (and (not (or (python-info-ppss-context 'string)
889 (python-info-ppss-context 'comment)))
890 (<= (point-marker) (save-excursion
891 (back-to-indentation)
892 (point-marker)))
893 (> (current-column) 0))
894 (python-indent-line t)
895 t))
896
897(defun python-indent-dedent-line-backspace (arg)
898 "De-indent current line.
899Argument ARG is passed to `backward-delete-char-untabify' when
900point is not in between the indentation."
901 (interactive "*p")
902 (when (not (python-indent-dedent-line))
903 (backward-delete-char-untabify arg)))
904(put 'python-indent-dedent-line-backspace 'delete-selection 'supersede)
834 905
835(defun python-indent-region (start end) 906(defun python-indent-region (start end)
836 "`indent-region-function' for Python. 907 "Indent a python region automagically.
837Leaves validly-indented lines alone, i.e. doesn't indent to 908
838another valid position." 909Called from a program, START and END specify the region to indent."
839 (save-excursion 910 (let ((deactivate-mark nil))
840 (goto-char end) 911 (save-excursion
841 (setq end (point-marker)) 912 (goto-char end)
842 (goto-char start) 913 (setq end (point-marker))
843 (or (bolp) (forward-line 1)) 914 (goto-char start)
844 (while (< (point) end) 915 (or (bolp) (forward-line 1))
845 (or (and (bolp) (eolp)) 916 (while (< (point) end)
846 (python-indent-line-1 t)) 917 (or (and (bolp) (eolp))
847 (forward-line 1)) 918 (let (word)
848 (move-marker end nil))) 919 (forward-line -1)
849 920 (back-to-indentation)
850(defun python-block-end-p () 921 (setq word (current-word))
851 "Non-nil if this is a line in a statement closing a block, 922 (forward-line 1)
852or a blank line indented to where it would close a block." 923 (when word
853 (and (not (python-comment-line-p)) 924 (beginning-of-line)
854 (or (python-close-block-statement-p t) 925 (delete-horizontal-space)
855 (< (current-indentation) 926 (indent-to (python-indent-calculate-indentation)))))
856 (save-excursion 927 (forward-line 1))
857 (python-previous-statement) 928 (move-marker end nil))))
858 (current-indentation)))))) 929
930(defun python-indent-shift-left (start end &optional count)
931 "Shift lines contained in region START END by COUNT columns to the left.
932COUNT defaults to `python-indent-offset'. If region isn't
933active, the current line is shifted. The shifted region includes
934the lines in which START and END lie. An error is signaled if
935any lines in the region are indented less than COUNT columns."
936 (interactive
937 (if mark-active
938 (list (region-beginning) (region-end) current-prefix-arg)
939 (list (line-beginning-position) (line-end-position) current-prefix-arg)))
940 (if count
941 (setq count (prefix-numeric-value count))
942 (setq count python-indent-offset))
943 (when (> count 0)
944 (let ((deactivate-mark nil))
945 (save-excursion
946 (goto-char start)
947 (while (< (point) end)
948 (if (and (< (current-indentation) count)
949 (not (looking-at "[ \t]*$")))
950 (error "Can't shift all lines enough"))
951 (forward-line))
952 (indent-rigidly start end (- count))))))
953
954(add-to-list 'debug-ignored-errors "^Can't shift all lines enough")
955
956(defun python-indent-shift-right (start end &optional count)
957 "Shift lines contained in region START END by COUNT columns to the left.
958COUNT defaults to `python-indent-offset'. If region isn't
959active, the current line is shifted. The shifted region includes
960the lines in which START and END lie."
961 (interactive
962 (if mark-active
963 (list (region-beginning) (region-end) current-prefix-arg)
964 (list (line-beginning-position) (line-end-position) current-prefix-arg)))
965 (let ((deactivate-mark nil))
966 (if count
967 (setq count (prefix-numeric-value count))
968 (setq count python-indent-offset))
969 (indent-rigidly start end count)))
970
971(defun python-indent-electric-colon (arg)
972 "Insert a colon and maybe de-indent the current line.
973With numeric ARG, just insert that many colons. With
974\\[universal-argument], just insert a single colon."
975 (interactive "*P")
976 (self-insert-command (if (not (integerp arg)) 1 arg))
977 (when (and (not arg)
978 (eolp)
979 (not (equal ?: (char-after (- (point-marker) 2))))
980 (not (or (python-info-ppss-context 'string)
981 (python-info-ppss-context 'comment))))
982 (let ((indentation (current-indentation))
983 (calculated-indentation (python-indent-calculate-indentation)))
984 (python-info-closing-block-message)
985 (when (> indentation calculated-indentation)
986 (save-excursion
987 (indent-line-to calculated-indentation)
988 (when (not (python-info-closing-block-message))
989 (indent-line-to indentation)))))))
990(put 'python-indent-electric-colon 'delete-selection t)
991
992(defun python-indent-post-self-insert-function ()
993 "Adjust closing paren line indentation after a char is added.
994This function is intended to be added to the
995`post-self-insert-hook.' If a line renders a paren alone, after
996adding a char before it, the line will be re-indented
997automatically if needed."
998 (when (and (eq (char-before) last-command-event)
999 (not (bolp))
1000 (memq (char-after) '(?\) ?\] ?\})))
1001 (save-excursion
1002 (goto-char (line-beginning-position))
1003 ;; If after going to the beginning of line the point
1004 ;; is still inside a paren it's ok to do the trick
1005 (when (python-info-ppss-context 'paren)
1006 (let ((indentation (python-indent-calculate-indentation)))
1007 (when (< (current-indentation) indentation)
1008 (indent-line-to indentation)))))))
1009
859 1010
860;;;; Movement. 1011;;; Navigation
861 1012
862;; Fixme: Define {for,back}ward-sexp-function? Maybe skip units like 1013(defvar python-nav-beginning-of-defun-regexp
863;; block, statement, depending on context. 1014 (python-rx line-start (* space) defun (+ space) (group symbol-name))
864 1015 "Regexp matching class or function definition.
865(defun python-beginning-of-defun () 1016The name of the defun should be grouped so it can be retrieved
866 "`beginning-of-defun-function' for Python. 1017via `match-string'.")
867Finds beginning of innermost nested class or method definition. 1018
868Returns the name of the definition found at the end, or nil if 1019(defun python-nav-beginning-of-defun (&optional arg)
869reached start of buffer." 1020 "Move point to `beginning-of-defun'.
870 (let ((ci (current-indentation)) 1021With positive ARG move search backwards. With negative do the
871 (def-re (rx line-start (0+ space) (or "def" "class") (1+ space) 1022same but forward. When ARG is nil or 0 defaults to 1. This is
872 (group (1+ (or word (syntax symbol)))))) 1023the main part of `python-beginning-of-defun-function'. Return
873 found lep) ;; def-line 1024non-nil if point is moved to `beginning-of-defun'."
874 (if (python-comment-line-p) 1025 (when (or (null arg) (= arg 0)) (setq arg 1))
875 (setq ci most-positive-fixnum)) 1026 (let* ((re-search-fn (if (> arg 0)
876 (while (and (not (bobp)) (not found)) 1027 #'re-search-backward
877 ;; Treat bol at beginning of function as outside function so 1028 #'re-search-forward))
878 ;; that successive C-M-a makes progress backwards. 1029 (line-beg-pos (line-beginning-position))
879 ;;(setq def-line (looking-at def-re)) 1030 (line-content-start (+ line-beg-pos (current-indentation)))
880 (unless (bolp) (end-of-line)) 1031 (pos (point-marker))
881 (setq lep (line-end-position)) 1032 (found
882 (if (and (re-search-backward def-re nil 'move) 1033 (progn
883 ;; Must be less indented or matching top level, or 1034 (when (and (< arg 0)
884 ;; equally indented if we started on a definition line. 1035 (python-info-looking-at-beginning-of-defun))
885 (let ((in (current-indentation))) 1036 (end-of-line 1))
886 (or (and (zerop ci) (zerop in)) 1037 (while (and (funcall re-search-fn
887 (= lep (line-end-position)) ; on initial line 1038 python-nav-beginning-of-defun-regexp nil t)
888 ;; Not sure why it was like this -- fails in case of 1039 (python-info-ppss-context-type)))
889 ;; last internal function followed by first 1040 (and (python-info-looking-at-beginning-of-defun)
890 ;; non-def statement of the main body. 1041 (or (not (= (line-number-at-pos pos)
891;; (and def-line (= in ci)) 1042 (line-number-at-pos)))
892 (= in ci) 1043 (and (>= (point) line-beg-pos)
893 (< in ci))) 1044 (<= (point) line-content-start)
894 (not (python-in-string/comment))) 1045 (> pos line-content-start)))))))
895 (setq found t))) 1046 (if found
1047 (or (beginning-of-line 1) t)
1048 (and (goto-char pos) nil))))
1049
1050(defun python-beginning-of-defun-function (&optional arg)
1051 "Move point to the beginning of def or class.
1052With positive ARG move that number of functions backwards. With
1053negative do the same but forward. When ARG is nil or 0 defaults
1054to 1. Return non-nil if point is moved to `beginning-of-defun'."
1055 (when (or (null arg) (= arg 0)) (setq arg 1))
1056 (let ((found))
1057 (cond ((and (eq this-command 'mark-defun)
1058 (python-info-looking-at-beginning-of-defun)))
1059 (t
1060 (dotimes (i (if (> arg 0) arg (- arg)))
1061 (when (and (python-nav-beginning-of-defun arg)
1062 (not found))
1063 (setq found t)))))
896 found)) 1064 found))
897 1065
898(defun python-end-of-defun () 1066(defun python-end-of-defun-function ()
899 "`end-of-defun-function' for Python. 1067 "Move point to the end of def or class.
900Finds end of innermost nested class or method definition." 1068Returns nil if point is not in a def or class."
901 (let ((orig (point)) 1069 (interactive)
902 (pattern (rx line-start (0+ space) (or "def" "class") space))) 1070 (let ((beg-defun-indent))
903 ;; Go to start of current block and check whether it's at top 1071 (when (or (python-info-looking-at-beginning-of-defun)
904 ;; level. If it is, and not a block start, look forward for 1072 (python-beginning-of-defun-function 1)
905 ;; definition statement. 1073 (python-beginning-of-defun-function -1))
906 (when (python-comment-line-p) 1074 (setq beg-defun-indent (current-indentation))
907 (end-of-line) 1075 (forward-line 1)
908 (forward-comment most-positive-fixnum)) 1076 ;; Go as forward as possible
909 (if (not (python-open-block-statement-p)) 1077 (while (and (or
910 (python-beginning-of-block)) 1078 (python-nav-beginning-of-defun -1)
911 (if (zerop (current-indentation)) 1079 (and (goto-char (point-max)) nil))
912 (unless (python-open-block-statement-p) 1080 (> (current-indentation) beg-defun-indent)))
913 (while (and (re-search-forward pattern nil 'move) 1081 (beginning-of-line 1)
914 (python-in-string/comment))) ; just loop 1082 ;; Go as backwards as possible
915 (unless (eobp) 1083 (while (and (forward-line -1)
916 (beginning-of-line))) 1084 (not (bobp))
917 ;; Don't move before top-level statement that would end defun. 1085 (or (not (current-word))
918 (end-of-line) 1086 (equal (char-after (+ (point) (current-indentation))) ?#)
919 (python-beginning-of-defun)) 1087 (<= (current-indentation) beg-defun-indent)
920 ;; If we got to the start of buffer, look forward for 1088 (looking-at (python-rx decorator))
921 ;; definition statement. 1089 (python-info-ppss-context-type))))
922 (if (and (bobp) (not (looking-at "def\\|class"))) 1090 (forward-line 1)
923 (while (and (not (eobp)) 1091 ;; If point falls inside a paren or string context the point is
924 (re-search-forward pattern nil 'move) 1092 ;; forwarded at the end of it (or end of buffer if its not closed)
925 (python-in-string/comment)))) ; just loop 1093 (let ((context-type (python-info-ppss-context-type)))
926 ;; We're at a definition statement (or end-of-buffer). 1094 (when (memq context-type '(paren string))
927 (unless (eobp) 1095 ;; Slow but safe.
928 (python-end-of-block) 1096 (while (and (not (eobp))
929 ;; Count trailing space in defun (but not trailing comments). 1097 (python-info-ppss-context-type))
930 (skip-syntax-forward " >") 1098 (forward-line 1)))))))
931 (unless (eobp) ; e.g. missing final newline 1099
932 (beginning-of-line))) 1100(defun python-nav-statement-start ()
933 ;; Catch pathological cases like this, where the beginning-of-defun 1101 "Move to start of current statement."
934 ;; skips to a definition we're not in: 1102 (interactive "^")
935 ;; if ...: 1103 (while (and (or (back-to-indentation) t)
936 ;; ... 1104 (not (bobp))
937 ;; else: 1105 (when (or
938 ;; ... # point here 1106 (save-excursion
939 ;; ... 1107 (forward-line -1)
940 ;; def ... 1108 (python-info-line-ends-backslash-p))
941 (if (< (point) orig) 1109 (python-info-ppss-context 'string)
942 (goto-char (point-max))))) 1110 (python-info-ppss-context 'paren))
943 1111 (forward-line -1)))))
944(defun python-beginning-of-statement () 1112
945 "Go to start of current statement. 1113(defun python-nav-statement-end ()
946Accounts for continuation lines, multi-line strings, and 1114 "Move to end of current statement."
947multi-line bracketed expressions." 1115 (interactive "^")
948 (while 1116 (while (and (goto-char (line-end-position))
949 (if (python-backslash-continuation-line-p) 1117 (not (eobp))
950 (progn (forward-line -1) t) 1118 (when (or
951 (beginning-of-line) 1119 (python-info-line-ends-backslash-p)
952 (or (python-beginning-of-string) 1120 (python-info-ppss-context 'string)
953 (python-skip-out)))) 1121 (python-info-ppss-context 'paren))
954 (back-to-indentation)) 1122 (forward-line 1)))))
955 1123
956(defun python-skip-out (&optional forward syntax) 1124(defun python-nav-backward-statement (&optional arg)
957 "Skip out of any nested brackets. 1125 "Move backward to previous statement.
958Skip forward if FORWARD is non-nil, else backward. 1126With ARG, repeat. See `python-nav-forward-statement'."
959If SYNTAX is non-nil it is the state returned by `syntax-ppss' at point. 1127 (interactive "^p")
960Return non-nil if and only if skipping was done." 1128 (or arg (setq arg 1))
961 ;; FIXME: Use syntax-ppss-toplevel-pos. 1129 (python-nav-forward-statement (- arg)))
962 (let ((depth (syntax-ppss-depth (or syntax (syntax-ppss)))) 1130
963 (forward (if forward -1 1))) 1131(defun python-nav-forward-statement (&optional arg)
964 (unless (zerop depth) 1132 "Move forward to next statement.
965 (if (> depth 0) 1133With ARG, repeat. With negative argument, move ARG times
966 ;; Skip forward out of nested brackets. 1134backward to previous statement."
967 (condition-case () ; beware invalid syntax 1135 (interactive "^p")
968 (progn (backward-up-list (* forward depth)) t) 1136 (or arg (setq arg 1))
969 (error nil)) 1137 (while (> arg 0)
970 ;; Invalid syntax (too many closed brackets). 1138 (python-nav-statement-end)
971 ;; Skip out of as many as possible. 1139 (python-util-forward-comment)
972 (let (done) 1140 (python-nav-statement-start)
973 (while (condition-case () 1141 (setq arg (1- arg)))
974 (progn (backward-up-list forward) 1142 (while (< arg 0)
975 (setq done t)) 1143 (python-nav-statement-start)
976 (error nil))) 1144 (python-util-forward-comment -1)
977 done))))) 1145 (python-nav-statement-start)
978 1146 (setq arg (1+ arg))))
979(defun python-end-of-statement () 1147
980 "Go to the end of the current statement and return point. 1148(defun python-nav-block-start ()
981Usually this is the start of the next line, but if this is a 1149 "Move to start of current block."
982multi-line statement we need to skip over the continuation lines. 1150 (interactive "^")
983On a comment line, go to end of line." 1151 (let ((starting-pos (point))
984 (end-of-line) 1152 (block-regexp (python-rx
985 (while (let (comment) 1153 line-start (* whitespace) block-start)))
986 ;; Move past any enclosing strings and sexps, or stop if 1154 (if (progn
987 ;; we're in a comment. 1155 (python-nav-statement-start)
988 (while (let ((s (syntax-ppss))) 1156 (looking-at (python-rx block-start)))
989 (cond ((eq 'comment (syntax-ppss-context s)) 1157 (point-marker)
990 (setq comment t) 1158 ;; Go to first line beginning a statement
991 nil) 1159 (while (and (not (bobp))
992 ((eq 'string (syntax-ppss-context s)) 1160 (or (and (python-nav-statement-start) nil)
993 ;; Go to start of string and skip it. 1161 (python-info-current-line-comment-p)
994 (let ((pos (point))) 1162 (python-info-current-line-empty-p)))
995 (goto-char (nth 8 s)) 1163 (forward-line -1))
996 (condition-case () ; beware invalid syntax 1164 (let ((block-matching-indent
997 (progn (forward-sexp) t) 1165 (- (current-indentation) python-indent-offset)))
998 ;; If there's a mismatched string, make sure 1166 (while
999 ;; we still overall move *forward*. 1167 (and (python-nav-backward-block)
1000 (error (goto-char pos) (end-of-line))))) 1168 (> (current-indentation) block-matching-indent)))
1001 ((python-skip-out t s)))) 1169 (if (and (looking-at (python-rx block-start))
1002 (end-of-line)) 1170 (= (current-indentation) block-matching-indent))
1003 (and (not comment) 1171 (point-marker)
1004 (not (eobp)) 1172 (and (goto-char starting-pos) nil))))))
1005 (eq ?\\ (char-before)))) ; Line continued? 1173
1006 (end-of-line 2)) ; Try next line. 1174(defun python-nav-block-end ()
1007 (point)) 1175 "Move to end of current block."
1008 1176 (interactive "^")
1009(defun python-previous-statement (&optional count) 1177 (when (python-nav-block-start)
1010 "Go to start of previous statement. 1178 (let ((block-indentation (current-indentation)))
1011With argument COUNT, do it COUNT times. Stop at beginning of buffer. 1179 (python-nav-statement-end)
1012Return count of statements left to move." 1180 (while (and (forward-line 1)
1013 (interactive "p") 1181 (not (eobp))
1014 (unless count (setq count 1)) 1182 (or (and (> (current-indentation) block-indentation)
1015 (if (< count 0) 1183 (or (python-nav-statement-end) t))
1016 (python-next-statement (- count)) 1184 (python-info-current-line-comment-p)
1017 (python-beginning-of-statement) 1185 (python-info-current-line-empty-p))))
1018 (while (and (> count 0) (not (bobp))) 1186 (python-util-forward-comment -1)
1019 (python-skip-comments/blanks t) 1187 (point-marker))))
1020 (python-beginning-of-statement) 1188
1021 (unless (bobp) (setq count (1- count)))) 1189(defun python-nav-backward-block (&optional arg)
1022 count)) 1190 "Move backward to previous block of code.
1023 1191With ARG, repeat. See `python-nav-forward-block'."
1024(defun python-next-statement (&optional count) 1192 (interactive "^p")
1025 "Go to start of next statement. 1193 (or arg (setq arg 1))
1026With argument COUNT, do it COUNT times. Stop at end of buffer. 1194 (python-nav-forward-block (- arg)))
1027Return count of statements left to move." 1195
1028 (interactive "p") 1196(defun python-nav-forward-block (&optional arg)
1029 (unless count (setq count 1)) 1197 "Move forward to next block of code.
1030 (if (< count 0) 1198With ARG, repeat. With negative argument, move ARG times
1031 (python-previous-statement (- count)) 1199backward to previous block."
1032 (beginning-of-line) 1200 (interactive "^p")
1033 (let (bogus) 1201 (or arg (setq arg 1))
1034 (while (and (> count 0) (not (eobp)) (not bogus)) 1202 (let ((block-start-regexp
1035 (python-end-of-statement) 1203 (python-rx line-start (* whitespace) block-start))
1036 (python-skip-comments/blanks) 1204 (starting-pos (point)))
1037 (if (eq 'string (syntax-ppss-context (syntax-ppss))) 1205 (while (> arg 0)
1038 (setq bogus t) 1206 (python-nav-statement-end)
1039 (unless (eobp) 1207 (while (and
1040 (setq count (1- count)))))) 1208 (re-search-forward block-start-regexp nil t)
1041 count)) 1209 (or (python-info-ppss-context 'string)
1042 1210 (python-info-ppss-context 'comment)
1043(defun python-beginning-of-block (&optional arg) 1211 (python-info-ppss-context 'paren))))
1044 "Go to start of current block.
1045With numeric arg, do it that many times. If ARG is negative, call
1046`python-end-of-block' instead.
1047If point is on the first line of a block, use its outer block.
1048If current statement is in column zero, don't move and return nil.
1049Otherwise return non-nil."
1050 (interactive "p")
1051 (unless arg (setq arg 1))
1052 (cond
1053 ((zerop arg))
1054 ((< arg 0) (python-end-of-block (- arg)))
1055 (t
1056 (let ((point (point)))
1057 (if (or (python-comment-line-p)
1058 (python-blank-line-p))
1059 (python-skip-comments/blanks t))
1060 (python-beginning-of-statement)
1061 (let ((ci (current-indentation)))
1062 (if (zerop ci)
1063 (not (goto-char point)) ; return nil
1064 ;; Look upwards for less indented statement.
1065 (if (catch 'done
1066;;; This is slower than the below.
1067;;; (while (zerop (python-previous-statement))
1068;;; (when (and (< (current-indentation) ci)
1069;;; (python-open-block-statement-p t))
1070;;; (beginning-of-line)
1071;;; (throw 'done t)))
1072 (while (and (zerop (forward-line -1)))
1073 (when (and (< (current-indentation) ci)
1074 (not (python-comment-line-p))
1075 ;; Move to beginning to save effort in case
1076 ;; this is in string.
1077 (progn (python-beginning-of-statement) t)
1078 (python-open-block-statement-p t))
1079 (beginning-of-line)
1080 (throw 'done t)))
1081 (not (goto-char point))) ; Failed -- return nil
1082 (python-beginning-of-block (1- arg)))))))))
1083
1084(defun python-end-of-block (&optional arg)
1085 "Go to end of current block.
1086With numeric arg, do it that many times. If ARG is negative,
1087call `python-beginning-of-block' instead.
1088If current statement is in column zero and doesn't open a block,
1089don't move and return nil. Otherwise return t."
1090 (interactive "p")
1091 (unless arg (setq arg 1))
1092 (if (< arg 0)
1093 (python-beginning-of-block (- arg))
1094 (while (and (> arg 0)
1095 (let* ((point (point))
1096 (_ (if (python-comment-line-p)
1097 (python-skip-comments/blanks t)))
1098 (ci (current-indentation))
1099 (open (python-open-block-statement-p)))
1100 (if (and (zerop ci) (not open))
1101 (not (goto-char point))
1102 (catch 'done
1103 (while (zerop (python-next-statement))
1104 (when (or (and open (<= (current-indentation) ci))
1105 (< (current-indentation) ci))
1106 (python-skip-comments/blanks t)
1107 (beginning-of-line 2)
1108 (throw 'done t)))))))
1109 (setq arg (1- arg))) 1212 (setq arg (1- arg)))
1110 (zerop arg))) 1213 (while (< arg 0)
1214 (python-nav-statement-start)
1215 (while (and
1216 (re-search-backward block-start-regexp nil t)
1217 (or (python-info-ppss-context 'string)
1218 (python-info-ppss-context 'comment)
1219 (python-info-ppss-context 'paren))))
1220 (setq arg (1+ arg)))
1221 (python-nav-statement-start)
1222 (if (not (looking-at (python-rx block-start)))
1223 (and (goto-char starting-pos) nil)
1224 (and (not (= (point) starting-pos)) (point-marker)))))
1225
1226(defun python-nav-forward-sexp-function (&optional arg)
1227 "Move forward across one block of code.
1228With ARG, do it that many times. Negative arg -N means
1229move backward N times."
1230 (interactive "^p")
1231 (or arg (setq arg 1))
1232 (while (> arg 0)
1233 (let ((block-starting-pos
1234 (save-excursion (python-nav-block-start)))
1235 (block-ending-pos
1236 (save-excursion (python-nav-block-end)))
1237 (next-block-starting-pos
1238 (save-excursion (python-nav-forward-block))))
1239 (cond ((not block-starting-pos)
1240 (python-nav-forward-block))
1241 ((= (point) block-starting-pos)
1242 (if (or (not next-block-starting-pos)
1243 (< block-ending-pos next-block-starting-pos))
1244 (python-nav-block-end)
1245 (python-nav-forward-block)))
1246 ((= block-ending-pos (point))
1247 (let ((parent-block-end-pos
1248 (save-excursion
1249 (python-util-forward-comment)
1250 (python-nav-block-start)
1251 (python-nav-block-end))))
1252 (if (and parent-block-end-pos
1253 (or (not next-block-starting-pos)
1254 (> next-block-starting-pos parent-block-end-pos)))
1255 (goto-char parent-block-end-pos)
1256 (python-nav-forward-block))))
1257 (t (python-nav-block-end))))
1258 (setq arg (1- arg)))
1259 (while (< arg 0)
1260 (let* ((block-starting-pos
1261 (save-excursion (python-nav-block-start)))
1262 (block-ending-pos
1263 (save-excursion (python-nav-block-end)))
1264 (prev-block-ending-pos
1265 (save-excursion (when (python-nav-backward-block)
1266 (python-nav-block-end))))
1267 (prev-block-parent-ending-pos
1268 (save-excursion
1269 (when prev-block-ending-pos
1270 (goto-char prev-block-ending-pos)
1271 (python-util-forward-comment)
1272 (python-nav-block-start)
1273 (python-nav-block-end)))))
1274 (cond ((not block-ending-pos)
1275 (and (python-nav-backward-block)
1276 (python-nav-block-end)))
1277 ((= (point) block-ending-pos)
1278 (let ((candidates))
1279 (dolist (name
1280 '(prev-block-parent-ending-pos
1281 prev-block-ending-pos
1282 block-ending-pos
1283 block-starting-pos))
1284 (when (and (symbol-value name)
1285 (< (symbol-value name) (point)))
1286 (add-to-list 'candidates (symbol-value name))))
1287 (goto-char (apply 'max candidates))))
1288 ((> (point) block-ending-pos)
1289 (python-nav-block-end))
1290 ((= (point) block-starting-pos)
1291 (if (not (> (point) (or prev-block-ending-pos (point))))
1292 (python-nav-backward-block)
1293 (goto-char prev-block-ending-pos)
1294 (let ((parent-block-ending-pos
1295 (save-excursion
1296 (python-nav-forward-sexp-function)
1297 (and (not (looking-at (python-rx block-start)))
1298 (point)))))
1299 (when (and parent-block-ending-pos
1300 (> parent-block-ending-pos prev-block-ending-pos))
1301 (goto-char parent-block-ending-pos)))))
1302 (t (python-nav-block-start))))
1303 (setq arg (1+ arg))))
1111 1304
1112(defvar python-which-func-length-limit 40 1305
1113 "Non-strict length limit for `python-which-func' output.") 1306;;; Shell integration
1114 1307
1115(defun python-which-func () 1308(defcustom python-shell-buffer-name "Python"
1116 (let ((function-name (python-current-defun python-which-func-length-limit))) 1309 "Default buffer name for Python interpreter."
1117 (set-text-properties 0 (length function-name) nil function-name) 1310 :type 'string
1118 function-name)) 1311 :group 'python
1312 :safe 'stringp)
1119 1313
1120 1314(defcustom python-shell-interpreter "python"
1121;;;; Imenu. 1315 "Default Python interpreter for shell."
1122 1316 :type 'string
1123;; For possibly speeding this up, here's the top of the ELP profile 1317 :group 'python)
1124;; for rescanning pydoc.py (2.2k lines, 90kb):
1125;; Function Name Call Count Elapsed Time Average Time
1126;; ==================================== ========== ============= ============
1127;; python-imenu-create-index 156 2.430906 0.0155827307
1128;; python-end-of-defun 155 1.2718260000 0.0082053290
1129;; python-end-of-block 155 1.1898689999 0.0076765741
1130;; python-next-statement 2970 1.024717 0.0003450225
1131;; python-end-of-statement 2970 0.4332190000 0.0001458649
1132;; python-beginning-of-defun 265 0.0918479999 0.0003465962
1133;; python-skip-comments/blanks 3125 0.0753319999 2.410...e-05
1134
1135(defvar python-recursing)
1136(defun python-imenu-create-index ()
1137 "`imenu-create-index-function' for Python.
1138
1139Makes nested Imenu menus from nested `class' and `def' statements.
1140The nested menus are headed by an item referencing the outer
1141definition; it has a space prepended to the name so that it sorts
1142first with `imenu--sort-by-name' (though, unfortunately, sub-menus
1143precede it)."
1144 (unless (boundp 'python-recursing) ; dynamically bound below
1145 ;; Normal call from Imenu.
1146 (goto-char (point-min))
1147 ;; Without this, we can get an infloop if the buffer isn't all
1148 ;; fontified. I guess this is really a bug in syntax.el. OTOH,
1149 ;; _with_ this, imenu doesn't immediately work; I can't figure out
1150 ;; what's going on, but it must be something to do with timers in
1151 ;; font-lock.
1152 ;; This can't be right, especially not when jit-lock is not used. --Stef
1153 ;; (unless (get-text-property (1- (point-max)) 'fontified)
1154 ;; (font-lock-fontify-region (point-min) (point-max)))
1155 )
1156 (let (index-alist) ; accumulated value to return
1157 (while (re-search-forward
1158 (rx line-start (0+ space) ; leading space
1159 (or (group "def") (group "class")) ; type
1160 (1+ space) (group (1+ (or word ?_)))) ; name
1161 nil t)
1162 (unless (python-in-string/comment)
1163 (let ((pos (match-beginning 0))
1164 (name (match-string-no-properties 3)))
1165 (if (match-beginning 2) ; def or class?
1166 (setq name (concat "class " name)))
1167 (save-restriction
1168 (narrow-to-defun)
1169 (let* ((python-recursing t)
1170 (sublist (python-imenu-create-index)))
1171 (if sublist
1172 (progn (push (cons (concat " " name) pos) sublist)
1173 (push (cons name sublist) index-alist))
1174 (push (cons name pos) index-alist)))))))
1175 (unless (boundp 'python-recursing)
1176 ;; Look for module variables.
1177 (let (vars)
1178 (goto-char (point-min))
1179 (while (re-search-forward
1180 (rx line-start (group (1+ (or word ?_))) (0+ space) "=")
1181 nil t)
1182 (unless (python-in-string/comment)
1183 (push (cons (match-string 1) (match-beginning 1))
1184 vars)))
1185 (setq index-alist (nreverse index-alist))
1186 (if vars
1187 (push (cons "Module variables"
1188 (nreverse vars))
1189 index-alist))))
1190 index-alist))
1191
1192;;;; `Electric' commands.
1193 1318
1194(defun python-electric-colon (arg) 1319(defcustom python-shell-internal-buffer-name "Python Internal"
1195 "Insert a colon and maybe outdent the line if it is a statement like `else'. 1320 "Default buffer name for the Internal Python interpreter."
1196With numeric ARG, just insert that many colons. With \\[universal-argument], 1321 :type 'string
1197just insert a single colon." 1322 :group 'python
1198 (interactive "*P") 1323 :safe 'stringp)
1199 (self-insert-command (if (not (integerp arg)) 1 arg))
1200 (and (not arg)
1201 (eolp)
1202 (python-outdent-p)
1203 (not (python-in-string/comment))
1204 (> (current-indentation) (python-calculate-indentation))
1205 (python-indent-line))) ; OK, do it
1206(put 'python-electric-colon 'delete-selection t)
1207
1208(defun python-backspace (arg)
1209 "Maybe delete a level of indentation on the current line.
1210Do so if point is at the end of the line's indentation outside
1211strings and comments.
1212Otherwise just call `backward-delete-char-untabify'.
1213Repeat ARG times."
1214 (interactive "*p")
1215 (if (or (/= (current-indentation) (current-column))
1216 (bolp)
1217 (python-continuation-line-p)
1218 (python-in-string/comment))
1219 (backward-delete-char-untabify arg)
1220 ;; Look for the largest valid indentation which is smaller than
1221 ;; the current indentation.
1222 (let ((indent 0)
1223 (ci (current-indentation))
1224 (indents (python-indentation-levels))
1225 initial)
1226 (dolist (x indents)
1227 (if (< (car x) ci)
1228 (setq indent (max indent (car x)))))
1229 (setq initial (cdr (assq indent indents)))
1230 (if (> (length initial) 0)
1231 (message "Closes %s" initial))
1232 (delete-horizontal-space)
1233 (indent-to indent))))
1234(put 'python-backspace 'delete-selection 'supersede)
1235
1236;;;; pychecker
1237 1324
1238(defcustom python-check-command "pychecker --stdlib" 1325(defcustom python-shell-interpreter-args "-i"
1239 "Command used to check a Python file." 1326 "Default arguments for the Python interpreter."
1240 :type 'string 1327 :type 'string
1241 :group 'python) 1328 :group 'python)
1242 1329
1243(defvar python-saved-check-command nil 1330(defcustom python-shell-prompt-regexp ">>> "
1244 "Internal use.") 1331 "Regular Expression matching top\-level input prompt of python shell.
1332It should not contain a caret (^) at the beginning."
1333 :type 'string
1334 :group 'python
1335 :safe 'stringp)
1245 1336
1246;; After `sgml-validate-command'. 1337(defcustom python-shell-prompt-block-regexp "[.][.][.] "
1247(defun python-check (command) 1338 "Regular Expression matching block input prompt of python shell.
1248 "Check a Python file (default current buffer's file). 1339It should not contain a caret (^) at the beginning."
1249Runs COMMAND, a shell command, as if by `compile'. 1340 :type 'string
1250See `python-check-command' for the default." 1341 :group 'python
1251 (interactive 1342 :safe 'stringp)
1252 (list (read-string "Checker command: " 1343
1253 (or python-saved-check-command 1344(defcustom python-shell-prompt-output-regexp ""
1254 (concat python-check-command " " 1345 "Regular Expression matching output prompt of python shell.
1255 (let ((name (buffer-file-name))) 1346It should not contain a caret (^) at the beginning."
1256 (if name 1347 :type 'string
1257 (file-name-nondirectory name)))))))) 1348 :group 'python
1258 (set (make-local-variable 'python-saved-check-command) command) 1349 :safe 'stringp)
1259 (require 'compile) ;To define compilation-* variables. 1350
1260 (save-some-buffers (not compilation-ask-about-save) nil) 1351(defcustom python-shell-prompt-pdb-regexp "[(<]*[Ii]?[Pp]db[>)]+ "
1261 (let ((compilation-error-regexp-alist 1352 "Regular Expression matching pdb input prompt of python shell.
1262 (cons '("(\\([^,]+\\), line \\([0-9]+\\))" 1 2) 1353It should not contain a caret (^) at the beginning."
1263 compilation-error-regexp-alist))) 1354 :type 'string
1264 (compilation-start command))) 1355 :group 'python
1265 1356 :safe 'stringp)
1266;;;; Inferior mode stuff (following cmuscheme).
1267 1357
1268(defcustom python-python-command "python" 1358(defcustom python-shell-enable-font-lock t
1269 "Shell command to run Python interpreter. 1359 "Should syntax highlighting be enabled in the python shell buffer?
1270Any arguments can't contain whitespace." 1360Restart the python shell after changing this variable for it to take effect."
1361 :type 'boolean
1271 :group 'python 1362 :group 'python
1272 :type 'string) 1363 :safe 'booleanp)
1273 1364
1274(defcustom python-jython-command "jython" 1365(defcustom python-shell-send-setup-max-wait 5
1275 "Shell command to run Jython interpreter. 1366 "Seconds to wait for process output before code setup.
1276Any arguments can't contain whitespace." 1367If output is received before the specified time then control is
1368returned in that moment and not after waiting."
1369 :type 'integer
1370 :group 'python
1371 :safe 'integerp)
1372
1373(defcustom python-shell-process-environment nil
1374 "List of environment variables for Python shell.
1375This variable follows the same rules as `process-environment'
1376since it merges with it before the process creation routines are
1377called. When this variable is nil, the Python shell is run with
1378the default `process-environment'."
1379 :type '(repeat string)
1277 :group 'python 1380 :group 'python
1278 :type 'string) 1381 :safe 'listp)
1279 1382
1280(defvar python-command python-python-command 1383(defcustom python-shell-extra-pythonpaths nil
1281 "Actual command used to run Python. 1384 "List of extra pythonpaths for Python shell.
1282May be `python-python-command' or `python-jython-command', possibly 1385The values of this variable are added to the existing value of
1283modified by the user. Additional arguments are added when the command 1386PYTHONPATH in the `process-environment' variable."
1284is used by `run-python' et al.") 1387 :type '(repeat string)
1285 1388 :group 'python
1286(defvar python-buffer nil 1389 :safe 'listp)
1287 "The current Python process buffer. 1390
1288 1391(defcustom python-shell-exec-path nil
1289Commands that send text from source buffers to Python processes have 1392 "List of path to search for binaries.
1290to choose a process to send to. This is determined by buffer-local 1393This variable follows the same rules as `exec-path' since it
1291value of `python-buffer'. If its value in the current buffer, 1394merges with it before the process creation routines are called.
1292i.e. both any local value and the default one, is nil, `run-python' 1395When this variable is nil, the Python shell is run with the
1293and commands that send to the Python process will start a new process. 1396default `exec-path'."
1294 1397 :type '(repeat string)
1295Whenever \\[run-python] starts a new process, it resets the default 1398 :group 'python
1296value of `python-buffer' to be the new process's buffer and sets the 1399 :safe 'listp)
1297buffer-local value similarly if the current buffer is in Python mode 1400
1298or Inferior Python mode, so that source buffer stays associated with a 1401(defcustom python-shell-virtualenv-path nil
1299specific sub-process. 1402 "Path to virtualenv root.
1300 1403This variable, when set to a string, makes the values stored in
1301Use \\[python-set-proc] to set the default value from a buffer with a 1404`python-shell-process-environment' and `python-shell-exec-path'
1302local value.") 1405to be modified properly so shells are started with the specified
1303(make-variable-buffer-local 'python-buffer) 1406virtualenv."
1304 1407 :type 'string
1305(defconst python-compilation-regexp-alist 1408 :group 'python
1306 ;; FIXME: maybe these should move to compilation-error-regexp-alist-alist. 1409 :safe 'stringp)
1307 ;; The first already is (for CAML), but the second isn't. Anyhow, 1410
1308 ;; these are specific to the inferior buffer. -- fx 1411(defcustom python-shell-setup-codes '(python-shell-completion-setup-code
1412 python-ffap-setup-code
1413 python-eldoc-setup-code)
1414 "List of code run by `python-shell-send-setup-codes'."
1415 :type '(repeat symbol)
1416 :group 'python
1417 :safe 'listp)
1418
1419(defcustom python-shell-compilation-regexp-alist
1309 `((,(rx line-start (1+ (any " \t")) "File \"" 1420 `((,(rx line-start (1+ (any " \t")) "File \""
1310 (group (1+ (not (any "\"<")))) ; avoid `<stdin>' &c 1421 (group (1+ (not (any "\"<")))) ; avoid `<stdin>' &c
1311 "\", line " (group (1+ digit))) 1422 "\", line " (group (1+ digit)))
1312 1 2) 1423 1 2)
1313 (,(rx " in file " (group (1+ not-newline)) " on line " 1424 (,(rx " in file " (group (1+ not-newline)) " on line "
1314 (group (1+ digit))) 1425 (group (1+ digit)))
1315 1 2) 1426 1 2)
1316 ;; pdb stack trace
1317 (,(rx line-start "> " (group (1+ (not (any "(\"<")))) 1427 (,(rx line-start "> " (group (1+ (not (any "(\"<"))))
1318 "(" (group (1+ digit)) ")" (1+ (not (any "("))) "()") 1428 "(" (group (1+ digit)) ")" (1+ (not (any "("))) "()")
1319 1 2)) 1429 1 2))
1320 "`compilation-error-regexp-alist' for inferior Python.") 1430 "`compilation-error-regexp-alist' for inferior Python."
1431 :type '(alist string)
1432 :group 'python)
1433
1434(defun python-shell-get-process-name (dedicated)
1435 "Calculate the appropriate process name for inferior Python process.
1436If DEDICATED is t and the variable `buffer-file-name' is non-nil
1437returns a string with the form
1438`python-shell-buffer-name'[variable `buffer-file-name'] else
1439returns the value of `python-shell-buffer-name'. After
1440calculating the process name adds the buffer name for the process
1441in the `same-window-buffer-names' list."
1442 (let ((process-name
1443 (if (and dedicated
1444 buffer-file-name)
1445 (format "%s[%s]" python-shell-buffer-name buffer-file-name)
1446 (format "%s" python-shell-buffer-name))))
1447 (add-to-list 'same-window-buffer-names (purecopy
1448 (format "*%s*" process-name)))
1449 process-name))
1450
1451(defun python-shell-internal-get-process-name ()
1452 "Calculate the appropriate process name for Internal Python process.
1453The name is calculated from `python-shell-global-buffer-name' and
1454a hash of all relevant global shell settings in order to ensure
1455uniqueness for different types of configurations."
1456 (format "%s [%s]"
1457 python-shell-internal-buffer-name
1458 (md5
1459 (concat
1460 (python-shell-parse-command)
1461 python-shell-prompt-regexp
1462 python-shell-prompt-block-regexp
1463 python-shell-prompt-output-regexp
1464 (mapconcat #'symbol-value python-shell-setup-codes "")
1465 (mapconcat #'identity python-shell-process-environment "")
1466 (mapconcat #'identity python-shell-extra-pythonpaths "")
1467 (mapconcat #'identity python-shell-exec-path "")
1468 (or python-shell-virtualenv-path "")
1469 (mapconcat #'identity python-shell-exec-path "")))))
1470
1471(defun python-shell-parse-command ()
1472 "Calculate the string used to execute the inferior Python process."
1473 (format "%s %s" python-shell-interpreter python-shell-interpreter-args))
1474
1475(defun python-shell-calculate-process-environment ()
1476 "Calculate process environment given `python-shell-virtualenv-path'."
1477 (let ((process-environment (append
1478 python-shell-process-environment
1479 process-environment nil))
1480 (virtualenv (if python-shell-virtualenv-path
1481 (directory-file-name python-shell-virtualenv-path)
1482 nil)))
1483 (when python-shell-extra-pythonpaths
1484 (setenv "PYTHONPATH"
1485 (format "%s%s%s"
1486 (mapconcat 'identity
1487 python-shell-extra-pythonpaths
1488 path-separator)
1489 path-separator
1490 (or (getenv "PYTHONPATH") ""))))
1491 (if (not virtualenv)
1492 process-environment
1493 (setenv "PYTHONHOME" nil)
1494 (setenv "PATH" (format "%s/bin%s%s"
1495 virtualenv path-separator
1496 (or (getenv "PATH") "")))
1497 (setenv "VIRTUAL_ENV" virtualenv))
1498 process-environment))
1499
1500(defun python-shell-calculate-exec-path ()
1501 "Calculate exec path given `python-shell-virtualenv-path'."
1502 (let ((path (append python-shell-exec-path
1503 exec-path nil)))
1504 (if (not python-shell-virtualenv-path)
1505 path
1506 (cons (format "%s/bin"
1507 (directory-file-name python-shell-virtualenv-path))
1508 path))))
1509
1510(defun python-comint-output-filter-function (output)
1511 "Hook run after content is put into comint buffer.
1512OUTPUT is a string with the contents of the buffer."
1513 (ansi-color-filter-apply output))
1321 1514
1322(defvar inferior-python-mode-map
1323 (let ((map (make-sparse-keymap)))
1324 ;; This will inherit from comint-mode-map.
1325 (define-key map "\C-c\C-l" 'python-load-file)
1326 (define-key map "\C-c\C-v" 'python-check)
1327 ;; Note that we _can_ still use these commands which send to the
1328 ;; Python process even at the prompt if we have a normal prompt,
1329 ;; i.e. '>>> ' and not '... '. See the comment before
1330 ;; python-send-region. Fixme: uncomment these if we address that.
1331
1332 ;; (define-key map [(meta ?\t)] 'python-complete-symbol)
1333 ;; (define-key map "\C-c\C-f" 'python-describe-symbol)
1334 map))
1335
1336(defvar inferior-python-mode-syntax-table
1337 (let ((st (make-syntax-table python-mode-syntax-table)))
1338 ;; Don't get confused by apostrophes in the process's output (e.g. if
1339 ;; you execute "help(os)").
1340 (modify-syntax-entry ?\' "." st)
1341 ;; Maybe we should do the same for double quotes?
1342 ;; (modify-syntax-entry ?\" "." st)
1343 st))
1344
1345;; Autoloaded.
1346(declare-function compilation-shell-minor-mode "compile" (&optional arg))
1347
1348(defvar python--prompt-regexp nil)
1349
1350(defun python--set-prompt-regexp ()
1351 (let ((prompt (cdr-safe (or (assoc python-python-command
1352 python-shell-prompt-alist)
1353 (assq t python-shell-prompt-alist))))
1354 (cprompt (cdr-safe (or (assoc python-python-command
1355 python-shell-continuation-prompt-alist)
1356 (assq t python-shell-continuation-prompt-alist)))))
1357 (set (make-local-variable 'comint-prompt-regexp)
1358 (concat "\\("
1359 (mapconcat 'identity
1360 (delq nil (list prompt cprompt "^([Pp]db) "))
1361 "\\|")
1362 "\\)"))
1363 (set (make-local-variable 'python--prompt-regexp) prompt)))
1364
1365;; Fixme: This should inherit some stuff from `python-mode', but I'm
1366;; not sure how much: at least some keybindings, like C-c C-f;
1367;; syntax?; font-locking, e.g. for triple-quoted strings?
1368(define-derived-mode inferior-python-mode comint-mode "Inferior Python" 1515(define-derived-mode inferior-python-mode comint-mode "Inferior Python"
1369 "Major mode for interacting with an inferior Python process. 1516 "Major mode for Python inferior process.
1370A Python process can be started with \\[run-python]. 1517Runs a Python interpreter as a subprocess of Emacs, with Python
1371 1518I/O through an Emacs buffer. Variables
1372Hooks `comint-mode-hook' and `inferior-python-mode-hook' are run in 1519`python-shell-interpreter' and `python-shell-interpreter-args'
1373that order. 1520controls which Python interpreter is run. Variables
1374 1521`python-shell-prompt-regexp',
1375You can send text to the inferior Python process from other buffers 1522`python-shell-prompt-output-regexp',
1376containing Python source. 1523`python-shell-prompt-block-regexp',
1377 * \\[python-switch-to-python] switches the current buffer to the Python 1524`python-shell-enable-font-lock',
1378 process buffer. 1525`python-shell-completion-setup-code',
1379 * \\[python-send-region] sends the current region to the Python process. 1526`python-shell-completion-string-code',
1380 * \\[python-send-region-and-go] switches to the Python process buffer 1527`python-shell-completion-module-string-code',
1381 after sending the text. 1528`python-eldoc-setup-code', `python-eldoc-string-code',
1382For running multiple processes in multiple buffers, see `run-python' and 1529`python-ffap-setup-code' and `python-ffap-string-code' can
1383`python-buffer'. 1530customize this mode for different Python interpreters.
1384 1531
1385\\{inferior-python-mode-map}" 1532You can also add additional setup code to be run at
1386 :group 'python 1533initialization of the interpreter via `python-shell-setup-codes'
1534variable.
1535
1536\(Type \\[describe-mode] in the process buffer for a list of commands.)"
1537 (set-syntax-table python-mode-syntax-table)
1387 (setq mode-line-process '(":%s")) 1538 (setq mode-line-process '(":%s"))
1388 (set (make-local-variable 'comint-input-filter) 'python-input-filter) 1539 (setq comint-prompt-regexp (format "^\\(?:%s\\|%s\\|%s\\)"
1389 (add-hook 'comint-preoutput-filter-functions #'python-preoutput-filter 1540 python-shell-prompt-regexp
1390 nil t) 1541 python-shell-prompt-block-regexp
1391 (python--set-prompt-regexp) 1542 python-shell-prompt-pdb-regexp))
1543 (make-local-variable 'comint-output-filter-functions)
1544 (add-hook 'comint-output-filter-functions
1545 'python-comint-output-filter-function)
1546 (add-hook 'comint-output-filter-functions
1547 'python-pdbtrack-comint-output-filter-function)
1392 (set (make-local-variable 'compilation-error-regexp-alist) 1548 (set (make-local-variable 'compilation-error-regexp-alist)
1393 python-compilation-regexp-alist) 1549 python-shell-compilation-regexp-alist)
1550 (define-key inferior-python-mode-map [remap complete-symbol]
1551 'completion-at-point)
1552 (add-hook 'completion-at-point-functions
1553 'python-shell-completion-complete-at-point nil 'local)
1554 (add-to-list (make-local-variable 'comint-dynamic-complete-functions)
1555 'python-shell-completion-complete-at-point)
1556 (define-key inferior-python-mode-map (kbd "<tab>")
1557 'python-shell-completion-complete-or-indent)
1558 (when python-shell-enable-font-lock
1559 (set (make-local-variable 'font-lock-defaults)
1560 '(python-font-lock-keywords nil nil nil nil))
1561 (set (make-local-variable 'syntax-propertize-function)
1562 python-syntax-propertize-function))
1394 (compilation-shell-minor-mode 1)) 1563 (compilation-shell-minor-mode 1))
1395 1564
1396(defcustom inferior-python-filter-regexp "\\`\\s-*\\S-?\\S-?\\s-*\\'" 1565(defun python-shell-make-comint (cmd proc-name &optional pop)
1397 "Input matching this regexp is not saved on the history list. 1566 "Create a python shell comint buffer.
1398Default ignores all inputs of 0, 1, or 2 non-blank characters." 1567CMD is the python command to be executed and PROC-NAME is the
1399 :type 'regexp 1568process name the comint buffer will get. After the comint buffer
1400 :group 'python) 1569is created the `inferior-python-mode' is activated. If POP is
1401 1570non-nil the buffer is shown."
1402(defcustom python-remove-cwd-from-path t 1571 (save-excursion
1403 "Whether to allow loading of Python modules from the current directory. 1572 (let* ((proc-buffer-name (format "*%s*" proc-name))
1404If this is non-nil, Emacs removes '' from sys.path when starting 1573 (process-environment (python-shell-calculate-process-environment))
1405an inferior Python process. This is the default, for security 1574 (exec-path (python-shell-calculate-exec-path)))
1406reasons, as it is easy for the Python process to be started 1575 (when (not (comint-check-proc proc-buffer-name))
1407without the user's realization (e.g. to perform completion)." 1576 (let* ((cmdlist (split-string-and-unquote cmd))
1408 :type 'boolean 1577 (buffer (apply 'make-comint proc-name (car cmdlist) nil
1409 :group 'python 1578 (cdr cmdlist)))
1410 :version "23.3") 1579 (current-buffer (current-buffer)))
1411 1580 (with-current-buffer buffer
1412(defun python-input-filter (str) 1581 (inferior-python-mode)
1413 "`comint-input-filter' function for inferior Python. 1582 (python-util-clone-local-variables current-buffer))))
1414Don't save anything for STR matching `inferior-python-filter-regexp'." 1583 (when pop
1415 (not (string-match inferior-python-filter-regexp str))) 1584 (pop-to-buffer proc-buffer-name))
1416 1585 proc-buffer-name)))
1417;; Fixme: Loses with quoted whitespace. 1586
1418(defun python-args-to-list (string) 1587(defun run-python (dedicated cmd)
1419 (let ((where (string-match "[ \t]" string))) 1588 "Run an inferior Python process.
1420 (cond ((null where) (list string)) 1589Input and output via buffer named after
1421 ((not (= where 0)) 1590`python-shell-buffer-name'. If there is a process already
1422 (cons (substring string 0 where) 1591running in that buffer, just switch to it.
1423 (python-args-to-list (substring string (+ 1 where))))) 1592With argument, allows you to define DEDICATED, so a dedicated
1424 (t (let ((pos (string-match "[^ \t]" string))) 1593process for the current buffer is open, and define CMD so you can
1425 (if pos (python-args-to-list (substring string pos)))))))) 1594edit the command used to call the interpreter (default is value
1426 1595of `python-shell-interpreter' and arguments defined in
1427(defvar python-preoutput-result nil 1596`python-shell-interpreter-args'). Runs the hook
1428 "Data from last `_emacs_out' line seen by the preoutput filter.") 1597`inferior-python-mode-hook' (after the `comint-mode-hook' is
1429 1598run).
1430(defvar python-preoutput-continuation nil 1599\(Type \\[describe-mode] in the process buffer for a list of commands.)"
1431 "If non-nil, funcall this when `python-preoutput-filter' sees `_emacs_ok'.") 1600 (interactive
1432 1601 (if current-prefix-arg
1433(defvar python-preoutput-leftover nil) 1602 (list
1434(defvar python-preoutput-skip-next-prompt nil) 1603 (y-or-n-p "Make dedicated process? ")
1435 1604 (read-string "Run Python: " (python-shell-parse-command)))
1436;; Using this stops us getting lines in the buffer like 1605 (list nil (python-shell-parse-command))))
1437;; >>> ... ... >>> 1606 (python-shell-make-comint cmd (python-shell-get-process-name dedicated))
1438;; Also look for (and delete) an `_emacs_ok' string and call 1607 dedicated)
1439;; `python-preoutput-continuation' if we get it. 1608
1440(defun python-preoutput-filter (s) 1609(defun run-python-internal ()
1441 "`comint-preoutput-filter-functions' function: ignore prompts not at bol." 1610 "Run an inferior Internal Python process.
1442 (when python-preoutput-leftover 1611Input and output via buffer named after
1443 (setq s (concat python-preoutput-leftover s)) 1612`python-shell-internal-buffer-name' and what
1444 (setq python-preoutput-leftover nil)) 1613`python-shell-internal-get-process-name' returns. This new kind
1445 (let ((start 0) 1614of shell is intended to be used for generic communication related
1446 (res "")) 1615to defined configurations. The main difference with global or
1447 ;; First process whole lines. 1616dedicated shells is that these ones are attached to a
1448 (while (string-match "\n" s start) 1617configuration, not a buffer. This means that can be used for
1449 (let ((line (substring s start (setq start (match-end 0))))) 1618example to retrieve the sys.path and other stuff, without messing
1450 ;; Skip prompt if needed. 1619with user shells. Runs the hook
1451 (when (and python-preoutput-skip-next-prompt 1620`inferior-python-mode-hook' (after the `comint-mode-hook' is
1452 (string-match comint-prompt-regexp line)) 1621run). \(Type \\[describe-mode] in the process buffer for a list
1453 (setq python-preoutput-skip-next-prompt nil) 1622of commands.)"
1454 (setq line (substring line (match-end 0))))
1455 ;; Recognize special _emacs_out lines.
1456 (if (and (string-match "\\`_emacs_out \\(.*\\)\n\\'" line)
1457 (local-variable-p 'python-preoutput-result))
1458 (progn
1459 (setq python-preoutput-result (match-string 1 line))
1460 (set (make-local-variable 'python-preoutput-skip-next-prompt) t))
1461 (setq res (concat res line)))))
1462 ;; Then process the remaining partial line.
1463 (unless (zerop start) (setq s (substring s start)))
1464 (cond ((and (string-match comint-prompt-regexp s)
1465 ;; Drop this prompt if it follows an _emacs_out...
1466 (or python-preoutput-skip-next-prompt
1467 ;; ... or if it's not gonna be inserted at BOL.
1468 ;; Maybe we could be more selective here.
1469 (if (zerop (length res))
1470 (not (bolp))
1471 (string-match ".\\'" res))))
1472 ;; The need for this seems to be system-dependent:
1473 ;; What is this all about, exactly? --Stef
1474 ;; (if (and (eq ?. (aref s 0)))
1475 ;; (accept-process-output (get-buffer-process (current-buffer)) 1))
1476 (setq python-preoutput-skip-next-prompt nil)
1477 res)
1478 ((let ((end (min (length "_emacs_out ") (length s))))
1479 (eq t (compare-strings s nil end "_emacs_out " nil end)))
1480 ;; The leftover string is a prefix of _emacs_out so we don't know
1481 ;; yet whether it's an _emacs_out or something else: wait until we
1482 ;; get more output so we can resolve this ambiguity.
1483 (set (make-local-variable 'python-preoutput-leftover) s)
1484 res)
1485 (t (concat res s)))))
1486
1487(defvar python-version-checked nil)
1488(defun python-check-version (cmd)
1489 "Check that CMD runs a suitable version of Python."
1490 ;; Fixme: Check on Jython.
1491 (unless (or python-version-checked
1492 (equal 0 (string-match (regexp-quote python-python-command)
1493 cmd)))
1494 (unless (shell-command-to-string cmd)
1495 (error "Can't run Python command `%s'" cmd))
1496 (let* ((res (shell-command-to-string
1497 (concat cmd
1498 " -c \"from sys import version_info;\
1499print version_info >= (2, 2) and version_info < (3, 0)\""))))
1500 (unless (string-match "True" res)
1501 (error "Only Python versions >= 2.2 and < 3.0 are supported")))
1502 (setq python-version-checked t)))
1503
1504;;;###autoload
1505(defun run-python (&optional cmd noshow new)
1506 "Run an inferior Python process, input and output via buffer *Python*.
1507CMD is the Python command to run. NOSHOW non-nil means don't
1508show the buffer automatically.
1509
1510Interactively, a prefix arg means to prompt for the initial
1511Python command line (default is `python-command').
1512
1513A new process is started if one isn't running attached to
1514`python-buffer', or if called from Lisp with non-nil arg NEW.
1515Otherwise, if a process is already running in `python-buffer',
1516switch to that buffer.
1517
1518This command runs the hook `inferior-python-mode-hook' after
1519running `comint-mode-hook'. Type \\[describe-mode] in the
1520process buffer for a list of commands.
1521
1522By default, Emacs inhibits the loading of Python modules from the
1523current working directory, for security reasons. To disable this
1524behavior, change `python-remove-cwd-from-path' to nil."
1525 (interactive (if current-prefix-arg
1526 (list (read-string "Run Python: " python-command) nil t)
1527 (list python-command)))
1528 (unless cmd (setq cmd python-command))
1529 (python-check-version cmd)
1530 (setq python-command cmd)
1531 ;; Fixme: Consider making `python-buffer' buffer-local as a buffer
1532 ;; (not a name) in Python buffers from which `run-python' &c is
1533 ;; invoked. Would support multiple processes better.
1534 (when (or new (not (comint-check-proc python-buffer)))
1535 (with-current-buffer
1536 (let* ((cmdlist
1537 (append (python-args-to-list cmd) '("-i")
1538 (if python-remove-cwd-from-path
1539 '("-c" "import sys; sys.path.remove('')"))))
1540 (path (getenv "PYTHONPATH"))
1541 (process-environment ; to import emacs.py
1542 (cons (concat "PYTHONPATH="
1543 (if path (concat path path-separator))
1544 data-directory)
1545 process-environment))
1546 ;; If we use a pipe, Unicode characters are not printed
1547 ;; correctly (Bug#5794) and IPython does not work at
1548 ;; all (Bug#5390).
1549 (process-connection-type t))
1550 (apply 'make-comint-in-buffer "Python"
1551 (generate-new-buffer "*Python*")
1552 (car cmdlist) nil (cdr cmdlist)))
1553 (setq-default python-buffer (current-buffer))
1554 (setq python-buffer (current-buffer))
1555 (accept-process-output (get-buffer-process python-buffer) 5)
1556 (inferior-python-mode)
1557 ;; Load function definitions we need.
1558 ;; Before the preoutput function was used, this was done via -c in
1559 ;; cmdlist, but that loses the banner and doesn't run the startup
1560 ;; file. The code might be inline here, but there's enough that it
1561 ;; seems worth putting in a separate file, and it's probably cleaner
1562 ;; to put it in a module.
1563 ;; Ensure we're at a prompt before doing anything else.
1564 (python-send-string "import emacs")
1565 ;; The following line was meant to ensure that we're at a prompt
1566 ;; before doing anything else. However, this can cause Emacs to
1567 ;; hang waiting for a response, if that Python function fails
1568 ;; (i.e. raises an exception).
1569 ;; (python-send-receive "print '_emacs_out ()'")
1570 ))
1571 (if (derived-mode-p 'python-mode)
1572 (setq python-buffer (default-value 'python-buffer))) ; buffer-local
1573 ;; Without this, help output goes into the inferior python buffer if
1574 ;; the process isn't already running.
1575 (sit-for 1 t) ;Should we use accept-process-output instead? --Stef
1576 (unless noshow (pop-to-buffer python-buffer t)))
1577
1578(defun python-send-command (command)
1579 "Like `python-send-string' but resets `compilation-shell-minor-mode'."
1580 (when (python-check-comint-prompt)
1581 (with-current-buffer (process-buffer (python-proc))
1582 (goto-char (point-max))
1583 (compilation-forget-errors)
1584 (python-send-string command)
1585 (setq compilation-last-buffer (current-buffer)))))
1586
1587(defun python-send-region (start end)
1588 "Send the region to the inferior Python process."
1589 ;; The region is evaluated from a temporary file. This avoids
1590 ;; problems with blank lines, which have different semantics
1591 ;; interactively and in files. It also saves the inferior process
1592 ;; buffer filling up with interpreter prompts. We need a Python
1593 ;; function to remove the temporary file when it has been evaluated
1594 ;; (though we could probably do it in Lisp with a Comint output
1595 ;; filter). This function also catches exceptions and truncates
1596 ;; tracebacks not to mention the frame of the function itself.
1597 ;;
1598 ;; The `compilation-shell-minor-mode' parsing takes care of relating
1599 ;; the reference to the temporary file to the source.
1600 ;;
1601 ;; Fixme: Write a `coding' header to the temp file if the region is
1602 ;; non-ASCII.
1603 (interactive "r")
1604 (let* ((f (make-temp-file "py" nil ".py"))
1605 (command
1606 ;; IPython puts the FakeModule module into __main__ so
1607 ;; emacs.eexecfile becomes useless.
1608 (if (string-match "^ipython" python-command)
1609 (format "execfile %S" f)
1610 (format "emacs.eexecfile(%S)" f)))
1611 (orig-start (copy-marker start)))
1612 (when (save-excursion
1613 (goto-char start)
1614 (/= 0 (current-indentation))) ; need dummy block
1615 (save-excursion
1616 (goto-char orig-start)
1617 ;; Wrong if we had indented code at buffer start.
1618 (set-marker orig-start (line-beginning-position 0)))
1619 (write-region "if True:\n" nil f nil 'nomsg))
1620 (write-region start end f t 'nomsg)
1621 (python-send-command command)
1622 (with-current-buffer (process-buffer (python-proc))
1623 ;; Tell compile.el to redirect error locations in file `f' to
1624 ;; positions past marker `orig-start'. It has to be done *after*
1625 ;; `python-send-command''s call to `compilation-forget-errors'.
1626 (compilation-fake-loc orig-start f))))
1627
1628(defun python-send-string (string)
1629 "Evaluate STRING in inferior Python process."
1630 (interactive "sPython command: ")
1631 (comint-send-string (python-proc) string)
1632 (unless (string-match "\n\\'" string)
1633 ;; Make sure the text is properly LF-terminated.
1634 (comint-send-string (python-proc) "\n"))
1635 (when (string-match "\n[ \t].*\n?\\'" string)
1636 ;; If the string contains a final indented line, add a second newline so
1637 ;; as to make sure we terminate the multiline instruction.
1638 (comint-send-string (python-proc) "\n")))
1639
1640(defun python-send-buffer ()
1641 "Send the current buffer to the inferior Python process."
1642 (interactive) 1623 (interactive)
1643 (python-send-region (point-min) (point-max))) 1624 (set-process-query-on-exit-flag
1625 (get-buffer-process
1626 (python-shell-make-comint
1627 (python-shell-parse-command)
1628 (python-shell-internal-get-process-name))) nil))
1629
1630(defun python-shell-get-process ()
1631 "Get inferior Python process for current buffer and return it."
1632 (let* ((dedicated-proc-name (python-shell-get-process-name t))
1633 (dedicated-proc-buffer-name (format "*%s*" dedicated-proc-name))
1634 (global-proc-name (python-shell-get-process-name nil))
1635 (global-proc-buffer-name (format "*%s*" global-proc-name))
1636 (dedicated-running (comint-check-proc dedicated-proc-buffer-name))
1637 (global-running (comint-check-proc global-proc-buffer-name)))
1638 ;; Always prefer dedicated
1639 (get-buffer-process (or (and dedicated-running dedicated-proc-buffer-name)
1640 (and global-running global-proc-buffer-name)))))
1641
1642(defun python-shell-get-or-create-process ()
1643 "Get or create an inferior Python process for current buffer and return it."
1644 (let* ((dedicated-proc-name (python-shell-get-process-name t))
1645 (dedicated-proc-buffer-name (format "*%s*" dedicated-proc-name))
1646 (global-proc-name (python-shell-get-process-name nil))
1647 (global-proc-buffer-name (format "*%s*" global-proc-name))
1648 (dedicated-running (comint-check-proc dedicated-proc-buffer-name))
1649 (global-running (comint-check-proc global-proc-buffer-name))
1650 (current-prefix-arg 4))
1651 (when (and (not dedicated-running) (not global-running))
1652 (if (call-interactively 'run-python)
1653 (setq dedicated-running t)
1654 (setq global-running t)))
1655 ;; Always prefer dedicated
1656 (get-buffer-process (if dedicated-running
1657 dedicated-proc-buffer-name
1658 global-proc-buffer-name))))
1659
1660(defvar python-shell-internal-buffer nil
1661 "Current internal shell buffer for the current buffer.
1662This is really not necessary at all for the code to work but it's
1663there for compatibility with CEDET.")
1664(make-variable-buffer-local 'python-shell-internal-buffer)
1665
1666(defun python-shell-internal-get-or-create-process ()
1667 "Get or create an inferior Internal Python process."
1668 (let* ((proc-name (python-shell-internal-get-process-name))
1669 (proc-buffer-name (format "*%s*" proc-name)))
1670 (run-python-internal)
1671 (setq python-shell-internal-buffer proc-buffer-name)
1672 (get-buffer-process proc-buffer-name)))
1673
1674(define-obsolete-function-alias
1675 'python-proc 'python-shell-internal-get-or-create-process "24.2")
1676
1677(define-obsolete-variable-alias
1678 'python-buffer 'python-shell-internal-buffer "24.2")
1679
1680(defun python-shell-send-string (string &optional process msg)
1681 "Send STRING to inferior Python PROCESS.
1682When MSG is non-nil messages the first line of STRING."
1683 (interactive "sPython command: ")
1684 (let ((process (or process (python-shell-get-or-create-process)))
1685 (lines (split-string string "\n" t)))
1686 (when msg
1687 (message (format "Sent: %s..." (nth 0 lines))))
1688 (if (> (length lines) 1)
1689 (let* ((temp-file-name (make-temp-file "py"))
1690 (file-name (or (buffer-file-name) temp-file-name)))
1691 (with-temp-file temp-file-name
1692 (insert string)
1693 (delete-trailing-whitespace))
1694 (python-shell-send-file file-name process temp-file-name))
1695 (comint-send-string process string)
1696 (when (or (not (string-match "\n$" string))
1697 (string-match "\n[ \t].*\n?$" string))
1698 (comint-send-string process "\n")))))
1699
1700(defun python-shell-send-string-no-output (string &optional process msg)
1701 "Send STRING to PROCESS and inhibit output.
1702When MSG is non-nil messages the first line of STRING. Return
1703the output."
1704 (let* ((output-buffer)
1705 (process (or process (python-shell-get-or-create-process)))
1706 (comint-preoutput-filter-functions
1707 (append comint-preoutput-filter-functions
1708 '(ansi-color-filter-apply
1709 (lambda (string)
1710 (setq output-buffer (concat output-buffer string))
1711 "")))))
1712 (python-shell-send-string string process msg)
1713 (accept-process-output process)
1714 (replace-regexp-in-string
1715 (if (> (length python-shell-prompt-output-regexp) 0)
1716 (format "\n*%s$\\|^%s\\|\n$"
1717 python-shell-prompt-regexp
1718 (or python-shell-prompt-output-regexp ""))
1719 (format "\n*$\\|^%s\\|\n$"
1720 python-shell-prompt-regexp))
1721 "" output-buffer)))
1722
1723(defun python-shell-internal-send-string (string)
1724 "Send STRING to the Internal Python interpreter.
1725Returns the output. See `python-shell-send-string-no-output'."
1726 (python-shell-send-string-no-output
1727 ;; Makes this function compatible with the old
1728 ;; python-send-receive. (At least for CEDET).
1729 (replace-regexp-in-string "_emacs_out +" "" string)
1730 (python-shell-internal-get-or-create-process) nil))
1731
1732(define-obsolete-function-alias
1733 'python-send-receive 'python-shell-internal-send-string "24.2")
1734
1735(define-obsolete-function-alias
1736 'python-send-string 'python-shell-internal-send-string "24.2")
1737
1738(defun python-shell-send-region (start end)
1739 "Send the region delimited by START and END to inferior Python process."
1740 (interactive "r")
1741 (python-shell-send-string (buffer-substring start end) nil t))
1644 1742
1645;; Fixme: Try to define the function or class within the relevant 1743(defun python-shell-send-buffer (&optional arg)
1646;; module, not just at top level. 1744 "Send the entire buffer to inferior Python process.
1647(defun python-send-defun ()
1648 "Send the current defun (class or method) to the inferior Python process."
1649 (interactive)
1650 (save-excursion (python-send-region (progn (beginning-of-defun) (point))
1651 (progn (end-of-defun) (point)))))
1652 1745
1653(defun python-switch-to-python (eob-p) 1746With prefix ARG include lines surrounded by \"if __name__ == '__main__':\""
1654 "Switch to the Python process buffer, maybe starting new process.
1655With prefix arg, position cursor at end of buffer."
1656 (interactive "P") 1747 (interactive "P")
1657 (pop-to-buffer (process-buffer (python-proc)) t) ;Runs python if needed. 1748 (save-restriction
1658 (when eob-p 1749 (widen)
1659 (push-mark) 1750 (python-shell-send-region
1660 (goto-char (point-max)))) 1751 (point-min)
1661 1752 (or (and
1662(defun python-send-region-and-go (start end) 1753 (not arg)
1663 "Send the region to the inferior Python process. 1754 (save-excursion
1664Then switch to the process buffer." 1755 (re-search-forward (python-rx if-name-main) nil t))
1665 (interactive "r") 1756 (match-beginning 0))
1666 (python-send-region start end) 1757 (point-max)))))
1667 (python-switch-to-python t)) 1758
1668 1759(defun python-shell-send-defun (arg)
1669(defcustom python-source-modes '(python-mode jython-mode) 1760 "Send the current defun to inferior Python process.
1670 "Used to determine if a buffer contains Python source code. 1761When argument ARG is non-nil do not include decorators."
1671If a file is loaded into a buffer that is in one of these major modes, 1762 (interactive "P")
1672it is considered Python source by `python-load-file', which uses the 1763 (save-excursion
1673value to determine defaults." 1764 (python-shell-send-region
1674 :type '(repeat function) 1765 (progn
1675 :group 'python) 1766 (end-of-line 1)
1676 1767 (while (and (or (python-beginning-of-defun-function)
1677(defvar python-prev-dir/file nil 1768 (beginning-of-line 1))
1678 "Caches (directory . file) pair used in the last `python-load-file' command. 1769 (> (current-indentation) 0)))
1679Used for determining the default in the next one.") 1770 (when (not arg)
1680 1771 (while (and (forward-line -1)
1681(defun python-load-file (file-name) 1772 (looking-at (python-rx decorator))))
1682 "Load a Python file FILE-NAME into the inferior Python process. 1773 (forward-line 1))
1683If the file has extension `.py' import or reload it as a module. 1774 (point-marker))
1684Treating it as a module keeps the global namespace clean, provides 1775 (progn
1685function location information for debugging, and supports users of 1776 (or (python-end-of-defun-function)
1686module-qualified names." 1777 (end-of-line 1))
1687 (interactive (comint-get-source "Load Python file: " python-prev-dir/file 1778 (point-marker)))))
1688 python-source-modes 1779
1689 t)) ; because execfile needs exact name 1780(defun python-shell-send-file (file-name &optional process temp-file-name)
1690 (comint-check-source file-name) ; Check to see if buffer needs saving. 1781 "Send FILE-NAME to inferior Python PROCESS.
1691 (setq python-prev-dir/file (cons (file-name-directory file-name) 1782If TEMP-FILE-NAME is passed then that file is used for processing
1692 (file-name-nondirectory file-name))) 1783instead, while internally the shell will continue to use
1693 (with-current-buffer (process-buffer (python-proc)) ;Runs python if needed. 1784FILE-NAME."
1694 ;; Fixme: I'm not convinced by this logic from python-mode.el. 1785 (interactive "fFile to send: ")
1695 (python-send-command 1786 (let* ((process (or process (python-shell-get-or-create-process)))
1696 (if (string-match "\\.py\\'" file-name) 1787 (temp-file-name (when temp-file-name
1697 (let ((module (file-name-sans-extension 1788 (expand-file-name temp-file-name)))
1698 (file-name-nondirectory file-name)))) 1789 (file-name (or (expand-file-name file-name) temp-file-name)))
1699 (format "emacs.eimport(%S,%S)" 1790 (when (not file-name)
1700 module (file-name-directory file-name))) 1791 (error "If FILE-NAME is nil then TEMP-FILE-NAME must be non-nil"))
1701 (format "execfile(%S)" file-name))) 1792 (python-shell-send-string
1702 (message "%s loaded" file-name))) 1793 (format
1703 1794 (concat "__pyfile = open('''%s''');"
1704(defun python-proc () 1795 "exec(compile(__pyfile.read(), '''%s''', 'exec'));"
1705 "Return the current Python process. 1796 "__pyfile.close()")
1706See variable `python-buffer'. Starts a new process if necessary." 1797 (or temp-file-name file-name) file-name)
1707 ;; Fixme: Maybe should look for another active process if there 1798 process)))
1708 ;; isn't one for `python-buffer'. 1799
1709 (unless (comint-check-proc python-buffer) 1800(defun python-shell-switch-to-shell ()
1710 (run-python nil t)) 1801 "Switch to inferior Python process buffer."
1711 (get-buffer-process (if (derived-mode-p 'inferior-python-mode)
1712 (current-buffer)
1713 python-buffer)))
1714
1715(defun python-set-proc ()
1716 "Set the default value of `python-buffer' to correspond to this buffer.
1717If the current buffer has a local value of `python-buffer', set the
1718default (global) value to that. The associated Python process is
1719the one that gets input from \\[python-send-region] et al when used
1720in a buffer that doesn't have a local value of `python-buffer'."
1721 (interactive) 1802 (interactive)
1722 (if (local-variable-p 'python-buffer) 1803 (pop-to-buffer (process-buffer (python-shell-get-or-create-process)) t))
1723 (setq-default python-buffer python-buffer) 1804
1724 (error "No local value of `python-buffer'"))) 1805(defun python-shell-send-setup-code ()
1806 "Send all setup code for shell.
1807This function takes the list of setup code to send from the
1808`python-shell-setup-codes' list."
1809 (let ((msg "Sent %s")
1810 (process (get-buffer-process (current-buffer))))
1811 (accept-process-output process python-shell-send-setup-max-wait)
1812 (dolist (code python-shell-setup-codes)
1813 (when code
1814 (message (format msg code))
1815 (python-shell-send-string
1816 (symbol-value code) process)))))
1817
1818(add-hook 'inferior-python-mode-hook
1819 #'python-shell-send-setup-code)
1820
1725 1821
1726;;;; Context-sensitive help. 1822;;; Shell completion
1823
1824(defcustom python-shell-completion-setup-code
1825 "try:
1826 import readline
1827except ImportError:
1828 def __COMPLETER_all_completions(text): []
1829else:
1830 import rlcompleter
1831 readline.set_completer(rlcompleter.Completer().complete)
1832 def __COMPLETER_all_completions(text):
1833 import sys
1834 completions = []
1835 try:
1836 i = 0
1837 while True:
1838 res = readline.get_completer()(text, i)
1839 if not res: break
1840 i += 1
1841 completions.append(res)
1842 except NameError:
1843 pass
1844 return completions"
1845 "Code used to setup completion in inferior Python processes."
1846 :type 'string
1847 :group 'python)
1727 1848
1728(defconst python-dotty-syntax-table 1849(defcustom python-shell-completion-string-code
1729 (let ((table (make-syntax-table))) 1850 "';'.join(__COMPLETER_all_completions('''%s'''))\n"
1730 (set-char-table-parent table python-mode-syntax-table) 1851 "Python code used to get a string of completions separated by semicolons."
1731 (modify-syntax-entry ?. "_" table) 1852 :type 'string
1732 table) 1853 :group 'python)
1733 "Syntax table giving `.' symbol syntax.
1734Otherwise inherits from `python-mode-syntax-table'.")
1735 1854
1736(defvar view-return-to-alist) 1855(defcustom python-shell-completion-module-string-code ""
1737(eval-when-compile (autoload 'help-buffer "help-fns")) 1856 "Python code used to get completions separated by semicolons for imports.
1738 1857
1739(defvar python-imports) ; forward declaration 1858For IPython v0.11, add the following line to
1859`python-shell-completion-setup-code':
1740 1860
1741;; Fixme: Should this actually be used instead of info-look, i.e. be 1861from IPython.core.completerlib import module_completion
1742;; bound to C-h S? [Probably not, since info-look may work in cases
1743;; where this doesn't.]
1744(defun python-describe-symbol (symbol)
1745 "Get help on SYMBOL using `help'.
1746Interactively, prompt for symbol.
1747 1862
1748Symbol may be anything recognized by the interpreter's `help' 1863and use the following as the value of this variable:
1749command -- e.g. `CALLS' -- not just variables in scope in the
1750interpreter. This only works for Python version 2.2 or newer
1751since earlier interpreters don't support `help'.
1752 1864
1753In some cases where this doesn't find documentation, \\[info-lookup-symbol] 1865';'.join(module_completion('''%s'''))\n"
1754will." 1866 :type 'string
1755 ;; Note that we do this in the inferior process, not a separate one, to 1867 :group 'python)
1756 ;; ensure the environment is appropriate.
1757 (interactive
1758 (let ((symbol (with-syntax-table python-dotty-syntax-table
1759 (current-word)))
1760 (enable-recursive-minibuffers t))
1761 (list (read-string (if symbol
1762 (format "Describe symbol (default %s): " symbol)
1763 "Describe symbol: ")
1764 nil nil symbol))))
1765 (if (equal symbol "") (error "No symbol"))
1766 ;; Ensure we have a suitable help buffer.
1767 ;; Fixme: Maybe process `Related help topics' a la help xrefs and
1768 ;; allow C-c C-f in help buffer.
1769 (let ((temp-buffer-show-hook ; avoid xref stuff
1770 (lambda ()
1771 (setq buffer-read-only t)
1772 (setq view-return-to-alist
1773 (list (cons (selected-window) help-return-method))))))
1774 (with-output-to-temp-buffer (help-buffer)
1775 (with-current-buffer standard-output
1776 ;; Fixme: Is this actually useful?
1777 (help-setup-xref (list 'python-describe-symbol symbol)
1778 (called-interactively-p 'interactive))
1779 (set (make-local-variable 'comint-redirect-subvert-readonly) t)
1780 (help-print-return-message))))
1781 (comint-redirect-send-command-to-process (format "emacs.ehelp(%S, %s)"
1782 symbol python-imports)
1783 "*Help*" (python-proc) nil nil))
1784
1785(add-to-list 'debug-ignored-errors "^No symbol")
1786
1787(defun python-send-receive (string)
1788 "Send STRING to inferior Python (if any) and return result.
1789The result is what follows `_emacs_out' in the output.
1790This is a no-op if `python-check-comint-prompt' returns nil."
1791 (python-send-string string)
1792 (let ((proc (python-proc)))
1793 (with-current-buffer (process-buffer proc)
1794 (when (python-check-comint-prompt proc)
1795 (set (make-local-variable 'python-preoutput-result) nil)
1796 (while (progn
1797 (accept-process-output proc 5)
1798 (null python-preoutput-result)))
1799 (prog1 python-preoutput-result
1800 (kill-local-variable 'python-preoutput-result))))))
1801
1802(defun python-check-comint-prompt (&optional proc)
1803 "Return non-nil if and only if there's a normal prompt in the inferior buffer.
1804If there isn't, it's probably not appropriate to send input to return Eldoc
1805information etc. If PROC is non-nil, check the buffer for that process."
1806 (with-current-buffer (process-buffer (or proc (python-proc)))
1807 (save-excursion
1808 (save-match-data
1809 (re-search-backward (concat python--prompt-regexp " *\\=")
1810 nil t)))))
1811 1868
1812;; Fixme: Is there anything reasonable we can do with random methods? 1869(defcustom python-shell-completion-pdb-string-code
1813;; (Currently only works with functions.) 1870 "';'.join(globals().keys() + locals().keys())"
1814(defun python-eldoc-function () 1871 "Python code used to get completions separated by semicolons for [i]pdb."
1815 "`eldoc-documentation-function' for Python. 1872 :type 'string
1816Only works when point is in a function name, not its arg list, for 1873 :group 'python)
1817instance. Assumes an inferior Python is running."
1818 (let ((symbol (with-syntax-table python-dotty-syntax-table
1819 (current-word))))
1820 ;; This is run from timers, so inhibit-quit tends to be set.
1821 (with-local-quit
1822 ;; First try the symbol we're on.
1823 (or (and symbol
1824 (python-send-receive (format "emacs.eargs(%S, %s)"
1825 symbol python-imports)))
1826 ;; Try moving to symbol before enclosing parens.
1827 (let ((s (syntax-ppss)))
1828 (unless (zerop (car s))
1829 (when (eq ?\( (char-after (nth 1 s)))
1830 (save-excursion
1831 (goto-char (nth 1 s))
1832 (skip-syntax-backward "-")
1833 (let ((point (point)))
1834 (skip-chars-backward "a-zA-Z._")
1835 (if (< (point) point)
1836 (python-send-receive
1837 (format "emacs.eargs(%S, %s)"
1838 (buffer-substring-no-properties (point) point)
1839 python-imports))))))))))))
1840
1841;;;; Info-look functionality.
1842 1874
1843(declare-function info-lookup-maybe-add-help "info-look" (&rest arg)) 1875(defun python-shell-completion--get-completions (input process completion-code)
1876 "Retrieve available completions for INPUT using PROCESS.
1877Argument COMPLETION-CODE is the python code used to get
1878completions on the current context."
1879 (with-current-buffer (process-buffer process)
1880 (let ((completions (python-shell-send-string-no-output
1881 (format completion-code input) process)))
1882 (when (> (length completions) 2)
1883 (split-string completions "^'\\|^\"\\|;\\|'$\\|\"$" t)))))
1884
1885(defun python-shell-completion--do-completion-at-point (process)
1886 "Do completion at point for PROCESS."
1887 (with-syntax-table python-dotty-syntax-table
1888 (let* ((beg
1889 (save-excursion
1890 (let* ((paren-depth (car (syntax-ppss)))
1891 (syntax-string "w_")
1892 (syntax-list (string-to-syntax syntax-string)))
1893 ;; Stop scanning for the beginning of the completion subject
1894 ;; after the char before point matches a delimiter
1895 (while (member (car (syntax-after (1- (point)))) syntax-list)
1896 (skip-syntax-backward syntax-string)
1897 (when (or (equal (char-before) ?\))
1898 (equal (char-before) ?\"))
1899 (forward-char -1))
1900 (while (or
1901 ;; honor initial paren depth
1902 (> (car (syntax-ppss)) paren-depth)
1903 (python-info-ppss-context 'string))
1904 (forward-char -1))))
1905 (point)))
1906 (end (point))
1907 (line (buffer-substring-no-properties (point-at-bol) end))
1908 (input (buffer-substring-no-properties beg end))
1909 ;; Get the last prompt for the inferior process buffer. This is
1910 ;; used for the completion code selection heuristic.
1911 (prompt
1912 (with-current-buffer (process-buffer process)
1913 (buffer-substring-no-properties
1914 (overlay-start comint-last-prompt-overlay)
1915 (overlay-end comint-last-prompt-overlay))))
1916 (completion-context
1917 ;; Check whether a prompt matches a pdb string, an import statement
1918 ;; or just the standard prompt and use the correct
1919 ;; python-shell-completion-*-code string
1920 (cond ((and (> (length python-shell-completion-pdb-string-code) 0)
1921 (string-match
1922 (concat "^" python-shell-prompt-pdb-regexp) prompt))
1923 'pdb)
1924 ((and (>
1925 (length python-shell-completion-module-string-code) 0)
1926 (string-match
1927 (concat "^" python-shell-prompt-regexp) prompt)
1928 (string-match "^[ \t]*\\(from\\|import\\)[ \t]" line))
1929 'import)
1930 ((string-match
1931 (concat "^" python-shell-prompt-regexp) prompt)
1932 'default)
1933 (t nil)))
1934 (completion-code
1935 (case completion-context
1936 ('pdb python-shell-completion-pdb-string-code)
1937 ('import python-shell-completion-module-string-code)
1938 ('default python-shell-completion-string-code)
1939 (t nil)))
1940 (input
1941 (if (eq completion-context 'import)
1942 (replace-regexp-in-string "^[ \t]+" "" line)
1943 input))
1944 (completions
1945 (and completion-code (> (length input) 0)
1946 (python-shell-completion--get-completions
1947 input process completion-code))))
1948 (list beg end completions))))
1949
1950(defun python-shell-completion-complete-at-point ()
1951 "Perform completion at point in inferior Python process."
1952 (interactive)
1953 (and comint-last-prompt-overlay
1954 (> (point-marker) (overlay-end comint-last-prompt-overlay))
1955 (python-shell-completion--do-completion-at-point
1956 (get-buffer-process (current-buffer)))))
1957
1958(defun python-shell-completion-complete-or-indent ()
1959 "Complete or indent depending on the context.
1960If content before pointer is all whitespace indent. If not try
1961to complete."
1962 (interactive)
1963 (if (string-match "^[[:space:]]*$"
1964 (buffer-substring (comint-line-beginning-position)
1965 (point-marker)))
1966 (indent-for-tab-command)
1967 (completion-at-point)))
1844 1968
1845;;;###autoload
1846(defun python-after-info-look ()
1847 "Set up info-look for Python.
1848Used with `eval-after-load'."
1849 (let* ((version (let ((s (shell-command-to-string (concat python-command
1850 " -V"))))
1851 (string-match "^Python \\([0-9]+\\.[0-9]+\\>\\)" s)
1852 (match-string 1 s)))
1853 ;; Whether info files have a Python version suffix, e.g. in Debian.
1854 (versioned
1855 (with-temp-buffer
1856 (with-no-warnings (Info-mode))
1857 (condition-case ()
1858 ;; Don't use `info' because it would pop-up a *info* buffer.
1859 (with-no-warnings
1860 (Info-goto-node (format "(python%s-lib)Miscellaneous Index"
1861 version))
1862 t)
1863 (error nil)))))
1864 (info-lookup-maybe-add-help
1865 :mode 'python-mode
1866 :regexp "[[:alnum:]_]+"
1867 :doc-spec
1868 ;; Fixme: Can this reasonably be made specific to indices with
1869 ;; different rules? Is the order of indices optimal?
1870 ;; (Miscellaneous in -ref first prefers lookup of keywords, for
1871 ;; instance.)
1872 (if versioned
1873 ;; The empty prefix just gets us highlighted terms.
1874 `((,(concat "(python" version "-ref)Miscellaneous Index") nil "")
1875 (,(concat "(python" version "-ref)Module Index" nil ""))
1876 (,(concat "(python" version "-ref)Function-Method-Variable Index"
1877 nil ""))
1878 (,(concat "(python" version "-ref)Class-Exception-Object Index"
1879 nil ""))
1880 (,(concat "(python" version "-lib)Module Index" nil ""))
1881 (,(concat "(python" version "-lib)Class-Exception-Object Index"
1882 nil ""))
1883 (,(concat "(python" version "-lib)Function-Method-Variable Index"
1884 nil ""))
1885 (,(concat "(python" version "-lib)Miscellaneous Index" nil "")))
1886 '(("(python-ref)Miscellaneous Index" nil "")
1887 ("(python-ref)Module Index" nil "")
1888 ("(python-ref)Function-Method-Variable Index" nil "")
1889 ("(python-ref)Class-Exception-Object Index" nil "")
1890 ("(python-lib)Module Index" nil "")
1891 ("(python-lib)Class-Exception-Object Index" nil "")
1892 ("(python-lib)Function-Method-Variable Index" nil "")
1893 ("(python-lib)Miscellaneous Index" nil ""))))))
1894(eval-after-load "info-look" '(python-after-info-look))
1895 1969
1896;;;; Miscellany. 1970;;; PDB Track integration
1897 1971
1898(defcustom python-jython-packages '("java" "javax" "org" "com") 1972(defcustom python-pdbtrack-activate t
1899 "Packages implying `jython-mode'. 1973 "Non-nil makes python shell enable pdbtracking."
1900If these are imported near the beginning of the buffer, `python-mode' 1974 :type 'boolean
1901actually punts to `jython-mode'." 1975 :group 'python
1902 :type '(repeat string) 1976 :safe 'booleanp)
1903 :group 'python)
1904
1905;; Called from `python-mode', this causes a recursive call of the
1906;; mode. See logic there to break out of the recursion.
1907(defun python-maybe-jython ()
1908 "Invoke `jython-mode' if the buffer appears to contain Jython code.
1909The criterion is either a match for `jython-mode' via
1910`interpreter-mode-alist' or an import of a module from the list
1911`python-jython-packages'."
1912 ;; The logic is taken from python-mode.el.
1913 (save-excursion
1914 (save-restriction
1915 (widen)
1916 (goto-char (point-min))
1917 (let ((interpreter (if (looking-at auto-mode-interpreter-regexp)
1918 (match-string 2))))
1919 (if (and interpreter (eq 'jython-mode
1920 (cdr (assoc (file-name-nondirectory
1921 interpreter)
1922 interpreter-mode-alist))))
1923 (jython-mode)
1924 (if (catch 'done
1925 (while (re-search-forward
1926 (rx line-start (or "import" "from") (1+ space)
1927 (group (1+ (not (any " \t\n.")))))
1928 (+ (point-min) 10000) ; Probably not worth customizing.
1929 t)
1930 (if (member (match-string 1) python-jython-packages)
1931 (throw 'done t))))
1932 (jython-mode)))))))
1933
1934(defun python-fill-paragraph (&optional justify)
1935 "`fill-paragraph-function' handling multi-line strings and possibly comments.
1936If any of the current line is in or at the end of a multi-line string,
1937fill the string or the paragraph of it that point is in, preserving
1938the string's indentation."
1939 (interactive "P")
1940 (or (fill-comment-paragraph justify)
1941 (save-excursion
1942 (end-of-line)
1943 (let* ((syntax (syntax-ppss))
1944 (orig (point))
1945 start end)
1946 (cond ((nth 4 syntax) ; comment. fixme: loses with trailing one
1947 (let (fill-paragraph-function)
1948 (fill-paragraph justify)))
1949 ;; The `paragraph-start' and `paragraph-separate'
1950 ;; variables don't allow us to delimit the last
1951 ;; paragraph in a multi-line string properly, so narrow
1952 ;; to the string and then fill around (the end of) the
1953 ;; current line.
1954 ((nth 3 syntax) ; in fenced string
1955 (goto-char (nth 8 syntax)) ; string start
1956 (setq start (line-beginning-position))
1957 (setq end (condition-case () ; for unbalanced quotes
1958 (progn (forward-sexp)
1959 (- (point) 3))
1960 (error (point-max)))))
1961 ((re-search-backward "\\s|\\s-*\\=" nil t) ; end of fenced string
1962 (forward-char)
1963 (setq end (point))
1964 (condition-case ()
1965 (progn (backward-sexp)
1966 (setq start (line-beginning-position)))
1967 (error nil))))
1968 (when end
1969 (save-restriction
1970 (narrow-to-region start end)
1971 (goto-char orig)
1972 ;; Avoid losing leading and trailing newlines in doc
1973 ;; strings written like:
1974 ;; """
1975 ;; ...
1976 ;; """
1977 (let ((paragraph-separate
1978 ;; Note that the string could be part of an
1979 ;; expression, so it can have preceding and
1980 ;; trailing non-whitespace.
1981 (concat
1982 (rx (or
1983 ;; Opening triple quote without following text.
1984 (and (* nonl)
1985 (group (syntax string-delimiter))
1986 (repeat 2 (backref 1))
1987 ;; Fixme: Not sure about including
1988 ;; trailing whitespace.
1989 (* (any " \t"))
1990 eol)
1991 ;; Closing trailing quote without preceding text.
1992 (and (group (any ?\" ?')) (backref 2)
1993 (syntax string-delimiter))))
1994 "\\(?:" paragraph-separate "\\)"))
1995 fill-paragraph-function)
1996 (fill-paragraph justify))))))) t)
1997
1998(defun python-shift-left (start end &optional count)
1999 "Shift lines in region COUNT (the prefix arg) columns to the left.
2000COUNT defaults to `python-indent'. If region isn't active, just shift
2001current line. The region shifted includes the lines in which START and
2002END lie. It is an error if any lines in the region are indented less than
2003COUNT columns."
2004 (interactive
2005 (if mark-active
2006 (list (region-beginning) (region-end) current-prefix-arg)
2007 (list (line-beginning-position) (line-end-position) current-prefix-arg)))
2008 (if count
2009 (setq count (prefix-numeric-value count))
2010 (setq count python-indent))
2011 (when (> count 0)
2012 (save-excursion
2013 (goto-char start)
2014 (while (< (point) end)
2015 (if (and (< (current-indentation) count)
2016 (not (looking-at "[ \t]*$")))
2017 (error "Can't shift all lines enough"))
2018 (forward-line))
2019 (indent-rigidly start end (- count)))))
2020 1977
2021(add-to-list 'debug-ignored-errors "^Can't shift all lines enough") 1978(defcustom python-pdbtrack-stacktrace-info-regexp
1979 "^> \\([^\"(<]+\\)(\\([0-9]+\\))\\([?a-zA-Z0-9_<>]+\\)()"
1980 "Regular Expression matching stacktrace information.
1981Used to extract the current line and module being inspected."
1982 :type 'string
1983 :group 'python
1984 :safe 'stringp)
1985
1986(defvar python-pdbtrack-tracked-buffer nil
1987 "Variable containing the value of the current tracked buffer.
1988Never set this variable directly, use
1989`python-pdbtrack-set-tracked-buffer' instead.")
1990(make-variable-buffer-local 'python-pdbtrack-tracked-buffer)
1991
1992(defvar python-pdbtrack-buffers-to-kill nil
1993 "List of buffers to be deleted after tracking finishes.")
1994(make-variable-buffer-local 'python-pdbtrack-buffers-to-kill)
1995
1996(defun python-pdbtrack-set-tracked-buffer (file-name)
1997 "Set the buffer for FILE-NAME as the tracked buffer.
1998Internally it uses the `python-pdbtrack-tracked-buffer' variable.
1999Returns the tracked buffer."
2000 (let ((file-buffer (get-file-buffer file-name)))
2001 (if file-buffer
2002 (setq python-pdbtrack-tracked-buffer file-buffer)
2003 (setq file-buffer (find-file-noselect file-name))
2004 (when (not (member file-buffer python-pdbtrack-buffers-to-kill))
2005 (add-to-list 'python-pdbtrack-buffers-to-kill file-buffer)))
2006 file-buffer))
2007
2008(defun python-pdbtrack-comint-output-filter-function (output)
2009 "Move overlay arrow to current pdb line in tracked buffer.
2010Argument OUTPUT is a string with the output from the comint process."
2011 (when (and python-pdbtrack-activate (not (string= output "")))
2012 (let* ((full-output (ansi-color-filter-apply
2013 (buffer-substring comint-last-input-end (point-max))))
2014 (line-number)
2015 (file-name
2016 (with-temp-buffer
2017 (insert full-output)
2018 (goto-char (point-min))
2019 ;; OK, this sucked but now it became a cool hack. The
2020 ;; stacktrace information normally is on the first line
2021 ;; but in some cases (like when doing a step-in) it is
2022 ;; on the second.
2023 (when (or (looking-at python-pdbtrack-stacktrace-info-regexp)
2024 (and
2025 (forward-line)
2026 (looking-at python-pdbtrack-stacktrace-info-regexp)))
2027 (setq line-number (string-to-number
2028 (match-string-no-properties 2)))
2029 (match-string-no-properties 1)))))
2030 (if (and file-name line-number)
2031 (let* ((tracked-buffer
2032 (python-pdbtrack-set-tracked-buffer file-name))
2033 (shell-buffer (current-buffer))
2034 (tracked-buffer-window (get-buffer-window tracked-buffer))
2035 (tracked-buffer-line-pos))
2036 (with-current-buffer tracked-buffer
2037 (set (make-local-variable 'overlay-arrow-string) "=>")
2038 (set (make-local-variable 'overlay-arrow-position) (make-marker))
2039 (setq tracked-buffer-line-pos (progn
2040 (goto-char (point-min))
2041 (forward-line (1- line-number))
2042 (point-marker)))
2043 (when tracked-buffer-window
2044 (set-window-point
2045 tracked-buffer-window tracked-buffer-line-pos))
2046 (set-marker overlay-arrow-position tracked-buffer-line-pos))
2047 (pop-to-buffer tracked-buffer)
2048 (switch-to-buffer-other-window shell-buffer))
2049 (when python-pdbtrack-tracked-buffer
2050 (with-current-buffer python-pdbtrack-tracked-buffer
2051 (set-marker overlay-arrow-position nil))
2052 (mapc #'(lambda (buffer)
2053 (ignore-errors (kill-buffer buffer)))
2054 python-pdbtrack-buffers-to-kill)
2055 (setq python-pdbtrack-tracked-buffer nil
2056 python-pdbtrack-buffers-to-kill nil)))))
2057 output)
2022 2058
2023(defun python-shift-right (start end &optional count)
2024 "Shift lines in region COUNT (the prefix arg) columns to the right.
2025COUNT defaults to `python-indent'. If region isn't active, just shift
2026current line. The region shifted includes the lines in which START and
2027END lie."
2028 (interactive
2029 (if mark-active
2030 (list (region-beginning) (region-end) current-prefix-arg)
2031 (list (line-beginning-position) (line-end-position) current-prefix-arg)))
2032 (if count
2033 (setq count (prefix-numeric-value count))
2034 (setq count python-indent))
2035 (indent-rigidly start end count))
2036
2037(defun python-outline-level ()
2038 "`outline-level' function for Python mode.
2039The level is the number of `python-indent' steps of indentation
2040of current line."
2041 (1+ (/ (current-indentation) python-indent)))
2042
2043;; Fixme: Consider top-level assignments, imports, &c.
2044(defun python-current-defun (&optional length-limit)
2045 "`add-log-current-defun-function' for Python."
2046 (save-excursion
2047 ;; Move up the tree of nested `class' and `def' blocks until we
2048 ;; get to zero indentation, accumulating the defined names.
2049 (let ((accum)
2050 (length -1))
2051 (catch 'done
2052 (while (or (null length-limit)
2053 (null (cdr accum))
2054 (< length length-limit))
2055 (let ((started-from (point)))
2056 (python-beginning-of-block)
2057 (end-of-line)
2058 (beginning-of-defun)
2059 (when (= (point) started-from)
2060 (throw 'done nil)))
2061 (when (looking-at (rx (0+ space) (or "def" "class") (1+ space)
2062 (group (1+ (or word (syntax symbol))))))
2063 (push (match-string 1) accum)
2064 (setq length (+ length 1 (length (car accum)))))
2065 (when (= (current-indentation) 0)
2066 (throw 'done nil))))
2067 (when accum
2068 (when (and length-limit (> length length-limit))
2069 (setcar accum ".."))
2070 (mapconcat 'identity accum ".")))))
2071
2072(defun python-mark-block ()
2073 "Mark the block around point.
2074Uses `python-beginning-of-block', `python-end-of-block'."
2075 (interactive)
2076 (push-mark)
2077 (python-beginning-of-block)
2078 (push-mark (point) nil t)
2079 (python-end-of-block)
2080 (exchange-point-and-mark))
2081
2082;; Fixme: Provide a find-function-like command to find source of a
2083;; definition (separate from BicycleRepairMan). Complicated by
2084;; finding the right qualified name.
2085 2059
2086;;;; Completion. 2060;;; Symbol completion
2087 2061
2088;; http://lists.gnu.org/archive/html/bug-gnu-emacs/2008-01/msg00076.html 2062(defun python-completion-complete-at-point ()
2089(defvar python-imports "None" 2063 "Complete current symbol at point.
2090 "String of top-level import statements updated by `python-find-imports'.") 2064For this to work the best as possible you should call
2091(make-variable-buffer-local 'python-imports) 2065`python-shell-send-buffer' from time to time so context in
2092 2066inferior python process is updated properly."
2093;; Fixme: Should font-lock try to run this when it deals with an import?
2094;; Maybe not a good idea if it gets run multiple times when the
2095;; statement is being edited, and is more likely to end up with
2096;; something syntactically incorrect.
2097;; However, what we should do is to trundle up the block tree from point
2098;; to extract imports that appear to be in scope, and add those.
2099(defun python-find-imports ()
2100 "Find top-level imports, updating `python-imports'."
2101 (interactive) 2067 (interactive)
2102 (save-excursion 2068 (let ((process (python-shell-get-process)))
2103 (let (lines) 2069 (if (not process)
2104 (goto-char (point-min)) 2070 (error "Completion needs an inferior Python process running")
2105 (while (re-search-forward "^import\\>\\|^from\\>" nil t) 2071 (python-shell-completion--do-completion-at-point process))))
2106 (unless (syntax-ppss-context (syntax-ppss))
2107 (let ((start (line-beginning-position)))
2108 ;; Skip over continued lines.
2109 (while (and (eq ?\\ (char-before (line-end-position)))
2110 (= 0 (forward-line 1)))
2111 t)
2112 (push (buffer-substring start (line-beginning-position 2))
2113 lines))))
2114 (setq python-imports
2115 (if lines
2116 (apply #'concat
2117;; This is probably best left out since you're unlikely to need the
2118;; doc for a function in the buffer and the import will lose if the
2119;; Python sub-process' working directory isn't the same as the
2120;; buffer's.
2121;; (if buffer-file-name
2122;; (concat
2123;; "import "
2124;; (file-name-sans-extension
2125;; (file-name-nondirectory buffer-file-name))))
2126 (nreverse lines))
2127 "None"))
2128 (when lines
2129 (set-text-properties 0 (length python-imports) nil python-imports)
2130 ;; The output ends up in the wrong place if the string we
2131 ;; send contains newlines (from the imports).
2132 (setq python-imports
2133 (replace-regexp-in-string "\n" "\\n"
2134 (format "%S" python-imports) t t))))))
2135
2136;; Fixme: This fails the first time if the sub-process isn't already
2137;; running. Presumably a timing issue with i/o to the process.
2138(defun python-symbol-completions (symbol)
2139 "Return a list of completions of the string SYMBOL from Python process.
2140The list is sorted.
2141Uses `python-imports' to load modules against which to complete."
2142 (when (stringp symbol)
2143 (let ((completions
2144 (condition-case ()
2145 (car (read-from-string
2146 (python-send-receive
2147 (format "emacs.complete(%S,%s)"
2148 (substring-no-properties symbol)
2149 python-imports))))
2150 (error nil))))
2151 (sort
2152 ;; We can get duplicates from the above -- don't know why.
2153 (delete-dups completions)
2154 #'string<))))
2155
2156(defun python-completion-at-point ()
2157 (let ((end (point))
2158 (start (save-excursion
2159 (and (re-search-backward
2160 (rx (or buffer-start (regexp "[^[:alnum:]._]"))
2161 (group (1+ (regexp "[[:alnum:]._]"))) point)
2162 nil t)
2163 (match-beginning 1)))))
2164 (when start
2165 (list start end
2166 (completion-table-dynamic 'python-symbol-completions)))))
2167
2168;;;; FFAP support
2169 2072
2170(defun python-module-path (module) 2073(add-to-list 'debug-ignored-errors
2171 "Function for `ffap-alist' to return path to MODULE." 2074 "^Completion needs an inferior Python process running.")
2172 (python-send-receive (format "emacs.modpath (%S)" module)))
2173 2075
2174(eval-after-load "ffap"
2175 '(push '(python-mode . python-module-path) ffap-alist))
2176 2076
2177;;;; Find-function support 2077;;; Fill paragraph
2178 2078
2179;; Fixme: key binding? 2079(defcustom python-fill-comment-function 'python-fill-comment
2080 "Function to fill comments.
2081This is the function used by `python-fill-paragraph-function' to
2082fill comments."
2083 :type 'symbol
2084 :group 'python
2085 :safe 'symbolp)
2180 2086
2181(defun python-find-function (name) 2087(defcustom python-fill-string-function 'python-fill-string
2182 "Find source of definition of function NAME. 2088 "Function to fill strings.
2183Interactively, prompt for name." 2089This is the function used by `python-fill-paragraph-function' to
2184 (interactive 2090fill strings."
2185 (let ((symbol (with-syntax-table python-dotty-syntax-table 2091 :type 'symbol
2186 (current-word))) 2092 :group 'python
2187 (enable-recursive-minibuffers t)) 2093 :safe 'symbolp)
2188 (list (read-string (if symbol 2094
2189 (format "Find location of (default %s): " symbol) 2095(defcustom python-fill-decorator-function 'python-fill-decorator
2190 "Find location of: ") 2096 "Function to fill decorators.
2191 nil nil symbol)))) 2097This is the function used by `python-fill-paragraph-function' to
2192 (unless python-imports 2098fill decorators."
2193 (error "Not called from buffer visiting Python file")) 2099 :type 'symbol
2194 (let* ((loc (python-send-receive (format "emacs.location_of (%S, %s)" 2100 :group 'python
2195 name python-imports))) 2101 :safe 'symbolp)
2196 (loc (car (read-from-string loc))) 2102
2197 (file (car loc)) 2103(defcustom python-fill-paren-function 'python-fill-paren
2198 (line (cdr loc))) 2104 "Function to fill parens.
2199 (unless file (error "Don't know where `%s' is defined" name)) 2105This is the function used by `python-fill-paragraph-function' to
2200 (pop-to-buffer (find-file-noselect file)) 2106fill parens."
2201 (when (integerp line) 2107 :type 'symbol
2108 :group 'python
2109 :safe 'symbolp)
2110
2111(defun python-fill-paragraph-function (&optional justify)
2112 "`fill-paragraph-function' handling multi-line strings and possibly comments.
2113If any of the current line is in or at the end of a multi-line string,
2114fill the string or the paragraph of it that point is in, preserving
2115the string's indentation.
2116Optional argument JUSTIFY defines if the paragraph should be justified."
2117 (interactive "P")
2118 (save-excursion
2119 (back-to-indentation)
2120 (cond
2121 ;; Comments
2122 ((funcall python-fill-comment-function justify))
2123 ;; Strings/Docstrings
2124 ((save-excursion (skip-chars-forward "\"'uUrR")
2125 (python-info-ppss-context 'string))
2126 (funcall python-fill-string-function justify))
2127 ;; Decorators
2128 ((equal (char-after (save-excursion
2129 (back-to-indentation)
2130 (point-marker))) ?@)
2131 (funcall python-fill-decorator-function justify))
2132 ;; Parens
2133 ((or (python-info-ppss-context 'paren)
2134 (looking-at (python-rx open-paren))
2135 (save-excursion
2136 (skip-syntax-forward "^(" (line-end-position))
2137 (looking-at (python-rx open-paren))))
2138 (funcall python-fill-paren-function justify))
2139 (t t))))
2140
2141(defun python-fill-comment (&optional justify)
2142 "Comment fill function for `python-fill-paragraph-function'.
2143JUSTIFY should be used (if applicable) as in `fill-paragraph'."
2144 (fill-comment-paragraph justify))
2145
2146(defun python-fill-string (&optional justify)
2147 "String fill function for `python-fill-paragraph-function'.
2148JUSTIFY should be used (if applicable) as in `fill-paragraph'."
2149 (let ((marker (point-marker))
2150 (string-start-marker
2151 (progn
2152 (skip-chars-forward "\"'uUrR")
2153 (goto-char (python-info-ppss-context 'string))
2154 (skip-chars-forward "\"'uUrR")
2155 (point-marker)))
2156 (reg-start (line-beginning-position))
2157 (string-end-marker
2158 (progn
2159 (while (python-info-ppss-context 'string)
2160 (goto-char (1+ (point-marker))))
2161 (skip-chars-backward "\"'")
2162 (point-marker)))
2163 (reg-end (line-end-position))
2164 (fill-paragraph-function))
2165 (save-restriction
2166 (narrow-to-region reg-start reg-end)
2167 (save-excursion
2168 (goto-char string-start-marker)
2169 (delete-region (point-marker) (progn
2170 (skip-syntax-forward "> ")
2171 (point-marker)))
2172 (goto-char string-end-marker)
2173 (delete-region (point-marker) (progn
2174 (skip-syntax-backward "> ")
2175 (point-marker)))
2176 (save-excursion
2177 (goto-char marker)
2178 (fill-paragraph justify))
2179 ;; If there is a newline in the docstring lets put triple
2180 ;; quote in it's own line to follow pep 8
2181 (when (save-excursion
2182 (re-search-backward "\n" string-start-marker t))
2183 (newline)
2184 (newline-and-indent))
2185 (fill-paragraph justify)))) t)
2186
2187(defun python-fill-decorator (&optional justify)
2188 "Decorator fill function for `python-fill-paragraph-function'.
2189JUSTIFY should be used (if applicable) as in `fill-paragraph'."
2190 t)
2191
2192(defun python-fill-paren (&optional justify)
2193 "Paren fill function for `python-fill-paragraph-function'.
2194JUSTIFY should be used (if applicable) as in `fill-paragraph'."
2195 (save-restriction
2196 (narrow-to-region (progn
2197 (while (python-info-ppss-context 'paren)
2198 (goto-char (1- (point-marker))))
2199 (point-marker)
2200 (line-beginning-position))
2201 (progn
2202 (when (not (python-info-ppss-context 'paren))
2203 (end-of-line)
2204 (when (not (python-info-ppss-context 'paren))
2205 (skip-syntax-backward "^)")))
2206 (while (python-info-ppss-context 'paren)
2207 (goto-char (1+ (point-marker))))
2208 (point-marker)))
2209 (let ((paragraph-start "\f\\|[ \t]*$")
2210 (paragraph-separate ",")
2211 (fill-paragraph-function))
2202 (goto-char (point-min)) 2212 (goto-char (point-min))
2203 (forward-line (1- line))))) 2213 (fill-paragraph justify))
2214 (while (not (eobp))
2215 (forward-line 1)
2216 (python-indent-line)
2217 (goto-char (line-end-position)))) t)
2218
2204 2219
2205;;;; Skeletons 2220;;; Skeletons
2206 2221
2207(defcustom python-use-skeletons nil 2222(defcustom python-skeleton-autoinsert nil
2208 "Non-nil means template skeletons will be automagically inserted. 2223 "Non-nil means template skeletons will be automagically inserted.
2209This happens when pressing \"if<SPACE>\", for example, to prompt for 2224This happens when pressing \"if<SPACE>\", for example, to prompt for
2210the if condition." 2225the if condition."
2211 :type 'boolean 2226 :type 'boolean
2212 :group 'python) 2227 :group 'python
2228 :safe 'booleanp)
2229
2230(define-obsolete-variable-alias
2231 'python-use-skeletons 'python-skeleton-autoinsert "24.2")
2232
2233(defvar python-skeleton-available '()
2234 "Internal list of available skeletons.")
2213 2235
2214(define-abbrev-table 'python-mode-abbrev-table () 2236(define-abbrev-table 'python-mode-abbrev-table ()
2215 "Abbrev table for Python mode." 2237 "Abbrev table for Python mode."
@@ -2217,514 +2239,652 @@ the if condition."
2217 ;; Allow / inside abbrevs. 2239 ;; Allow / inside abbrevs.
2218 :regexp "\\(?:^\\|[^/]\\)\\<\\([[:word:]/]+\\)\\W*" 2240 :regexp "\\(?:^\\|[^/]\\)\\<\\([[:word:]/]+\\)\\W*"
2219 ;; Only expand in code. 2241 ;; Only expand in code.
2220 :enable-function (lambda () (not (python-in-string/comment)))) 2242 :enable-function (lambda ()
2221 2243 (and
2222(eval-when-compile 2244 (not (or (python-info-ppss-context 'string)
2223 ;; Define a user-level skeleton and add it to the abbrev table. 2245 (python-info-ppss-context 'comment)))
2224(defmacro def-python-skeleton (name &rest elements) 2246 python-skeleton-autoinsert)))
2247
2248(defmacro python-skeleton-define (name doc &rest skel)
2249 "Define a `python-mode' skeleton using NAME DOC and SKEL.
2250The skeleton will be bound to python-skeleton-NAME and will
2251be added to `python-mode-abbrev-table'."
2225 (declare (indent 2)) 2252 (declare (indent 2))
2226 (let* ((name (symbol-name name)) 2253 (let* ((name (symbol-name name))
2227 (function (intern (concat "python-insert-" name)))) 2254 (function-name (intern (concat "python-skeleton-" name))))
2228 `(progn 2255 `(progn
2229 ;; Usual technique for inserting a skeleton, but expand 2256 (define-abbrev python-mode-abbrev-table ,name "" ',function-name
2230 ;; to the original abbrev instead if in a comment or string. 2257 :system t)
2231 (when python-use-skeletons 2258 (setq python-skeleton-available
2232 (define-abbrev python-mode-abbrev-table ,name "" 2259 (cons ',function-name python-skeleton-available))
2233 ',function 2260 (define-skeleton ,function-name
2234 nil t)) ; system abbrev 2261 ,(or doc
2235 (define-skeleton ,function 2262 (format "Insert %s statement." name))
2236 ,(format "Insert Python \"%s\" template." name) 2263 ,@skel))))
2237 ,@elements))))) 2264
2238 2265(defmacro python-define-auxiliary-skeleton (name doc &optional &rest skel)
2239;; From `skeleton-further-elements' set below: 2266 "Define a `python-mode' auxiliary skeleton using NAME DOC and SKEL.
2240;; `<': outdent a level; 2267The skeleton will be bound to python-skeleton-NAME."
2241;; `^': delete indentation on current line and also previous newline. 2268 (declare (indent 2))
2242;; Not quite like `delete-indentation'. Assumes point is at 2269 (let* ((name (symbol-name name))
2243;; beginning of indentation. 2270 (function-name (intern (concat "python-skeleton--" name)))
2244 2271 (msg (format
2245(def-python-skeleton if 2272 "Add '%s' clause? " name)))
2273 (when (not skel)
2274 (setq skel
2275 `(< ,(format "%s:" name) \n \n
2276 > _ \n)))
2277 `(define-skeleton ,function-name
2278 ,(or doc
2279 (format "Auxiliary skeleton for %s statement." name))
2280 nil
2281 (unless (y-or-n-p ,msg)
2282 (signal 'quit t))
2283 ,@skel)))
2284
2285(python-define-auxiliary-skeleton else nil)
2286
2287(python-define-auxiliary-skeleton except nil)
2288
2289(python-define-auxiliary-skeleton finally nil)
2290
2291(python-skeleton-define if nil
2246 "Condition: " 2292 "Condition: "
2247 "if " str ":" \n 2293 "if " str ":" \n
2248 > -1 ; Fixme: I don't understand the spurious space this removes.
2249 _ \n 2294 _ \n
2250 ("other condition, %s: " 2295 ("other condition, %s: "
2251 < ; Avoid wrong indentation after block opening. 2296 <
2252 "elif " str ":" \n 2297 "elif " str ":" \n
2253 > _ \n nil) 2298 > _ \n nil)
2254 '(python-else) | ^) 2299 '(python-skeleton--else) | ^)
2255 2300
2256(define-skeleton python-else 2301(python-skeleton-define while nil
2257 "Auxiliary skeleton."
2258 nil
2259 (unless (eq ?y (read-char "Add `else' clause? (y for yes or RET for no) "))
2260 (signal 'quit t))
2261 < "else:" \n
2262 > _ \n)
2263
2264(def-python-skeleton while
2265 "Condition: " 2302 "Condition: "
2266 "while " str ":" \n 2303 "while " str ":" \n
2267 > -1 _ \n 2304 > _ \n
2268 '(python-else) | ^) 2305 '(python-skeleton--else) | ^)
2269 2306
2270(def-python-skeleton for 2307(python-skeleton-define for nil
2271 "Target, %s: " 2308 "Iteration spec: "
2272 "for " str " in " (skeleton-read "Expression, %s: ") ":" \n 2309 "for " str ":" \n
2273 > -1 _ \n 2310 > _ \n
2274 '(python-else) | ^) 2311 '(python-skeleton--else) | ^)
2275 2312
2276(def-python-skeleton try/except 2313(python-skeleton-define try nil
2277 nil 2314 nil
2278 "try:" \n 2315 "try:" \n
2279 > -1 _ \n 2316 > _ \n
2280 ("Exception, %s: " 2317 ("Exception, %s: "
2281 < "except " str '(python-target) ":" \n 2318 <
2319 "except " str ":" \n
2282 > _ \n nil) 2320 > _ \n nil)
2283 < "except:" \n 2321 resume:
2284 > _ \n 2322 '(python-skeleton--except)
2285 '(python-else) | ^) 2323 '(python-skeleton--else)
2286 2324 '(python-skeleton--finally) | ^)
2287(define-skeleton python-target 2325
2288 "Auxiliary skeleton." 2326(python-skeleton-define def nil
2289 "Target, %s: " ", " str | -2) 2327 "Function name: "
2290 2328 "def " str " (" ("Parameter, %s: "
2291(def-python-skeleton try/finally 2329 (unless (equal ?\( (char-before)) ", ")
2292 nil 2330 str) "):" \n
2293 "try:" \n 2331 "\"\"\"" - "\"\"\"" \n
2294 > -1 _ \n 2332 > _ \n)
2295 < "finally:" \n 2333
2296 > _ \n) 2334(python-skeleton-define class nil
2297 2335 "Class name: "
2298(def-python-skeleton def
2299 "Name: "
2300 "def " str " (" ("Parameter, %s: " (unless (equal ?\( (char-before)) ", ")
2301 str) "):" \n
2302 "\"\"\"" - "\"\"\"" \n ; Fixme: extra space inserted -- why?).
2303 > _ \n)
2304
2305(def-python-skeleton class
2306 "Name: "
2307 "class " str " (" ("Inheritance, %s: " 2336 "class " str " (" ("Inheritance, %s: "
2308 (unless (equal ?\( (char-before)) ", ") 2337 (unless (equal ?\( (char-before)) ", ")
2309 str) 2338 str)
2310 & ")" | -2 ; close list or remove opening 2339 & ")" | -2
2311 ":" \n 2340 ":" \n
2312 "\"\"\"" - "\"\"\"" \n 2341 "\"\"\"" - "\"\"\"" \n
2313 > _ \n) 2342 > _ \n)
2314 2343
2315(defvar python-default-template "if" 2344(defun python-skeleton-add-menu-items ()
2316 "Default template to expand by `python-expand-template'. 2345 "Add menu items to Python->Skeletons menu."
2317Updated on each expansion.") 2346 (let ((skeletons (sort python-skeleton-available 'string<))
2347 (items))
2348 (dolist (skeleton skeletons)
2349 (easy-menu-add-item
2350 nil '("Python" "Skeletons")
2351 `[,(format
2352 "Insert %s" (caddr (split-string (symbol-name skeleton) "-")))
2353 ,skeleton t]))))
2354
2355;;; FFAP
2356
2357(defcustom python-ffap-setup-code
2358 "def __FFAP_get_module_path(module):
2359 try:
2360 import os
2361 path = __import__(module).__file__
2362 if path[-4:] == '.pyc' and os.path.exists(path[0:-1]):
2363 path = path[:-1]
2364 return path
2365 except:
2366 return ''"
2367 "Python code to get a module path."
2368 :type 'string
2369 :group 'python)
2370
2371(defcustom python-ffap-string-code
2372 "__FFAP_get_module_path('''%s''')\n"
2373 "Python code used to get a string with the path of a module."
2374 :type 'string
2375 :group 'python)
2376
2377(defun python-ffap-module-path (module)
2378 "Function for `ffap-alist' to return path for MODULE."
2379 (let ((process (or
2380 (and (eq major-mode 'inferior-python-mode)
2381 (get-buffer-process (current-buffer)))
2382 (python-shell-get-process))))
2383 (if (not process)
2384 nil
2385 (let ((module-file
2386 (python-shell-send-string-no-output
2387 (format python-ffap-string-code module) process)))
2388 (when module-file
2389 (substring-no-properties module-file 1 -1))))))
2390
2391(eval-after-load "ffap"
2392 '(progn
2393 (push '(python-mode . python-ffap-module-path) ffap-alist)
2394 (push '(inferior-python-mode . python-ffap-module-path) ffap-alist)))
2318 2395
2319(defun python-expand-template (name)
2320 "Expand template named NAME.
2321Interactively, prompt for the name with completion."
2322 (interactive
2323 (list (completing-read (format "Template to expand (default %s): "
2324 python-default-template)
2325 python-mode-abbrev-table nil t nil nil
2326 python-default-template)))
2327 (if (equal "" name)
2328 (setq name python-default-template)
2329 (setq python-default-template name))
2330 (let ((sym (abbrev-symbol name python-mode-abbrev-table)))
2331 (if sym
2332 (abbrev-insert sym)
2333 (error "Undefined template: %s" name))))
2334 2396
2335;;;; Bicycle Repair Man support 2397;;; Code check
2336 2398
2337(autoload 'pymacs-load "pymacs" nil t) 2399(defcustom python-check-command
2338(autoload 'brm-init "bikeemacs") 2400 "pyflakes"
2339(defvar brm-menu) 2401 "Command used to check a Python file."
2340 2402 :type 'string
2341;; I'm not sure how useful BRM really is, and it's certainly dangerous 2403 :group 'python)
2342;; the way it modifies files outside Emacs... Also note that the 2404
2343;; current BRM loses with tabs used for indentation -- I submitted a 2405(defcustom python-check-buffer-name
2344;; fix <URL:http://www.loveshack.ukfsn.org/emacs/bikeemacs.py.diff>. 2406 "*Python check: %s*"
2345(defun python-setup-brm () 2407 "Buffer name used for check commands."
2346 "Set up Bicycle Repair Man refactoring tool (if available). 2408 :type 'string
2347 2409 :group 'python)
2348Note that the `refactoring' features change files independently of 2410
2349Emacs and may modify and save the contents of the current buffer 2411(defvar python-check-custom-command nil
2350without confirmation." 2412 "Internal use.")
2351 (interactive) 2413
2352 (condition-case data 2414(defun python-check (command)
2353 (unless (fboundp 'brm-rename) 2415 "Check a Python file (default current buffer's file).
2354 (pymacs-load "bikeemacs" "brm-") ; first line of normal recipe 2416Runs COMMAND, a shell command, as if by `compile'. See
2355 (let ((py-mode-map (make-sparse-keymap)) ; it assumes this 2417`python-check-command' for the default."
2356 (features (cons 'python-mode features))) ; and requires this 2418 (interactive
2357 (brm-init) ; second line of normal recipe 2419 (list (read-string "Check command: "
2358 (remove-hook 'python-mode-hook ; undo this from `brm-init' 2420 (or python-check-custom-command
2359 (lambda () (easy-menu-add brm-menu))) 2421 (concat python-check-command " "
2360 (easy-menu-define 2422 (shell-quote-argument
2361 python-brm-menu python-mode-map 2423 (or
2362 "Bicycle Repair Man" 2424 (let ((name (buffer-file-name)))
2363 '("BicycleRepairMan" 2425 (and name
2364 :help "Interface to navigation and refactoring tool" 2426 (file-name-nondirectory name)))
2365 "Queries" 2427 "")))))))
2366 ["Find References" brm-find-references 2428 (setq python-check-custom-command command)
2367 :help "Find references to name at point in compilation buffer"] 2429 (save-some-buffers (not compilation-ask-about-save) nil)
2368 ["Find Definition" brm-find-definition 2430 (let ((process-environment (python-shell-calculate-process-environment))
2369 :help "Find definition of name at point"] 2431 (exec-path (python-shell-calculate-exec-path)))
2370 "-" 2432 (compilation-start command nil
2371 "Refactoring" 2433 (lambda (mode-name)
2372 ["Rename" brm-rename 2434 (format python-check-buffer-name command)))))
2373 :help "Replace name at point with a new name everywhere"] 2435
2374 ["Extract Method" brm-extract-method
2375 :active (and mark-active (not buffer-read-only))
2376 :help "Replace statements in region with a method"]
2377 ["Extract Local Variable" brm-extract-local-variable
2378 :active (and mark-active (not buffer-read-only))
2379 :help "Replace expression in region with an assignment"]
2380 ["Inline Local Variable" brm-inline-local-variable
2381 :help
2382 "Substitute uses of variable at point with its definition"]
2383 ;; Fixme: Should check for anything to revert.
2384 ["Undo Last Refactoring" brm-undo :help ""]))))
2385 (error (error "BicycleRepairMan setup failed: %s" data))))
2386 2436
2387;;;; Modes. 2437;;; Eldoc
2438
2439(defcustom python-eldoc-setup-code
2440 "def __PYDOC_get_help(obj):
2441 try:
2442 import inspect
2443 if hasattr(obj, 'startswith'):
2444 obj = eval(obj, globals())
2445 doc = inspect.getdoc(obj)
2446 if not doc and callable(obj):
2447 target = None
2448 if inspect.isclass(obj) and hasattr(obj, '__init__'):
2449 target = obj.__init__
2450 objtype = 'class'
2451 else:
2452 target = obj
2453 objtype = 'def'
2454 if target:
2455 args = inspect.formatargspec(
2456 *inspect.getargspec(target)
2457 )
2458 name = obj.__name__
2459 doc = '{objtype} {name}{args}'.format(
2460 objtype=objtype, name=name, args=args
2461 )
2462 else:
2463 doc = doc.splitlines()[0]
2464 except:
2465 doc = ''
2466 try:
2467 exec('print doc')
2468 except SyntaxError:
2469 print(doc)"
2470 "Python code to setup documentation retrieval."
2471 :type 'string
2472 :group 'python)
2388 2473
2389;; pdb tracking is alert once this file is loaded, but takes no action if 2474(defcustom python-eldoc-string-code
2390;; `python-pdbtrack-do-tracking-p' is nil. 2475 "__PYDOC_get_help('''%s''')\n"
2391(add-hook 'comint-output-filter-functions 'python-pdbtrack-track-stack-file) 2476 "Python code used to get a string with the documentation of an object."
2477 :type 'string
2478 :group 'python)
2479
2480(defun python-eldoc--get-doc-at-point (&optional force-input force-process)
2481 "Internal implementation to get documentation at point.
2482If not FORCE-INPUT is passed then what `current-word' returns
2483will be used. If not FORCE-PROCESS is passed what
2484`python-shell-get-process' returns is used."
2485 (let ((process (or force-process (python-shell-get-process))))
2486 (if (not process)
2487 "Eldoc needs an inferior Python process running."
2488 (let* ((current-defun (python-info-current-defun))
2489 (input (or force-input
2490 (with-syntax-table python-dotty-syntax-table
2491 (if (not current-defun)
2492 (current-word)
2493 (concat current-defun "." (current-word))))))
2494 (ppss (syntax-ppss))
2495 (help (when (and
2496 input
2497 (not (string= input (concat current-defun ".")))
2498 (not (or (python-info-ppss-context 'string ppss)
2499 (python-info-ppss-context 'comment ppss))))
2500 (when (string-match
2501 (concat
2502 (regexp-quote (concat current-defun "."))
2503 "self\\.") input)
2504 (with-temp-buffer
2505 (insert input)
2506 (goto-char (point-min))
2507 (forward-word)
2508 (forward-char)
2509 (delete-region
2510 (point-marker) (search-forward "self."))
2511 (setq input (buffer-substring
2512 (point-min) (point-max)))))
2513 (python-shell-send-string-no-output
2514 (format python-eldoc-string-code input) process))))
2515 (with-current-buffer (process-buffer process)
2516 (when comint-last-prompt-overlay
2517 (delete-region comint-last-input-end
2518 (overlay-start comint-last-prompt-overlay))))
2519 (when (and help
2520 (not (string= help "\n")))
2521 help)))))
2522
2523(defun python-eldoc-function ()
2524 "`eldoc-documentation-function' for Python.
2525For this to work the best as possible you should call
2526`python-shell-send-buffer' from time to time so context in
2527inferior python process is updated properly."
2528 (python-eldoc--get-doc-at-point))
2392 2529
2393(defvar outline-heading-end-regexp) 2530(defun python-eldoc-at-point (symbol)
2394(defvar eldoc-documentation-function) 2531 "Get help on SYMBOL using `help'.
2395(defvar python-mode-running) ;Dynamically scoped var. 2532Interactively, prompt for symbol."
2533 (interactive
2534 (let ((symbol (with-syntax-table python-dotty-syntax-table
2535 (current-word)))
2536 (enable-recursive-minibuffers t))
2537 (list (read-string (if symbol
2538 (format "Describe symbol (default %s): " symbol)
2539 "Describe symbol: ")
2540 nil nil symbol))))
2541 (let ((process (python-shell-get-process)))
2542 (if (not process)
2543 (message "Eldoc needs an inferior Python process running.")
2544 (message (python-eldoc--get-doc-at-point symbol process)))))
2545
2546
2547;;; Misc helpers
2548
2549(defun python-info-current-defun (&optional include-type)
2550 "Return name of surrounding function with Python compatible dotty syntax.
2551Optional argument INCLUDE-TYPE indicates to include the type of the defun.
2552This function is compatible to be used as
2553`add-log-current-defun-function' since it returns nil if point is
2554not inside a defun."
2555 (let ((names '())
2556 (min-indent)
2557 (first-run t))
2558 (save-restriction
2559 (widen)
2560 (save-excursion
2561 (end-of-line 1)
2562 (setq min-indent (current-indentation))
2563 (while (python-beginning-of-defun-function 1)
2564 (when (or (< (current-indentation) min-indent)
2565 first-run)
2566 (setq first-run nil)
2567 (setq min-indent (current-indentation))
2568 (looking-at python-nav-beginning-of-defun-regexp)
2569 (setq names (cons
2570 (if (not include-type)
2571 (match-string-no-properties 1)
2572 (mapconcat 'identity
2573 (split-string
2574 (match-string-no-properties 0)) " "))
2575 names))))))
2576 (when names
2577 (mapconcat (lambda (string) string) names "."))))
2578
2579(defun python-info-closing-block ()
2580 "Return the point of the block the current line closes."
2581 (let ((closing-word (save-excursion
2582 (back-to-indentation)
2583 (current-word)))
2584 (indentation (current-indentation)))
2585 (when (member closing-word python-indent-dedenters)
2586 (save-excursion
2587 (forward-line -1)
2588 (while (and (> (current-indentation) indentation)
2589 (not (bobp))
2590 (not (back-to-indentation))
2591 (forward-line -1)))
2592 (back-to-indentation)
2593 (cond
2594 ((not (equal indentation (current-indentation))) nil)
2595 ((string= closing-word "elif")
2596 (when (member (current-word) '("if" "elif"))
2597 (point-marker)))
2598 ((string= closing-word "else")
2599 (when (member (current-word) '("if" "elif" "except" "for" "while"))
2600 (point-marker)))
2601 ((string= closing-word "except")
2602 (when (member (current-word) '("try"))
2603 (point-marker)))
2604 ((string= closing-word "finally")
2605 (when (member (current-word) '("except" "else"))
2606 (point-marker))))))))
2607
2608(defun python-info-closing-block-message (&optional closing-block-point)
2609 "Message the contents of the block the current line closes.
2610With optional argument CLOSING-BLOCK-POINT use that instead of
2611recalculating it calling `python-info-closing-block'."
2612 (let ((point (or closing-block-point (python-info-closing-block))))
2613 (when point
2614 (save-restriction
2615 (widen)
2616 (message "Closes %s" (save-excursion
2617 (goto-char point)
2618 (back-to-indentation)
2619 (buffer-substring
2620 (point) (line-end-position))))))))
2621
2622(defun python-info-line-ends-backslash-p (&optional line-number)
2623 "Return non-nil if current line ends with backslash.
2624With optional argument LINE-NUMBER, check that line instead."
2625 (save-excursion
2626 (save-restriction
2627 (widen)
2628 (when line-number
2629 (goto-char line-number))
2630 (while (and (not (eobp))
2631 (goto-char (line-end-position))
2632 (python-info-ppss-context 'paren)
2633 (not (equal (char-before (point)) ?\\)))
2634 (forward-line 1))
2635 (when (equal (char-before) ?\\)
2636 (point-marker)))))
2637
2638(defun python-info-beginning-of-backslash (&optional line-number)
2639 "Return the point where the backslashed line start.
2640Optional argument LINE-NUMBER forces the line number to check against."
2641 (save-excursion
2642 (save-restriction
2643 (widen)
2644 (when line-number
2645 (goto-char line-number))
2646 (when (python-info-line-ends-backslash-p)
2647 (while (save-excursion
2648 (goto-char (line-beginning-position))
2649 (python-info-ppss-context 'paren))
2650 (forward-line -1))
2651 (back-to-indentation)
2652 (point-marker)))))
2653
2654(defun python-info-continuation-line-p ()
2655 "Check if current line is continuation of another.
2656When current line is continuation of another return the point
2657where the continued line ends."
2658 (save-excursion
2659 (save-restriction
2660 (widen)
2661 (let* ((context-type (progn
2662 (back-to-indentation)
2663 (python-info-ppss-context-type)))
2664 (line-start (line-number-at-pos))
2665 (context-start (when context-type
2666 (python-info-ppss-context context-type))))
2667 (cond ((equal context-type 'paren)
2668 ;; Lines inside a paren are always a continuation line
2669 ;; (except the first one).
2670 (when (equal (python-info-ppss-context-type) 'paren)
2671 (python-util-forward-comment -1)
2672 (python-util-forward-comment -1)
2673 (point-marker)))
2674 ((or (equal context-type 'comment)
2675 (equal context-type 'string))
2676 ;; move forward an roll again
2677 (goto-char context-start)
2678 (python-util-forward-comment)
2679 (python-info-continuation-line-p))
2680 (t
2681 ;; Not within a paren, string or comment, the only way we are
2682 ;; dealing with a continuation line is that previous line
2683 ;; contains a backslash, and this can only be the previous line
2684 ;; from current
2685 (back-to-indentation)
2686 (python-util-forward-comment -1)
2687 (python-util-forward-comment -1)
2688 (when (and (equal (1- line-start) (line-number-at-pos))
2689 (python-info-line-ends-backslash-p))
2690 (point-marker))))))))
2691
2692(defun python-info-block-continuation-line-p ()
2693 "Return non-nil if current line is a continuation of a block."
2694 (save-excursion
2695 (when (python-info-continuation-line-p)
2696 (forward-line -1)
2697 (back-to-indentation)
2698 (when (looking-at (python-rx block-start))
2699 (point-marker)))))
2700
2701(defun python-info-assignment-continuation-line-p ()
2702 "Check if current line is a continuation of an assignment.
2703When current line is continuation of another with an assignment
2704return the point of the first non-blank character after the
2705operator."
2706 (save-excursion
2707 (when (python-info-continuation-line-p)
2708 (forward-line -1)
2709 (back-to-indentation)
2710 (when (and (not (looking-at (python-rx block-start)))
2711 (and (re-search-forward (python-rx not-simple-operator
2712 assignment-operator
2713 not-simple-operator)
2714 (line-end-position) t)
2715 (not (or (python-info-ppss-context 'string)
2716 (python-info-ppss-context 'paren)
2717 (python-info-ppss-context 'comment)))))
2718 (skip-syntax-forward "\s")
2719 (point-marker)))))
2720
2721(defun python-info-ppss-context (type &optional syntax-ppss)
2722 "Return non-nil if point is on TYPE using SYNTAX-PPSS.
2723TYPE can be 'comment, 'string or 'paren. It returns the start
2724character address of the specified TYPE."
2725 (let ((ppss (or syntax-ppss (syntax-ppss))))
2726 (case type
2727 ('comment
2728 (and (nth 4 ppss)
2729 (nth 8 ppss)))
2730 ('string
2731 (nth 8 ppss))
2732 ('paren
2733 (nth 1 ppss))
2734 (t nil))))
2735
2736(defun python-info-ppss-context-type (&optional syntax-ppss)
2737 "Return the context type using SYNTAX-PPSS.
2738The type returned can be 'comment, 'string or 'paren."
2739 (let ((ppss (or syntax-ppss (syntax-ppss))))
2740 (cond
2741 ((and (nth 4 ppss)
2742 (nth 8 ppss))
2743 'comment)
2744 ((nth 8 ppss)
2745 'string)
2746 ((nth 1 ppss)
2747 'paren)
2748 (t nil))))
2749
2750(defun python-info-looking-at-beginning-of-defun (&optional syntax-ppss)
2751 "Check if point is at `beginning-of-defun' using SYNTAX-PPSS."
2752 (and (not (python-info-ppss-context-type (or syntax-ppss (syntax-ppss))))
2753 (save-excursion
2754 (beginning-of-line 1)
2755 (looking-at python-nav-beginning-of-defun-regexp))))
2756
2757(defun python-info-current-line-comment-p ()
2758 "Check if current line is a comment line."
2759 (char-equal (or (char-after (+ (point) (current-indentation))) ?_) ?#))
2760
2761(defun python-info-current-line-empty-p ()
2762 "Check if current line is empty, ignoring whitespace."
2763 (save-excursion
2764 (beginning-of-line 1)
2765 (looking-at
2766 (python-rx line-start (* whitespace)
2767 (group (* not-newline))
2768 (* whitespace) line-end))
2769 (string-equal "" (match-string-no-properties 1))))
2396 2770
2771
2772;;; Utility functions
2773
2774(defun python-util-position (item seq)
2775 "Find the first occurrence of ITEM in SEQ.
2776Return the index of the matching item, or nil if not found."
2777 (let ((member-result (member item seq)))
2778 (when member-result
2779 (- (length seq) (length member-result)))))
2780
2781;; Stolen from org-mode
2782(defun python-util-clone-local-variables (from-buffer &optional regexp)
2783 "Clone local variables from FROM-BUFFER.
2784Optional argument REGEXP selects variables to clone and defaults
2785to \"^python-\"."
2786 (mapc
2787 (lambda (pair)
2788 (and (symbolp (car pair))
2789 (string-match (or regexp "^python-")
2790 (symbol-name (car pair)))
2791 (set (make-local-variable (car pair))
2792 (cdr pair))))
2793 (buffer-local-variables from-buffer)))
2794
2795(defun python-util-forward-comment (&optional direction)
2796 "Python mode specific version of `forward-comment'.
2797Optional argument DIRECTION defines the direction to move to."
2798 (let ((comment-start (python-info-ppss-context 'comment))
2799 (factor (if (< (or direction 0) 0)
2800 -99999
2801 99999)))
2802 (when comment-start
2803 (goto-char comment-start))
2804 (forward-comment factor)))
2805
2806
2397;;;###autoload 2807;;;###autoload
2398(define-derived-mode python-mode prog-mode "Python" 2808(define-derived-mode python-mode prog-mode "Python"
2399 "Major mode for editing Python files. 2809 "Major mode for editing Python files.
2400Turns on Font Lock mode unconditionally since it is currently required 2810
2401for correct parsing of the source. 2811\\{python-mode-map}
2402See also `jython-mode', which is actually invoked if the buffer appears to 2812Entry to this mode calls the value of `python-mode-hook'
2403contain Jython code. See also `run-python' and associated Python mode 2813if that value is non-nil."
2404commands for running Python under Emacs. 2814 (set (make-local-variable 'tab-width) 8)
2405 2815 (set (make-local-variable 'indent-tabs-mode) nil)
2406The Emacs commands which work with `defun's, e.g. \\[beginning-of-defun], deal 2816
2407with nested `def' and `class' blocks. They take the innermost one as 2817 (set (make-local-variable 'comment-start) "# ")
2408current without distinguishing method and class definitions. Used multiple 2818 (set (make-local-variable 'comment-start-skip) "#+\\s-*")
2409times, they move over others at the same indentation level until they reach 2819
2410the end of definitions at that level, when they move up a level. 2820 (set (make-local-variable 'parse-sexp-lookup-properties) t)
2411\\<python-mode-map> 2821 (set (make-local-variable 'parse-sexp-ignore-comments) t)
2412Colon is electric: it outdents the line if appropriate, e.g. for 2822
2413an else statement. \\[python-backspace] at the beginning of an indented statement 2823 (set (make-local-variable 'forward-sexp-function)
2414deletes a level of indentation to close the current block; otherwise it 2824 'python-nav-forward-sexp-function)
2415deletes a character backward. TAB indents the current line relative to 2825
2416the preceding code. Successive TABs, with no intervening command, cycle
2417through the possibilities for indentation on the basis of enclosing blocks.
2418
2419\\[fill-paragraph] fills comments and multi-line strings appropriately, but has no
2420effect outside them.
2421
2422Supports Eldoc mode (only for functions, using a Python process),
2423Info-Look and Imenu. In Outline minor mode, `class' and `def'
2424lines count as headers. Symbol completion is available in the
2425same way as in the Python shell using the `rlcompleter' module
2426and this is added to the Hippie Expand functions locally if
2427Hippie Expand mode is turned on. Completion of symbols of the
2428form x.y only works if the components are literal
2429module/attribute names, not variables. An abbrev table is set up
2430with skeleton expansions for compound statement templates.
2431
2432\\{python-mode-map}"
2433 :group 'python
2434 (set (make-local-variable 'font-lock-defaults) 2826 (set (make-local-variable 'font-lock-defaults)
2435 '(python-font-lock-keywords nil nil nil nil 2827 '(python-font-lock-keywords nil nil nil nil))
2436 ;; This probably isn't worth it. 2828
2437 ;; (font-lock-syntactic-face-function
2438 ;; . python-font-lock-syntactic-face-function)
2439 ))
2440 (set (make-local-variable 'syntax-propertize-function) 2829 (set (make-local-variable 'syntax-propertize-function)
2441 python-syntax-propertize-function) 2830 python-syntax-propertize-function)
2442 (set (make-local-variable 'parse-sexp-lookup-properties) t) 2831
2443 (set (make-local-variable 'parse-sexp-ignore-comments) t) 2832 (set (make-local-variable 'indent-line-function)
2444 (set (make-local-variable 'comment-start) "# ") 2833 #'python-indent-line-function)
2445 (set (make-local-variable 'indent-line-function) #'python-indent-line)
2446 (set (make-local-variable 'indent-region-function) #'python-indent-region) 2834 (set (make-local-variable 'indent-region-function) #'python-indent-region)
2835
2447 (set (make-local-variable 'paragraph-start) "\\s-*$") 2836 (set (make-local-variable 'paragraph-start) "\\s-*$")
2448 (set (make-local-variable 'fill-paragraph-function) 'python-fill-paragraph) 2837 (set (make-local-variable 'fill-paragraph-function)
2449 (set (make-local-variable 'require-final-newline) mode-require-final-newline) 2838 'python-fill-paragraph-function)
2450 (set (make-local-variable 'add-log-current-defun-function) 2839
2451 #'python-current-defun)
2452 (set (make-local-variable 'outline-regexp)
2453 (rx (* space) (or "class" "def" "elif" "else" "except" "finally"
2454 "for" "if" "try" "while" "with")
2455 symbol-end))
2456 (set (make-local-variable 'outline-heading-end-regexp) ":\\s-*\n")
2457 (set (make-local-variable 'outline-level) #'python-outline-level)
2458 (set (make-local-variable 'open-paren-in-column-0-is-defun-start) nil)
2459 (set (make-local-variable 'beginning-of-defun-function) 2840 (set (make-local-variable 'beginning-of-defun-function)
2460 'python-beginning-of-defun) 2841 #'python-beginning-of-defun-function)
2461 (set (make-local-variable 'end-of-defun-function) 'python-end-of-defun) 2842 (set (make-local-variable 'end-of-defun-function)
2462 (add-hook 'which-func-functions 'python-which-func nil t) 2843 #'python-end-of-defun-function)
2463 (setq imenu-create-index-function #'python-imenu-create-index) 2844
2464 (set (make-local-variable 'eldoc-documentation-function)
2465 #'python-eldoc-function)
2466 (add-hook 'eldoc-mode-hook
2467 (lambda () (run-python nil t)) ; need it running
2468 nil t)
2469 (add-hook 'completion-at-point-functions 2845 (add-hook 'completion-at-point-functions
2470 'python-completion-at-point nil 'local) 2846 'python-completion-complete-at-point nil 'local)
2847
2848 (add-hook 'post-self-insert-hook
2849 'python-indent-post-self-insert-function nil 'local)
2850
2851 (set (make-local-variable 'imenu-extract-index-name-function)
2852 #'python-info-current-defun)
2853
2854 (set (make-local-variable 'add-log-current-defun-function)
2855 #'python-info-current-defun)
2856
2857 (add-hook 'which-func-functions #'python-info-current-defun nil t)
2858
2471 (set (make-local-variable 'skeleton-further-elements) 2859 (set (make-local-variable 'skeleton-further-elements)
2472 '((< '(backward-delete-char-untabify (min python-indent 2860 '((abbrev-mode nil)
2473 (current-column)))) 2861 (< '(backward-delete-char-untabify (min python-indent-offset
2474 (^ '(- (1+ (current-indentation)))))) 2862 (current-column))))
2475 ;; Python defines TABs as being 8-char wide. 2863 (^ '(- (1+ (current-indentation))))))
2476 (set (make-local-variable 'tab-width) 8)
2477 (when python-guess-indent (python-guess-indent))
2478 ;; Let's make it harder for the user to shoot himself in the foot.
2479 (unless (= tab-width python-indent)
2480 (setq indent-tabs-mode nil))
2481 (set (make-local-variable 'python-command) python-python-command)
2482 (python-find-imports)
2483 (unless (boundp 'python-mode-running) ; kill the recursion from jython-mode
2484 (let ((python-mode-running t))
2485 (python-maybe-jython))))
2486
2487;; Not done automatically in Emacs 21 or 22.
2488(defcustom python-mode-hook nil
2489 "Hook run when entering Python mode."
2490 :group 'python
2491 :type 'hook)
2492(custom-add-option 'python-mode-hook 'imenu-add-menubar-index)
2493(custom-add-option 'python-mode-hook
2494 (lambda ()
2495 "Turn off Indent Tabs mode."
2496 (setq indent-tabs-mode nil)))
2497(custom-add-option 'python-mode-hook 'turn-on-eldoc-mode)
2498(custom-add-option 'python-mode-hook 'abbrev-mode)
2499(custom-add-option 'python-mode-hook 'python-setup-brm)
2500 2864
2501;;;###autoload 2865 (set (make-local-variable 'eldoc-documentation-function)
2502(define-derived-mode jython-mode python-mode "Jython" 2866 #'python-eldoc-function)
2503 "Major mode for editing Jython files.
2504Like `python-mode', but sets up parameters for Jython subprocesses.
2505Runs `jython-mode-hook' after `python-mode-hook'."
2506 :group 'python
2507 (set (make-local-variable 'python-command) python-jython-command))
2508 2867
2509 2868 (add-to-list 'hs-special-modes-alist
2869 `(python-mode "^\\s-*\\(?:def\\|class\\)\\>" nil "#"
2870 ,(lambda (arg)
2871 (python-end-of-defun-function)) nil))
2510 2872
2511;; pdbtrack features 2873 (set (make-local-variable 'mode-require-final-newline) t)
2512
2513(defun python-pdbtrack-overlay-arrow (activation)
2514 "Activate or deactivate arrow at beginning-of-line in current buffer."
2515 (if activation
2516 (progn
2517 (setq overlay-arrow-position (make-marker)
2518 overlay-arrow-string "=>"
2519 python-pdbtrack-is-tracking-p t)
2520 (set-marker overlay-arrow-position
2521 (line-beginning-position)
2522 (current-buffer)))
2523 (setq overlay-arrow-position nil
2524 python-pdbtrack-is-tracking-p nil)))
2525
2526(defun python-pdbtrack-track-stack-file (_text)
2527 "Show the file indicated by the pdb stack entry line, in a separate window.
2528
2529Activity is disabled if the buffer-local variable
2530`python-pdbtrack-do-tracking-p' is nil.
2531
2532We depend on the pdb input prompt being a match for
2533`python-pdbtrack-input-prompt'.
2534
2535If the traceback target file path is invalid, we look for the
2536most recently visited python-mode buffer which either has the
2537name of the current function or class, or which defines the
2538function or class. This is to provide for scripts not in the
2539local file system (e.g., Zope's 'Script \(Python)', but it's not
2540Zope specific). If you put a copy of the script in a buffer
2541named for the script and activate python-mode, then pdbtrack will
2542find it."
2543 ;; Instead of trying to piece things together from partial text
2544 ;; (which can be almost useless depending on Emacs version), we
2545 ;; monitor to the point where we have the next pdb prompt, and then
2546 ;; check all text from comint-last-input-end to process-mark.
2547 ;;
2548 ;; Also, we're very conservative about clearing the overlay arrow,
2549 ;; to minimize residue. This means, for instance, that executing
2550 ;; other pdb commands wipe out the highlight. You can always do a
2551 ;; 'where' (aka 'w') PDB command to reveal the overlay arrow.
2552
2553 (let* ((origbuf (current-buffer))
2554 (currproc (get-buffer-process origbuf)))
2555
2556 (if (not (and currproc python-pdbtrack-do-tracking-p))
2557 (python-pdbtrack-overlay-arrow nil)
2558
2559 (let* ((procmark (process-mark currproc))
2560 (block (buffer-substring (max comint-last-input-end
2561 (- procmark
2562 python-pdbtrack-track-range))
2563 procmark))
2564 target target_fname target_lineno target_buffer)
2565
2566 (if (not (string-match (concat python-pdbtrack-input-prompt "$") block))
2567 (python-pdbtrack-overlay-arrow nil)
2568
2569 (setq block (ansi-color-filter-apply block))
2570 (setq target (python-pdbtrack-get-source-buffer block))
2571
2572 (if (stringp target)
2573 (progn
2574 (python-pdbtrack-overlay-arrow nil)
2575 (message "pdbtrack: %s" target))
2576
2577 (setq target_lineno (car target)
2578 target_buffer (cadr target)
2579 target_fname (buffer-file-name target_buffer))
2580 (switch-to-buffer-other-window target_buffer)
2581 (goto-char (point-min))
2582 (forward-line (1- target_lineno))
2583 (message "pdbtrack: line %s, file %s" target_lineno target_fname)
2584 (python-pdbtrack-overlay-arrow t)
2585 (pop-to-buffer origbuf t)
2586 ;; in large shell buffers, above stuff may cause point to lag output
2587 (goto-char procmark)
2588 )))))
2589 )
2590
2591(defun python-pdbtrack-get-source-buffer (block)
2592 "Return line number and buffer of code indicated by block's traceback text.
2593
2594We look first to visit the file indicated in the trace.
2595
2596Failing that, we look for the most recently visited python-mode buffer
2597with the same name or having the named function.
2598
2599If we're unable find the source code we return a string describing the
2600problem."
2601
2602 (if (not (string-match python-pdbtrack-stack-entry-regexp block))
2603
2604 "Traceback cue not found"
2605
2606 (let* ((filename (match-string 1 block))
2607 (lineno (string-to-number (match-string 2 block)))
2608 (funcname (match-string 3 block))
2609 (msg (get-text-property 0 'compilation-message filename))
2610 (loc (and msg (compilation--message->loc msg)))
2611 funcbuffer)
2612
2613 (cond ((and loc (markerp (compilation--loc->marker loc)))
2614 (setq funcbuffer (marker-buffer (compilation--loc->marker loc)))
2615 (list (with-current-buffer funcbuffer
2616 (line-number-at-pos (compilation--loc->marker loc)))
2617 funcbuffer))
2618
2619 ((file-exists-p filename)
2620 (list lineno (find-file-noselect filename)))
2621
2622 ((setq funcbuffer (python-pdbtrack-grub-for-buffer funcname lineno))
2623 (if (string-match "/Script (Python)$" filename)
2624 ;; Add in number of lines for leading '##' comments:
2625 (setq lineno
2626 (+ lineno
2627 (with-current-buffer funcbuffer
2628 (if (equal (point-min)(point-max))
2629 0
2630 (count-lines
2631 (point-min)
2632 (max (point-min)
2633 (string-match "^\\([^#]\\|#[^#]\\|#$\\)"
2634 (buffer-substring
2635 (point-min) (point-max)))
2636 )))))))
2637 (list lineno funcbuffer))
2638
2639 ((= (elt filename 0) ?\<)
2640 (format "(Non-file source: '%s')" filename))
2641
2642 (t (format "Not found: %s(), %s" funcname filename))))))
2643
2644(defun python-pdbtrack-grub-for-buffer (funcname _lineno)
2645 "Find recent Python mode buffer named, or having function named FUNCNAME."
2646 (let ((buffers (buffer-list))
2647 buf
2648 got)
2649 (while (and buffers (not got))
2650 (setq buf (car buffers)
2651 buffers (cdr buffers))
2652 (if (and (with-current-buffer buf
2653 (string= major-mode "python-mode"))
2654 (or (string-match funcname (buffer-name buf))
2655 (string-match (concat "^\\s-*\\(def\\|class\\)\\s-+"
2656 funcname "\\s-*(")
2657 (with-current-buffer buf
2658 (buffer-substring (point-min)
2659 (point-max))))))
2660 (setq got buf)))
2661 got))
2662
2663;; Python subprocess utilities and filters
2664(defun python-execute-file (proc filename)
2665 "Send to Python interpreter process PROC \"execfile('FILENAME')\".
2666Make that process's buffer visible and force display. Also make
2667comint believe the user typed this string so that
2668`kill-output-from-shell' does The Right Thing."
2669 (let ((curbuf (current-buffer))
2670 (procbuf (process-buffer proc))
2671; (comint-scroll-to-bottom-on-output t)
2672 (msg (format "## working on region in file %s...\n" filename))
2673 ;; add some comment, so that we can filter it out of history
2674 (cmd (format "execfile(r'%s') # PYTHON-MODE\n" filename)))
2675 (unwind-protect
2676 (with-current-buffer procbuf
2677 (goto-char (point-max))
2678 (move-marker (process-mark proc) (point))
2679 (funcall (process-filter proc) proc msg))
2680 (set-buffer curbuf))
2681 (process-send-string proc cmd)))
2682
2683(defun python-pdbtrack-toggle-stack-tracking (arg)
2684 (interactive "P")
2685 (if (not (get-buffer-process (current-buffer)))
2686 (error "No process associated with buffer '%s'" (current-buffer)))
2687 ;; missing or 0 is toggle, >0 turn on, <0 turn off
2688 (if (or (not arg)
2689 (zerop (setq arg (prefix-numeric-value arg))))
2690 (setq python-pdbtrack-do-tracking-p (not python-pdbtrack-do-tracking-p))
2691 (setq python-pdbtrack-do-tracking-p (> arg 0)))
2692 (message "%sabled Python's pdbtrack"
2693 (if python-pdbtrack-do-tracking-p "En" "Dis")))
2694
2695(defun turn-on-pdbtrack ()
2696 (interactive)
2697 (python-pdbtrack-toggle-stack-tracking 1))
2698 2874
2699(defun turn-off-pdbtrack () 2875 (set (make-local-variable 'outline-regexp)
2700 (interactive) 2876 (python-rx (* space) block-start))
2701 (python-pdbtrack-toggle-stack-tracking 0)) 2877 (set (make-local-variable 'outline-heading-end-regexp) ":\\s-*\n")
2702 2878 (set (make-local-variable 'outline-level)
2703(defun python-sentinel (_proc _msg) 2879 #'(lambda ()
2704 (setq overlay-arrow-position nil)) 2880 "`outline-level' function for Python mode."
2705 2881 (1+ (/ (current-indentation) python-indent-offset))))
2706(defun python-unload-function ()
2707 "Unload the Python library."
2708 (remove-hook 'comint-output-filter-functions 'python-pdbtrack-track-stack-file)
2709 (setq minor-mode-alist (assq-delete-all 'python-pdbtrack-is-tracking-p
2710 minor-mode-alist))
2711 (dolist (error '("^No symbol" "^Can't shift all lines enough"))
2712 (setq debug-ignored-errors (delete error debug-ignored-errors)))
2713 ;; continue standard unloading
2714 nil)
2715
2716;;;; Finish up
2717;; Fixme: should be in hideshow. This seems to be of limited use
2718;; since it isn't (can't be) indentation-based. Also hide-level
2719;; doesn't seem to work properly.
2720(add-to-list 'hs-special-modes-alist
2721 `(python-mode "^\\s-*\\(?:def\\|class\\)\\>" nil "#"
2722 ,(lambda (_arg)
2723 (python-end-of-defun)
2724 (skip-chars-backward " \t\n"))
2725 nil))
2726 2882
2727(provide 'python) 2883 (python-skeleton-add-menu-items)
2728(provide 'python-21)
2729 2884
2885 (when python-indent-guess-indent-offset
2886 (python-indent-guess-indent-offset)))
2887
2888
2889(provide 'python)
2730;;; python.el ends here 2890;;; python.el ends here