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