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