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