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