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