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