declare smobs in alloc.c
[bpt/emacs.git] / lisp / progmodes / python.el
CommitLineData
fbcc63a3 1;;; python.el --- Python's flying circus support for Emacs -*- lexical-binding: t -*-
45c138ac 2
ba318903 3;; Copyright (C) 2003-2014 Free Software Foundation, Inc.
45c138ac
FEG
4
5;; Author: Fabián E. Gallina <fabian@anue.biz>
b7f13559 6;; URL: https://github.com/fgallina/python.el
09268a54 7;; Version: 0.24.2
34dc21db 8;; Maintainer: emacs-devel@gnu.org
45c138ac
FEG
9;; Created: Jul 2010
10;; Keywords: languages
11
09268a54 12;; This file is part of GNU Emacs.
45c138ac 13
09268a54
FEG
14;; GNU Emacs is free software: you can redistribute it and/or modify
15;; it under the terms of the GNU General Public License as published
16;; by the Free Software Foundation, either version 3 of the License,
17;; or (at your option) any later version.
45c138ac 18
09268a54
FEG
19;; GNU Emacs is distributed in the hope that it will be useful, but
20;; WITHOUT ANY WARRANTY; without even the implied warranty of
21;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22;; General Public License for more details.
45c138ac
FEG
23
24;; You should have received a copy of the GNU General Public License
09268a54 25;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
45c138ac
FEG
26
27;;; Commentary:
28
29;; Major mode for editing Python files with some fontification and
30;; indentation bits extracted from original Dave Love's python.el
31;; found in GNU/Emacs.
32
45c138ac 33;; Implements Syntax highlighting, Indentation, Movement, Shell
64348c32
FEG
34;; interaction, Shell completion, Shell virtualenv support, Pdb
35;; tracking, Symbol completion, Skeletons, FFAP, Code Check, Eldoc,
207cb73c 36;; Imenu.
45c138ac
FEG
37
38;; Syntax highlighting: Fontification of code is provided and supports
39;; python's triple quoted strings properly.
40
41;; Indentation: Automatic indentation with indentation cycling is
42;; provided, it allows you to navigate different available levels of
bd15d9d1
SM
43;; indentation by hitting <tab> several times. Also electric-indent-mode
44;; is supported such that when inserting a colon the current line is
45;; dedented automatically if needed.
45c138ac
FEG
46
47;; Movement: `beginning-of-defun' and `end-of-defun' functions are
fc6c545e 48;; properly implemented. There are also specialized
032d23ab
FEG
49;; `forward-sentence' and `backward-sentence' replacements called
50;; `python-nav-forward-block', `python-nav-backward-block'
51;; respectively which navigate between beginning of blocks of code.
52;; Extra functions `python-nav-forward-statement',
bcdc27d7
FEG
53;; `python-nav-backward-statement',
54;; `python-nav-beginning-of-statement', `python-nav-end-of-statement',
e5c144d6
FEG
55;; `python-nav-beginning-of-block', `python-nav-end-of-block' and
56;; `python-nav-if-name-main' are included but no bound to any key. At
57;; last but not least the specialized `python-nav-forward-sexp' allows
58;; easy navigation between code blocks. If you prefer `cc-mode'-like
59;; `forward-sexp' movement, setting `forward-sexp-function' to nil is
60;; enough, You can do that using the `python-mode-hook':
ea5f4192
FEG
61
62;; (add-hook 'python-mode-hook
63;; (lambda () (setq forward-sexp-function nil)))
45c138ac 64
fc6c545e 65;; Shell interaction: is provided and allows you to execute easily any
45c138ac
FEG
66;; block of code of your current buffer in an inferior Python process.
67
68;; Shell completion: hitting tab will try to complete the current
4e531f7a 69;; word. Shell completion is implemented in a manner that if you
45c138ac
FEG
70;; change the `python-shell-interpreter' to any other (for example
71;; IPython) it should be easy to integrate another way to calculate
57808175 72;; completions. You just need to specify your custom
45c138ac 73;; `python-shell-completion-setup-code' and
4cafacb5 74;; `python-shell-completion-string-code'.
62feb915
FEG
75
76;; Here is a complete example of the settings you would use for
1faf2911 77;; iPython 0.11:
62feb915
FEG
78
79;; (setq
80;; python-shell-interpreter "ipython"
81;; python-shell-interpreter-args ""
82;; python-shell-prompt-regexp "In \\[[0-9]+\\]: "
83;; python-shell-prompt-output-regexp "Out\\[[0-9]+\\]: "
9399498e
FEG
84;; python-shell-completion-setup-code
85;; "from IPython.core.completerlib import module_completion"
f6b59cd1 86;; python-shell-completion-module-string-code
9399498e 87;; "';'.join(module_completion('''%s'''))\n"
62feb915 88;; python-shell-completion-string-code
9399498e 89;; "';'.join(get_ipython().Completer.all_completions('''%s'''))\n")
1faf2911
FEG
90
91;; For iPython 0.10 everything would be the same except for
936bc833
FEG
92;; `python-shell-completion-string-code' and
93;; `python-shell-completion-module-string-code':
1faf2911
FEG
94
95;; (setq python-shell-completion-string-code
936bc833
FEG
96;; "';'.join(__IP.complete('''%s'''))\n"
97;; python-shell-completion-module-string-code "")
45c138ac 98
a1ea6ab8
FEG
99;; Unfortunately running iPython on Windows needs some more tweaking.
100;; The way you must set `python-shell-interpreter' and
101;; `python-shell-interpreter-args' is as follows:
102
103;; (setq
104;; python-shell-interpreter "C:\\Python27\\python.exe"
105;; python-shell-interpreter-args
106;; "-i C:\\Python27\\Scripts\\ipython-script.py")
107
108;; That will spawn the iPython process correctly (Of course you need
109;; to modify the paths according to your system).
110
099bf010
FEG
111;; Please note that the default completion system depends on the
112;; readline module, so if you are using some Operating System that
113;; bundles Python without it (like Windows) just install the
114;; pyreadline from http://ipython.scipy.org/moin/PyReadline/Intro and
115;; you should be good to go.
116
64348c32
FEG
117;; Shell virtualenv support: The shell also contains support for
118;; virtualenvs and other special environment modifications thanks to
66bbb27f
FEG
119;; `python-shell-process-environment' and `python-shell-exec-path'.
120;; These two variables allows you to modify execution paths and
307bd2e8 121;; environment variables to make easy for you to setup virtualenv rules
64348c32 122;; or behavior modifications when running shells. Here is an example
66bbb27f
FEG
123;; of how to make shell processes to be run using the /path/to/env/
124;; virtualenv:
125
126;; (setq python-shell-process-environment
127;; (list
128;; (format "PATH=%s" (mapconcat
129;; 'identity
130;; (reverse
131;; (cons (getenv "PATH")
132;; '("/path/to/env/bin/")))
133;; ":"))
134;; "VIRTUAL_ENV=/path/to/env/"))
135;; (python-shell-exec-path . ("/path/to/env/bin/"))
136
48d1354e 137;; Since the above is cumbersome and can be programmatically
64348c32
FEG
138;; calculated, the variable `python-shell-virtualenv-path' is
139;; provided. When this variable is set with the path of the
140;; virtualenv to use, `process-environment' and `exec-path' get proper
141;; values in order to run shells inside the specified virtualenv. So
142;; the following will achieve the same as the previous example:
143
144;; (setq python-shell-virtualenv-path "/path/to/env/")
145
929036b4
FEG
146;; Also the `python-shell-extra-pythonpaths' variable have been
147;; introduced as simple way of adding paths to the PYTHONPATH without
148;; affecting existing values.
149
45c138ac
FEG
150;; Pdb tracking: when you execute a block of code that contains some
151;; call to pdb (or ipdb) it will prompt the block of code and will
152;; follow the execution of pdb marking the current line with an arrow.
153
4e531f7a 154;; Symbol completion: you can complete the symbol at point. It uses
45c138ac
FEG
155;; the shell completion in background so you should run
156;; `python-shell-send-buffer' from time to time to get better results.
157
c77f4a90
MM
158;; Skeletons: skeletons are provided for simple inserting of things like class,
159;; def, for, import, if, try, and while. These skeletons are
160;; integrated with abbrev. If you have `abbrev-mode' activated and
e2803784
FEG
161;; `python-skeleton-autoinsert' is set to t, then whenever you type
162;; the name of any of those defined and hit SPC, they will be
345f866e 163;; automatically expanded. As an alternative you can use the defined
c77f4a90 164;; skeleton commands: `python-skeleton-<foo>'.
e2803784 165
2947016a
FEG
166;; FFAP: You can find the filename for a given module when using ffap
167;; out of the box. This feature needs an inferior python shell
168;; running.
169
2d63ad56
FEG
170;; Code check: Check the current file for errors with `python-check'
171;; using the program defined in `python-check-command'.
8b3e0e76 172
45c138ac 173;; Eldoc: returns documentation for object at point by using the
4e531f7a 174;; inferior python subprocess to inspect its documentation. As you
45c138ac
FEG
175;; might guessed you should run `python-shell-send-buffer' from time
176;; to time to get better results too.
177
adc31213
FEG
178;; Imenu: There are two index building functions to be used as
179;; `imenu-create-index-function': `python-imenu-create-index' (the
180;; default one, builds the alist in form of a tree) and
fbcc63a3 181;; `python-imenu-create-flat-index'. See also
adc31213
FEG
182;; `python-imenu-format-item-label-function',
183;; `python-imenu-format-parent-item-label-function',
184;; `python-imenu-format-parent-item-jump-label-function' variables for
185;; changing the way labels are formatted in the tree version.
fc2dc7df 186
57808175
FEG
187;; If you used python-mode.el you probably will miss auto-indentation
188;; when inserting newlines. To achieve the same behavior you have
189;; two options:
190
191;; 1) Use GNU/Emacs' standard binding for `newline-and-indent': C-j.
192
193;; 2) Add the following hook in your .emacs:
194
195;; (add-hook 'python-mode-hook
196;; #'(lambda ()
197;; (define-key python-mode-map "\C-m" 'newline-and-indent)))
198
199;; I'd recommend the first one since you'll get the same behavior for
200;; all modes out-of-the-box.
201
45c138ac
FEG
202;;; Installation:
203
204;; Add this to your .emacs:
205
206;; (add-to-list 'load-path "/folder/containing/file")
207;; (require 'python)
208
209;;; TODO:
210
45c138ac
FEG
211;;; Code:
212
45c138ac 213(require 'ansi-color)
73ed6836 214(require 'comint)
45c138ac 215
14146222
SM
216;; Avoid compiler warnings
217(defvar view-return-to-alist)
218(defvar compilation-error-regexp-alist)
219(defvar outline-heading-end-regexp)
45c138ac
FEG
220
221(autoload 'comint-mode "comint")
222
223;;;###autoload
224(add-to-list 'auto-mode-alist (cons (purecopy "\\.py\\'") 'python-mode))
225;;;###autoload
2a08047a 226(add-to-list 'interpreter-mode-alist (cons (purecopy "python[0-9.]*") 'python-mode))
45c138ac
FEG
227
228(defgroup python nil
229 "Python Language's flying circus support for Emacs."
230 :group 'languages
5b63c74a 231 :version "24.3"
45c138ac
FEG
232 :link '(emacs-commentary-link "python"))
233
234\f
235;;; Bindings
236
237(defvar python-mode-map
238 (let ((map (make-sparse-keymap)))
9fff1858 239 ;; Movement
55cd00c8
FEG
240 (define-key map [remap backward-sentence] 'python-nav-backward-block)
241 (define-key map [remap forward-sentence] 'python-nav-forward-block)
242 (define-key map [remap backward-up-list] 'python-nav-backward-up-list)
758e556a 243 (define-key map "\C-c\C-j" 'imenu)
45c138ac
FEG
244 ;; Indent specific
245 (define-key map "\177" 'python-indent-dedent-line-backspace)
246 (define-key map (kbd "<backtab>") 'python-indent-dedent-line)
247 (define-key map "\C-c<" 'python-indent-shift-left)
248 (define-key map "\C-c>" 'python-indent-shift-right)
e2803784
FEG
249 ;; Skeletons
250 (define-key map "\C-c\C-tc" 'python-skeleton-class)
251 (define-key map "\C-c\C-td" 'python-skeleton-def)
252 (define-key map "\C-c\C-tf" 'python-skeleton-for)
253 (define-key map "\C-c\C-ti" 'python-skeleton-if)
c77f4a90 254 (define-key map "\C-c\C-tm" 'python-skeleton-import)
e2803784
FEG
255 (define-key map "\C-c\C-tt" 'python-skeleton-try)
256 (define-key map "\C-c\C-tw" 'python-skeleton-while)
45c138ac 257 ;; Shell interaction
a90dfb95 258 (define-key map "\C-c\C-p" 'run-python)
45c138ac
FEG
259 (define-key map "\C-c\C-s" 'python-shell-send-string)
260 (define-key map "\C-c\C-r" 'python-shell-send-region)
261 (define-key map "\C-\M-x" 'python-shell-send-defun)
262 (define-key map "\C-c\C-c" 'python-shell-send-buffer)
263 (define-key map "\C-c\C-l" 'python-shell-send-file)
264 (define-key map "\C-c\C-z" 'python-shell-switch-to-shell)
8b3e0e76
FEG
265 ;; Some util commands
266 (define-key map "\C-c\C-v" 'python-check)
78334b43 267 (define-key map "\C-c\C-f" 'python-eldoc-at-point)
45c138ac
FEG
268 ;; Utilities
269 (substitute-key-definition 'complete-symbol 'completion-at-point
6cad4c6e 270 map global-map)
45c138ac
FEG
271 (easy-menu-define python-menu map "Python Mode menu"
272 `("Python"
6cad4c6e
FEG
273 :help "Python-specific Features"
274 ["Shift region left" python-indent-shift-left :active mark-active
275 :help "Shift region left by a single indentation step"]
276 ["Shift region right" python-indent-shift-right :active mark-active
277 :help "Shift region right by a single indentation step"]
278 "-"
279 ["Start of def/class" beginning-of-defun
280 :help "Go to start of outermost definition around point"]
281 ["End of def/class" end-of-defun
282 :help "Go to end of definition around point"]
283 ["Mark def/class" mark-defun
284 :help "Mark outermost definition around point"]
758e556a 285 ["Jump to def/class" imenu
6cad4c6e 286 :help "Jump to a class or function definition"]
fc6c545e 287 "--"
6cad4c6e 288 ("Skeletons")
fc6c545e 289 "---"
6cad4c6e
FEG
290 ["Start interpreter" run-python
291 :help "Run inferior Python process in a separate buffer"]
292 ["Switch to shell" python-shell-switch-to-shell
293 :help "Switch to running inferior Python process"]
294 ["Eval string" python-shell-send-string
295 :help "Eval string in inferior Python session"]
296 ["Eval buffer" python-shell-send-buffer
297 :help "Eval buffer in inferior Python session"]
298 ["Eval region" python-shell-send-region
299 :help "Eval region in inferior Python session"]
300 ["Eval defun" python-shell-send-defun
301 :help "Eval defun in inferior Python session"]
302 ["Eval file" python-shell-send-file
303 :help "Eval file in inferior Python session"]
304 ["Debugger" pdb :help "Run pdb under GUD"]
fc6c545e 305 "----"
6cad4c6e
FEG
306 ["Check file" python-check
307 :help "Check file for errors"]
308 ["Help on symbol" python-eldoc-at-point
309 :help "Get help on symbol at point"]
310 ["Complete symbol" completion-at-point
311 :help "Complete symbol before point"]))
45c138ac
FEG
312 map)
313 "Keymap for `python-mode'.")
314
315\f
316;;; Python specialized rx
317
73ed6836
FEG
318(eval-when-compile
319 (defconst python-rx-constituents
25f09295 320 `((block-start . ,(rx symbol-start
73ed6836
FEG
321 (or "def" "class" "if" "elif" "else" "try"
322 "except" "finally" "for" "while" "with")
323 symbol-end))
25f09295 324 (decorator . ,(rx line-start (* space) ?@ (any letter ?_)
6cad4c6e 325 (* (any word ?_))))
25f09295
SM
326 (defun . ,(rx symbol-start (or "def" "class") symbol-end))
327 (if-name-main . ,(rx line-start "if" (+ space) "__name__"
90a41b9d
FEG
328 (+ space) "==" (+ space)
329 (any ?' ?\") "__main__" (any ?' ?\")
330 (* space) ?:))
25f09295
SM
331 (symbol-name . ,(rx (any letter ?_) (* (any word ?_))))
332 (open-paren . ,(rx (or "{" "[" "(")))
333 (close-paren . ,(rx (or "}" "]" ")")))
334 (simple-operator . ,(rx (any ?+ ?- ?/ ?& ?^ ?~ ?| ?* ?< ?> ?= ?%)))
335 ;; FIXME: rx should support (not simple-operator).
336 (not-simple-operator . ,(rx
6cad4c6e
FEG
337 (not
338 (any ?+ ?- ?/ ?& ?^ ?~ ?| ?* ?< ?> ?= ?%))))
25f09295
SM
339 ;; FIXME: Use regexp-opt.
340 (operator . ,(rx (or "+" "-" "/" "&" "^" "~" "|" "*" "<" ">"
73ed6836
FEG
341 "=" "%" "**" "//" "<<" ">>" "<=" "!="
342 "==" ">=" "is" "not")))
25f09295
SM
343 ;; FIXME: Use regexp-opt.
344 (assignment-operator . ,(rx (or "=" "+=" "-=" "*=" "/=" "//=" "%=" "**="
a5b773c4
FEG
345 ">>=" "<<=" "&=" "^=" "|=")))
346 (string-delimiter . ,(rx (and
347 ;; Match even number of backslashes.
348 (or (not (any ?\\ ?\' ?\")) point
349 ;; Quotes might be preceded by a escaped quote.
350 (and (or (not (any ?\\)) point) ?\\
351 (* ?\\ ?\\) (any ?\' ?\")))
352 (* ?\\ ?\\)
353 ;; Match single or triple quotes of any kind.
354 (group (or "\"" "\"\"\"" "'" "'''"))))))
355 "Additional Python specific sexps for `python-rx'")
356
357 (defmacro python-rx (&rest regexps)
358 "Python mode specialized rx macro.
fd16b061 359This variant of `rx' supports common Python named REGEXPS."
a5b773c4
FEG
360 (let ((rx-constituents (append python-rx-constituents rx-constituents)))
361 (cond ((null regexps)
362 (error "No regexp"))
363 ((cdr regexps)
364 (rx-to-string `(and ,@regexps) t))
365 (t
366 (rx-to-string (car regexps) t))))))
45c138ac
FEG
367
368\f
369;;; Font-lock and syntax
2d79ec42 370
619ed6e1
FEG
371(eval-when-compile
372 (defun python-syntax--context-compiler-macro (form type &optional syntax-ppss)
373 (pcase type
374 (`'comment
375 `(let ((ppss (or ,syntax-ppss (syntax-ppss))))
376 (and (nth 4 ppss) (nth 8 ppss))))
377 (`'string
378 `(let ((ppss (or ,syntax-ppss (syntax-ppss))))
379 (and (nth 3 ppss) (nth 8 ppss))))
380 (`'paren
381 `(nth 1 (or ,syntax-ppss (syntax-ppss))))
382 (_ form))))
383
2d79ec42
FEG
384(defun python-syntax-context (type &optional syntax-ppss)
385 "Return non-nil if point is on TYPE using SYNTAX-PPSS.
386TYPE can be `comment', `string' or `paren'. It returns the start
387character address of the specified TYPE."
619ed6e1 388 (declare (compiler-macro python-syntax--context-compiler-macro))
2d79ec42 389 (let ((ppss (or syntax-ppss (syntax-ppss))))
14146222
SM
390 (pcase type
391 (`comment (and (nth 4 ppss) (nth 8 ppss)))
392 (`string (and (nth 3 ppss) (nth 8 ppss)))
393 (`paren (nth 1 ppss))
394 (_ nil))))
2d79ec42
FEG
395
396(defun python-syntax-context-type (&optional syntax-ppss)
397 "Return the context type using SYNTAX-PPSS.
398The type returned can be `comment', `string' or `paren'."
399 (let ((ppss (or syntax-ppss (syntax-ppss))))
400 (cond
401 ((nth 8 ppss) (if (nth 4 ppss) 'comment 'string))
402 ((nth 1 ppss) 'paren))))
403
404(defsubst python-syntax-comment-or-string-p ()
405 "Return non-nil if point is inside 'comment or 'string."
406 (nth 8 (syntax-ppss)))
407
408(define-obsolete-function-alias
2a1e2476 409 'python-info-ppss-context #'python-syntax-context "24.3")
2d79ec42
FEG
410
411(define-obsolete-function-alias
2a1e2476 412 'python-info-ppss-context-type #'python-syntax-context-type "24.3")
2d79ec42
FEG
413
414(define-obsolete-function-alias
415 'python-info-ppss-comment-or-string-p
2a1e2476 416 #'python-syntax-comment-or-string-p "24.3")
2d79ec42 417
45c138ac
FEG
418(defvar python-font-lock-keywords
419 ;; Keywords
420 `(,(rx symbol-start
27d7f16f
FEG
421 (or
422 "and" "del" "from" "not" "while" "as" "elif" "global" "or" "with"
423 "assert" "else" "if" "pass" "yield" "break" "except" "import" "class"
424 "in" "raise" "continue" "finally" "is" "return" "def" "for" "lambda"
425 "try"
426 ;; Python 2:
427 "print" "exec"
428 ;; Python 3:
429 ;; False, None, and True are listed as keywords on the Python 3
430 ;; documentation, but since they also qualify as constants they are
431 ;; fontified like that in order to keep font-lock consistent between
432 ;; Python versions.
479a14cc
FEG
433 "nonlocal"
434 ;; Extra:
435 "self")
45c138ac
FEG
436 symbol-end)
437 ;; functions
438 (,(rx symbol-start "def" (1+ space) (group (1+ (or word ?_))))
439 (1 font-lock-function-name-face))
440 ;; classes
441 (,(rx symbol-start "class" (1+ space) (group (1+ (or word ?_))))
442 (1 font-lock-type-face))
443 ;; Constants
c61d750e 444 (,(rx symbol-start
27d7f16f
FEG
445 (or
446 "Ellipsis" "False" "None" "NotImplemented" "True" "__debug__"
447 ;; copyright, license, credits, quit and exit are added by the site
448 ;; module and they are not intended to be used in programs
449 "copyright" "credits" "exit" "license" "quit")
c61d750e 450 symbol-end) . font-lock-constant-face)
45c138ac
FEG
451 ;; Decorators.
452 (,(rx line-start (* (any " \t")) (group "@" (1+ (or word ?_))
453 (0+ "." (1+ (or word ?_)))))
454 (1 font-lock-type-face))
455 ;; Builtin Exceptions
456 (,(rx symbol-start
27d7f16f
FEG
457 (or
458 "ArithmeticError" "AssertionError" "AttributeError" "BaseException"
459 "DeprecationWarning" "EOFError" "EnvironmentError" "Exception"
460 "FloatingPointError" "FutureWarning" "GeneratorExit" "IOError"
461 "ImportError" "ImportWarning" "IndexError" "KeyError"
462 "KeyboardInterrupt" "LookupError" "MemoryError" "NameError"
463 "NotImplementedError" "OSError" "OverflowError"
464 "PendingDeprecationWarning" "ReferenceError" "RuntimeError"
465 "RuntimeWarning" "StopIteration" "SyntaxError" "SyntaxWarning"
466 "SystemError" "SystemExit" "TypeError" "UnboundLocalError"
467 "UnicodeDecodeError" "UnicodeEncodeError" "UnicodeError"
468 "UnicodeTranslateError" "UnicodeWarning" "UserWarning" "VMSError"
469 "ValueError" "Warning" "WindowsError" "ZeroDivisionError"
470 ;; Python 2:
471 "StandardError"
472 ;; Python 3:
473 "BufferError" "BytesWarning" "IndentationError" "ResourceWarning"
474 "TabError")
45c138ac
FEG
475 symbol-end) . font-lock-type-face)
476 ;; Builtins
9438f1ef 477 (,(rx symbol-start
27d7f16f
FEG
478 (or
479 "abs" "all" "any" "bin" "bool" "callable" "chr" "classmethod"
480 "compile" "complex" "delattr" "dict" "dir" "divmod" "enumerate"
481 "eval" "filter" "float" "format" "frozenset" "getattr" "globals"
482 "hasattr" "hash" "help" "hex" "id" "input" "int" "isinstance"
483 "issubclass" "iter" "len" "list" "locals" "map" "max" "memoryview"
484 "min" "next" "object" "oct" "open" "ord" "pow" "print" "property"
485 "range" "repr" "reversed" "round" "set" "setattr" "slice" "sorted"
486 "staticmethod" "str" "sum" "super" "tuple" "type" "vars" "zip"
487 "__import__"
488 ;; Python 2:
489 "basestring" "cmp" "execfile" "file" "long" "raw_input" "reduce"
490 "reload" "unichr" "unicode" "xrange" "apply" "buffer" "coerce"
491 "intern"
492 ;; Python 3:
493 "ascii" "bytearray" "bytes" "exec"
494 ;; Extra:
495 "__all__" "__doc__" "__name__" "__package__")
9438f1ef 496 symbol-end) . font-lock-builtin-face)
48d1354e 497 ;; assignments
45c138ac
FEG
498 ;; support for a = b = c = 5
499 (,(lambda (limit)
d8e594db
FEG
500 (let ((re (python-rx (group (+ (any word ?. ?_)))
501 (? ?\[ (+ (not (any ?\]))) ?\]) (* space)
9e89d835
SM
502 assignment-operator))
503 (res nil))
504 (while (and (setq res (re-search-forward re limit t))
505 (or (python-syntax-context 'paren)
506 (equal (char-after (point-marker)) ?=))))
507 res))
45c138ac
FEG
508 (1 font-lock-variable-name-face nil nil))
509 ;; support for a, b, c = (1, 2, 3)
510 (,(lambda (limit)
511 (let ((re (python-rx (group (+ (any word ?. ?_))) (* space)
512 (* ?, (* space) (+ (any word ?. ?_)) (* space))
513 ?, (* space) (+ (any word ?. ?_)) (* space)
9e89d835
SM
514 assignment-operator))
515 (res nil))
516 (while (and (setq res (re-search-forward re limit t))
517 (goto-char (match-end 1))
518 (python-syntax-context 'paren)))
519 res))
45c138ac
FEG
520 (1 font-lock-variable-name-face nil nil))))
521
aeadd9a4 522(defconst python-syntax-propertize-function
aeadd9a4 523 (syntax-propertize-rules
a5b773c4 524 ((python-rx string-delimiter)
5727eadf 525 (0 (ignore (python-syntax-stringify))))))
8fb8b88f
FEG
526
527(defsubst python-syntax-count-quotes (quote-char &optional point limit)
528 "Count number of quotes around point (max is 3).
529QUOTE-CHAR is the quote char to count. Optional argument POINT is
fd16b061 530the point where scan starts (defaults to current point), and LIMIT
8fb8b88f
FEG
531is used to limit the scan."
532 (let ((i 0))
533 (while (and (< i 3)
534 (or (not limit) (< (+ point i) limit))
535 (eq (char-after (+ point i)) quote-char))
66164d2f 536 (setq i (1+ i)))
8fb8b88f
FEG
537 i))
538
539(defun python-syntax-stringify ()
540 "Put `syntax-table' property correctly on single/triple quotes."
a1a9f411 541 (let* ((num-quotes (length (match-string-no-properties 1)))
8fb8b88f
FEG
542 (ppss (prog2
543 (backward-char num-quotes)
544 (syntax-ppss)
545 (forward-char num-quotes)))
546 (string-start (and (not (nth 4 ppss)) (nth 8 ppss)))
547 (quote-starting-pos (- (point) num-quotes))
548 (quote-ending-pos (point))
549 (num-closing-quotes
550 (and string-start
551 (python-syntax-count-quotes
552 (char-before) string-start quote-starting-pos))))
553 (cond ((and string-start (= num-closing-quotes 0))
554 ;; This set of quotes doesn't match the string starting
555 ;; kind. Do nothing.
556 nil)
557 ((not string-start)
558 ;; This set of quotes delimit the start of a string.
559 (put-text-property quote-starting-pos (1+ quote-starting-pos)
560 'syntax-table (string-to-syntax "|")))
561 ((= num-quotes num-closing-quotes)
562 ;; This set of quotes delimit the end of a string.
563 (put-text-property (1- quote-ending-pos) quote-ending-pos
564 'syntax-table (string-to-syntax "|")))
565 ((> num-quotes num-closing-quotes)
566 ;; This may only happen whenever a triple quote is closing
567 ;; a single quoted string. Add string delimiter syntax to
568 ;; all three quotes.
569 (put-text-property quote-starting-pos quote-ending-pos
570 'syntax-table (string-to-syntax "|"))))))
45c138ac
FEG
571
572(defvar python-mode-syntax-table
573 (let ((table (make-syntax-table)))
574 ;; Give punctuation syntax to ASCII that normally has symbol
575 ;; syntax or has word syntax and isn't a letter.
576 (let ((symbol (string-to-syntax "_"))
6cad4c6e 577 (sst (standard-syntax-table)))
45c138ac 578 (dotimes (i 128)
6cad4c6e
FEG
579 (unless (= i ?_)
580 (if (equal symbol (aref sst i))
581 (modify-syntax-entry i "." table)))))
45c138ac
FEG
582 (modify-syntax-entry ?$ "." table)
583 (modify-syntax-entry ?% "." table)
584 ;; exceptions
585 (modify-syntax-entry ?# "<" table)
586 (modify-syntax-entry ?\n ">" table)
587 (modify-syntax-entry ?' "\"" table)
588 (modify-syntax-entry ?` "$" table)
589 table)
590 "Syntax table for Python files.")
591
592(defvar python-dotty-syntax-table
593 (let ((table (make-syntax-table python-mode-syntax-table)))
594 (modify-syntax-entry ?. "w" table)
595 (modify-syntax-entry ?_ "w" table)
596 table)
597 "Dotty syntax table for Python files.
598It makes underscores and dots word constituent chars.")
599
600\f
601;;; Indentation
602
603(defcustom python-indent-offset 4
604 "Default indentation offset for Python."
605 :group 'python
606 :type 'integer
607 :safe 'integerp)
608
609(defcustom python-indent-guess-indent-offset t
610 "Non-nil tells Python mode to guess `python-indent-offset' value."
611 :type 'boolean
0f55249e
FEG
612 :group 'python
613 :safe 'booleanp)
45c138ac 614
ccb1c17e
FEG
615(defcustom python-indent-trigger-commands
616 '(indent-for-tab-command yas-expand yas/expand)
617 "Commands that might trigger a `python-indent-line' call."
618 :type '(repeat symbol)
619 :group 'python)
620
9ddf3c74 621(define-obsolete-variable-alias
2a1e2476 622 'python-indent 'python-indent-offset "24.3")
9ddf3c74
FEG
623
624(define-obsolete-variable-alias
2a1e2476 625 'python-guess-indent 'python-indent-guess-indent-offset "24.3")
9ddf3c74 626
45c138ac
FEG
627(defvar python-indent-current-level 0
628 "Current indentation level `python-indent-line-function' is using.")
629
630(defvar python-indent-levels '(0)
631 "Levels of indentation available for `python-indent-line-function'.")
632
633(defvar python-indent-dedenters '("else" "elif" "except" "finally")
634 "List of words that should be dedented.
635These make `python-indent-calculate-indentation' subtract the value of
636`python-indent-offset'.")
637
f782d531
FEG
638(defvar python-indent-block-enders
639 '("break" "continue" "pass" "raise" "return")
c9886b39
FEG
640 "List of words that mark the end of a block.
641These make `python-indent-calculate-indentation' subtract the
642value of `python-indent-offset' when `python-indent-context' is
643AFTER-LINE.")
644
45c138ac 645(defun python-indent-guess-indent-offset ()
954aa7bd 646 "Guess and set `python-indent-offset' for the current buffer."
9ddf3c74 647 (interactive)
6cad4c6e
FEG
648 (save-excursion
649 (save-restriction
650 (widen)
651 (goto-char (point-min))
652 (let ((block-end))
653 (while (and (not block-end)
654 (re-search-forward
655 (python-rx line-start block-start) nil t))
656 (when (and
2d79ec42 657 (not (python-syntax-context-type))
6cad4c6e
FEG
658 (progn
659 (goto-char (line-end-position))
660 (python-util-forward-comment -1)
661 (if (equal (char-before) ?:)
662 t
663 (forward-line 1)
664 (when (python-info-block-continuation-line-p)
665 (while (and (python-info-continuation-line-p)
666 (not (eobp)))
667 (forward-line 1))
668 (python-util-forward-comment -1)
669 (when (equal (char-before) ?:)
670 t)))))
671 (setq block-end (point-marker))))
672 (let ((indentation
673 (when block-end
674 (goto-char block-end)
675 (python-util-forward-comment)
676 (current-indentation))))
0bf3f0fa 677 (if (and indentation (not (zerop indentation)))
98f99594 678 (set (make-local-variable 'python-indent-offset) indentation)
6cad4c6e
FEG
679 (message "Can't guess python-indent-offset, using defaults: %s"
680 python-indent-offset)))))))
45c138ac 681
e2d8d479
FEG
682(defun python-indent-context ()
683 "Get information on indentation context.
684Context information is returned with a cons with the form:
fd16b061 685 (STATUS . START)
45c138ac
FEG
686
687Where status can be any of the following symbols:
09faee72
FEG
688
689 * after-comment: When current line might continue a comment block
45c138ac
FEG
690 * inside-paren: If point in between (), {} or []
691 * inside-string: If point is inside a string
692 * after-backslash: Previous line ends in a backslash
693 * after-beginning-of-block: Point is after beginning of block
694 * after-line: Point is after normal line
695 * no-indent: Point is at beginning of buffer or other special case
45c138ac
FEG
696START is the buffer position where the sexp starts."
697 (save-restriction
698 (widen)
699 (let ((ppss (save-excursion (beginning-of-line) (syntax-ppss)))
700 (start))
701 (cons
702 (cond
69bab1de 703 ;; Beginning of buffer
19b122e4
FEG
704 ((save-excursion
705 (goto-char (line-beginning-position))
706 (bobp))
69bab1de 707 'no-indent)
09faee72
FEG
708 ;; Comment continuation
709 ((save-excursion
710 (when (and
711 (or
712 (python-info-current-line-comment-p)
713 (python-info-current-line-empty-p))
714 (progn
715 (forward-comment -1)
716 (python-info-current-line-comment-p)))
717 (setq start (point))
718 'after-comment)))
45c138ac 719 ;; Inside string
2d79ec42 720 ((setq start (python-syntax-context 'string ppss))
45c138ac 721 'inside-string)
be0d5bae
FEG
722 ;; Inside a paren
723 ((setq start (python-syntax-context 'paren ppss))
724 'inside-paren)
45c138ac 725 ;; After backslash
2d79ec42
FEG
726 ((setq start (when (not (or (python-syntax-context 'string ppss)
727 (python-syntax-context 'comment ppss)))
2af3b9c1
FEG
728 (let ((line-beg-pos (line-number-at-pos)))
729 (python-info-line-ends-backslash-p
730 (1- line-beg-pos)))))
45c138ac
FEG
731 'after-backslash)
732 ;; After beginning of block
733 ((setq start (save-excursion
0674d3fa
FEG
734 (when (progn
735 (back-to-indentation)
736 (python-util-forward-comment -1)
737 (equal (char-before) ?:))
738 ;; Move to the first block start that's not in within
739 ;; a string, comment or paren and that's not a
740 ;; continuation line.
741 (while (and (re-search-backward
742 (python-rx block-start) nil t)
743 (or
2d79ec42 744 (python-syntax-context-type)
0674d3fa
FEG
745 (python-info-continuation-line-p))))
746 (when (looking-at (python-rx block-start))
45c138ac
FEG
747 (point-marker)))))
748 'after-beginning-of-block)
749 ;; After normal line
750 ((setq start (save-excursion
257b0017 751 (back-to-indentation)
be0d5bae 752 (skip-chars-backward (rx (or whitespace ?\n)))
bcdc27d7 753 (python-nav-beginning-of-statement)
45c138ac
FEG
754 (point-marker)))
755 'after-line)
756 ;; Do not indent
757 (t 'no-indent))
758 start))))
759
760(defun python-indent-calculate-indentation ()
761 "Calculate correct indentation offset for the current line."
762 (let* ((indentation-context (python-indent-context))
763 (context-status (car indentation-context))
764 (context-start (cdr indentation-context)))
765 (save-restriction
766 (widen)
767 (save-excursion
14146222
SM
768 (pcase context-status
769 (`no-indent 0)
09faee72
FEG
770 (`after-comment
771 (goto-char context-start)
772 (current-indentation))
0674d3fa
FEG
773 ;; When point is after beginning of block just add one level
774 ;; of indentation relative to the context-start
14146222 775 (`after-beginning-of-block
45c138ac
FEG
776 (goto-char context-start)
777 (+ (current-indentation) python-indent-offset))
0674d3fa
FEG
778 ;; When after a simple line just use previous line
779 ;; indentation, in the case current line starts with a
780 ;; `python-indent-dedenters' de-indent one level.
14146222 781 (`after-line
bc9222c9
FEG
782 (let* ((pair (save-excursion
783 (goto-char context-start)
784 (cons
785 (current-indentation)
786 (python-info-beginning-of-block-p))))
787 (context-indentation (car pair))
788 (after-block-start-p (cdr pair))
789 (adjustment
790 (if (or (save-excursion
791 (back-to-indentation)
792 (and
793 ;; De-indent only when dedenters are not
794 ;; next to a block start. This allows
795 ;; one-liner constructs such as:
796 ;; if condition: print "yay"
797 ;; else: print "wry"
798 (not after-block-start-p)
799 (looking-at (regexp-opt python-indent-dedenters))))
800 (save-excursion
801 (python-util-forward-comment -1)
802 (python-nav-beginning-of-statement)
803 (looking-at (regexp-opt python-indent-block-enders))))
804 python-indent-offset
805 0)))
806 (- context-indentation adjustment)))
0674d3fa
FEG
807 ;; When inside of a string, do nothing. just use the current
808 ;; indentation. XXX: perhaps it would be a good idea to
809 ;; invoke standard text indentation here
14146222 810 (`inside-string
45c138ac
FEG
811 (goto-char context-start)
812 (current-indentation))
48d1354e 813 ;; After backslash we have several possibilities.
14146222 814 (`after-backslash
0674d3fa
FEG
815 (cond
816 ;; Check if current line is a dot continuation. For this
817 ;; the current line must start with a dot and previous
818 ;; line must contain a dot too.
819 ((save-excursion
820 (back-to-indentation)
821 (when (looking-at "\\.")
dc4f2e53
FEG
822 ;; If after moving one line back point is inside a paren it
823 ;; needs to move back until it's not anymore
824 (while (prog2
825 (forward-line -1)
826 (and (not (bobp))
2d79ec42 827 (python-syntax-context 'paren))))
0674d3fa 828 (goto-char (line-end-position))
6cad4c6e
FEG
829 (while (and (re-search-backward
830 "\\." (line-beginning-position) t)
2d79ec42 831 (python-syntax-context-type)))
0674d3fa 832 (if (and (looking-at "\\.")
2d79ec42 833 (not (python-syntax-context-type)))
0674d3fa
FEG
834 ;; The indentation is the same column of the
835 ;; first matching dot that's not inside a
836 ;; comment, a string or a paren
837 (current-column)
838 ;; No dot found on previous line, just add another
839 ;; indentation level.
840 (+ (current-indentation) python-indent-offset)))))
841 ;; Check if prev line is a block continuation
842 ((let ((block-continuation-start
843 (python-info-block-continuation-line-p)))
844 (when block-continuation-start
845 ;; If block-continuation-start is set jump to that
846 ;; marker and use first column after the block start
847 ;; as indentation value.
848 (goto-char block-continuation-start)
849 (re-search-forward
850 (python-rx block-start (* space))
851 (line-end-position) t)
852 (current-column))))
853 ;; Check if current line is an assignment continuation
854 ((let ((assignment-continuation-start
855 (python-info-assignment-continuation-line-p)))
856 (when assignment-continuation-start
857 ;; If assignment-continuation is set jump to that
858 ;; marker and use first column after the assignment
859 ;; operator as indentation value.
860 (goto-char assignment-continuation-start)
861 (current-column))))
862 (t
863 (forward-line -1)
48d1354e 864 (goto-char (python-info-beginning-of-backslash))
0674d3fa
FEG
865 (if (save-excursion
866 (and
0674d3fa 867 (forward-line -1)
dc4f2e53 868 (goto-char
48d1354e 869 (or (python-info-beginning-of-backslash) (point)))
0674d3fa
FEG
870 (python-info-line-ends-backslash-p)))
871 ;; The two previous lines ended in a backslash so we must
872 ;; respect previous line indentation.
873 (current-indentation)
874 ;; What happens here is that we are dealing with the second
875 ;; line of a backslash continuation, in that case we just going
876 ;; to add one indentation level.
877 (+ (current-indentation) python-indent-offset)))))
878 ;; When inside a paren there's a need to handle nesting
879 ;; correctly
14146222 880 (`inside-paren
0674d3fa 881 (cond
48d1354e 882 ;; If current line closes the outermost open paren use the
0674d3fa
FEG
883 ;; current indentation of the context-start line.
884 ((save-excursion
885 (skip-syntax-forward "\s" (line-end-position))
886 (when (and (looking-at (regexp-opt '(")" "]" "}")))
887 (progn
888 (forward-char 1)
2d79ec42 889 (not (python-syntax-context 'paren))))
0674d3fa
FEG
890 (goto-char context-start)
891 (current-indentation))))
892 ;; If open paren is contained on a line by itself add another
893 ;; indentation level, else look for the first word after the
894 ;; opening paren and use it's column position as indentation
895 ;; level.
896 ((let* ((content-starts-in-newline)
897 (indent
898 (save-excursion
899 (if (setq content-starts-in-newline
900 (progn
901 (goto-char context-start)
902 (forward-char)
903 (save-restriction
904 (narrow-to-region
905 (line-beginning-position)
906 (line-end-position))
907 (python-util-forward-comment))
908 (looking-at "$")))
909 (+ (current-indentation) python-indent-offset)
910 (current-column)))))
911 ;; Adjustments
912 (cond
913 ;; If current line closes a nested open paren de-indent one
914 ;; level.
915 ((progn
17d13b85 916 (back-to-indentation)
0674d3fa
FEG
917 (looking-at (regexp-opt '(")" "]" "}"))))
918 (- indent python-indent-offset))
919 ;; If the line of the opening paren that wraps the current
920 ;; line starts a block add another level of indentation to
921 ;; follow new pep8 recommendation. See: http://ur1.ca/5rojx
922 ((save-excursion
923 (when (and content-starts-in-newline
924 (progn
925 (goto-char context-start)
926 (back-to-indentation)
927 (looking-at (python-rx block-start))))
928 (+ indent python-indent-offset))))
929 (t indent)))))))))))
45c138ac
FEG
930
931(defun python-indent-calculate-levels ()
932 "Calculate `python-indent-levels' and reset `python-indent-current-level'."
933 (let* ((indentation (python-indent-calculate-indentation))
934 (remainder (% indentation python-indent-offset))
935 (steps (/ (- indentation remainder) python-indent-offset)))
65e4f764 936 (setq python-indent-levels (list 0))
45c138ac 937 (dotimes (step steps)
65e4f764 938 (push (* python-indent-offset (1+ step)) python-indent-levels))
45c138ac 939 (when (not (eq 0 remainder))
65e4f764 940 (push (+ (* python-indent-offset steps) remainder) python-indent-levels))
45c138ac
FEG
941 (setq python-indent-levels (nreverse python-indent-levels))
942 (setq python-indent-current-level (1- (length python-indent-levels)))))
943
944(defun python-indent-toggle-levels ()
945 "Toggle `python-indent-current-level' over `python-indent-levels'."
946 (setq python-indent-current-level (1- python-indent-current-level))
947 (when (< python-indent-current-level 0)
948 (setq python-indent-current-level (1- (length python-indent-levels)))))
949
950(defun python-indent-line (&optional force-toggle)
951 "Internal implementation of `python-indent-line-function'.
45c138ac
FEG
952Uses the offset calculated in
953`python-indent-calculate-indentation' and available levels
e2d8d479
FEG
954indicated by the variable `python-indent-levels' to set the
955current indentation.
45c138ac 956
ccb1c17e
FEG
957When the variable `last-command' is equal to one of the symbols
958inside `python-indent-trigger-commands' or FORCE-TOGGLE is
959non-nil it cycles levels indicated in the variable
960`python-indent-levels' by setting the current level in the
961variable `python-indent-current-level'.
962
963When the variable `last-command' is not equal to one of the
964symbols inside `python-indent-trigger-commands' and FORCE-TOGGLE
fd16b061
JB
965is nil it calculates possible indentation levels and saves them
966in the variable `python-indent-levels'. Afterwards it sets the
ccb1c17e 967variable `python-indent-current-level' correctly so offset is
fd16b061
JB
968equal to
969 (nth python-indent-current-level python-indent-levels)"
095bb823 970 (or
ccb1c17e 971 (and (or (and (memq this-command python-indent-trigger-commands)
095bb823
FEG
972 (eq last-command this-command))
973 force-toggle)
974 (not (equal python-indent-levels '(0)))
975 (or (python-indent-toggle-levels) t))
976 (python-indent-calculate-levels))
977 (let* ((starting-pos (point-marker))
978 (indent-ending-position
979 (+ (line-beginning-position) (current-indentation)))
980 (follow-indentation-p
981 (or (bolp)
982 (and (<= (line-beginning-position) starting-pos)
983 (>= indent-ending-position starting-pos))))
984 (next-indent (nth python-indent-current-level python-indent-levels)))
985 (unless (= next-indent (current-indentation))
986 (beginning-of-line)
987 (delete-horizontal-space)
988 (indent-to next-indent)
989 (goto-char starting-pos))
990 (and follow-indentation-p (back-to-indentation)))
cd7ab092 991 (python-info-closing-block-message))
45c138ac
FEG
992
993(defun python-indent-line-function ()
994 "`indent-line-function' for Python mode.
e2d8d479 995See `python-indent-line' for details."
45c138ac
FEG
996 (python-indent-line))
997
998(defun python-indent-dedent-line ()
e2d8d479 999 "De-indent current line."
45c138ac 1000 (interactive "*")
2d79ec42 1001 (when (and (not (python-syntax-comment-or-string-p))
45c138ac
FEG
1002 (<= (point-marker) (save-excursion
1003 (back-to-indentation)
1004 (point-marker)))
1005 (> (current-column) 0))
1006 (python-indent-line t)
1007 t))
1008
1009(defun python-indent-dedent-line-backspace (arg)
e2d8d479 1010 "De-indent current line.
45c138ac 1011Argument ARG is passed to `backward-delete-char-untabify' when
fd16b061 1012point is not in between the indentation."
45c138ac
FEG
1013 (interactive "*p")
1014 (when (not (python-indent-dedent-line))
1015 (backward-delete-char-untabify arg)))
183f9296 1016(put 'python-indent-dedent-line-backspace 'delete-selection 'supersede)
45c138ac
FEG
1017
1018(defun python-indent-region (start end)
fd16b061 1019 "Indent a Python region automagically.
45c138ac
FEG
1020
1021Called from a program, START and END specify the region to indent."
cb42456f
FEG
1022 (let ((deactivate-mark nil))
1023 (save-excursion
1024 (goto-char end)
1025 (setq end (point-marker))
1026 (goto-char start)
1027 (or (bolp) (forward-line 1))
1028 (while (< (point) end)
1029 (or (and (bolp) (eolp))
1030 (let (word)
1031 (forward-line -1)
1032 (back-to-indentation)
1033 (setq word (current-word))
1034 (forward-line 1)
be0d5bae
FEG
1035 (when (and word
1036 ;; Don't mess with strings, unless it's the
1037 ;; enclosing set of quotes.
1038 (or (not (python-syntax-context 'string))
1039 (eq
1040 (syntax-after
1041 (+ (1- (point))
1042 (current-indentation)
1043 (python-syntax-count-quotes (char-after) (point))))
1044 (string-to-syntax "|"))))
cb42456f
FEG
1045 (beginning-of-line)
1046 (delete-horizontal-space)
1047 (indent-to (python-indent-calculate-indentation)))))
1048 (forward-line 1))
1049 (move-marker end nil))))
45c138ac
FEG
1050
1051(defun python-indent-shift-left (start end &optional count)
1052 "Shift lines contained in region START END by COUNT columns to the left.
e2d8d479
FEG
1053COUNT defaults to `python-indent-offset'. If region isn't
1054active, the current line is shifted. The shifted region includes
1055the lines in which START and END lie. An error is signaled if
1056any lines in the region are indented less than COUNT columns."
45c138ac
FEG
1057 (interactive
1058 (if mark-active
1059 (list (region-beginning) (region-end) current-prefix-arg)
1060 (list (line-beginning-position) (line-end-position) current-prefix-arg)))
1061 (if count
1062 (setq count (prefix-numeric-value count))
1063 (setq count python-indent-offset))
1064 (when (> count 0)
cb42456f
FEG
1065 (let ((deactivate-mark nil))
1066 (save-excursion
1067 (goto-char start)
1068 (while (< (point) end)
1069 (if (and (< (current-indentation) count)
1070 (not (looking-at "[ \t]*$")))
1071 (error "Can't shift all lines enough"))
1072 (forward-line))
1073 (indent-rigidly start end (- count))))))
45c138ac
FEG
1074
1075(add-to-list 'debug-ignored-errors "^Can't shift all lines enough")
1076
1077(defun python-indent-shift-right (start end &optional count)
fd16b061 1078 "Shift lines contained in region START END by COUNT columns to the right.
e2d8d479
FEG
1079COUNT defaults to `python-indent-offset'. If region isn't
1080active, the current line is shifted. The shifted region includes
1081the lines in which START and END lie."
45c138ac
FEG
1082 (interactive
1083 (if mark-active
1084 (list (region-beginning) (region-end) current-prefix-arg)
1085 (list (line-beginning-position) (line-end-position) current-prefix-arg)))
cb42456f 1086 (let ((deactivate-mark nil))
bd15d9d1
SM
1087 (setq count (if count (prefix-numeric-value count)
1088 python-indent-offset))
cb42456f 1089 (indent-rigidly start end count)))
45c138ac 1090
5eae76ae 1091(defun python-indent-post-self-insert-function ()
bd15d9d1 1092 "Adjust indentation after insertion of some characters.
fd16b061
JB
1093This function is intended to be added to `post-self-insert-hook.'
1094If a line renders a paren alone, after adding a char before it,
1095the line will be re-indented automatically if needed."
bd15d9d1
SM
1096 (when (and electric-indent-mode
1097 (eq (char-before) last-command-event))
1098 (cond
1099 ((and (not (bolp))
1100 (memq (char-after) '(?\) ?\] ?\})))
1101 (save-excursion
1102 (goto-char (line-beginning-position))
1103 ;; If after going to the beginning of line the point
1104 ;; is still inside a paren it's ok to do the trick
1105 (when (python-syntax-context 'paren)
1106 (let ((indentation (python-indent-calculate-indentation)))
1107 (when (< (current-indentation) indentation)
1108 (indent-line-to indentation))))))
1109 ((and (eq ?: last-command-event)
1110 (memq ?: electric-indent-chars)
1111 (not current-prefix-arg)
1112 (eolp)
1113 (not (equal ?: (char-before (1- (point)))))
1114 (not (python-syntax-comment-or-string-p)))
1115 (let ((indentation (current-indentation))
1116 (calculated-indentation (python-indent-calculate-indentation)))
1117 (python-info-closing-block-message)
1118 (when (> indentation calculated-indentation)
1119 (save-excursion
1120 (indent-line-to calculated-indentation)
1121 (when (not (python-info-closing-block-message))
1122 (indent-line-to indentation)))))))))
5eae76ae 1123
45c138ac
FEG
1124\f
1125;;; Navigation
1126
0567effb 1127(defvar python-nav-beginning-of-defun-regexp
af5c1beb 1128 (python-rx line-start (* space) defun (+ space) (group symbol-name))
fc6c545e 1129 "Regexp matching class or function definition.
fc2dc7df
FEG
1130The name of the defun should be grouped so it can be retrieved
1131via `match-string'.")
45c138ac 1132
2e6625b5
FEG
1133(defun python-nav--beginning-of-defun (&optional arg)
1134 "Internal implementation of `python-nav-beginning-of-defun'.
1135With positive ARG search backwards, else search forwards."
8c6f9e60
FEG
1136 (when (or (null arg) (= arg 0)) (setq arg 1))
1137 (let* ((re-search-fn (if (> arg 0)
1138 #'re-search-backward
1139 #'re-search-forward))
1140 (line-beg-pos (line-beginning-position))
1141 (line-content-start (+ line-beg-pos (current-indentation)))
1142 (pos (point-marker))
2e6625b5
FEG
1143 (beg-indentation
1144 (and (> arg 0)
1145 (save-excursion
207cb73c
FEG
1146 (while (and
1147 (not (python-info-looking-at-beginning-of-defun))
1148 (python-nav-backward-block)))
1149 (or (and (python-info-looking-at-beginning-of-defun)
1150 (+ (current-indentation) python-indent-offset))
1151 0))))
8c6f9e60
FEG
1152 (found
1153 (progn
1154 (when (and (< arg 0)
1155 (python-info-looking-at-beginning-of-defun))
1156 (end-of-line 1))
1157 (while (and (funcall re-search-fn
1158 python-nav-beginning-of-defun-regexp nil t)
2e6625b5
FEG
1159 (or (python-syntax-context-type)
1160 ;; Handle nested defuns when moving
1161 ;; backwards by checking indentation.
1162 (and (> arg 0)
1163 (not (= (current-indentation) 0))
1164 (>= (current-indentation) beg-indentation)))))
8c6f9e60
FEG
1165 (and (python-info-looking-at-beginning-of-defun)
1166 (or (not (= (line-number-at-pos pos)
1167 (line-number-at-pos)))
1168 (and (>= (point) line-beg-pos)
1169 (<= (point) line-content-start)
1170 (> pos line-content-start)))))))
1171 (if found
1172 (or (beginning-of-line 1) t)
1173 (and (goto-char pos) nil))))
1174
2e6625b5
FEG
1175(defun python-nav-beginning-of-defun (&optional arg)
1176 "Move point to `beginning-of-defun'.
fd16b061
JB
1177With positive ARG search backwards else search forward.
1178ARG nil or 0 defaults to 1. When searching backwards,
1179nested defuns are handled with care depending on current
1180point position. Return non-nil if point is moved to
2e6625b5 1181`beginning-of-defun'."
0567effb 1182 (when (or (null arg) (= arg 0)) (setq arg 1))
8c6f9e60 1183 (let ((found))
fbcc63a3
FEG
1184 (while (and (not (= arg 0))
1185 (let ((keep-searching-p
1186 (python-nav--beginning-of-defun arg)))
1187 (when (and keep-searching-p (null found))
1188 (setq found t))
1189 keep-searching-p))
1190 (setq arg (if (> arg 0) (1- arg) (1+ arg))))
8c6f9e60 1191 found))
45c138ac 1192
2e6625b5 1193(defun python-nav-end-of-defun ()
45c138ac
FEG
1194 "Move point to the end of def or class.
1195Returns nil if point is not in a def or class."
0567effb 1196 (interactive)
2e6625b5
FEG
1197 (let ((beg-defun-indent)
1198 (beg-pos (point)))
8c6f9e60 1199 (when (or (python-info-looking-at-beginning-of-defun)
2e6625b5
FEG
1200 (python-nav-beginning-of-defun 1)
1201 (python-nav-beginning-of-defun -1))
8c6f9e60 1202 (setq beg-defun-indent (current-indentation))
2e6625b5
FEG
1203 (while (progn
1204 (python-nav-end-of-statement)
1205 (python-util-forward-comment 1)
1206 (and (> (current-indentation) beg-defun-indent)
1207 (not (eobp)))))
1208 (python-util-forward-comment -1)
8c6f9e60 1209 (forward-line 1)
2e6625b5
FEG
1210 ;; Ensure point moves forward.
1211 (and (> beg-pos (point)) (goto-char beg-pos)))))
45c138ac 1212
04754d36
FEG
1213(defun python-nav--syntactically (fn poscompfn &optional contextfn)
1214 "Move point using FN avoiding places with specific context.
adc31213 1215FN must take no arguments. POSCOMPFN is a two arguments function
04754d36
FEG
1216used to compare current and previous point after it is moved
1217using FN, this is normally a less-than or greater-than
1218comparison. Optional argument CONTEXTFN defaults to
1219`python-syntax-context-type' and is used for checking current
1220point context, it must return a non-nil value if this point must
1221be skipped."
1222 (let ((contextfn (or contextfn 'python-syntax-context-type))
1223 (start-pos (point-marker))
1224 (prev-pos))
1225 (catch 'found
1226 (while t
1227 (let* ((newpos
1228 (and (funcall fn) (point-marker)))
1229 (context (funcall contextfn)))
1230 (cond ((and (not context) newpos
1231 (or (and (not prev-pos) newpos)
1232 (and prev-pos newpos
1233 (funcall poscompfn newpos prev-pos))))
1234 (throw 'found (point-marker)))
1235 ((and newpos context)
1236 (setq prev-pos (point)))
1237 (t (when (not newpos) (goto-char start-pos))
1238 (throw 'found nil))))))))
083850a6
FEG
1239
1240(defun python-nav--forward-defun (arg)
1241 "Internal implementation of python-nav-{backward,forward}-defun.
1242Uses ARG to define which function to call, and how many times
1243repeat it."
1244 (let ((found))
1245 (while (and (> arg 0)
1246 (setq found
1247 (python-nav--syntactically
1248 (lambda ()
1249 (re-search-forward
1250 python-nav-beginning-of-defun-regexp nil t))
1251 '>)))
1252 (setq arg (1- arg)))
1253 (while (and (< arg 0)
1254 (setq found
1255 (python-nav--syntactically
1256 (lambda ()
1257 (re-search-backward
1258 python-nav-beginning-of-defun-regexp nil t))
1259 '<)))
1260 (setq arg (1+ arg)))
1261 found))
1262
1263(defun python-nav-backward-defun (&optional arg)
1264 "Navigate to closer defun backward ARG times.
1265Unlikely `python-nav-beginning-of-defun' this doesn't care about
1266nested definitions."
1267 (interactive "^p")
1268 (python-nav--forward-defun (- (or arg 1))))
1269
1270(defun python-nav-forward-defun (&optional arg)
1271 "Navigate to closer defun forward ARG times.
1272Unlikely `python-nav-beginning-of-defun' this doesn't care about
1273nested definitions."
1274 (interactive "^p")
1275 (python-nav--forward-defun (or arg 1)))
1276
bcdc27d7 1277(defun python-nav-beginning-of-statement ()
032d23ab 1278 "Move to start of current statement."
3697b531 1279 (interactive "^")
89c868ad
FEG
1280 (back-to-indentation)
1281 (let* ((ppss (syntax-ppss))
1282 (context-point
1283 (or
1284 (python-syntax-context 'paren ppss)
1285 (python-syntax-context 'string ppss))))
1286 (cond ((bobp))
1287 (context-point
1288 (goto-char context-point)
1289 (python-nav-beginning-of-statement))
1290 ((save-excursion
1291 (forward-line -1)
1292 (python-info-line-ends-backslash-p))
1293 (forward-line -1)
1294 (python-nav-beginning-of-statement))))
8dbce54c 1295 (point-marker))
3697b531 1296
6861432e
FEG
1297(defun python-nav-end-of-statement (&optional noend)
1298 "Move to end of current statement.
1299Optional argument NOEND is internal and makes the logic to not
1300jump to the end of line when moving forward searching for the end
1301of the statement."
3697b531 1302 (interactive "^")
6861432e
FEG
1303 (let (string-start bs-pos)
1304 (while (and (or noend (goto-char (line-end-position)))
1305 (not (eobp))
1306 (cond ((setq string-start (python-syntax-context 'string))
1307 (goto-char string-start)
50620051
FEG
1308 (if (python-syntax-context 'paren)
1309 ;; Ended up inside a paren, roll again.
1310 (python-nav-end-of-statement t)
1311 ;; This is not inside a paren, move to the
1312 ;; end of this string.
1313 (goto-char (+ (point)
1314 (python-syntax-count-quotes
1315 (char-after (point)) (point))))
1316 (or (re-search-forward (rx (syntax string-delimiter)) nil t)
1317 (goto-char (point-max)))))
6861432e
FEG
1318 ((python-syntax-context 'paren)
1319 ;; The statement won't end before we've escaped
1320 ;; at least one level of parenthesis.
1321 (condition-case err
1322 (goto-char (scan-lists (point) 1 -1))
1323 (scan-error (goto-char (nth 3 err)))))
1324 ((setq bs-pos (python-info-line-ends-backslash-p))
1325 (goto-char bs-pos)
1326 (forward-line 1))))))
8dbce54c 1327 (point-marker))
3697b531 1328
032d23ab
FEG
1329(defun python-nav-backward-statement (&optional arg)
1330 "Move backward to previous statement.
1331With ARG, repeat. See `python-nav-forward-statement'."
9fff1858
FEG
1332 (interactive "^p")
1333 (or arg (setq arg 1))
032d23ab 1334 (python-nav-forward-statement (- arg)))
9fff1858 1335
032d23ab
FEG
1336(defun python-nav-forward-statement (&optional arg)
1337 "Move forward to next statement.
1338With ARG, repeat. With negative argument, move ARG times
1339backward to previous statement."
9fff1858
FEG
1340 (interactive "^p")
1341 (or arg (setq arg 1))
1342 (while (> arg 0)
bcdc27d7 1343 (python-nav-end-of-statement)
0674d3fa 1344 (python-util-forward-comment)
bcdc27d7 1345 (python-nav-beginning-of-statement)
9fff1858
FEG
1346 (setq arg (1- arg)))
1347 (while (< arg 0)
bcdc27d7 1348 (python-nav-beginning-of-statement)
0674d3fa 1349 (python-util-forward-comment -1)
bcdc27d7 1350 (python-nav-beginning-of-statement)
032d23ab
FEG
1351 (setq arg (1+ arg))))
1352
bcdc27d7 1353(defun python-nav-beginning-of-block ()
032d23ab
FEG
1354 "Move to start of current block."
1355 (interactive "^")
c0458e0b 1356 (let ((starting-pos (point)))
032d23ab 1357 (if (progn
bcdc27d7 1358 (python-nav-beginning-of-statement)
032d23ab
FEG
1359 (looking-at (python-rx block-start)))
1360 (point-marker)
1361 ;; Go to first line beginning a statement
1362 (while (and (not (bobp))
bcdc27d7 1363 (or (and (python-nav-beginning-of-statement) nil)
032d23ab
FEG
1364 (python-info-current-line-comment-p)
1365 (python-info-current-line-empty-p)))
1366 (forward-line -1))
1367 (let ((block-matching-indent
1368 (- (current-indentation) python-indent-offset)))
1369 (while
1370 (and (python-nav-backward-block)
1371 (> (current-indentation) block-matching-indent)))
1372 (if (and (looking-at (python-rx block-start))
1373 (= (current-indentation) block-matching-indent))
1374 (point-marker)
1375 (and (goto-char starting-pos) nil))))))
1376
bcdc27d7 1377(defun python-nav-end-of-block ()
032d23ab
FEG
1378 "Move to end of current block."
1379 (interactive "^")
bcdc27d7 1380 (when (python-nav-beginning-of-block)
032d23ab 1381 (let ((block-indentation (current-indentation)))
bcdc27d7 1382 (python-nav-end-of-statement)
032d23ab
FEG
1383 (while (and (forward-line 1)
1384 (not (eobp))
1385 (or (and (> (current-indentation) block-indentation)
bcdc27d7 1386 (or (python-nav-end-of-statement) t))
032d23ab
FEG
1387 (python-info-current-line-comment-p)
1388 (python-info-current-line-empty-p))))
1389 (python-util-forward-comment -1)
1390 (point-marker))))
1391
1392(defun python-nav-backward-block (&optional arg)
1393 "Move backward to previous block of code.
1394With ARG, repeat. See `python-nav-forward-block'."
1395 (interactive "^p")
1396 (or arg (setq arg 1))
1397 (python-nav-forward-block (- arg)))
1398
1399(defun python-nav-forward-block (&optional arg)
1400 "Move forward to next block of code.
1401With ARG, repeat. With negative argument, move ARG times
1402backward to previous block."
1403 (interactive "^p")
1404 (or arg (setq arg 1))
1405 (let ((block-start-regexp
1406 (python-rx line-start (* whitespace) block-start))
1407 (starting-pos (point)))
1408 (while (> arg 0)
bcdc27d7 1409 (python-nav-end-of-statement)
032d23ab
FEG
1410 (while (and
1411 (re-search-forward block-start-regexp nil t)
2d79ec42 1412 (python-syntax-context-type)))
032d23ab
FEG
1413 (setq arg (1- arg)))
1414 (while (< arg 0)
bcdc27d7 1415 (python-nav-beginning-of-statement)
032d23ab
FEG
1416 (while (and
1417 (re-search-backward block-start-regexp nil t)
2d79ec42 1418 (python-syntax-context-type)))
032d23ab 1419 (setq arg (1+ arg)))
bcdc27d7 1420 (python-nav-beginning-of-statement)
032d23ab
FEG
1421 (if (not (looking-at (python-rx block-start)))
1422 (and (goto-char starting-pos) nil)
1423 (and (not (= (point) starting-pos)) (point-marker)))))
1424
01379221
FEG
1425(defun python-nav--lisp-forward-sexp (&optional arg)
1426 "Standard version `forward-sexp'.
1427It ignores completely the value of `forward-sexp-function' by
1428setting it to nil before calling `forward-sexp'. With positive
1429ARG move forward only one sexp, else move backwards."
50620051 1430 (let ((forward-sexp-function)
01379221
FEG
1431 (arg (if (or (not arg) (> arg 0)) 1 -1)))
1432 (forward-sexp arg)))
1433
1434(defun python-nav--lisp-forward-sexp-safe (&optional arg)
1435 "Safe version of standard `forward-sexp'.
1436When at end of sexp (i.e. looking at a opening/closing paren)
1437skips it instead of throwing an error. With positive ARG move
1438forward only one sexp, else move backwards."
1439 (let* ((arg (if (or (not arg) (> arg 0)) 1 -1))
1440 (paren-regexp
1441 (if (> arg 0) (python-rx close-paren) (python-rx open-paren)))
1442 (search-fn
1443 (if (> arg 0) #'re-search-forward #'re-search-backward)))
489af14f 1444 (condition-case nil
01379221 1445 (python-nav--lisp-forward-sexp arg)
489af14f
FEG
1446 (error
1447 (while (and (funcall search-fn paren-regexp nil t)
1448 (python-syntax-context 'paren)))))))
1449
01379221 1450(defun python-nav--forward-sexp (&optional dir safe)
8dbce54c 1451 "Move to forward sexp.
01379221
FEG
1452With positive optional argument DIR direction move forward, else
1453backwards. When optional argument SAFE is non-nil do not throw
1454errors when at end of sexp, skip it instead."
8dbce54c
FEG
1455 (setq dir (or dir 1))
1456 (unless (= dir 0)
1457 (let* ((forward-p (if (> dir 0)
1458 (and (setq dir 1) t)
1459 (and (setq dir -1) nil)))
8dbce54c
FEG
1460 (context-type (python-syntax-context-type)))
1461 (cond
ea5f4192 1462 ((memq context-type '(string comment))
8dbce54c 1463 ;; Inside of a string, get out of it.
ea5f4192
FEG
1464 (let ((forward-sexp-function))
1465 (forward-sexp dir)))
8dbce54c
FEG
1466 ((or (eq context-type 'paren)
1467 (and forward-p (looking-at (python-rx open-paren)))
1468 (and (not forward-p)
1469 (eq (syntax-class (syntax-after (1- (point))))
1470 (car (string-to-syntax ")")))))
1471 ;; Inside a paren or looking at it, lisp knows what to do.
01379221
FEG
1472 (if safe
1473 (python-nav--lisp-forward-sexp-safe dir)
1474 (python-nav--lisp-forward-sexp dir)))
8dbce54c
FEG
1475 (t
1476 ;; This part handles the lispy feel of
1477 ;; `python-nav-forward-sexp'. Knowing everything about the
1478 ;; current context and the context of the next sexp tries to
1479 ;; follow the lisp sexp motion commands in a symmetric manner.
1480 (let* ((context
1481 (cond
1482 ((python-info-beginning-of-block-p) 'block-start)
1483 ((python-info-end-of-block-p) 'block-end)
1484 ((python-info-beginning-of-statement-p) 'statement-start)
1485 ((python-info-end-of-statement-p) 'statement-end)))
1486 (next-sexp-pos
1487 (save-excursion
01379221
FEG
1488 (if safe
1489 (python-nav--lisp-forward-sexp-safe dir)
1490 (python-nav--lisp-forward-sexp dir))
8dbce54c 1491 (point)))
ea5f4192
FEG
1492 (next-sexp-context
1493 (save-excursion
1494 (goto-char next-sexp-pos)
1495 (cond
1496 ((python-info-beginning-of-block-p) 'block-start)
1497 ((python-info-end-of-block-p) 'block-end)
1498 ((python-info-beginning-of-statement-p) 'statement-start)
1499 ((python-info-end-of-statement-p) 'statement-end)
1500 ((python-info-statement-starts-block-p) 'starts-block)
1501 ((python-info-statement-ends-block-p) 'ends-block)))))
8dbce54c
FEG
1502 (if forward-p
1503 (cond ((and (not (eobp))
1504 (python-info-current-line-empty-p))
1505 (python-util-forward-comment dir)
1506 (python-nav--forward-sexp dir))
1507 ((eq context 'block-start)
1508 (python-nav-end-of-block))
1509 ((eq context 'statement-start)
1510 (python-nav-end-of-statement))
1511 ((and (memq context '(statement-end block-end))
1512 (eq next-sexp-context 'ends-block))
1513 (goto-char next-sexp-pos)
1514 (python-nav-end-of-block))
1515 ((and (memq context '(statement-end block-end))
1516 (eq next-sexp-context 'starts-block))
1517 (goto-char next-sexp-pos)
1518 (python-nav-end-of-block))
1519 ((memq context '(statement-end block-end))
1520 (goto-char next-sexp-pos)
1521 (python-nav-end-of-statement))
1522 (t (goto-char next-sexp-pos)))
1523 (cond ((and (not (bobp))
1524 (python-info-current-line-empty-p))
ea5f4192
FEG
1525 (python-util-forward-comment dir)
1526 (python-nav--forward-sexp dir))
8dbce54c
FEG
1527 ((eq context 'block-end)
1528 (python-nav-beginning-of-block))
1529 ((eq context 'statement-end)
1530 (python-nav-beginning-of-statement))
1531 ((and (memq context '(statement-start block-start))
1532 (eq next-sexp-context 'starts-block))
1533 (goto-char next-sexp-pos)
1534 (python-nav-beginning-of-block))
1535 ((and (memq context '(statement-start block-start))
1536 (eq next-sexp-context 'ends-block))
1537 (goto-char next-sexp-pos)
1538 (python-nav-beginning-of-block))
1539 ((memq context '(statement-start block-start))
1540 (goto-char next-sexp-pos)
1541 (python-nav-beginning-of-statement))
1542 (t (goto-char next-sexp-pos))))))))))
489af14f 1543
489af14f 1544(defun python-nav-forward-sexp (&optional arg)
01379221
FEG
1545 "Move forward across expressions.
1546With ARG, do it that many times. Negative arg -N means move
1547backward N times."
1548 (interactive "^p")
1549 (or arg (setq arg 1))
1550 (while (> arg 0)
1551 (python-nav--forward-sexp 1)
1552 (setq arg (1- arg)))
1553 (while (< arg 0)
1554 (python-nav--forward-sexp -1)
1555 (setq arg (1+ arg))))
1556
1557(defun python-nav-backward-sexp (&optional arg)
1558 "Move backward across expressions.
1559With ARG, do it that many times. Negative arg -N means move
fd16b061 1560forward N times."
01379221
FEG
1561 (interactive "^p")
1562 (or arg (setq arg 1))
1563 (python-nav-forward-sexp (- arg)))
1564
1565(defun python-nav-forward-sexp-safe (&optional arg)
1566 "Move forward safely across expressions.
1567With ARG, do it that many times. Negative arg -N means move
1568backward N times."
032d23ab
FEG
1569 (interactive "^p")
1570 (or arg (setq arg 1))
1571 (while (> arg 0)
01379221 1572 (python-nav--forward-sexp 1 t)
489af14f 1573 (setq arg (1- arg)))
032d23ab 1574 (while (< arg 0)
01379221 1575 (python-nav--forward-sexp -1 t)
9fff1858
FEG
1576 (setq arg (1+ arg))))
1577
01379221
FEG
1578(defun python-nav-backward-sexp-safe (&optional arg)
1579 "Move backward safely across expressions.
1580With ARG, do it that many times. Negative arg -N means move
fd16b061 1581forward N times."
01379221
FEG
1582 (interactive "^p")
1583 (or arg (setq arg 1))
1584 (python-nav-forward-sexp-safe (- arg)))
1585
a4ff7fe1
FEG
1586(defun python-nav--up-list (&optional dir)
1587 "Internal implementation of `python-nav-up-list'.
1588DIR is always 1 or -1 and comes sanitized from
1589`python-nav-up-list' calls."
1590 (let ((context (python-syntax-context-type))
1591 (forward-p (> dir 0)))
1592 (cond
1593 ((memq context '(string comment)))
1594 ((eq context 'paren)
1595 (let ((forward-sexp-function))
1596 (up-list dir)))
1597 ((and forward-p (python-info-end-of-block-p))
1598 (let ((parent-end-pos
1599 (save-excursion
1600 (let ((indentation (and
1601 (python-nav-beginning-of-block)
1602 (current-indentation))))
1603 (while (and indentation
1604 (> indentation 0)
1605 (>= (current-indentation) indentation)
1606 (python-nav-backward-block)))
1607 (python-nav-end-of-block)))))
1608 (and (> (or parent-end-pos (point)) (point))
1609 (goto-char parent-end-pos))))
1610 (forward-p (python-nav-end-of-block))
1611 ((and (not forward-p)
1612 (> (current-indentation) 0)
1613 (python-info-beginning-of-block-p))
1614 (let ((prev-block-pos
1615 (save-excursion
1616 (let ((indentation (current-indentation)))
1617 (while (and (python-nav-backward-block)
55cd00c8 1618 (>= (current-indentation) indentation))))
a4ff7fe1
FEG
1619 (point))))
1620 (and (> (point) prev-block-pos)
1621 (goto-char prev-block-pos))))
1622 ((not forward-p) (python-nav-beginning-of-block)))))
1623
1624(defun python-nav-up-list (&optional arg)
1625 "Move forward out of one level of parentheses (or blocks).
1626With ARG, do this that many times.
1627A negative argument means move backward but still to a less deep spot.
1628This command assumes point is not in a string or comment."
1629 (interactive "^p")
1630 (or arg (setq arg 1))
1631 (while (> arg 0)
1632 (python-nav--up-list 1)
1633 (setq arg (1- arg)))
1634 (while (< arg 0)
1635 (python-nav--up-list -1)
1636 (setq arg (1+ arg))))
1637
1638(defun python-nav-backward-up-list (&optional arg)
1639 "Move backward out of one level of parentheses (or blocks).
1640With ARG, do this that many times.
fd16b061 1641A negative argument means move forward but still to a less deep spot.
a4ff7fe1
FEG
1642This command assumes point is not in a string or comment."
1643 (interactive "^p")
1644 (or arg (setq arg 1))
1645 (python-nav-up-list (- arg)))
1646
e5c144d6
FEG
1647(defun python-nav-if-name-main ()
1648 "Move point at the beginning the __main__ block.
1649When \"if __name__ == '__main__':\" is found returns its
1650position, else returns nil."
1651 (interactive)
1652 (let ((point (point))
1653 (found (catch 'found
1654 (goto-char (point-min))
1655 (while (re-search-forward
1656 (python-rx line-start
1657 "if" (+ space)
1658 "__name__" (+ space)
1659 "==" (+ space)
1660 (group-n 1 (or ?\" ?\'))
1661 "__main__" (backref 1) (* space) ":")
1662 nil t)
1663 (when (not (python-syntax-context-type))
1664 (beginning-of-line)
1665 (throw 'found t))))))
1666 (if found
1667 (point)
1668 (ignore (goto-char point)))))
1669
45c138ac
FEG
1670\f
1671;;; Shell integration
1672
0f55249e
FEG
1673(defcustom python-shell-buffer-name "Python"
1674 "Default buffer name for Python interpreter."
1675 :type 'string
1676 :group 'python
1677 :safe 'stringp)
45c138ac
FEG
1678
1679(defcustom python-shell-interpreter "python"
1680 "Default Python interpreter for shell."
45c138ac 1681 :type 'string
c4b155cb 1682 :group 'python)
45c138ac 1683
0f55249e
FEG
1684(defcustom python-shell-internal-buffer-name "Python Internal"
1685 "Default buffer name for the Internal Python interpreter."
1686 :type 'string
1687 :group 'python
1688 :safe 'stringp)
1fe1b5aa 1689
45c138ac
FEG
1690(defcustom python-shell-interpreter-args "-i"
1691 "Default arguments for the Python interpreter."
45c138ac 1692 :type 'string
c4b155cb 1693 :group 'python)
45c138ac
FEG
1694
1695(defcustom python-shell-prompt-regexp ">>> "
fd16b061 1696 "Regular expression matching top-level input prompt of Python shell.
e2d8d479 1697It should not contain a caret (^) at the beginning."
45c138ac
FEG
1698 :type 'string
1699 :group 'python
1700 :safe 'stringp)
1701
1702(defcustom python-shell-prompt-block-regexp "[.][.][.] "
fd16b061 1703 "Regular expression matching block input prompt of Python shell.
e2d8d479 1704It should not contain a caret (^) at the beginning."
45c138ac
FEG
1705 :type 'string
1706 :group 'python
1707 :safe 'stringp)
1708
0f55249e 1709(defcustom python-shell-prompt-output-regexp ""
fd16b061 1710 "Regular expression matching output prompt of Python shell.
e2d8d479 1711It should not contain a caret (^) at the beginning."
62feb915
FEG
1712 :type 'string
1713 :group 'python
1714 :safe 'stringp)
1715
45c138ac 1716(defcustom python-shell-prompt-pdb-regexp "[(<]*[Ii]?[Pp]db[>)]+ "
fd16b061 1717 "Regular expression matching pdb input prompt of Python shell.
e2d8d479 1718It should not contain a caret (^) at the beginning."
45c138ac
FEG
1719 :type 'string
1720 :group 'python
1721 :safe 'stringp)
1722
a7a6d8ff 1723(defcustom python-shell-enable-font-lock t
fd16b061
JB
1724 "Should syntax highlighting be enabled in the Python shell buffer?
1725Restart the Python shell after changing this variable for it to take effect."
b4b661d8
DD
1726 :type 'boolean
1727 :group 'python
1728 :safe 'booleanp)
1729
66bbb27f 1730(defcustom python-shell-process-environment nil
307bd2e8
FEG
1731 "List of environment variables for Python shell.
1732This variable follows the same rules as `process-environment'
66bbb27f
FEG
1733since it merges with it before the process creation routines are
1734called. When this variable is nil, the Python shell is run with
307bd2e8 1735the default `process-environment'."
66bbb27f
FEG
1736 :type '(repeat string)
1737 :group 'python
1738 :safe 'listp)
1739
929036b4
FEG
1740(defcustom python-shell-extra-pythonpaths nil
1741 "List of extra pythonpaths for Python shell.
1742The values of this variable are added to the existing value of
1743PYTHONPATH in the `process-environment' variable."
1744 :type '(repeat string)
1745 :group 'python
1746 :safe 'listp)
1747
66bbb27f
FEG
1748(defcustom python-shell-exec-path nil
1749 "List of path to search for binaries.
1750This variable follows the same rules as `exec-path' since it
1751merges with it before the process creation routines are called.
1752When this variable is nil, the Python shell is run with the
1753default `exec-path'."
1754 :type '(repeat string)
1755 :group 'python
1756 :safe 'listp)
1757
64348c32
FEG
1758(defcustom python-shell-virtualenv-path nil
1759 "Path to virtualenv root.
1760This variable, when set to a string, makes the values stored in
1761`python-shell-process-environment' and `python-shell-exec-path'
1762to be modified properly so shells are started with the specified
1763virtualenv."
a931698a 1764 :type '(choice (const nil) string)
64348c32
FEG
1765 :group 'python
1766 :safe 'stringp)
1767
c0428ba0
FEG
1768(defcustom python-shell-setup-codes '(python-shell-completion-setup-code
1769 python-ffap-setup-code
1770 python-eldoc-setup-code)
279c9272 1771 "List of code run by `python-shell-send-setup-codes'."
c0428ba0
FEG
1772 :type '(repeat symbol)
1773 :group 'python
1774 :safe 'listp)
1775
45c138ac
FEG
1776(defcustom python-shell-compilation-regexp-alist
1777 `((,(rx line-start (1+ (any " \t")) "File \""
6cad4c6e
FEG
1778 (group (1+ (not (any "\"<")))) ; avoid `<stdin>' &c
1779 "\", line " (group (1+ digit)))
45c138ac
FEG
1780 1 2)
1781 (,(rx " in file " (group (1+ not-newline)) " on line "
6cad4c6e 1782 (group (1+ digit)))
45c138ac
FEG
1783 1 2)
1784 (,(rx line-start "> " (group (1+ (not (any "(\"<"))))
6cad4c6e 1785 "(" (group (1+ digit)) ")" (1+ (not (any "("))) "()")
45c138ac
FEG
1786 1 2))
1787 "`compilation-error-regexp-alist' for inferior Python."
1788 :type '(alist string)
1789 :group 'python)
1790
1791(defun python-shell-get-process-name (dedicated)
e37a4551 1792 "Calculate the appropriate process name for inferior Python process.
45c138ac
FEG
1793If DEDICATED is t and the variable `buffer-file-name' is non-nil
1794returns a string with the form
1795`python-shell-buffer-name'[variable `buffer-file-name'] else
1530c98e 1796returns the value of `python-shell-buffer-name'."
45c138ac
FEG
1797 (let ((process-name
1798 (if (and dedicated
1799 buffer-file-name)
1800 (format "%s[%s]" python-shell-buffer-name buffer-file-name)
1801 (format "%s" python-shell-buffer-name))))
45c138ac
FEG
1802 process-name))
1803
1fe1b5aa 1804(defun python-shell-internal-get-process-name ()
e37a4551 1805 "Calculate the appropriate process name for Internal Python process.
1fe1b5aa
FEG
1806The name is calculated from `python-shell-global-buffer-name' and
1807a hash of all relevant global shell settings in order to ensure
1808uniqueness for different types of configurations."
1809 (format "%s [%s]"
1810 python-shell-internal-buffer-name
1811 (md5
1812 (concat
1813 (python-shell-parse-command)
279c9272
FEG
1814 python-shell-prompt-regexp
1815 python-shell-prompt-block-regexp
1816 python-shell-prompt-output-regexp
1fe1b5aa 1817 (mapconcat #'symbol-value python-shell-setup-codes "")
2bdce388
FEG
1818 (mapconcat #'identity python-shell-process-environment "")
1819 (mapconcat #'identity python-shell-extra-pythonpaths "")
1820 (mapconcat #'identity python-shell-exec-path "")
64348c32 1821 (or python-shell-virtualenv-path "")
2bdce388 1822 (mapconcat #'identity python-shell-exec-path "")))))
1fe1b5aa 1823
45c138ac 1824(defun python-shell-parse-command ()
e2d8d479 1825 "Calculate the string used to execute the inferior Python process."
e4497086
FEG
1826 (let ((process-environment (python-shell-calculate-process-environment))
1827 (exec-path (python-shell-calculate-exec-path)))
1828 (format "%s %s"
1829 (executable-find python-shell-interpreter)
1830 python-shell-interpreter-args)))
45c138ac 1831
307bd2e8
FEG
1832(defun python-shell-calculate-process-environment ()
1833 "Calculate process environment given `python-shell-virtualenv-path'."
40417cb3
FEG
1834 (let ((process-environment (append
1835 python-shell-process-environment
1836 process-environment nil))
64348c32
FEG
1837 (virtualenv (if python-shell-virtualenv-path
1838 (directory-file-name python-shell-virtualenv-path)
1839 nil)))
929036b4
FEG
1840 (when python-shell-extra-pythonpaths
1841 (setenv "PYTHONPATH"
1842 (format "%s%s%s"
1843 (mapconcat 'identity
1844 python-shell-extra-pythonpaths
1845 path-separator)
1846 path-separator
1847 (or (getenv "PYTHONPATH") ""))))
64348c32 1848 (if (not virtualenv)
40417cb3
FEG
1849 process-environment
1850 (setenv "PYTHONHOME" nil)
1851 (setenv "PATH" (format "%s/bin%s%s"
929036b4
FEG
1852 virtualenv path-separator
1853 (or (getenv "PATH") "")))
40417cb3
FEG
1854 (setenv "VIRTUAL_ENV" virtualenv))
1855 process-environment))
64348c32
FEG
1856
1857(defun python-shell-calculate-exec-path ()
1858 "Calculate exec path given `python-shell-virtualenv-path'."
40417cb3
FEG
1859 (let ((path (append python-shell-exec-path
1860 exec-path nil)))
64348c32
FEG
1861 (if (not python-shell-virtualenv-path)
1862 path
1863 (cons (format "%s/bin"
1864 (directory-file-name python-shell-virtualenv-path))
1865 path))))
1866
45c138ac
FEG
1867(defun python-comint-output-filter-function (output)
1868 "Hook run after content is put into comint buffer.
1869OUTPUT is a string with the contents of the buffer."
1870 (ansi-color-filter-apply output))
1871
f27c99dc
FEG
1872(defvar python-shell--parent-buffer nil)
1873
a5b773c4
FEG
1874(defvar python-shell-output-syntax-table
1875 (let ((table (make-syntax-table python-dotty-syntax-table)))
1876 (modify-syntax-entry ?\' "." table)
1877 (modify-syntax-entry ?\" "." table)
1878 (modify-syntax-entry ?\( "." table)
1879 (modify-syntax-entry ?\[ "." table)
1880 (modify-syntax-entry ?\{ "." table)
1881 (modify-syntax-entry ?\) "." table)
1882 (modify-syntax-entry ?\] "." table)
1883 (modify-syntax-entry ?\} "." table)
1884 table)
1885 "Syntax table for shell output.
1886It makes parens and quotes be treated as punctuation chars.")
1887
45c138ac 1888(define-derived-mode inferior-python-mode comint-mode "Inferior Python"
62feb915 1889 "Major mode for Python inferior process.
e2d8d479 1890Runs a Python interpreter as a subprocess of Emacs, with Python
fd16b061
JB
1891I/O through an Emacs buffer. Variables `python-shell-interpreter'
1892and `python-shell-interpreter-args' control which Python
1893interpreter is run. Variables
e2d8d479
FEG
1894`python-shell-prompt-regexp',
1895`python-shell-prompt-output-regexp',
1896`python-shell-prompt-block-regexp',
a7a6d8ff 1897`python-shell-enable-font-lock',
e2d8d479 1898`python-shell-completion-setup-code',
9399498e 1899`python-shell-completion-string-code',
f6b59cd1 1900`python-shell-completion-module-string-code',
9399498e
FEG
1901`python-eldoc-setup-code', `python-eldoc-string-code',
1902`python-ffap-setup-code' and `python-ffap-string-code' can
1903customize this mode for different Python interpreters.
e2d8d479
FEG
1904
1905You can also add additional setup code to be run at
1906initialization of the interpreter via `python-shell-setup-codes'
1907variable.
1908
1909\(Type \\[describe-mode] in the process buffer for a list of commands.)"
f27c99dc
FEG
1910 (and python-shell--parent-buffer
1911 (python-util-clone-local-variables python-shell--parent-buffer))
1912 (setq comint-prompt-regexp (format "^\\(?:%s\\|%s\\|%s\\)"
1913 python-shell-prompt-regexp
1914 python-shell-prompt-block-regexp
1915 python-shell-prompt-pdb-regexp))
45c138ac 1916 (setq mode-line-process '(":%s"))
45c138ac
FEG
1917 (make-local-variable 'comint-output-filter-functions)
1918 (add-hook 'comint-output-filter-functions
1919 'python-comint-output-filter-function)
1920 (add-hook 'comint-output-filter-functions
1921 'python-pdbtrack-comint-output-filter-function)
1922 (set (make-local-variable 'compilation-error-regexp-alist)
1923 python-shell-compilation-regexp-alist)
ed0eb594
FEG
1924 (define-key inferior-python-mode-map [remap complete-symbol]
1925 'completion-at-point)
1926 (add-hook 'completion-at-point-functions
1927 'python-shell-completion-complete-at-point nil 'local)
62feb915
FEG
1928 (add-to-list (make-local-variable 'comint-dynamic-complete-functions)
1929 'python-shell-completion-complete-at-point)
aa81af71 1930 (define-key inferior-python-mode-map "\t"
62feb915 1931 'python-shell-completion-complete-or-indent)
e0cc4efa
FEG
1932 (make-local-variable 'python-pdbtrack-buffers-to-kill)
1933 (make-local-variable 'python-pdbtrack-tracked-buffer)
1934 (make-local-variable 'python-shell-internal-last-output)
a7a6d8ff 1935 (when python-shell-enable-font-lock
a5b773c4 1936 (set-syntax-table python-mode-syntax-table)
aeadd9a4
FEG
1937 (set (make-local-variable 'font-lock-defaults)
1938 '(python-font-lock-keywords nil nil nil nil))
1939 (set (make-local-variable 'syntax-propertize-function)
12fd5ee1
FEG
1940 (eval
1941 ;; XXX: Unfortunately eval is needed here to make use of the
1942 ;; dynamic value of `comint-prompt-regexp'.
1943 `(syntax-propertize-rules
1944 (,comint-prompt-regexp
1945 (0 (ignore
1946 (put-text-property
1947 comint-last-input-start end 'syntax-table
1948 python-shell-output-syntax-table)
1949 ;; XXX: This might look weird, but it is the easiest
1950 ;; way to ensure font lock gets cleaned up before the
1951 ;; current prompt, which is needed for unclosed
1952 ;; strings to not mess up with current input.
1953 (font-lock-unfontify-region comint-last-input-start end))))
1954 (,(python-rx string-delimiter)
1955 (0 (ignore
1956 (and (not (eq (get-text-property start 'field) 'output))
1957 (python-syntax-stringify)))))))))
45c138ac
FEG
1958 (compilation-shell-minor-mode 1))
1959
ba7b0154 1960(defun python-shell-make-comint (cmd proc-name &optional pop internal)
fd16b061
JB
1961 "Create a Python shell comint buffer.
1962CMD is the Python command to be executed and PROC-NAME is the
77afb61a 1963process name the comint buffer will get. After the comint buffer
ba7b0154
FEG
1964is created the `inferior-python-mode' is activated. When
1965optional argument POP is non-nil the buffer is shown. When
1966optional argument INTERNAL is non-nil this process is run on a
1967buffer with a name that starts with a space, following the Emacs
1968convention for temporary/internal buffers, and also makes sure
1969the user is not queried for confirmation when the process is
1970killed."
77afb61a 1971 (save-excursion
ba7b0154
FEG
1972 (let* ((proc-buffer-name
1973 (format (if (not internal) "*%s*" " *%s*") proc-name))
307bd2e8 1974 (process-environment (python-shell-calculate-process-environment))
77afb61a
FEG
1975 (exec-path (python-shell-calculate-exec-path)))
1976 (when (not (comint-check-proc proc-buffer-name))
96eeb83a 1977 (let* ((cmdlist (split-string-and-unquote cmd))
ba7b0154
FEG
1978 (buffer (apply #'make-comint-in-buffer proc-name proc-buffer-name
1979 (car cmdlist) nil (cdr cmdlist)))
f27c99dc 1980 (python-shell--parent-buffer (current-buffer))
ba7b0154 1981 (process (get-buffer-process buffer)))
96eeb83a 1982 (with-current-buffer buffer
f27c99dc 1983 (inferior-python-mode))
ba7b0154
FEG
1984 (accept-process-output process)
1985 (and pop (pop-to-buffer buffer t))
1986 (and internal (set-process-query-on-exit-flag process nil))))
a0686d71 1987 proc-buffer-name)))
77afb61a 1988
a90dfb95
FEG
1989;;;###autoload
1990(defun run-python (cmd &optional dedicated show)
45c138ac 1991 "Run an inferior Python process.
e2d8d479
FEG
1992Input and output via buffer named after
1993`python-shell-buffer-name'. If there is a process already
1994running in that buffer, just switch to it.
a90dfb95
FEG
1995
1996With argument, allows you to define CMD so you can edit the
1997command used to call the interpreter and define DEDICATED, so a
1998dedicated process for the current buffer is open. When numeric
1999prefix arg is other than 0 or 4 do not SHOW.
2000
fd16b061
JB
2001Runs the hook `inferior-python-mode-hook' after
2002`comint-mode-hook' is run. (Type \\[describe-mode] in the
a90dfb95 2003process buffer for a list of commands.)"
45c138ac
FEG
2004 (interactive
2005 (if current-prefix-arg
2006 (list
846e6e84 2007 (read-shell-command "Run Python: " (python-shell-parse-command))
45c138ac 2008 (y-or-n-p "Make dedicated process? ")
a90dfb95
FEG
2009 (= (prefix-numeric-value current-prefix-arg) 4))
2010 (list (python-shell-parse-command) nil t)))
2011 (python-shell-make-comint
2012 cmd (python-shell-get-process-name dedicated) show)
45c138ac
FEG
2013 dedicated)
2014
1fe1b5aa
FEG
2015(defun run-python-internal ()
2016 "Run an inferior Internal Python process.
2017Input and output via buffer named after
2018`python-shell-internal-buffer-name' and what
0d49da68
FEG
2019`python-shell-internal-get-process-name' returns.
2020
2021This new kind of shell is intended to be used for generic
fd16b061 2022communication related to defined configurations; the main
0d49da68
FEG
2023difference with global or dedicated shells is that these ones are
2024attached to a configuration, not a buffer. This means that can
2025be used for example to retrieve the sys.path and other stuff,
2026without messing with user shells. Note that
2027`python-shell-enable-font-lock' and `inferior-python-mode-hook'
2028are set to nil for these shells, so setup codes are not sent at
2029startup."
2030 (let ((python-shell-enable-font-lock nil)
2031 (inferior-python-mode-hook nil))
ba7b0154
FEG
2032 (get-buffer-process
2033 (python-shell-make-comint
2034 (python-shell-parse-command)
2035 (python-shell-internal-get-process-name) nil t))))
1fe1b5aa 2036
195ee2f0 2037(defun python-shell-get-buffer ()
fd16b061 2038 "Return inferior Python buffer for current buffer."
45c138ac
FEG
2039 (let* ((dedicated-proc-name (python-shell-get-process-name t))
2040 (dedicated-proc-buffer-name (format "*%s*" dedicated-proc-name))
2041 (global-proc-name (python-shell-get-process-name nil))
2042 (global-proc-buffer-name (format "*%s*" global-proc-name))
2043 (dedicated-running (comint-check-proc dedicated-proc-buffer-name))
2044 (global-running (comint-check-proc global-proc-buffer-name)))
2045 ;; Always prefer dedicated
195ee2f0
SM
2046 (or (and dedicated-running dedicated-proc-buffer-name)
2047 (and global-running global-proc-buffer-name))))
2048
2049(defun python-shell-get-process ()
fd16b061 2050 "Return inferior Python process for current buffer."
195ee2f0 2051 (get-buffer-process (python-shell-get-buffer)))
45c138ac
FEG
2052
2053(defun python-shell-get-or-create-process ()
2054 "Get or create an inferior Python process for current buffer and return it."
035c45e3 2055 (let* ((dedicated-proc-name (python-shell-get-process-name t))
45c138ac
FEG
2056 (dedicated-proc-buffer-name (format "*%s*" dedicated-proc-name))
2057 (global-proc-name (python-shell-get-process-name nil))
2058 (global-proc-buffer-name (format "*%s*" global-proc-name))
2059 (dedicated-running (comint-check-proc dedicated-proc-buffer-name))
b8e11d41 2060 (global-running (comint-check-proc global-proc-buffer-name)))
45c138ac
FEG
2061 (when (and (not dedicated-running) (not global-running))
2062 (if (call-interactively 'run-python)
2063 (setq dedicated-running t)
2064 (setq global-running t)))
2065 ;; Always prefer dedicated
2066 (get-buffer-process (if dedicated-running
2067 dedicated-proc-buffer-name
2068 global-proc-buffer-name))))
2069
722c985b
FEG
2070(defvar python-shell-internal-buffer nil
2071 "Current internal shell buffer for the current buffer.
2072This is really not necessary at all for the code to work but it's
2073there for compatibility with CEDET.")
722c985b 2074
0d49da68
FEG
2075(defvar python-shell-internal-last-output nil
2076 "Last output captured by the internal shell.
2077This is really not necessary at all for the code to work but it's
2078there for compatibility with CEDET.")
0d49da68 2079
1fe1b5aa
FEG
2080(defun python-shell-internal-get-or-create-process ()
2081 "Get or create an inferior Internal Python process."
2082 (let* ((proc-name (python-shell-internal-get-process-name))
ba7b0154 2083 (proc-buffer-name (format " *%s*" proc-name)))
0d49da68
FEG
2084 (when (not (process-live-p proc-name))
2085 (run-python-internal)
2086 (setq python-shell-internal-buffer proc-buffer-name)
2087 ;; XXX: Why is this `sit-for' needed?
2088 ;; `python-shell-make-comint' calls `accept-process-output'
2089 ;; already but it is not helping to get proper output on
2090 ;; 'gnu/linux when the internal shell process is not running and
2091 ;; a call to `python-shell-internal-send-string' is issued.
2092 (sit-for 0.1 t))
1fe1b5aa
FEG
2093 (get-buffer-process proc-buffer-name)))
2094
722c985b 2095(define-obsolete-function-alias
2a1e2476 2096 'python-proc 'python-shell-internal-get-or-create-process "24.3")
722c985b
FEG
2097
2098(define-obsolete-variable-alias
2a1e2476 2099 'python-buffer 'python-shell-internal-buffer "24.3")
722c985b 2100
0d49da68 2101(define-obsolete-variable-alias
2a1e2476 2102 'python-preoutput-result 'python-shell-internal-last-output "24.3")
0d49da68 2103
e5afbcac
SM
2104(defun python-shell--save-temp-file (string)
2105 (let* ((temporary-file-directory
2106 (if (file-remote-p default-directory)
2107 (concat (file-remote-p default-directory) "/tmp")
2108 temporary-file-directory))
2109 (temp-file-name (make-temp-file "py"))
2110 (coding-system-for-write 'utf-8))
2111 (with-temp-file temp-file-name
2112 (insert "# -*- coding: utf-8 -*-\n") ;Not needed for Python-3.
2113 (insert string)
2114 (delete-trailing-whitespace))
2115 temp-file-name))
2116
2117(defun python-shell-send-string (string &optional process)
dd27d13b 2118 "Send STRING to inferior Python PROCESS."
45c138ac 2119 (interactive "sPython command: ")
e5afbcac
SM
2120 (let ((process (or process (python-shell-get-or-create-process))))
2121 (if (string-match ".\n+." string) ;Multiline.
2122 (let* ((temp-file-name (python-shell--save-temp-file string)))
3cfb6af3 2123 (python-shell-send-file temp-file-name process temp-file-name t))
9ce938be 2124 (comint-send-string process string)
e5afbcac
SM
2125 (when (or (not (string-match "\n\\'" string))
2126 (string-match "\n[ \t].*\n?\\'" string))
2127 (comint-send-string process "\n")))))
9ce938be 2128
08f18c3d
FEG
2129(defvar python-shell-output-filter-in-progress nil)
2130(defvar python-shell-output-filter-buffer nil)
2131
2132(defun python-shell-output-filter (string)
2133 "Filter used in `python-shell-send-string-no-output' to grab output.
2134STRING is the output received to this point from the process.
2135This filter saves received output from the process in
2136`python-shell-output-filter-buffer' and stops receiving it after
2137detecting a prompt at the end of the buffer."
2138 (setq
2139 string (ansi-color-filter-apply string)
2140 python-shell-output-filter-buffer
2141 (concat python-shell-output-filter-buffer string))
2142 (when (string-match
51867ae2
FEG
2143 ;; XXX: It seems on OSX an extra carriage return is attached
2144 ;; at the end of output, this handles that too.
2145 (format "\r?\n\\(?:%s\\|%s\\|%s\\)$"
08f18c3d
FEG
2146 python-shell-prompt-regexp
2147 python-shell-prompt-block-regexp
2148 python-shell-prompt-pdb-regexp)
2149 python-shell-output-filter-buffer)
2150 ;; Output ends when `python-shell-output-filter-buffer' contains
2151 ;; the prompt attached at the end of it.
2152 (setq python-shell-output-filter-in-progress nil
2153 python-shell-output-filter-buffer
2154 (substring python-shell-output-filter-buffer
2155 0 (match-beginning 0)))
2156 (when (and (> (length python-shell-prompt-output-regexp) 0)
2157 (string-match (concat "^" python-shell-prompt-output-regexp)
2158 python-shell-output-filter-buffer))
2159 ;; Some shells, like iPython might append a prompt before the
2160 ;; output, clean that.
2161 (setq python-shell-output-filter-buffer
2162 (substring python-shell-output-filter-buffer (match-end 0)))))
2163 "")
0478776b 2164
e5afbcac 2165(defun python-shell-send-string-no-output (string &optional process)
9ce938be 2166 "Send STRING to PROCESS and inhibit output.
dd27d13b 2167Return the output."
0478776b
FEG
2168 (let ((process (or process (python-shell-get-or-create-process)))
2169 (comint-preoutput-filter-functions
08f18c3d
FEG
2170 '(python-shell-output-filter))
2171 (python-shell-output-filter-in-progress t)
0478776b 2172 (inhibit-quit t))
191da00e
FEG
2173 (or
2174 (with-local-quit
e5afbcac 2175 (python-shell-send-string string process)
08f18c3d
FEG
2176 (while python-shell-output-filter-in-progress
2177 ;; `python-shell-output-filter' takes care of setting
2178 ;; `python-shell-output-filter-in-progress' to NIL after it
2179 ;; detects end of output.
0478776b
FEG
2180 (accept-process-output process))
2181 (prog1
08f18c3d
FEG
2182 python-shell-output-filter-buffer
2183 (setq python-shell-output-filter-buffer nil)))
191da00e
FEG
2184 (with-current-buffer (process-buffer process)
2185 (comint-interrupt-subjob)))))
45c138ac 2186
1fe1b5aa
FEG
2187(defun python-shell-internal-send-string (string)
2188 "Send STRING to the Internal Python interpreter.
2189Returns the output. See `python-shell-send-string-no-output'."
0d49da68
FEG
2190 ;; XXX Remove `python-shell-internal-last-output' once CEDET is
2191 ;; updated to support this new mode.
2192 (setq python-shell-internal-last-output
2193 (python-shell-send-string-no-output
2194 ;; Makes this function compatible with the old
2195 ;; python-send-receive. (At least for CEDET).
2196 (replace-regexp-in-string "_emacs_out +" "" string)
e5afbcac 2197 (python-shell-internal-get-or-create-process))))
1fe1b5aa
FEG
2198
2199(define-obsolete-function-alias
2a1e2476 2200 'python-send-receive 'python-shell-internal-send-string "24.3")
722c985b
FEG
2201
2202(define-obsolete-function-alias
2a1e2476 2203 'python-send-string 'python-shell-internal-send-string "24.3")
1fe1b5aa 2204
e5afbcac
SM
2205(defvar python--use-fake-loc nil
2206 "If non-nil, use `compilation-fake-loc' to trace errors back to the buffer.
2207If nil, regions of text are prepended by the corresponding number of empty
2208lines and Python is told to output error messages referring to the whole
2209source file.")
2210
96edb677
FEG
2211(defun python-shell-buffer-substring (start end &optional nomain)
2212 "Send buffer substring from START to END formatted for shell.
2213This is a wrapper over `buffer-substring' that takes care of
2214different transformations for the code sent to be evaluated in
2215the python shell:
fd16b061 2216 1. When optional argument NOMAIN is non-nil everything under an
96edb677
FEG
2217 \"if __name__ == '__main__'\" block will be removed.
2218 2. When a subregion of the buffer is sent, it takes care of
71bd1a00 2219 appending extra empty lines so tracebacks are correct.
96edb677
FEG
2220 3. Wraps indented regions under an \"if True:\" block so the
2221 interpreter evaluates them correctly."
2222 (let ((substring (buffer-substring-no-properties start end))
e5afbcac
SM
2223 (fillstr (unless python--use-fake-loc
2224 (make-string (1- (line-number-at-pos start)) ?\n)))
96edb677
FEG
2225 (toplevel-block-p (save-excursion
2226 (goto-char start)
2227 (or (zerop (line-number-at-pos start))
2228 (progn
2229 (python-util-forward-comment 1)
2230 (zerop (current-indentation)))))))
2231 (with-temp-buffer
2232 (python-mode)
e5afbcac 2233 (if fillstr (insert fillstr))
96edb677
FEG
2234 (insert substring)
2235 (goto-char (point-min))
e5afbcac
SM
2236 (unless python--use-fake-loc
2237 ;; python-shell--save-temp-file adds an extra coding line, which would
2238 ;; throw off the line-counts, so let's try to compensate here.
2239 (if (looking-at "[ \t]*[#\n]")
2240 (delete-region (point) (line-beginning-position 2))))
96edb677
FEG
2241 (when (not toplevel-block-p)
2242 (insert "if True:")
2243 (delete-region (point) (line-end-position)))
2244 (when nomain
2245 (let* ((if-name-main-start-end
2246 (and nomain
2247 (save-excursion
2248 (when (python-nav-if-name-main)
2249 (cons (point)
01379221 2250 (progn (python-nav-forward-sexp-safe)
96edb677
FEG
2251 (point)))))))
2252 ;; Oh destructuring bind, how I miss you.
2253 (if-name-main-start (car if-name-main-start-end))
2254 (if-name-main-end (cdr if-name-main-start-end)))
2255 (when if-name-main-start-end
2256 (goto-char if-name-main-start)
2257 (delete-region if-name-main-start if-name-main-end)
2258 (insert
2259 (make-string
2260 (- (line-number-at-pos if-name-main-end)
2261 (line-number-at-pos if-name-main-start)) ?\n)))))
2262 (buffer-substring-no-properties (point-min) (point-max)))))
2263
195ee2f0
SM
2264(declare-function compilation-fake-loc "compile"
2265 (marker file &optional line col))
2266
e5afbcac 2267(defun python-shell-send-region (start end &optional nomain)
45c138ac
FEG
2268 "Send the region delimited by START and END to inferior Python process."
2269 (interactive "r")
e5afbcac
SM
2270 (let* ((python--use-fake-loc
2271 (or python--use-fake-loc (not buffer-file-name)))
2272 (string (python-shell-buffer-substring start end nomain))
2273 (process (python-shell-get-or-create-process))
2274 (_ (string-match "\\`\n*\\(.*\\)" string)))
2275 (message "Sent: %s..." (match-string 1 string))
2276 (let* ((temp-file-name (python-shell--save-temp-file string))
2277 (file-name (or (buffer-file-name) temp-file-name)))
3cfb6af3 2278 (python-shell-send-file file-name process temp-file-name t)
e5afbcac
SM
2279 (unless python--use-fake-loc
2280 (with-current-buffer (process-buffer process)
2281 (compilation-fake-loc (copy-marker start) temp-file-name
2282 2)) ;; Not 1, because of the added coding line.
2283 ))))
45c138ac 2284
6da55e59
DD
2285(defun python-shell-send-buffer (&optional arg)
2286 "Send the entire buffer to inferior Python process.
dc4f818b 2287With prefix ARG allow execution of code inside blocks delimited
fd16b061 2288by \"if __name__== '__main__':\"."
6da55e59 2289 (interactive "P")
45c138ac
FEG
2290 (save-restriction
2291 (widen)
e5afbcac 2292 (python-shell-send-region (point-min) (point-max) (not arg))))
45c138ac
FEG
2293
2294(defun python-shell-send-defun (arg)
2ed294c5 2295 "Send the current defun to inferior Python process.
8c6f9e60 2296When argument ARG is non-nil do not include decorators."
45c138ac
FEG
2297 (interactive "P")
2298 (save-excursion
2ed294c5
FEG
2299 (python-shell-send-region
2300 (progn
8c6f9e60 2301 (end-of-line 1)
2e6625b5 2302 (while (and (or (python-nav-beginning-of-defun)
8c6f9e60
FEG
2303 (beginning-of-line 1))
2304 (> (current-indentation) 0)))
2305 (when (not arg)
2306 (while (and (forward-line -1)
2307 (looking-at (python-rx decorator))))
2308 (forward-line 1))
1dae378f 2309 (point-marker))
2ed294c5 2310 (progn
2e6625b5 2311 (or (python-nav-end-of-defun)
8c6f9e60 2312 (end-of-line 1))
1dae378f 2313 (point-marker)))))
45c138ac 2314
3cfb6af3
GM
2315(defun python-shell-send-file (file-name &optional process temp-file-name
2316 delete)
d439cda5
FEG
2317 "Send FILE-NAME to inferior Python PROCESS.
2318If TEMP-FILE-NAME is passed then that file is used for processing
fd16b061
JB
2319instead, while internally the shell will continue to use FILE-NAME.
2320If DELETE is non-nil, delete the file afterwards."
45c138ac 2321 (interactive "fFile to send: ")
9ce938be
FEG
2322 (let* ((process (or process (python-shell-get-or-create-process)))
2323 (temp-file-name (when temp-file-name
9dd40b00
MM
2324 (expand-file-name
2325 (or (file-remote-p temp-file-name 'localname)
2326 temp-file-name))))
2327 (file-name (or (when file-name
2328 (expand-file-name
2329 (or (file-remote-p file-name 'localname)
2330 file-name)))
2331 temp-file-name)))
9ce938be
FEG
2332 (when (not file-name)
2333 (error "If FILE-NAME is nil then TEMP-FILE-NAME must be non-nil"))
13d914ed 2334 (python-shell-send-string
b962ebad 2335 (format
d439cda5
FEG
2336 (concat "__pyfile = open('''%s''');"
2337 "exec(compile(__pyfile.read(), '''%s''', 'exec'));"
3cfb6af3
GM
2338 "__pyfile.close()%s")
2339 (or temp-file-name file-name) file-name
2340 (if delete (format "; import os; os.remove('''%s''')"
2341 (or temp-file-name file-name))
2342 ""))
13d914ed 2343 process)))
45c138ac
FEG
2344
2345(defun python-shell-switch-to-shell ()
2346 "Switch to inferior Python process buffer."
2347 (interactive)
2348 (pop-to-buffer (process-buffer (python-shell-get-or-create-process)) t))
2349
c0428ba0
FEG
2350(defun python-shell-send-setup-code ()
2351 "Send all setup code for shell.
2352This function takes the list of setup code to send from the
2353`python-shell-setup-codes' list."
925411b4 2354 (let ((process (get-buffer-process (current-buffer))))
c0428ba0
FEG
2355 (dolist (code python-shell-setup-codes)
2356 (when code
925411b4 2357 (message "Sent %s" code)
a1ea6ab8 2358 (python-shell-send-string
c0428ba0
FEG
2359 (symbol-value code) process)))))
2360
2361(add-hook 'inferior-python-mode-hook
2362 #'python-shell-send-setup-code)
2363
45c138ac
FEG
2364\f
2365;;; Shell completion
2366
0f55249e 2367(defcustom python-shell-completion-setup-code
45c138ac
FEG
2368 "try:
2369 import readline
2370except ImportError:
2371 def __COMPLETER_all_completions(text): []
2372else:
2373 import rlcompleter
2374 readline.set_completer(rlcompleter.Completer().complete)
2375 def __COMPLETER_all_completions(text):
2376 import sys
2377 completions = []
2378 try:
2379 i = 0
2380 while True:
2381 res = readline.get_completer()(text, i)
2382 if not res: break
2383 i += 1
2384 completions.append(res)
2385 except NameError:
2386 pass
2387 return completions"
0f55249e
FEG
2388 "Code used to setup completion in inferior Python processes."
2389 :type 'string
c4b155cb 2390 :group 'python)
45c138ac 2391
0f55249e 2392(defcustom python-shell-completion-string-code
45c138ac 2393 "';'.join(__COMPLETER_all_completions('''%s'''))\n"
0f55249e
FEG
2394 "Python code used to get a string of completions separated by semicolons."
2395 :type 'string
c4b155cb 2396 :group 'python)
45c138ac 2397
f6b59cd1 2398(defcustom python-shell-completion-module-string-code ""
8386d830 2399 "Python code used to get completions separated by semicolons for imports.
9253ea69
DD
2400
2401For IPython v0.11, add the following line to
2402`python-shell-completion-setup-code':
2403
2404from IPython.core.completerlib import module_completion
2405
2406and use the following as the value of this variable:
2407
2408';'.join(module_completion('''%s'''))\n"
2409 :type 'string
c4b155cb 2410 :group 'python)
9253ea69 2411
aa409935
FEG
2412(defcustom python-shell-completion-pdb-string-code
2413 "';'.join(globals().keys() + locals().keys())"
2414 "Python code used to get completions separated by semicolons for [i]pdb."
2415 :type 'string
c4b155cb 2416 :group 'python)
aa409935 2417
5beed586
FEG
2418(defun python-shell-completion-get-completions (process line input)
2419 "Do completion at point for PROCESS.
fd16b061 2420LINE is used to detect the context on how to complete given INPUT."
5beed586 2421 (let* ((prompt
cd16c5f1
FEG
2422 ;; Get last prompt of the inferior process buffer (this
2423 ;; intentionally avoids using `comint-last-prompt' because
2424 ;; of incompatibilities with Emacs 24.x).
5beed586 2425 (with-current-buffer (process-buffer process)
cd16c5f1
FEG
2426 (save-excursion
2427 (buffer-substring-no-properties
2428 (- (point) (length line))
2429 (progn
2430 (re-search-backward "^")
2431 (python-util-forward-comment)
2432 (point))))))
5beed586
FEG
2433 (completion-context
2434 ;; Check whether a prompt matches a pdb string, an import
2435 ;; statement or just the standard prompt and use the
2436 ;; correct python-shell-completion-*-code string
2437 (cond ((and (> (length python-shell-completion-pdb-string-code) 0)
2438 (string-match
2439 (concat "^" python-shell-prompt-pdb-regexp) prompt))
2440 'pdb)
2441 ((and (>
2442 (length python-shell-completion-module-string-code) 0)
2443 (string-match
2444 (concat "^" python-shell-prompt-regexp) prompt)
2445 (string-match "^[ \t]*\\(from\\|import\\)[ \t]" line))
2446 'import)
2447 ((string-match
2448 (concat "^" python-shell-prompt-regexp) prompt)
2449 'default)
2450 (t nil)))
2451 (completion-code
14146222
SM
2452 (pcase completion-context
2453 (`pdb python-shell-completion-pdb-string-code)
2454 (`import python-shell-completion-module-string-code)
2455 (`default python-shell-completion-string-code)
2456 (_ nil)))
5beed586
FEG
2457 (input
2458 (if (eq completion-context 'import)
2459 (replace-regexp-in-string "^[ \t]+" "" line)
2460 input)))
2461 (and completion-code
2462 (> (length input) 0)
2463 (with-current-buffer (process-buffer process)
656f99be
FEG
2464 (let ((completions
2465 (python-util-strip-string
2466 (python-shell-send-string-no-output
2467 (format completion-code input) process))))
5beed586
FEG
2468 (and (> (length completions) 2)
2469 (split-string completions
2470 "^'\\|^\"\\|;\\|'$\\|\"$" t)))))))
2471
2472(defun python-shell-completion-complete-at-point (&optional process)
2473 "Perform completion at point in inferior Python.
2474Optional argument PROCESS forces completions to be retrieved
2475using that one instead of current buffer's process."
2476 (setq process (or process (get-buffer-process (current-buffer))))
2477 (let* ((start
2478 (save-excursion
2479 (with-syntax-table python-dotty-syntax-table
cb37c7e3
FEG
2480 (let* ((paren-depth (car (syntax-ppss)))
2481 (syntax-string "w_")
2482 (syntax-list (string-to-syntax syntax-string)))
5beed586
FEG
2483 ;; Stop scanning for the beginning of the completion
2484 ;; subject after the char before point matches a
2485 ;; delimiter
2486 (while (member
2487 (car (syntax-after (1- (point)))) syntax-list)
cb37c7e3
FEG
2488 (skip-syntax-backward syntax-string)
2489 (when (or (equal (char-before) ?\))
2490 (equal (char-before) ?\"))
2491 (forward-char -1))
2492 (while (or
2493 ;; honor initial paren depth
2494 (> (car (syntax-ppss)) paren-depth)
2d79ec42 2495 (python-syntax-context 'string))
5beed586
FEG
2496 (forward-char -1)))
2497 (point)))))
2498 (end (point)))
2499 (list start end
2500 (completion-table-dynamic
2501 (apply-partially
2502 #'python-shell-completion-get-completions
2503 process (buffer-substring-no-properties
2504 (line-beginning-position) end))))))
45c138ac 2505
45c138ac
FEG
2506(defun python-shell-completion-complete-or-indent ()
2507 "Complete or indent depending on the context.
fd16b061
JB
2508If content before pointer is all whitespace, indent.
2509If not try to complete."
45c138ac
FEG
2510 (interactive)
2511 (if (string-match "^[[:space:]]*$"
2512 (buffer-substring (comint-line-beginning-position)
2513 (point-marker)))
2514 (indent-for-tab-command)
799aa2af 2515 (completion-at-point)))
45c138ac 2516
45c138ac
FEG
2517\f
2518;;; PDB Track integration
2519
76a9ea3b 2520(defcustom python-pdbtrack-activate t
fd16b061 2521 "Non-nil makes Python shell enable pdbtracking."
76a9ea3b
FEG
2522 :type 'boolean
2523 :group 'python
2524 :safe 'booleanp)
2525
0f55249e 2526(defcustom python-pdbtrack-stacktrace-info-regexp
ce030451 2527 "> \\([^\"(<]+\\)(\\([0-9]+\\))\\([?a-zA-Z0-9_<>]+\\)()"
fd16b061 2528 "Regular expression matching stacktrace information.
aeac8c27 2529Used to extract the current line and module being inspected."
0f55249e
FEG
2530 :type 'string
2531 :group 'python
2532 :safe 'stringp)
45c138ac 2533
e1f00930
FEG
2534(defvar python-pdbtrack-tracked-buffer nil
2535 "Variable containing the value of the current tracked buffer.
2536Never set this variable directly, use
2537`python-pdbtrack-set-tracked-buffer' instead.")
e1f00930
FEG
2538
2539(defvar python-pdbtrack-buffers-to-kill nil
2540 "List of buffers to be deleted after tracking finishes.")
e1f00930
FEG
2541
2542(defun python-pdbtrack-set-tracked-buffer (file-name)
2543 "Set the buffer for FILE-NAME as the tracked buffer.
2544Internally it uses the `python-pdbtrack-tracked-buffer' variable.
2545Returns the tracked buffer."
ce030451
FEG
2546 (let ((file-buffer (get-file-buffer
2547 (concat (file-remote-p default-directory)
2548 file-name))))
e1f00930
FEG
2549 (if file-buffer
2550 (setq python-pdbtrack-tracked-buffer file-buffer)
2551 (setq file-buffer (find-file-noselect file-name))
2552 (when (not (member file-buffer python-pdbtrack-buffers-to-kill))
2553 (add-to-list 'python-pdbtrack-buffers-to-kill file-buffer)))
2554 file-buffer))
45c138ac
FEG
2555
2556(defun python-pdbtrack-comint-output-filter-function (output)
2557 "Move overlay arrow to current pdb line in tracked buffer.
2558Argument OUTPUT is a string with the output from the comint process."
76a9ea3b 2559 (when (and python-pdbtrack-activate (not (string= output "")))
aeac8c27
FEG
2560 (let* ((full-output (ansi-color-filter-apply
2561 (buffer-substring comint-last-input-end (point-max))))
2562 (line-number)
2563 (file-name
2564 (with-temp-buffer
aeac8c27 2565 (insert full-output)
6ff930c3
FEG
2566 ;; When the debugger encounters a pdb.set_trace()
2567 ;; command, it prints a single stack frame. Sometimes
2568 ;; it prints a bit of extra information about the
2569 ;; arguments of the present function. When ipdb
2570 ;; encounters an exception, it prints the _entire_ stack
2571 ;; trace. To handle all of these cases, we want to find
2572 ;; the _last_ stack frame printed in the most recent
d9c287e5 2573 ;; batch of output, then jump to the corresponding
6ff930c3
FEG
2574 ;; file/line number.
2575 (goto-char (point-max))
2576 (when (re-search-backward python-pdbtrack-stacktrace-info-regexp nil t)
aeac8c27
FEG
2577 (setq line-number (string-to-number
2578 (match-string-no-properties 2)))
2579 (match-string-no-properties 1)))))
2580 (if (and file-name line-number)
6cad4c6e
FEG
2581 (let* ((tracked-buffer
2582 (python-pdbtrack-set-tracked-buffer file-name))
e1f00930
FEG
2583 (shell-buffer (current-buffer))
2584 (tracked-buffer-window (get-buffer-window tracked-buffer))
45c138ac 2585 (tracked-buffer-line-pos))
e1f00930 2586 (with-current-buffer tracked-buffer
aeac8c27
FEG
2587 (set (make-local-variable 'overlay-arrow-string) "=>")
2588 (set (make-local-variable 'overlay-arrow-position) (make-marker))
2589 (setq tracked-buffer-line-pos (progn
2590 (goto-char (point-min))
2591 (forward-line (1- line-number))
2592 (point-marker)))
2593 (when tracked-buffer-window
2594 (set-window-point
2595 tracked-buffer-window tracked-buffer-line-pos))
2596 (set-marker overlay-arrow-position tracked-buffer-line-pos))
e1f00930
FEG
2597 (pop-to-buffer tracked-buffer)
2598 (switch-to-buffer-other-window shell-buffer))
2599 (when python-pdbtrack-tracked-buffer
2600 (with-current-buffer python-pdbtrack-tracked-buffer
2601 (set-marker overlay-arrow-position nil))
2602 (mapc #'(lambda (buffer)
2603 (ignore-errors (kill-buffer buffer)))
2604 python-pdbtrack-buffers-to-kill)
2605 (setq python-pdbtrack-tracked-buffer nil
2606 python-pdbtrack-buffers-to-kill nil)))))
45c138ac
FEG
2607 output)
2608
2609\f
2610;;; Symbol completion
2611
2612(defun python-completion-complete-at-point ()
2613 "Complete current symbol at point.
fd16b061 2614For this to work as best as possible you should call
45c138ac 2615`python-shell-send-buffer' from time to time so context in
fd16b061 2616inferior Python process is updated properly."
45c138ac
FEG
2617 (let ((process (python-shell-get-process)))
2618 (if (not process)
4289485a 2619 (error "Completion needs an inferior Python process running")
5beed586 2620 (python-shell-completion-complete-at-point process))))
45c138ac 2621
6cad4c6e
FEG
2622(add-to-list 'debug-ignored-errors
2623 "^Completion needs an inferior Python process running.")
45c138ac
FEG
2624
2625\f
2626;;; Fill paragraph
2627
c2cb97ae
FEG
2628(defcustom python-fill-comment-function 'python-fill-comment
2629 "Function to fill comments.
24517d82 2630This is the function used by `python-fill-paragraph' to
c2cb97ae
FEG
2631fill comments."
2632 :type 'symbol
fc345011 2633 :group 'python)
c2cb97ae
FEG
2634
2635(defcustom python-fill-string-function 'python-fill-string
2636 "Function to fill strings.
24517d82 2637This is the function used by `python-fill-paragraph' to
c2cb97ae
FEG
2638fill strings."
2639 :type 'symbol
fc345011 2640 :group 'python)
c2cb97ae
FEG
2641
2642(defcustom python-fill-decorator-function 'python-fill-decorator
2643 "Function to fill decorators.
24517d82 2644This is the function used by `python-fill-paragraph' to
c2cb97ae
FEG
2645fill decorators."
2646 :type 'symbol
fc345011 2647 :group 'python)
c2cb97ae
FEG
2648
2649(defcustom python-fill-paren-function 'python-fill-paren
2650 "Function to fill parens.
24517d82 2651This is the function used by `python-fill-paragraph' to
c2cb97ae
FEG
2652fill parens."
2653 :type 'symbol
fc345011
FEG
2654 :group 'python)
2655
7fa36ccb 2656(defcustom python-fill-docstring-style 'pep-257
fc345011
FEG
2657 "Style used to fill docstrings.
2658This affects `python-fill-string' behavior with regards to
2659triple quotes positioning.
2660
fd16b061
JB
2661Possible values are `django', `onetwo', `pep-257', `pep-257-nn',
2662`symmetric', and nil. A value of nil won't care about quotes
7fa36ccb
FEG
2663position and will treat docstrings a normal string, any other
2664value may result in one of the following docstring styles:
fc345011 2665
fd16b061 2666`django':
fc345011
FEG
2667
2668 \"\"\"
2669 Process foo, return bar.
2670 \"\"\"
2671
2672 \"\"\"
2673 Process foo, return bar.
2674
2675 If processing fails throw ProcessingError.
2676 \"\"\"
2677
fd16b061 2678`onetwo':
7fa36ccb
FEG
2679
2680 \"\"\"Process foo, return bar.\"\"\"
2681
2682 \"\"\"
2683 Process foo, return bar.
2684
2685 If processing fails throw ProcessingError.
2686
2687 \"\"\"
2688
fd16b061 2689`pep-257':
fc345011
FEG
2690
2691 \"\"\"Process foo, return bar.\"\"\"
2692
2693 \"\"\"Process foo, return bar.
2694
2695 If processing fails throw ProcessingError.
2696
2697 \"\"\"
2698
fd16b061 2699`pep-257-nn':
fc345011
FEG
2700
2701 \"\"\"Process foo, return bar.\"\"\"
2702
2703 \"\"\"Process foo, return bar.
2704
2705 If processing fails throw ProcessingError.
2706 \"\"\"
2707
fd16b061 2708`symmetric':
fc345011
FEG
2709
2710 \"\"\"Process foo, return bar.\"\"\"
2711
2712 \"\"\"
2713 Process foo, return bar.
2714
2715 If processing fails throw ProcessingError.
2716 \"\"\""
7fa36ccb
FEG
2717 :type '(choice
2718 (const :tag "Don't format docstrings" nil)
2719 (const :tag "Django's coding standards style." django)
2720 (const :tag "One newline and start and Two at end style." onetwo)
2721 (const :tag "PEP-257 with 2 newlines at end of string." pep-257)
2722 (const :tag "PEP-257 with 1 newline at end of string." pep-257-nn)
2723 (const :tag "Symmetric style." symmetric))
c2cb97ae 2724 :group 'python
7fa36ccb
FEG
2725 :safe (lambda (val)
2726 (memq val '(django onetwo pep-257 pep-257-nn symmetric nil))))
c2cb97ae 2727
24517d82 2728(defun python-fill-paragraph (&optional justify)
45c138ac
FEG
2729 "`fill-paragraph-function' handling multi-line strings and possibly comments.
2730If any of the current line is in or at the end of a multi-line string,
2731fill the string or the paragraph of it that point is in, preserving
4e531f7a
FEG
2732the string's indentation.
2733Optional argument JUSTIFY defines if the paragraph should be justified."
45c138ac
FEG
2734 (interactive "P")
2735 (save-excursion
45c138ac
FEG
2736 (cond
2737 ;; Comments
fc345011
FEG
2738 ((python-syntax-context 'comment)
2739 (funcall python-fill-comment-function justify))
c2cb97ae 2740 ;; Strings/Docstrings
fc345011
FEG
2741 ((save-excursion (or (python-syntax-context 'string)
2742 (equal (string-to-syntax "|")
2743 (syntax-after (point)))))
c2cb97ae 2744 (funcall python-fill-string-function justify))
45c138ac
FEG
2745 ;; Decorators
2746 ((equal (char-after (save-excursion
24517d82 2747 (python-nav-beginning-of-statement))) ?@)
c2cb97ae 2748 (funcall python-fill-decorator-function justify))
45c138ac 2749 ;; Parens
2d79ec42 2750 ((or (python-syntax-context 'paren)
45c138ac
FEG
2751 (looking-at (python-rx open-paren))
2752 (save-excursion
2753 (skip-syntax-forward "^(" (line-end-position))
2754 (looking-at (python-rx open-paren))))
c2cb97ae 2755 (funcall python-fill-paren-function justify))
45c138ac
FEG
2756 (t t))))
2757
c2cb97ae 2758(defun python-fill-comment (&optional justify)
24517d82 2759 "Comment fill function for `python-fill-paragraph'.
053a6c72 2760JUSTIFY should be used (if applicable) as in `fill-paragraph'."
c2cb97ae
FEG
2761 (fill-comment-paragraph justify))
2762
2763(defun python-fill-string (&optional justify)
24517d82 2764 "String fill function for `python-fill-paragraph'.
053a6c72 2765JUSTIFY should be used (if applicable) as in `fill-paragraph'."
c0458e0b 2766 (let* ((str-start-pos
66164d2f
FEG
2767 (set-marker
2768 (make-marker)
2769 (or (python-syntax-context 'string)
2770 (and (equal (string-to-syntax "|")
2771 (syntax-after (point)))
2772 (point)))))
fc345011
FEG
2773 (num-quotes (python-syntax-count-quotes
2774 (char-after str-start-pos) str-start-pos))
2775 (str-end-pos
2776 (save-excursion
2777 (goto-char (+ str-start-pos num-quotes))
2778 (or (re-search-forward (rx (syntax string-delimiter)) nil t)
2779 (goto-char (point-max)))
2780 (point-marker)))
2781 (multi-line-p
2782 ;; Docstring styles may vary for oneliners and multi-liners.
2783 (> (count-matches "\n" str-start-pos str-end-pos) 0))
2784 (delimiters-style
14146222 2785 (pcase python-fill-docstring-style
fc345011
FEG
2786 ;; delimiters-style is a cons cell with the form
2787 ;; (START-NEWLINES . END-NEWLINES). When any of the sexps
2788 ;; is NIL means to not add any newlines for start or end
7fa36ccb 2789 ;; of docstring. See `python-fill-docstring-style' for a
fc345011 2790 ;; graphic idea of each style.
14146222
SM
2791 (`django (cons 1 1))
2792 (`onetwo (and multi-line-p (cons 1 2)))
2793 (`pep-257 (and multi-line-p (cons nil 2)))
2794 (`pep-257-nn (and multi-line-p (cons nil 1)))
2795 (`symmetric (and multi-line-p (cons 1 1)))))
fc345011
FEG
2796 (docstring-p (save-excursion
2797 ;; Consider docstrings those strings which
2798 ;; start on a line by themselves.
7fa36ccb
FEG
2799 (python-nav-beginning-of-statement)
2800 (and (= (point) str-start-pos))))
fc345011 2801 (fill-paragraph-function))
c2cb97ae 2802 (save-restriction
fc345011
FEG
2803 (narrow-to-region str-start-pos str-end-pos)
2804 (fill-paragraph justify))
2805 (save-excursion
7fa36ccb 2806 (when (and docstring-p python-fill-docstring-style)
fc345011
FEG
2807 ;; Add the number of newlines indicated by the selected style
2808 ;; at the start of the docstring.
2809 (goto-char (+ str-start-pos num-quotes))
2810 (delete-region (point) (progn
2811 (skip-syntax-forward "> ")
2812 (point)))
2813 (and (car delimiters-style)
2814 (or (newline (car delimiters-style)) t)
2815 ;; Indent only if a newline is added.
2816 (indent-according-to-mode))
2817 ;; Add the number of newlines indicated by the selected style
2818 ;; at the end of the docstring.
2819 (goto-char (if (not (= str-end-pos (point-max)))
2820 (- str-end-pos num-quotes)
2821 str-end-pos))
2822 (delete-region (point) (progn
2823 (skip-syntax-backward "> ")
2824 (point)))
2825 (and (cdr delimiters-style)
2826 ;; Add newlines only if string ends.
2827 (not (= str-end-pos (point-max)))
2828 (or (newline (cdr delimiters-style)) t)
2829 ;; Again indent only if a newline is added.
2830 (indent-according-to-mode))))) t)
c2cb97ae 2831
c0458e0b 2832(defun python-fill-decorator (&optional _justify)
24517d82 2833 "Decorator fill function for `python-fill-paragraph'.
053a6c72 2834JUSTIFY should be used (if applicable) as in `fill-paragraph'."
c2cb97ae
FEG
2835 t)
2836
2837(defun python-fill-paren (&optional justify)
24517d82 2838 "Paren fill function for `python-fill-paragraph'.
053a6c72 2839JUSTIFY should be used (if applicable) as in `fill-paragraph'."
c2cb97ae
FEG
2840 (save-restriction
2841 (narrow-to-region (progn
2d79ec42 2842 (while (python-syntax-context 'paren)
c2cb97ae
FEG
2843 (goto-char (1- (point-marker))))
2844 (point-marker)
2845 (line-beginning-position))
2846 (progn
2d79ec42 2847 (when (not (python-syntax-context 'paren))
c2cb97ae 2848 (end-of-line)
2d79ec42 2849 (when (not (python-syntax-context 'paren))
c2cb97ae 2850 (skip-syntax-backward "^)")))
2d79ec42 2851 (while (python-syntax-context 'paren)
c2cb97ae
FEG
2852 (goto-char (1+ (point-marker))))
2853 (point-marker)))
2854 (let ((paragraph-start "\f\\|[ \t]*$")
2855 (paragraph-separate ",")
2856 (fill-paragraph-function))
2857 (goto-char (point-min))
2858 (fill-paragraph justify))
2859 (while (not (eobp))
2860 (forward-line 1)
2861 (python-indent-line)
2862 (goto-char (line-end-position)))) t)
2863
45c138ac 2864\f
e2803784
FEG
2865;;; Skeletons
2866
2867(defcustom python-skeleton-autoinsert nil
2868 "Non-nil means template skeletons will be automagically inserted.
2869This happens when pressing \"if<SPACE>\", for example, to prompt for
2870the if condition."
2871 :type 'boolean
0f55249e
FEG
2872 :group 'python
2873 :safe 'booleanp)
e2803784 2874
9ddf3c74 2875(define-obsolete-variable-alias
2a1e2476 2876 'python-use-skeletons 'python-skeleton-autoinsert "24.3")
9ddf3c74 2877
e2803784
FEG
2878(defvar python-skeleton-available '()
2879 "Internal list of available skeletons.")
e2803784 2880
351edece
SM
2881(define-abbrev-table 'python-mode-skeleton-abbrev-table ()
2882 "Abbrev table for Python mode skeletons."
e2803784
FEG
2883 :case-fixed t
2884 ;; Allow / inside abbrevs.
2885 :regexp "\\(?:^\\|[^/]\\)\\<\\([[:word:]/]+\\)\\W*"
2886 ;; Only expand in code.
2887 :enable-function (lambda ()
e2803784 2888 (and
2d79ec42 2889 (not (python-syntax-comment-or-string-p))
e2803784
FEG
2890 python-skeleton-autoinsert)))
2891
2892(defmacro python-skeleton-define (name doc &rest skel)
2893 "Define a `python-mode' skeleton using NAME DOC and SKEL.
2894The skeleton will be bound to python-skeleton-NAME and will
351edece 2895be added to `python-mode-skeleton-abbrev-table'."
25f09295 2896 (declare (indent 2))
e2803784 2897 (let* ((name (symbol-name name))
6cad4c6e 2898 (function-name (intern (concat "python-skeleton-" name))))
73ed6836 2899 `(progn
351edece
SM
2900 (define-abbrev python-mode-skeleton-abbrev-table
2901 ,name "" ',function-name :system t)
73ed6836
FEG
2902 (setq python-skeleton-available
2903 (cons ',function-name python-skeleton-available))
2904 (define-skeleton ,function-name
2905 ,(or doc
2906 (format "Insert %s statement." name))
2907 ,@skel))))
e2803784 2908
351edece
SM
2909(define-abbrev-table 'python-mode-abbrev-table ()
2910 "Abbrev table for Python mode."
2911 :parents (list python-mode-skeleton-abbrev-table))
2912
e2803784
FEG
2913(defmacro python-define-auxiliary-skeleton (name doc &optional &rest skel)
2914 "Define a `python-mode' auxiliary skeleton using NAME DOC and SKEL.
2915The skeleton will be bound to python-skeleton-NAME."
25f09295 2916 (declare (indent 2))
e2803784 2917 (let* ((name (symbol-name name))
6cad4c6e 2918 (function-name (intern (concat "python-skeleton--" name)))
e2803784
FEG
2919 (msg (format
2920 "Add '%s' clause? " name)))
2921 (when (not skel)
2922 (setq skel
2923 `(< ,(format "%s:" name) \n \n
2924 > _ \n)))
2925 `(define-skeleton ,function-name
2926 ,(or doc
2927 (format "Auxiliary skeleton for %s statement." name))
2928 nil
2929 (unless (y-or-n-p ,msg)
2930 (signal 'quit t))
2931 ,@skel)))
e2803784
FEG
2932
2933(python-define-auxiliary-skeleton else nil)
2934
2935(python-define-auxiliary-skeleton except nil)
2936
2937(python-define-auxiliary-skeleton finally nil)
2938
2939(python-skeleton-define if nil
2940 "Condition: "
2941 "if " str ":" \n
2942 _ \n
2943 ("other condition, %s: "
2944 <
2945 "elif " str ":" \n
2946 > _ \n nil)
2947 '(python-skeleton--else) | ^)
2948
2949(python-skeleton-define while nil
2950 "Condition: "
2951 "while " str ":" \n
2952 > _ \n
2953 '(python-skeleton--else) | ^)
2954
2955(python-skeleton-define for nil
2956 "Iteration spec: "
2957 "for " str ":" \n
2958 > _ \n
2959 '(python-skeleton--else) | ^)
2960
c77f4a90
MM
2961(python-skeleton-define import nil
2962 "Import from module: "
2963 "from " str & " " | -5
2964 "import "
2965 ("Identifier: " str ", ") -2 \n _)
2966
e2803784
FEG
2967(python-skeleton-define try nil
2968 nil
2969 "try:" \n
2970 > _ \n
2971 ("Exception, %s: "
2972 <
2973 "except " str ":" \n
2974 > _ \n nil)
2975 resume:
2976 '(python-skeleton--except)
2977 '(python-skeleton--else)
2978 '(python-skeleton--finally) | ^)
2979
2980(python-skeleton-define def nil
2981 "Function name: "
2c43a9ad
FEG
2982 "def " str "(" ("Parameter, %s: "
2983 (unless (equal ?\( (char-before)) ", ")
2984 str) "):" \n
2985 "\"\"\"" - "\"\"\"" \n
2986 > _ \n)
e2803784
FEG
2987
2988(python-skeleton-define class nil
2989 "Class name: "
2c43a9ad
FEG
2990 "class " str "(" ("Inheritance, %s: "
2991 (unless (equal ?\( (char-before)) ", ")
2992 str)
82fb2a08 2993 & ")" | -1
e2803784
FEG
2994 ":" \n
2995 "\"\"\"" - "\"\"\"" \n
2996 > _ \n)
2997
2998(defun python-skeleton-add-menu-items ()
2999 "Add menu items to Python->Skeletons menu."
c0458e0b 3000 (let ((skeletons (sort python-skeleton-available 'string<)))
e2803784
FEG
3001 (dolist (skeleton skeletons)
3002 (easy-menu-add-item
3003 nil '("Python" "Skeletons")
3004 `[,(format
14146222 3005 "Insert %s" (nth 2 (split-string (symbol-name skeleton) "-")))
e2803784
FEG
3006 ,skeleton t]))))
3007\f
046428d3
FEG
3008;;; FFAP
3009
0f55249e 3010(defcustom python-ffap-setup-code
046428d3
FEG
3011 "def __FFAP_get_module_path(module):
3012 try:
3013 import os
3014 path = __import__(module).__file__
3015 if path[-4:] == '.pyc' and os.path.exists(path[0:-1]):
3016 path = path[:-1]
3017 return path
3018 except:
3019 return ''"
0f55249e
FEG
3020 "Python code to get a module path."
3021 :type 'string
c4b155cb 3022 :group 'python)
046428d3 3023
0f55249e 3024(defcustom python-ffap-string-code
046428d3 3025 "__FFAP_get_module_path('''%s''')\n"
0f55249e
FEG
3026 "Python code used to get a string with the path of a module."
3027 :type 'string
c4b155cb 3028 :group 'python)
046428d3 3029
046428d3
FEG
3030(defun python-ffap-module-path (module)
3031 "Function for `ffap-alist' to return path for MODULE."
3032 (let ((process (or
3033 (and (eq major-mode 'inferior-python-mode)
3034 (get-buffer-process (current-buffer)))
3035 (python-shell-get-process))))
3036 (if (not process)
3037 nil
3038 (let ((module-file
9ce938be 3039 (python-shell-send-string-no-output
046428d3
FEG
3040 (format python-ffap-string-code module) process)))
3041 (when module-file
6cad4c6e 3042 (substring-no-properties module-file 1 -1))))))
046428d3 3043
e0df2d14
GM
3044(defvar ffap-alist)
3045
046428d3
FEG
3046(eval-after-load "ffap"
3047 '(progn
3048 (push '(python-mode . python-ffap-module-path) ffap-alist)
3049 (push '(inferior-python-mode . python-ffap-module-path) ffap-alist)))
3050
046428d3 3051\f
8b3e0e76
FEG
3052;;; Code check
3053
0f55249e 3054(defcustom python-check-command
bba416bc 3055 "pyflakes"
0f55249e
FEG
3056 "Command used to check a Python file."
3057 :type 'string
c4b155cb 3058 :group 'python)
8b3e0e76 3059
bbd27e07
FEG
3060(defcustom python-check-buffer-name
3061 "*Python check: %s*"
3062 "Buffer name used for check commands."
3063 :type 'string
3064 :group 'python)
3065
8b3e0e76
FEG
3066(defvar python-check-custom-command nil
3067 "Internal use.")
3068
3069(defun python-check (command)
3070 "Check a Python file (default current buffer's file).
fd16b061
JB
3071Runs COMMAND, a shell command, as if by `compile'.
3072See `python-check-command' for the default."
8b3e0e76
FEG
3073 (interactive
3074 (list (read-string "Check command: "
6cad4c6e
FEG
3075 (or python-check-custom-command
3076 (concat python-check-command " "
8b3e0e76
FEG
3077 (shell-quote-argument
3078 (or
3079 (let ((name (buffer-file-name)))
3080 (and name
3081 (file-name-nondirectory name)))
3082 "")))))))
3083 (setq python-check-custom-command command)
3084 (save-some-buffers (not compilation-ask-about-save) nil)
bba416bc
FEG
3085 (let ((process-environment (python-shell-calculate-process-environment))
3086 (exec-path (python-shell-calculate-exec-path)))
bbd27e07 3087 (compilation-start command nil
c0458e0b 3088 (lambda (_modename)
bbd27e07 3089 (format python-check-buffer-name command)))))
8b3e0e76
FEG
3090
3091\f
45c138ac
FEG
3092;;; Eldoc
3093
0f55249e 3094(defcustom python-eldoc-setup-code
45c138ac
FEG
3095 "def __PYDOC_get_help(obj):
3096 try:
15cc40b8 3097 import inspect
9e662938
FEG
3098 if hasattr(obj, 'startswith'):
3099 obj = eval(obj, globals())
15cc40b8
FEG
3100 doc = inspect.getdoc(obj)
3101 if not doc and callable(obj):
3102 target = None
3103 if inspect.isclass(obj) and hasattr(obj, '__init__'):
3104 target = obj.__init__
3105 objtype = 'class'
3106 else:
3107 target = obj
3108 objtype = 'def'
3109 if target:
3110 args = inspect.formatargspec(
3111 *inspect.getargspec(target)
3112 )
3113 name = obj.__name__
3114 doc = '{objtype} {name}{args}'.format(
3115 objtype=objtype, name=name, args=args
3116 )
3117 else:
3118 doc = doc.splitlines()[0]
45c138ac 3119 except:
9e662938
FEG
3120 doc = ''
3121 try:
3122 exec('print doc')
3123 except SyntaxError:
3124 print(doc)"
0f55249e
FEG
3125 "Python code to setup documentation retrieval."
3126 :type 'string
c4b155cb 3127 :group 'python)
45c138ac 3128
0f55249e 3129(defcustom python-eldoc-string-code
9e662938 3130 "__PYDOC_get_help('''%s''')\n"
0f55249e
FEG
3131 "Python code used to get a string with the documentation of an object."
3132 :type 'string
c4b155cb 3133 :group 'python)
45c138ac 3134
78334b43 3135(defun python-eldoc--get-doc-at-point (&optional force-input force-process)
d439cda5 3136 "Internal implementation to get documentation at point.
fd16b061
JB
3137If not FORCE-INPUT is passed then what `python-info-current-symbol'
3138returns will be used. If not FORCE-PROCESS is passed what
3139`python-shell-get-process' returns is used."
78334b43 3140 (let ((process (or force-process (python-shell-get-process))))
45c138ac 3141 (if (not process)
d583cbe6
FEG
3142 (error "Eldoc needs an inferior Python process running")
3143 (let ((input (or force-input
3144 (python-info-current-symbol t))))
3145 (and input
3146 (python-shell-send-string-no-output
3147 (format python-eldoc-string-code input)
3148 process))))))
45c138ac 3149
78334b43
FEG
3150(defun python-eldoc-function ()
3151 "`eldoc-documentation-function' for Python.
fd16b061 3152For this to work as best as possible you should call
78334b43 3153`python-shell-send-buffer' from time to time so context in
fd16b061 3154inferior Python process is updated properly."
78334b43
FEG
3155 (python-eldoc--get-doc-at-point))
3156
3157(defun python-eldoc-at-point (symbol)
3158 "Get help on SYMBOL using `help'.
3159Interactively, prompt for symbol."
6cad4c6e 3160 (interactive
d583cbe6 3161 (let ((symbol (python-info-current-symbol t))
6cad4c6e
FEG
3162 (enable-recursive-minibuffers t))
3163 (list (read-string (if symbol
3164 (format "Describe symbol (default %s): " symbol)
3165 "Describe symbol: ")
3166 nil nil symbol))))
d583cbe6
FEG
3167 (message (python-eldoc--get-doc-at-point symbol)))
3168
3169(add-to-list 'debug-ignored-errors
3170 "^Eldoc needs an inferior Python process running.")
78334b43 3171
45c138ac 3172\f
207cb73c
FEG
3173;;; Imenu
3174
adc31213
FEG
3175(defvar python-imenu-format-item-label-function
3176 'python-imenu-format-item-label
3177 "Imenu function used to format an item label.
3178It must be a function with two arguments: TYPE and NAME.")
3179
3180(defvar python-imenu-format-parent-item-label-function
3181 'python-imenu-format-parent-item-label
3182 "Imenu function used to format a parent item label.
3183It must be a function with two arguments: TYPE and NAME.")
3184
3185(defvar python-imenu-format-parent-item-jump-label-function
3186 'python-imenu-format-parent-item-jump-label
3187 "Imenu function used to format a parent jump item label.
3188It must be a function with two arguments: TYPE and NAME.")
3189
3190(defun python-imenu-format-item-label (type name)
fd16b061 3191 "Return Imenu label for single node using TYPE and NAME."
adc31213
FEG
3192 (format "%s (%s)" name type))
3193
3194(defun python-imenu-format-parent-item-label (type name)
fd16b061 3195 "Return Imenu label for parent node using TYPE and NAME."
adc31213
FEG
3196 (format "%s..." (python-imenu-format-item-label type name)))
3197
c0458e0b 3198(defun python-imenu-format-parent-item-jump-label (type _name)
fd16b061 3199 "Return Imenu label for parent node jump using TYPE and NAME."
adc31213
FEG
3200 (if (string= type "class")
3201 "*class definition*"
3202 "*function definition*"))
3203
ad756449
FEG
3204(defun python-imenu--put-parent (type name pos tree)
3205 "Add the parent with TYPE, NAME and POS to TREE."
adc31213
FEG
3206 (let ((label
3207 (funcall python-imenu-format-item-label-function type name))
3208 (jump-label
3209 (funcall python-imenu-format-parent-item-jump-label-function type name)))
ad756449
FEG
3210 (if (not tree)
3211 (cons label pos)
3212 (cons label (cons (cons jump-label pos) tree)))))
adc31213 3213
ad756449 3214(defun python-imenu--build-tree (&optional min-indent prev-indent tree)
adc31213 3215 "Recursively build the tree of nested definitions of a node.
fd16b061 3216Arguments MIN-INDENT, PREV-INDENT and TREE are internal and should
ad756449
FEG
3217not be passed explicitly unless you know what you are doing."
3218 (setq min-indent (or min-indent 0)
3219 prev-indent (or prev-indent python-indent-offset))
adc31213
FEG
3220 (let* ((pos (python-nav-backward-defun))
3221 (type)
3222 (name (when (and pos (looking-at python-nav-beginning-of-defun-regexp))
3223 (let ((split (split-string (match-string-no-properties 0))))
3224 (setq type (car split))
3225 (cadr split))))
3226 (label (when name
3227 (funcall python-imenu-format-item-label-function type name)))
ad756449
FEG
3228 (indent (current-indentation))
3229 (children-indent-limit (+ python-indent-offset min-indent)))
adc31213 3230 (cond ((not pos)
ad756449
FEG
3231 ;; Nothing found, probably near to bobp.
3232 nil)
3233 ((<= indent min-indent)
3234 ;; The current indentation points that this is a parent
3235 ;; node, add it to the tree and stop recursing.
3236 (python-imenu--put-parent type name pos tree))
adc31213
FEG
3237 (t
3238 (python-imenu--build-tree
3239 min-indent
3240 indent
ad756449 3241 (if (<= indent children-indent-limit)
526e5233
PE
3242 ;; This lies within the children indent offset range,
3243 ;; so it's a normal child of its parent (i.e., not
3244 ;; a child of a child).
ad756449 3245 (cons (cons label pos) tree)
526e5233
PE
3246 ;; Oh no, a child of a child?! Fear not, we
3247 ;; know how to roll. We recursively parse these by
ad756449 3248 ;; swapping prev-indent and min-indent plus adding this
526e5233 3249 ;; newly found item to a fresh subtree. This works, I
ad756449
FEG
3250 ;; promise.
3251 (cons
3252 (python-imenu--build-tree
3253 prev-indent indent (list (cons label pos)))
3254 tree)))))))
adc31213
FEG
3255
3256(defun python-imenu-create-index ()
fd16b061 3257 "Return tree Imenu alist for the current Python buffer.
adc31213
FEG
3258Change `python-imenu-format-item-label-function',
3259`python-imenu-format-parent-item-label-function',
3260`python-imenu-format-parent-item-jump-label-function' to
3261customize how labels are formatted."
3262 (goto-char (point-max))
3263 (let ((index)
3264 (tree))
3265 (while (setq tree (python-imenu--build-tree))
3266 (setq index (cons tree index)))
3267 index))
3268
3269(defun python-imenu-create-flat-index (&optional alist prefix)
fd16b061
JB
3270 "Return flat outline of the current Python buffer for Imenu.
3271Optional argument ALIST is the tree to be flattened; when nil
adc31213
FEG
3272`python-imenu-build-index' is used with
3273`python-imenu-format-parent-item-jump-label-function'
3274`python-imenu-format-parent-item-label-function'
fd16b061
JB
3275`python-imenu-format-item-label-function' set to
3276 (lambda (type name) name)
3277Optional argument PREFIX is used in recursive calls and should
3278not be passed explicitly.
adc31213
FEG
3279
3280Converts this:
3281
fd16b061 3282 ((\"Foo\" . 103)
adc31213
FEG
3283 (\"Bar\" . 138)
3284 (\"decorator\"
3285 (\"decorator\" . 173)
3286 (\"wrap\"
3287 (\"wrap\" . 353)
3288 (\"wrapped_f\" . 393))))
3289
3290To this:
3291
fd16b061 3292 ((\"Foo\" . 103)
adc31213
FEG
3293 (\"Bar\" . 138)
3294 (\"decorator\" . 173)
3295 (\"decorator.wrap\" . 353)
3296 (\"decorator.wrapped_f\" . 393))"
6bd1a072 3297 ;; Inspired by imenu--flatten-index-alist removed in revno 21853.
adc31213
FEG
3298 (apply
3299 'nconc
3300 (mapcar
3301 (lambda (item)
3302 (let ((name (if prefix
3303 (concat prefix "." (car item))
3304 (car item)))
3305 (pos (cdr item)))
3306 (cond ((or (numberp pos) (markerp pos))
3307 (list (cons name pos)))
3308 ((listp pos)
adc31213
FEG
3309 (cons
3310 (cons name (cdar pos))
3311 (python-imenu-create-flat-index (cddr item) name))))))
3312 (or alist
c0458e0b 3313 (let* ((fn (lambda (_type name) name))
6bd1a072
FEG
3314 (python-imenu-format-item-label-function fn)
3315 (python-imenu-format-parent-item-label-function fn)
3316 (python-imenu-format-parent-item-jump-label-function fn))
adc31213 3317 (python-imenu-create-index))))))
207cb73c
FEG
3318
3319\f
45c138ac
FEG
3320;;; Misc helpers
3321
fc2dc7df 3322(defun python-info-current-defun (&optional include-type)
45c138ac 3323 "Return name of surrounding function with Python compatible dotty syntax.
fc2dc7df 3324Optional argument INCLUDE-TYPE indicates to include the type of the defun.
fd16b061
JB
3325This function can be used as the value of `add-log-current-defun-function'
3326since it returns nil if point is not inside a defun."
dcbec5e2
FEG
3327 (save-restriction
3328 (widen)
3329 (save-excursion
3330 (end-of-line 1)
3331 (let ((names)
3332 (starting-indentation (current-indentation))
3333 (starting-pos (point))
3334 (first-run t)
3335 (last-indent)
3336 (type))
3337 (catch 'exit
3338 (while (python-nav-beginning-of-defun 1)
c132ab79
FEG
3339 (when (save-match-data
3340 (and
3341 (or (not last-indent)
3342 (< (current-indentation) last-indent))
3343 (or
3344 (and first-run
3345 (save-excursion
3346 ;; If this is the first run, we may add
3347 ;; the current defun at point.
3348 (setq first-run nil)
3349 (goto-char starting-pos)
3350 (python-nav-beginning-of-statement)
3351 (beginning-of-line 1)
3352 (looking-at-p
3353 python-nav-beginning-of-defun-regexp)))
3354 (< starting-pos
2e6625b5 3355 (save-excursion
c132ab79
FEG
3356 (let ((min-indent
3357 (+ (current-indentation)
3358 python-indent-offset)))
3359 (if (< starting-indentation min-indent)
3360 ;; If the starting indentation is not
3361 ;; within the min defun indent make the
3362 ;; check fail.
3363 starting-pos
3364 ;; Else go to the end of defun and add
3365 ;; up the current indentation to the
3366 ;; ending position.
3367 (python-nav-end-of-defun)
3368 (+ (point)
3369 (if (>= (current-indentation) min-indent)
3370 (1+ (current-indentation))
3371 0)))))))))
3372 (save-match-data (setq last-indent (current-indentation)))
dcbec5e2
FEG
3373 (if (or (not include-type) type)
3374 (setq names (cons (match-string-no-properties 1) names))
3375 (let ((match (split-string (match-string-no-properties 0))))
3376 (setq type (car match))
3377 (setq names (cons (cadr match) names)))))
3378 ;; Stop searching ASAP.
3379 (and (= (current-indentation) 0) (throw 'exit t))))
3380 (and names
3381 (concat (and type (format "%s " type))
3382 (mapconcat 'identity names ".")))))))
45c138ac 3383
d583cbe6
FEG
3384(defun python-info-current-symbol (&optional replace-self)
3385 "Return current symbol using dotty syntax.
3386With optional argument REPLACE-SELF convert \"self\" to current
3387parent defun name."
3388 (let ((name
2d79ec42 3389 (and (not (python-syntax-comment-or-string-p))
d583cbe6
FEG
3390 (with-syntax-table python-dotty-syntax-table
3391 (let ((sym (symbol-at-point)))
3392 (and sym
3393 (substring-no-properties (symbol-name sym))))))))
3394 (when name
3395 (if (not replace-self)
3396 name
3397 (let ((current-defun (python-info-current-defun)))
3398 (if (not current-defun)
3399 name
3400 (replace-regexp-in-string
3401 (python-rx line-start word-start "self" word-end ?.)
3402 (concat
3403 (mapconcat 'identity
3404 (butlast (split-string current-defun "\\."))
3405 ".") ".")
3406 name)))))))
3407
8dbce54c 3408(defun python-info-statement-starts-block-p ()
0a60bc10
FEG
3409 "Return non-nil if current statement opens a block."
3410 (save-excursion
3411 (python-nav-beginning-of-statement)
3412 (looking-at (python-rx block-start))))
3413
8dbce54c
FEG
3414(defun python-info-statement-ends-block-p ()
3415 "Return non-nil if point is at end of block."
3416 (let ((end-of-block-pos (save-excursion
3417 (python-nav-end-of-block)))
3418 (end-of-statement-pos (save-excursion
3419 (python-nav-end-of-statement))))
3420 (and end-of-block-pos end-of-statement-pos
3421 (= end-of-block-pos end-of-statement-pos))))
3422
3423(defun python-info-beginning-of-statement-p ()
3424 "Return non-nil if point is at beginning of statement."
3425 (= (point) (save-excursion
3426 (python-nav-beginning-of-statement)
3427 (point))))
3428
3429(defun python-info-end-of-statement-p ()
3430 "Return non-nil if point is at end of statement."
3431 (= (point) (save-excursion
3432 (python-nav-end-of-statement)
3433 (point))))
3434
3435(defun python-info-beginning-of-block-p ()
3436 "Return non-nil if point is at beginning of block."
3437 (and (python-info-beginning-of-statement-p)
3438 (python-info-statement-starts-block-p)))
3439
3440(defun python-info-end-of-block-p ()
3441 "Return non-nil if point is at end of block."
3442 (and (python-info-end-of-statement-p)
3443 (python-info-statement-ends-block-p)))
3444
45c138ac 3445(defun python-info-closing-block ()
e2d8d479 3446 "Return the point of the block the current line closes."
45c138ac
FEG
3447 (let ((closing-word (save-excursion
3448 (back-to-indentation)
3449 (current-word)))
3450 (indentation (current-indentation)))
3451 (when (member closing-word python-indent-dedenters)
3452 (save-excursion
3453 (forward-line -1)
3454 (while (and (> (current-indentation) indentation)
3455 (not (bobp))
3456 (not (back-to-indentation))
3457 (forward-line -1)))
3458 (back-to-indentation)
3459 (cond
3460 ((not (equal indentation (current-indentation))) nil)
3461 ((string= closing-word "elif")
3462 (when (member (current-word) '("if" "elif"))
3463 (point-marker)))
3464 ((string= closing-word "else")
3465 (when (member (current-word) '("if" "elif" "except" "for" "while"))
3466 (point-marker)))
3467 ((string= closing-word "except")
3468 (when (member (current-word) '("try"))
3469 (point-marker)))
3470 ((string= closing-word "finally")
3471 (when (member (current-word) '("except" "else"))
3472 (point-marker))))))))
3473
cd7ab092
FEG
3474(defun python-info-closing-block-message (&optional closing-block-point)
3475 "Message the contents of the block the current line closes.
3476With optional argument CLOSING-BLOCK-POINT use that instead of
3477recalculating it calling `python-info-closing-block'."
3478 (let ((point (or closing-block-point (python-info-closing-block))))
3479 (when point
3480 (save-restriction
3481 (widen)
3482 (message "Closes %s" (save-excursion
3483 (goto-char point)
3484 (back-to-indentation)
3485 (buffer-substring
3486 (point) (line-end-position))))))))
3487
0674d3fa 3488(defun python-info-line-ends-backslash-p (&optional line-number)
6cad4c6e 3489 "Return non-nil if current line ends with backslash.
0674d3fa 3490With optional argument LINE-NUMBER, check that line instead."
6cad4c6e
FEG
3491 (save-excursion
3492 (save-restriction
dc4f2e53 3493 (widen)
6cad4c6e 3494 (when line-number
2af3b9c1 3495 (python-util-goto-line line-number))
dc4f2e53
FEG
3496 (while (and (not (eobp))
3497 (goto-char (line-end-position))
2d79ec42 3498 (python-syntax-context 'paren)
dc4f2e53
FEG
3499 (not (equal (char-before (point)) ?\\)))
3500 (forward-line 1))
3501 (when (equal (char-before) ?\\)
3502 (point-marker)))))
3503
48d1354e
PE
3504(defun python-info-beginning-of-backslash (&optional line-number)
3505 "Return the point where the backslashed line start.
4289485a 3506Optional argument LINE-NUMBER forces the line number to check against."
dc4f2e53
FEG
3507 (save-excursion
3508 (save-restriction
6cad4c6e 3509 (widen)
dc4f2e53 3510 (when line-number
2af3b9c1 3511 (python-util-goto-line line-number))
dc4f2e53
FEG
3512 (when (python-info-line-ends-backslash-p)
3513 (while (save-excursion
3514 (goto-char (line-beginning-position))
2d79ec42 3515 (python-syntax-context 'paren))
dc4f2e53
FEG
3516 (forward-line -1))
3517 (back-to-indentation)
3518 (point-marker)))))
45c138ac
FEG
3519
3520(defun python-info-continuation-line-p ()
0674d3fa
FEG
3521 "Check if current line is continuation of another.
3522When current line is continuation of another return the point
3523where the continued line ends."
3524 (save-excursion
3525 (save-restriction
3526 (widen)
3527 (let* ((context-type (progn
3528 (back-to-indentation)
2d79ec42 3529 (python-syntax-context-type)))
0674d3fa
FEG
3530 (line-start (line-number-at-pos))
3531 (context-start (when context-type
2d79ec42 3532 (python-syntax-context context-type))))
0674d3fa
FEG
3533 (cond ((equal context-type 'paren)
3534 ;; Lines inside a paren are always a continuation line
3535 ;; (except the first one).
1d29cc7d
FEG
3536 (python-util-forward-comment -1)
3537 (point-marker))
3538 ((member context-type '(string comment))
0674d3fa
FEG
3539 ;; move forward an roll again
3540 (goto-char context-start)
3541 (python-util-forward-comment)
3542 (python-info-continuation-line-p))
3543 (t
1d29cc7d
FEG
3544 ;; Not within a paren, string or comment, the only way
3545 ;; we are dealing with a continuation line is that
3546 ;; previous line contains a backslash, and this can
3547 ;; only be the previous line from current
0674d3fa
FEG
3548 (back-to-indentation)
3549 (python-util-forward-comment -1)
0674d3fa
FEG
3550 (when (and (equal (1- line-start) (line-number-at-pos))
3551 (python-info-line-ends-backslash-p))
3552 (point-marker))))))))
45c138ac
FEG
3553
3554(defun python-info-block-continuation-line-p ()
3555 "Return non-nil if current line is a continuation of a block."
3556 (save-excursion
0674d3fa
FEG
3557 (when (python-info-continuation-line-p)
3558 (forward-line -1)
3559 (back-to-indentation)
3560 (when (looking-at (python-rx block-start))
3561 (point-marker)))))
45c138ac
FEG
3562
3563(defun python-info-assignment-continuation-line-p ()
0674d3fa
FEG
3564 "Check if current line is a continuation of an assignment.
3565When current line is continuation of another with an assignment
3566return the point of the first non-blank character after the
3567operator."
45c138ac 3568 (save-excursion
0674d3fa
FEG
3569 (when (python-info-continuation-line-p)
3570 (forward-line -1)
3571 (back-to-indentation)
3572 (when (and (not (looking-at (python-rx block-start)))
45c138ac
FEG
3573 (and (re-search-forward (python-rx not-simple-operator
3574 assignment-operator
3575 not-simple-operator)
3576 (line-end-position) t)
2d79ec42 3577 (not (python-syntax-context-type))))
0674d3fa
FEG
3578 (skip-syntax-forward "\s")
3579 (point-marker)))))
45c138ac 3580
8c6f9e60 3581(defun python-info-looking-at-beginning-of-defun (&optional syntax-ppss)
4289485a 3582 "Check if point is at `beginning-of-defun' using SYNTAX-PPSS."
2d79ec42 3583 (and (not (python-syntax-context-type (or syntax-ppss (syntax-ppss))))
8c6f9e60
FEG
3584 (save-excursion
3585 (beginning-of-line 1)
3586 (looking-at python-nav-beginning-of-defun-regexp))))
3587
032d23ab 3588(defun python-info-current-line-comment-p ()
fd16b061 3589 "Return non-nil if current line is a comment line."
2af3b9c1
FEG
3590 (char-equal
3591 (or (char-after (+ (line-beginning-position) (current-indentation))) ?_)
3592 ?#))
032d23ab
FEG
3593
3594(defun python-info-current-line-empty-p ()
fd16b061 3595 "Return non-nil if current line is empty, ignoring whitespace."
032d23ab
FEG
3596 (save-excursion
3597 (beginning-of-line 1)
3598 (looking-at
3599 (python-rx line-start (* whitespace)
3600 (group (* not-newline))
3601 (* whitespace) line-end))
3602 (string-equal "" (match-string-no-properties 1))))
3603
45c138ac 3604\f
c942de99
FEG
3605;;; Utility functions
3606
2af3b9c1
FEG
3607(defun python-util-goto-line (line-number)
3608 "Move point to LINE-NUMBER."
3609 (goto-char (point-min))
3610 (forward-line (1- line-number)))
c942de99 3611
d2190c57 3612;; Stolen from org-mode
fbc39529 3613(defun python-util-clone-local-variables (from-buffer &optional regexp)
d2190c57
FEG
3614 "Clone local variables from FROM-BUFFER.
3615Optional argument REGEXP selects variables to clone and defaults
3616to \"^python-\"."
3617 (mapc
3618 (lambda (pair)
3619 (and (symbolp (car pair))
3620 (string-match (or regexp "^python-")
3621 (symbol-name (car pair)))
6cad4c6e
FEG
3622 (set (make-local-variable (car pair))
3623 (cdr pair))))
d2190c57
FEG
3624 (buffer-local-variables from-buffer)))
3625
0674d3fa 3626(defun python-util-forward-comment (&optional direction)
4289485a
FEG
3627 "Python mode specific version of `forward-comment'.
3628Optional argument DIRECTION defines the direction to move to."
2d79ec42 3629 (let ((comment-start (python-syntax-context 'comment))
0674d3fa
FEG
3630 (factor (if (< (or direction 0) 0)
3631 -99999
3632 99999)))
3633 (when comment-start
3634 (goto-char comment-start))
3635 (forward-comment factor)))
3636
adc31213
FEG
3637(defun python-util-popn (lst n)
3638 "Return LST first N elements.
fd16b061
JB
3639N should be an integer, when negative its opposite is used.
3640When N is bigger than the length of LST, the list is
3641returned as is."
adc31213
FEG
3642 (let* ((n (min (abs n)))
3643 (len (length lst))
3644 (acc))
3645 (if (> n len)
3646 lst
3647 (while (< 0 n)
3648 (setq acc (cons (car lst) acc)
3649 lst (cdr lst)
3650 n (1- n)))
3651 (reverse acc))))
3652
656f99be
FEG
3653(defun python-util-strip-string (string)
3654 "Strip STRING whitespace and newlines from end and beginning."
3655 (replace-regexp-in-string
3656 (rx (or (: string-start (* (any whitespace ?\r ?\n)))
3657 (: (* (any whitespace ?\r ?\n)) string-end)))
3658 ""
3659 string))
3660
c942de99 3661\f
e5afbcac
SM
3662(defun python-electric-pair-string-delimiter ()
3663 (when (and electric-pair-mode
3664 (memq last-command-event '(?\" ?\'))
3665 (let ((count 0))
3666 (while (eq (char-before (- (point) count)) last-command-event)
3667 (cl-incf count))
7aecc2f6
JT
3668 (= count 3))
3669 (eq (char-after) last-command-event))
3670 (save-excursion (insert (make-string 2 last-command-event)))))
e5afbcac 3671
2abb4e65
SM
3672(defvar electric-indent-inhibit)
3673
45c138ac 3674;;;###autoload
68f12411 3675(define-derived-mode python-mode prog-mode "Python"
e2d8d479
FEG
3676 "Major mode for editing Python files.
3677
ae1f1ce1 3678\\{python-mode-map}"
45c138ac
FEG
3679 (set (make-local-variable 'tab-width) 8)
3680 (set (make-local-variable 'indent-tabs-mode) nil)
3681
3682 (set (make-local-variable 'comment-start) "# ")
3683 (set (make-local-variable 'comment-start-skip) "#+\\s-*")
3684
3685 (set (make-local-variable 'parse-sexp-lookup-properties) t)
3686 (set (make-local-variable 'parse-sexp-ignore-comments) t)
3687
032d23ab 3688 (set (make-local-variable 'forward-sexp-function)
489af14f 3689 'python-nav-forward-sexp)
032d23ab 3690
45c138ac 3691 (set (make-local-variable 'font-lock-defaults)
aeadd9a4
FEG
3692 '(python-font-lock-keywords nil nil nil nil))
3693
3694 (set (make-local-variable 'syntax-propertize-function)
3695 python-syntax-propertize-function)
45c138ac 3696
6cad4c6e
FEG
3697 (set (make-local-variable 'indent-line-function)
3698 #'python-indent-line-function)
45c138ac 3699 (set (make-local-variable 'indent-region-function) #'python-indent-region)
2abb4e65
SM
3700 ;; Because indentation is not redundant, we cannot safely reindent code.
3701 (setq-local electric-indent-inhibit t)
bd15d9d1 3702 (setq-local electric-indent-chars (cons ?: electric-indent-chars))
e5afbcac
SM
3703
3704 ;; Add """ ... """ pairing to electric-pair-mode.
3705 (add-hook 'post-self-insert-hook
3706 #'python-electric-pair-string-delimiter 'append t)
3707
45c138ac 3708 (set (make-local-variable 'paragraph-start) "\\s-*$")
6cad4c6e 3709 (set (make-local-variable 'fill-paragraph-function)
bd15d9d1 3710 #'python-fill-paragraph)
45c138ac
FEG
3711
3712 (set (make-local-variable 'beginning-of-defun-function)
2e6625b5 3713 #'python-nav-beginning-of-defun)
45c138ac 3714 (set (make-local-variable 'end-of-defun-function)
2e6625b5 3715 #'python-nav-end-of-defun)
45c138ac
FEG
3716
3717 (add-hook 'completion-at-point-functions
bd15d9d1 3718 #'python-completion-complete-at-point nil 'local)
45c138ac 3719
5eae76ae 3720 (add-hook 'post-self-insert-hook
bd15d9d1 3721 #'python-indent-post-self-insert-function 'append 'local)
5eae76ae 3722
adc31213
FEG
3723 (set (make-local-variable 'imenu-create-index-function)
3724 #'python-imenu-create-index)
207cb73c 3725
45c138ac
FEG
3726 (set (make-local-variable 'add-log-current-defun-function)
3727 #'python-info-current-defun)
3728
c6d3df36
FEG
3729 (add-hook 'which-func-functions #'python-info-current-defun nil t)
3730
e2803784
FEG
3731 (set (make-local-variable 'skeleton-further-elements)
3732 '((abbrev-mode nil)
3733 (< '(backward-delete-char-untabify (min python-indent-offset
6cad4c6e
FEG
3734 (current-column))))
3735 (^ '(- (1+ (current-indentation))))))
e2803784 3736
45c138ac
FEG
3737 (set (make-local-variable 'eldoc-documentation-function)
3738 #'python-eldoc-function)
3739
3740 (add-to-list 'hs-special-modes-alist
6cad4c6e 3741 `(python-mode "^\\s-*\\(?:def\\|class\\)\\>" nil "#"
c0458e0b 3742 ,(lambda (_arg)
2e6625b5 3743 (python-nav-end-of-defun)) nil))
45c138ac 3744
82c2b0de
FEG
3745 (set (make-local-variable 'mode-require-final-newline) t)
3746
45c138ac
FEG
3747 (set (make-local-variable 'outline-regexp)
3748 (python-rx (* space) block-start))
3114d9e7 3749 (set (make-local-variable 'outline-heading-end-regexp) ":[^\n]*\n")
45c138ac
FEG
3750 (set (make-local-variable 'outline-level)
3751 #'(lambda ()
3752 "`outline-level' function for Python mode."
3753 (1+ (/ (current-indentation) python-indent-offset))))
3754
e2803784
FEG
3755 (python-skeleton-add-menu-items)
3756
e0cc4efa
FEG
3757 (make-local-variable 'python-shell-internal-buffer)
3758
45c138ac
FEG
3759 (when python-indent-guess-indent-offset
3760 (python-indent-guess-indent-offset)))
3761
3762
3763(provide 'python)
d617c457
FEG
3764
3765;; Local Variables:
3766;; coding: utf-8
3767;; indent-tabs-mode: nil
3768;; End:
3769
45c138ac 3770;;; python.el ends here