Fixed pdb-track on Windows
[bpt/emacs.git] / lisp / progmodes / python.el
CommitLineData
45c138ac
FEG
1;;; python.el -- Python's flying circus support for Emacs
2
3;; Copyright (C) 2010 Free Software Foundation, Inc.
4
5;; Author: Fabián E. Gallina <fabian@anue.biz>
6;; Maintainer: FSF
7;; Created: Jul 2010
8;; Keywords: languages
9
10;; This file is NOT part of GNU Emacs.
11
12;; python.el is free software: you can redistribute it and/or modify
13;; it under the terms of the GNU General Public License as published by
14;; the Free Software Foundation, either version 3 of the License, or
15;; (at your option) any later version.
16
17;; python.el is distributed in the hope that it will be useful,
18;; but WITHOUT ANY WARRANTY; without even the implied warranty of
19;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20;; GNU General Public License for more details.
21
22;; You should have received a copy of the GNU General Public License
23;; along with python.el. If not, see <http://www.gnu.org/licenses/>.
24
25;;; Commentary:
26
27;; Major mode for editing Python files with some fontification and
28;; indentation bits extracted from original Dave Love's python.el
29;; found in GNU/Emacs.
30
31;; While it probably has less features than Dave Love's python.el and
32;; PSF's python-mode.el it provides the main stuff you'll need while
33;; keeping it simple :)
34
35;; Implements Syntax highlighting, Indentation, Movement, Shell
36;; interaction, Shell completion, Pdb tracking, Symbol completion,
37;; Eldoc.
38
39;; Syntax highlighting: Fontification of code is provided and supports
40;; python's triple quoted strings properly.
41
42;; Indentation: Automatic indentation with indentation cycling is
43;; provided, it allows you to navigate different available levels of
44;; indentation by hitting <tab> several times.
45
46;; Movement: `beginning-of-defun' and `end-of-defun' functions are
47;; properly implemented. A `beginning-of-innermost-defun' is defined
48;; to navigate nested defuns.
49
50;; Shell interaction: is provided and allows you easily execute any
51;; block of code of your current buffer in an inferior Python process.
52
53;; Shell completion: hitting tab will try to complete the current
4e531f7a 54;; word. Shell completion is implemented in a manner that if you
45c138ac
FEG
55;; change the `python-shell-interpreter' to any other (for example
56;; IPython) it should be easy to integrate another way to calculate
4e531f7a 57;; completions. You just need to especify your custom
45c138ac
FEG
58;; `python-shell-completion-setup-code' and
59;; `python-shell-completion-strings-code'
60
61;; Pdb tracking: when you execute a block of code that contains some
62;; call to pdb (or ipdb) it will prompt the block of code and will
63;; follow the execution of pdb marking the current line with an arrow.
64
4e531f7a 65;; Symbol completion: you can complete the symbol at point. It uses
45c138ac
FEG
66;; the shell completion in background so you should run
67;; `python-shell-send-buffer' from time to time to get better results.
68
2947016a
FEG
69;; FFAP: You can find the filename for a given module when using ffap
70;; out of the box. This feature needs an inferior python shell
71;; running.
72
8b3e0e76
FEG
73;; Code check: Check the current file for errors using
74;; `python-check-command'
75
45c138ac 76;; Eldoc: returns documentation for object at point by using the
4e531f7a 77;; inferior python subprocess to inspect its documentation. As you
45c138ac
FEG
78;; might guessed you should run `python-shell-send-buffer' from time
79;; to time to get better results too.
80
81;;; Installation:
82
83;; Add this to your .emacs:
84
85;; (add-to-list 'load-path "/folder/containing/file")
86;; (require 'python)
87
88;;; TODO:
89
90;; Ordered by priority:
91
92;; Better decorator support for beginning of defun
93
db1497be 94;; Review code and cleanup
45c138ac 95
db1497be 96;; (Perhaps) some skeletons (I never use them because of yasnippet)
45c138ac
FEG
97
98;;; Code:
99
100(require 'comint)
101(require 'ansi-color)
102(require 'outline)
103
104(eval-when-compile
105 (require 'cl))
106
107(autoload 'comint-mode "comint")
108
109;;;###autoload
110(add-to-list 'auto-mode-alist (cons (purecopy "\\.py\\'") 'python-mode))
111;;;###autoload
112(add-to-list 'interpreter-mode-alist (cons (purecopy "python") 'python-mode))
113
114(defgroup python nil
115 "Python Language's flying circus support for Emacs."
116 :group 'languages
117 :version "23.2"
118 :link '(emacs-commentary-link "python"))
119
120\f
121;;; Bindings
122
123(defvar python-mode-map
124 (let ((map (make-sparse-keymap)))
125 ;; Indent specific
126 (define-key map "\177" 'python-indent-dedent-line-backspace)
127 (define-key map (kbd "<backtab>") 'python-indent-dedent-line)
128 (define-key map "\C-c<" 'python-indent-shift-left)
129 (define-key map "\C-c>" 'python-indent-shift-right)
130 ;; Shell interaction
131 (define-key map "\C-c\C-s" 'python-shell-send-string)
132 (define-key map "\C-c\C-r" 'python-shell-send-region)
133 (define-key map "\C-\M-x" 'python-shell-send-defun)
134 (define-key map "\C-c\C-c" 'python-shell-send-buffer)
135 (define-key map "\C-c\C-l" 'python-shell-send-file)
136 (define-key map "\C-c\C-z" 'python-shell-switch-to-shell)
8b3e0e76
FEG
137 ;; Some util commands
138 (define-key map "\C-c\C-v" 'python-check)
78334b43 139 (define-key map "\C-c\C-f" 'python-eldoc-at-point)
45c138ac
FEG
140 ;; Utilities
141 (substitute-key-definition 'complete-symbol 'completion-at-point
142 map global-map)
143 (easy-menu-define python-menu map "Python Mode menu"
144 `("Python"
145 :help "Python-specific Features"
146 ["Shift region left" python-indent-shift-left :active mark-active
147 :help "Shift region left by a single indentation step"]
148 ["Shift region right" python-indent-shift-right :active mark-active
149 :help "Shift region right by a single indentation step"]
150 "-"
151 ["Mark def/class" mark-defun
152 :help "Mark outermost definition around point"]
153 "-"
154 ["Start of def/class" beginning-of-defun
155 :help "Go to start of outermost definition around point"]
156 ["Start of def/class" python-beginning-of-innermost-defun
157 :help "Go to start of innermost definition around point"]
158 ["End of def/class" end-of-defun
159 :help "Go to end of definition around point"]
160 "-"
161 ["Start interpreter" run-python
162 :help "Run inferior Python process in a separate buffer"]
163 ["Switch to shell" python-shell-switch-to-shell
164 :help "Switch to running inferior Python process"]
165 ["Eval string" python-shell-send-string
166 :help "Eval string in inferior Python session"]
167 ["Eval buffer" python-shell-send-buffer
168 :help "Eval buffer in inferior Python session"]
169 ["Eval region" python-shell-send-region
170 :help "Eval region in inferior Python session"]
171 ["Eval defun" python-shell-send-defun
172 :help "Eval defun in inferior Python session"]
173 ["Eval file" python-shell-send-file
174 :help "Eval file in inferior Python session"]
175 ["Debugger" pdb :help "Run pdb under GUD"]
176 "-"
8b3e0e76
FEG
177 ["Check file" python-check
178 :help "Check file for errors"]
78334b43
FEG
179 ["Help on symbol" python-eldoc-at-point
180 :help "Get help on symbol at point"]
45c138ac
FEG
181 ["Complete symbol" completion-at-point
182 :help "Complete symbol before point"]))
183 map)
184 "Keymap for `python-mode'.")
185
186\f
187;;; Python specialized rx
188
189(defconst python-rx-constituents
190 (list
191 `(block-start . ,(rx symbol-start
192 (or "def" "class" "if" "elif" "else" "try"
193 "except" "finally" "for" "while" "with")
194 symbol-end))
195 `(defun . ,(rx symbol-start (or "def" "class") symbol-end))
196 `(open-paren . ,(rx (or "{" "[" "(")))
197 `(close-paren . ,(rx (or "}" "]" ")")))
198 `(simple-operator . ,(rx (any ?+ ?- ?/ ?& ?^ ?~ ?| ?* ?< ?> ?= ?%)))
199 `(not-simple-operator . ,(rx (not (any ?+ ?- ?/ ?& ?^ ?~ ?| ?* ?< ?> ?= ?%))))
200 `(operator . ,(rx (or "+" "-" "/" "&" "^" "~" "|" "*" "<" ">"
201 "=" "%" "**" "//" "<<" ">>" "<=" "!="
202 "==" ">=" "is" "not")))
203 `(assignment-operator . ,(rx (or "=" "+=" "-=" "*=" "/=" "//=" "%=" "**="
204 ">>=" "<<=" "&=" "^=" "|=")))))
205
206(defmacro python-rx (&rest regexps)
4e531f7a 207 "Python mode especialized rx macro which supports common python named REGEXPS."
45c138ac
FEG
208 (let ((rx-constituents (append python-rx-constituents rx-constituents)))
209 (cond ((null regexps)
210 (error "No regexp"))
211 ((cdr regexps)
212 (rx-to-string `(and ,@regexps) t))
213 (t
214 (rx-to-string (car regexps) t)))))
215
216\f
217;;; Font-lock and syntax
218
219(defvar python-font-lock-keywords
220 ;; Keywords
221 `(,(rx symbol-start
222 (or "and" "del" "from" "not" "while" "as" "elif" "global" "or" "with"
223 "assert" "else" "if" "pass" "yield" "break" "except" "import"
224 "print" "class" "exec" "in" "raise" "continue" "finally" "is"
225 "return" "def" "for" "lambda" "try" "self")
226 symbol-end)
227 ;; functions
228 (,(rx symbol-start "def" (1+ space) (group (1+ (or word ?_))))
229 (1 font-lock-function-name-face))
230 ;; classes
231 (,(rx symbol-start "class" (1+ space) (group (1+ (or word ?_))))
232 (1 font-lock-type-face))
233 ;; Constants
234 (,(rx symbol-start (group "None" symbol-end))
235 (1 font-lock-constant-face))
236 ;; Decorators.
237 (,(rx line-start (* (any " \t")) (group "@" (1+ (or word ?_))
238 (0+ "." (1+ (or word ?_)))))
239 (1 font-lock-type-face))
240 ;; Builtin Exceptions
241 (,(rx symbol-start
242 (or "ArithmeticError" "AssertionError" "AttributeError"
243 "BaseException" "BufferError" "BytesWarning" "DeprecationWarning"
244 "EOFError" "EnvironmentError" "Exception" "FloatingPointError"
245 "FutureWarning" "GeneratorExit" "IOError" "ImportError"
246 "ImportWarning" "IndentationError" "IndexError" "KeyError"
247 "KeyboardInterrupt" "LookupError" "MemoryError" "NameError"
248 "NotImplemented" "NotImplementedError" "OSError" "OverflowError"
249 "PendingDeprecationWarning" "ReferenceError" "RuntimeError"
250 "RuntimeWarning" "StandardError" "StopIteration" "SyntaxError"
251 "SyntaxWarning" "SystemError" "SystemExit" "TabError" "TypeError"
252 "UnboundLocalError" "UnicodeDecodeError" "UnicodeEncodeError"
253 "UnicodeError" "UnicodeTranslateError" "UnicodeWarning"
254 "UserWarning" "ValueError" "Warning" "ZeroDivisionError")
255 symbol-end) . font-lock-type-face)
256 ;; Builtins
257 (,(rx (or line-start (not (any ". \t"))) (* (any " \t")) symbol-start
258 (group
259 (or "_" "__debug__" "__doc__" "__import__" "__name__" "__package__"
260 "abs" "all" "any" "apply" "basestring" "bin" "bool" "buffer"
261 "bytearray" "bytes" "callable" "chr" "classmethod" "cmp" "coerce"
262 "compile" "complex" "copyright" "credits" "delattr" "dict" "dir"
263 "divmod" "enumerate" "eval" "execfile" "exit" "file" "filter"
264 "float" "format" "frozenset" "getattr" "globals" "hasattr" "hash"
265 "help" "hex" "id" "input" "int" "intern" "isinstance" "issubclass"
266 "iter" "len" "license" "list" "locals" "long" "map" "max" "min"
267 "next" "object" "oct" "open" "ord" "pow" "print" "property" "quit"
268 "range" "raw_input" "reduce" "reload" "repr" "reversed" "round"
269 "set" "setattr" "slice" "sorted" "staticmethod" "str" "sum"
270 "super" "tuple" "type" "unichr" "unicode" "vars" "xrange" "zip"
271 "True" "False" "Ellipsis")) symbol-end)
272 (1 font-lock-builtin-face))
273 ;; asignations
274 ;; support for a = b = c = 5
275 (,(lambda (limit)
276 (let ((re (python-rx (group (+ (any word ?. ?_))) (* space)
277 assignment-operator)))
278 (when (re-search-forward re limit t)
279 (while (and (not (equal (nth 0 (syntax-ppss)) 0))
280 (re-search-forward re limit t)))
534e2438
FEG
281 (if (and (equal (nth 0 (syntax-ppss)) 0)
282 (not (equal (char-after (point-marker)) ?=)))
45c138ac
FEG
283 t
284 (set-match-data nil)))))
285 (1 font-lock-variable-name-face nil nil))
286 ;; support for a, b, c = (1, 2, 3)
287 (,(lambda (limit)
288 (let ((re (python-rx (group (+ (any word ?. ?_))) (* space)
289 (* ?, (* space) (+ (any word ?. ?_)) (* space))
290 ?, (* space) (+ (any word ?. ?_)) (* space)
291 assignment-operator)))
292 (when (and (re-search-forward re limit t)
293 (goto-char (nth 3 (match-data))))
294 (while (and (not (equal (nth 0 (syntax-ppss)) 0))
295 (re-search-forward re limit t))
296 (goto-char (nth 3 (match-data))))
297 (if (equal (nth 0 (syntax-ppss)) 0)
298 t
299 (set-match-data nil)))))
300 (1 font-lock-variable-name-face nil nil))))
301
302;; Fixme: Is there a better way?
303(defconst python-font-lock-syntactic-keywords
304 ;; First avoid a sequence preceded by an odd number of backslashes.
305 `((,(rx (not (any ?\\))
306 ?\\ (* (and ?\\ ?\\))
307 (group (syntax string-quote))
308 (backref 1)
309 (group (backref 1)))
310 (2 ,(string-to-syntax "\""))) ; dummy
311 (,(rx (group (optional (any "uUrR"))) ; prefix gets syntax property
312 (optional (any "rR")) ; possible second prefix
313 (group (syntax string-quote)) ; maybe gets property
314 (backref 2) ; per first quote
315 (group (backref 2))) ; maybe gets property
316 (1 (python-quote-syntax 1))
317 (2 (python-quote-syntax 2))
318 (3 (python-quote-syntax 3))))
319 "Make outer chars of triple-quote strings into generic string delimiters.")
320
321(defun python-quote-syntax (n)
322 "Put `syntax-table' property correctly on triple quote.
323Used for syntactic keywords. N is the match number (1, 2 or 3)."
324 ;; Given a triple quote, we have to check the context to know
325 ;; whether this is an opening or closing triple or whether it's
326 ;; quoted anyhow, and should be ignored. (For that we need to do
327 ;; the same job as `syntax-ppss' to be correct and it seems to be OK
328 ;; to use it here despite initial worries.) We also have to sort
329 ;; out a possible prefix -- well, we don't _have_ to, but I think it
330 ;; should be treated as part of the string.
331
332 ;; Test cases:
333 ;; ur"""ar""" x='"' # """
334 ;; x = ''' """ ' a
335 ;; '''
336 ;; x '"""' x """ \"""" x
337 (save-excursion
338 (goto-char (match-beginning 0))
339 (cond
340 ;; Consider property for the last char if in a fenced string.
341 ((= n 3)
342 (let* ((font-lock-syntactic-keywords nil)
343 (syntax (syntax-ppss)))
344 (when (eq t (nth 3 syntax)) ; after unclosed fence
345 (goto-char (nth 8 syntax)) ; fence position
346 (skip-chars-forward "uUrR") ; skip any prefix
347 ;; Is it a matching sequence?
348 (if (eq (char-after) (char-after (match-beginning 2)))
349 (eval-when-compile (string-to-syntax "|"))))))
350 ;; Consider property for initial char, accounting for prefixes.
351 ((or (and (= n 2) ; leading quote (not prefix)
352 (= (match-beginning 1) (match-end 1))) ; prefix is null
353 (and (= n 1) ; prefix
354 (/= (match-beginning 1) (match-end 1)))) ; non-empty
355 (let ((font-lock-syntactic-keywords nil))
356 (unless (eq 'string (syntax-ppss-context (syntax-ppss)))
357 (eval-when-compile (string-to-syntax "|")))))
358 ;; Otherwise (we're in a non-matching string) the property is
359 ;; nil, which is OK.
360 )))
361
362(defvar python-mode-syntax-table
363 (let ((table (make-syntax-table)))
364 ;; Give punctuation syntax to ASCII that normally has symbol
365 ;; syntax or has word syntax and isn't a letter.
366 (let ((symbol (string-to-syntax "_"))
367 (sst (standard-syntax-table)))
368 (dotimes (i 128)
369 (unless (= i ?_)
370 (if (equal symbol (aref sst i))
371 (modify-syntax-entry i "." table)))))
372 (modify-syntax-entry ?$ "." table)
373 (modify-syntax-entry ?% "." table)
374 ;; exceptions
375 (modify-syntax-entry ?# "<" table)
376 (modify-syntax-entry ?\n ">" table)
377 (modify-syntax-entry ?' "\"" table)
378 (modify-syntax-entry ?` "$" table)
379 table)
380 "Syntax table for Python files.")
381
382(defvar python-dotty-syntax-table
383 (let ((table (make-syntax-table python-mode-syntax-table)))
384 (modify-syntax-entry ?. "w" table)
385 (modify-syntax-entry ?_ "w" table)
386 table)
387 "Dotty syntax table for Python files.
388It makes underscores and dots word constituent chars.")
389
390\f
391;;; Indentation
392
393(defcustom python-indent-offset 4
394 "Default indentation offset for Python."
395 :group 'python
396 :type 'integer
397 :safe 'integerp)
398
399(defcustom python-indent-guess-indent-offset t
400 "Non-nil tells Python mode to guess `python-indent-offset' value."
401 :type 'boolean
402 :group 'python)
403
404(defvar python-indent-current-level 0
405 "Current indentation level `python-indent-line-function' is using.")
406
407(defvar python-indent-levels '(0)
408 "Levels of indentation available for `python-indent-line-function'.")
409
410(defvar python-indent-dedenters '("else" "elif" "except" "finally")
411 "List of words that should be dedented.
412These make `python-indent-calculate-indentation' subtract the value of
413`python-indent-offset'.")
414
415(defun python-indent-guess-indent-offset ()
954aa7bd 416 "Guess and set `python-indent-offset' for the current buffer."
bbac1eb8
FEG
417 (save-excursion
418 (save-restriction
419 (widen)
420 (goto-char (point-min))
421 (let ((found-block))
422 (while (and (not found-block)
423 (re-search-forward
424 (python-rx line-start block-start) nil t))
425 (when (and (not (syntax-ppss-context (syntax-ppss)))
426 (progn
427 (goto-char (line-end-position))
428 (forward-comment -1)
429 (eq ?: (char-before))))
430 (setq found-block t)))
431 (if (not found-block)
432 (message "Can't guess python-indent-offset, using defaults: %s"
433 python-indent-offset)
434 (while (and (progn
435 (goto-char (line-end-position))
436 (python-info-continuation-line-p))
437 (not (eobp)))
438 (forward-line 1))
439 (forward-line 1)
440 (forward-comment 1)
14d9f80c
FEG
441 (let ((indent-offset (current-indentation)))
442 (when (> indent-offset 0)
443 (setq python-indent-offset indent-offset))))))))
45c138ac
FEG
444
445(defun python-indent-context (&optional stop)
446 "Return information on indentation context.
447Optional argument STOP serves to stop recursive calls.
448
449Returns a cons with the form:
450
451\(STATUS . START)
452
453Where status can be any of the following symbols:
454
455 * inside-paren: If point in between (), {} or []
456 * inside-string: If point is inside a string
457 * after-backslash: Previous line ends in a backslash
458 * after-beginning-of-block: Point is after beginning of block
459 * after-line: Point is after normal line
460 * no-indent: Point is at beginning of buffer or other special case
461
462START is the buffer position where the sexp starts."
463 (save-restriction
464 (widen)
465 (let ((ppss (save-excursion (beginning-of-line) (syntax-ppss)))
466 (start))
467 (cons
468 (cond
69bab1de 469 ;; Beginning of buffer
19b122e4
FEG
470 ((save-excursion
471 (goto-char (line-beginning-position))
472 (bobp))
69bab1de 473 'no-indent)
45c138ac
FEG
474 ;; Inside a paren
475 ((setq start (nth 1 ppss))
476 'inside-paren)
477 ;; Inside string
478 ((setq start (when (and (nth 3 ppss))
479 (nth 8 ppss)))
480 'inside-string)
481 ;; After backslash
482 ((setq start (when (not (syntax-ppss-context ppss))
483 (let ((line-beg-pos (line-beginning-position)))
484 (when (eq ?\\ (char-before (1- line-beg-pos)))
485 (- line-beg-pos 2)))))
486 'after-backslash)
487 ;; After beginning of block
488 ((setq start (save-excursion
489 (let ((block-regexp (python-rx block-start))
490 (block-start-line-end ":[[:space:]]*$"))
491 (back-to-indentation)
492 (while (and (forward-comment -1) (not (bobp))))
493 (back-to-indentation)
494 (when (or (python-info-continuation-line-p)
495 (and (not (looking-at block-regexp))
496 (save-excursion
497 (re-search-forward
498 block-start-line-end
499 (line-end-position) t))))
500 (while (and (forward-line -1)
501 (python-info-continuation-line-p)
502 (not (bobp))))
503 (when (not (looking-at block-regexp))
504 (forward-line 1)))
505 (back-to-indentation)
506 (when (and (looking-at block-regexp)
507 (or (re-search-forward
508 block-start-line-end
509 (line-end-position) t)
510 (python-info-continuation-line-p)))
511 (point-marker)))))
512 'after-beginning-of-block)
513 ;; After normal line
514 ((setq start (save-excursion
515 (while (and (forward-comment -1) (not (bobp))))
516 (while (and (not (back-to-indentation))
517 (not (bobp))
518 (if (> (nth 0 (syntax-ppss)) 0)
519 (forward-line -1)
520 (if (save-excursion
521 (forward-line -1)
522 (python-info-line-ends-backslash-p))
523 (forward-line -1)))))
524 (point-marker)))
525 'after-line)
526 ;; Do not indent
527 (t 'no-indent))
528 start))))
529
530(defun python-indent-calculate-indentation ()
531 "Calculate correct indentation offset for the current line."
532 (let* ((indentation-context (python-indent-context))
533 (context-status (car indentation-context))
534 (context-start (cdr indentation-context)))
535 (save-restriction
536 (widen)
537 (save-excursion
538 (case context-status
539 ('no-indent 0)
540 ('after-beginning-of-block
541 (goto-char context-start)
542 (+ (current-indentation) python-indent-offset))
543 ('after-line
544 (-
545 (save-excursion
546 (goto-char context-start)
547 (current-indentation))
548 (if (progn
549 (back-to-indentation)
550 (looking-at (regexp-opt python-indent-dedenters)))
551 python-indent-offset
552 0)))
553 ('inside-string
554 (goto-char context-start)
555 (current-indentation))
556 ('after-backslash
557 (let* ((block-continuation
558 (save-excursion
559 (forward-line -1)
560 (python-info-block-continuation-line-p)))
561 (assignment-continuation
562 (save-excursion
563 (forward-line -1)
564 (python-info-assignment-continuation-line-p)))
565 (indentation (cond (block-continuation
566 (goto-char block-continuation)
567 (re-search-forward
568 (python-rx block-start (* space))
569 (line-end-position) t)
570 (current-column))
571 (assignment-continuation
572 (goto-char assignment-continuation)
573 (re-search-forward
574 (python-rx simple-operator)
575 (line-end-position) t)
576 (forward-char 1)
577 (re-search-forward
578 (python-rx (* space))
579 (line-end-position) t)
580 (current-column))
581 (t
582 (goto-char context-start)
583 (current-indentation)))))
584 indentation))
585 ('inside-paren
586 (-
587 (save-excursion
588 (goto-char context-start)
589 (forward-char)
13d1a42e
FEG
590 (save-restriction
591 (narrow-to-region
592 (line-beginning-position)
593 (line-end-position))
594 (forward-comment 1))
595 (if (looking-at "$")
45c138ac
FEG
596 (+ (current-indentation) python-indent-offset)
597 (forward-comment 1)
598 (current-column)))
599 (if (progn
600 (back-to-indentation)
601 (looking-at (regexp-opt '(")" "]" "}"))))
602 python-indent-offset
603 0))))))))
604
605(defun python-indent-calculate-levels ()
606 "Calculate `python-indent-levels' and reset `python-indent-current-level'."
607 (let* ((indentation (python-indent-calculate-indentation))
608 (remainder (% indentation python-indent-offset))
609 (steps (/ (- indentation remainder) python-indent-offset)))
610 (setq python-indent-levels '())
611 (setq python-indent-levels (cons 0 python-indent-levels))
612 (dotimes (step steps)
613 (setq python-indent-levels
614 (cons (* python-indent-offset (1+ step)) python-indent-levels)))
615 (when (not (eq 0 remainder))
616 (setq python-indent-levels
617 (cons (+ (* python-indent-offset steps) remainder)
618 python-indent-levels)))
619 (setq python-indent-levels (nreverse python-indent-levels))
620 (setq python-indent-current-level (1- (length python-indent-levels)))))
621
622(defun python-indent-toggle-levels ()
623 "Toggle `python-indent-current-level' over `python-indent-levels'."
624 (setq python-indent-current-level (1- python-indent-current-level))
625 (when (< python-indent-current-level 0)
626 (setq python-indent-current-level (1- (length python-indent-levels)))))
627
628(defun python-indent-line (&optional force-toggle)
629 "Internal implementation of `python-indent-line-function'.
630
631Uses the offset calculated in
632`python-indent-calculate-indentation' and available levels
633indicated by the variable `python-indent-levels'.
634
635When the variable `last-command' is equal to
636`indent-for-tab-command' or FORCE-TOGGLE is non-nil:
637
638* Cycles levels indicated in the variable `python-indent-levels'
639 by setting the current level in the variable
640 `python-indent-current-level'.
641
642When the variable `last-command' is not equal to
643`indent-for-tab-command' and FORCE-TOGGLE is nil:
644
645* calculates possible indentation levels and saves it in the
646 variable `python-indent-levels'.
647
648* sets the variable `python-indent-current-level' correctly so
649 offset is equal to (`nth' `python-indent-current-level'
650 `python-indent-levels')"
651 (if (or (and (eq this-command 'indent-for-tab-command)
652 (eq last-command this-command))
653 force-toggle)
654 (python-indent-toggle-levels)
655 (python-indent-calculate-levels))
656 (beginning-of-line)
657 (delete-horizontal-space)
658 (indent-to (nth python-indent-current-level python-indent-levels))
659 (save-restriction
660 (widen)
661 (let ((closing-block-point (python-info-closing-block)))
662 (when closing-block-point
663 (message "Closes %s" (buffer-substring
664 closing-block-point
665 (save-excursion
666 (goto-char closing-block-point)
667 (line-end-position))))))))
668
669(defun python-indent-line-function ()
670 "`indent-line-function' for Python mode.
671Internally just calls `python-indent-line'."
672 (python-indent-line))
673
674(defun python-indent-dedent-line ()
675 "Dedent current line."
676 (interactive "*")
677 (when (and (not (syntax-ppss-context (syntax-ppss)))
678 (<= (point-marker) (save-excursion
679 (back-to-indentation)
680 (point-marker)))
681 (> (current-column) 0))
682 (python-indent-line t)
683 t))
684
685(defun python-indent-dedent-line-backspace (arg)
686 "Dedent current line.
687Argument ARG is passed to `backward-delete-char-untabify' when
688point is not in between the indentation."
689 (interactive "*p")
690 (when (not (python-indent-dedent-line))
691 (backward-delete-char-untabify arg)))
183f9296 692(put 'python-indent-dedent-line-backspace 'delete-selection 'supersede)
45c138ac
FEG
693
694(defun python-indent-region (start end)
695 "Indent a python region automagically.
696
697Called from a program, START and END specify the region to indent."
698 (save-excursion
699 (goto-char end)
700 (setq end (point-marker))
701 (goto-char start)
702 (or (bolp) (forward-line 1))
703 (while (< (point) end)
704 (or (and (bolp) (eolp))
705 (let (word)
706 (forward-line -1)
707 (back-to-indentation)
708 (setq word (current-word))
709 (forward-line 1)
710 (when word
711 (beginning-of-line)
712 (delete-horizontal-space)
713 (indent-to (python-indent-calculate-indentation)))))
714 (forward-line 1))
715 (move-marker end nil)))
716
717(defun python-indent-shift-left (start end &optional count)
718 "Shift lines contained in region START END by COUNT columns to the left.
719
720COUNT defaults to `python-indent-offset'.
721
722If region isn't active, the current line is shifted.
723
724The shifted region includes the lines in which START and END lie.
725
726An error is signaled if any lines in the region are indented less
727than COUNT columns."
728 (interactive
729 (if mark-active
730 (list (region-beginning) (region-end) current-prefix-arg)
731 (list (line-beginning-position) (line-end-position) current-prefix-arg)))
732 (if count
733 (setq count (prefix-numeric-value count))
734 (setq count python-indent-offset))
735 (when (> count 0)
736 (save-excursion
737 (goto-char start)
738 (while (< (point) end)
739 (if (and (< (current-indentation) count)
740 (not (looking-at "[ \t]*$")))
741 (error "Can't shift all lines enough"))
742 (forward-line))
743 (indent-rigidly start end (- count)))))
744
745(add-to-list 'debug-ignored-errors "^Can't shift all lines enough")
746
747(defun python-indent-shift-right (start end &optional count)
748 "Shift lines contained in region START END by COUNT columns to the left.
749
750COUNT defaults to `python-indent-offset'.
751
752If region isn't active, the current line is shifted.
753
754The shifted region includes the lines in which START and END
755lie."
756 (interactive
757 (if mark-active
758 (list (region-beginning) (region-end) current-prefix-arg)
759 (list (line-beginning-position) (line-end-position) current-prefix-arg)))
760 (if count
761 (setq count (prefix-numeric-value count))
762 (setq count python-indent-offset))
763 (indent-rigidly start end count))
764
765\f
766;;; Navigation
767
768(defvar python-beginning-of-defun-regexp
769 "^\\(def\\|class\\)[[:space:]]+[[:word:]]+"
770 "Regular expresion matching beginning of outermost class or function.")
771
772(defvar python-beginning-of-innermost-defun-regexp
773 "^[[:space:]]*\\(def\\|class\\)[[:space:]]+[[:word:]]+"
774 "Regular expresion matching beginning of innermost class or function.")
775
776(defun python-beginning-of-defun (&optional innermost)
777 "Move point to the beginning of innermost/outermost def or class.
778If INNERMOST is non-nil then move to the beginning of the
779innermost definition."
780 (let ((starting-point (point-marker))
781 (nonblank-line-indent)
782 (defun-indent)
783 (defun-point)
784 (regexp (if innermost
785 python-beginning-of-innermost-defun-regexp
786 python-beginning-of-defun-regexp)))
787 (back-to-indentation)
788 (if (and (not (looking-at "@"))
789 (not (looking-at regexp)))
790 (forward-comment -1)
791 (while (and (not (eobp))
792 (forward-line 1)
793 (not (back-to-indentation))
794 (looking-at "@"))))
795 (when (not (looking-at regexp))
796 (re-search-backward regexp nil t))
797 (setq nonblank-line-indent (+ (current-indentation) python-indent-offset))
798 (setq defun-indent (current-indentation))
799 (setq defun-point (point-marker))
800 (if (> nonblank-line-indent defun-indent)
801 (progn
802 (goto-char defun-point)
803 (forward-line -1)
804 (while (and (looking-at "@")
805 (forward-line -1)
806 (not (bobp))
807 (not (back-to-indentation))))
df700cc9
FEG
808 (unless (bobp)
809 (forward-line 1))
45c138ac
FEG
810 (point-marker))
811 (if innermost
812 (python-beginning-of-defun)
813 (goto-char starting-point)
814 nil))))
815
816(defun python-beginning-of-defun-function ()
817 "Move point to the beginning of outermost def or class.
818Returns nil if point is not in a def or class."
819 (python-beginning-of-defun nil))
820
821(defun python-beginning-of-innermost-defun ()
822 "Move point to the beginning of innermost def or class.
823Returns nil if point is not in a def or class."
824 (interactive)
825 (python-beginning-of-defun t))
826
827(defun python-end-of-defun-function ()
828 "Move point to the end of def or class.
829Returns nil if point is not in a def or class."
830 (let ((starting-point (point-marker))
831 (defun-regexp (python-rx defun))
832 (beg-defun-indent))
833 (back-to-indentation)
834 (if (looking-at "@")
835 (while (and (not (eobp))
836 (forward-line 1)
837 (not (back-to-indentation))
838 (looking-at "@")))
839 (while (and (not (bobp))
840 (not (progn (back-to-indentation) (current-word)))
841 (forward-line -1))))
842 (when (or (not (equal (current-indentation) 0))
843 (string-match defun-regexp (current-word)))
844 (setq beg-defun-indent (save-excursion
845 (or (looking-at defun-regexp)
846 (python-beginning-of-innermost-defun))
847 (current-indentation)))
848 (while (and (forward-line 1)
849 (not (eobp))
850 (or (not (current-word))
851 (> (current-indentation) beg-defun-indent))))
852 (while (and (forward-comment -1)
853 (not (bobp))))
854 (forward-line 1)
855 (point-marker))))
856
857\f
858;;; Shell integration
859
860(defvar python-shell-buffer-name "Python"
861 "Default buffer name for Python interpreter.")
862
863(defcustom python-shell-interpreter "python"
864 "Default Python interpreter for shell."
865 :group 'python
866 :type 'string
867 :safe 'stringp)
868
869(defcustom python-shell-interpreter-args "-i"
870 "Default arguments for the Python interpreter."
871 :group 'python
872 :type 'string
873 :safe 'stringp)
874
875(defcustom python-shell-prompt-regexp ">>> "
876 "Regex matching top\-level input prompt of python shell.
877The regex should not contain a caret (^) at the beginning."
878 :type 'string
879 :group 'python
880 :safe 'stringp)
881
882(defcustom python-shell-prompt-block-regexp "[.][.][.] "
883 "Regex matching block input prompt of python shell.
884The regex should not contain a caret (^) at the beginning."
885 :type 'string
886 :group 'python
887 :safe 'stringp)
888
889(defcustom python-shell-prompt-pdb-regexp "[(<]*[Ii]?[Pp]db[>)]+ "
890 "Regex matching pdb input prompt of python shell.
891The regex should not contain a caret (^) at the beginning."
892 :type 'string
893 :group 'python
894 :safe 'stringp)
895
896(defcustom python-shell-compilation-regexp-alist
897 `((,(rx line-start (1+ (any " \t")) "File \""
898 (group (1+ (not (any "\"<")))) ; avoid `<stdin>' &c
899 "\", line " (group (1+ digit)))
900 1 2)
901 (,(rx " in file " (group (1+ not-newline)) " on line "
902 (group (1+ digit)))
903 1 2)
904 (,(rx line-start "> " (group (1+ (not (any "(\"<"))))
905 "(" (group (1+ digit)) ")" (1+ (not (any "("))) "()")
906 1 2))
907 "`compilation-error-regexp-alist' for inferior Python."
908 :type '(alist string)
909 :group 'python)
910
911(defun python-shell-get-process-name (dedicated)
912 "Calculate the appropiate process name for inferior Python process.
913
914If DEDICATED is t and the variable `buffer-file-name' is non-nil
915returns a string with the form
916`python-shell-buffer-name'[variable `buffer-file-name'] else
917returns the value of `python-shell-buffer-name'.
918
919After calculating the process name add the buffer name for the
920process in the `same-window-buffer-names' list"
921 (let ((process-name
922 (if (and dedicated
923 buffer-file-name)
924 (format "%s[%s]" python-shell-buffer-name buffer-file-name)
925 (format "%s" python-shell-buffer-name))))
926 (add-to-list 'same-window-buffer-names (purecopy
927 (format "*%s*" process-name)))
928 process-name))
929
930(defun python-shell-parse-command ()
931 "Calculates the string used to execute the inferior Python process."
932 (format "%s %s" python-shell-interpreter python-shell-interpreter-args))
933
934(defun python-comint-output-filter-function (output)
935 "Hook run after content is put into comint buffer.
936OUTPUT is a string with the contents of the buffer."
937 (ansi-color-filter-apply output))
938
939(defvar inferior-python-mode-current-file nil
940 "Current file from which a region was sent.")
941(make-variable-buffer-local 'inferior-python-mode-current-file)
942
943(defvar inferior-python-mode-current-temp-file nil
944 "Current temp file sent to process.")
945(make-variable-buffer-local 'inferior-python-mode-current-file)
946
947(define-derived-mode inferior-python-mode comint-mode "Inferior Python"
948 "Major mode for Python inferior process."
949 (set-syntax-table python-mode-syntax-table)
950 (setq mode-line-process '(":%s"))
951 (setq comint-prompt-regexp (format "^\\(?:%s\\|%s\\|%s\\)"
952 python-shell-prompt-regexp
953 python-shell-prompt-block-regexp
954 python-shell-prompt-pdb-regexp))
955 (make-local-variable 'comint-output-filter-functions)
956 (add-hook 'comint-output-filter-functions
957 'python-comint-output-filter-function)
958 (add-hook 'comint-output-filter-functions
959 'python-pdbtrack-comint-output-filter-function)
960 (set (make-local-variable 'compilation-error-regexp-alist)
961 python-shell-compilation-regexp-alist)
ed0eb594
FEG
962 (define-key inferior-python-mode-map [remap complete-symbol]
963 'completion-at-point)
964 (add-hook 'completion-at-point-functions
965 'python-shell-completion-complete-at-point nil 'local)
45c138ac
FEG
966 (compilation-shell-minor-mode 1))
967
968(defun run-python (dedicated cmd)
969 "Run an inferior Python process.
970
971Input and output via buffer *\\[python-shell-buffer-name]*.
972
973If there is a process already running in
974*\\[python-shell-buffer-name]*, switch to that buffer.
975
976With argument, allows you to:
977
978 * Define DEDICATED so a dedicated process for the current buffer
979 is open.
980
981 * Define CMD so you can edit the command used to call the
982interpreter (default is value of `python-shell-interpreter' and
983arguments defined in `python-shell-interpreter-args').
984
985Runs the hook `inferior-python-mode-hook' (after the
986`comint-mode-hook' is run).
987
988\(Type \\[describe-mode] in the process buffer for a list of
989commands.)"
990 (interactive
991 (if current-prefix-arg
992 (list
993 (y-or-n-p "Make dedicated process? ")
994 (read-string "Run Python: " (python-shell-parse-command)))
995 (list nil (python-shell-parse-command))))
996 (let* ((proc-name (python-shell-get-process-name dedicated))
997 (proc-buffer-name (format "*%s*" proc-name)))
998 (when (not (comint-check-proc proc-buffer-name))
999 (let ((cmdlist (split-string-and-unquote cmd)))
1000 (set-buffer
1001 (apply 'make-comint proc-name (car cmdlist) nil
1002 (cdr cmdlist)))
1003 (inferior-python-mode)))
1004 (pop-to-buffer proc-buffer-name))
1005 dedicated)
1006
1007(defun python-shell-get-process ()
1008 "Get inferior Python process for current buffer and return it."
1009 (let* ((dedicated-proc-name (python-shell-get-process-name t))
1010 (dedicated-proc-buffer-name (format "*%s*" dedicated-proc-name))
1011 (global-proc-name (python-shell-get-process-name nil))
1012 (global-proc-buffer-name (format "*%s*" global-proc-name))
1013 (dedicated-running (comint-check-proc dedicated-proc-buffer-name))
1014 (global-running (comint-check-proc global-proc-buffer-name)))
1015 ;; Always prefer dedicated
1016 (get-buffer-process (or (and dedicated-running dedicated-proc-buffer-name)
1017 (and global-running global-proc-buffer-name)))))
1018
1019(defun python-shell-get-or-create-process ()
1020 "Get or create an inferior Python process for current buffer and return it."
79dafa51
FEG
1021 (let* ((old-buffer (current-buffer))
1022 (dedicated-proc-name (python-shell-get-process-name t))
45c138ac
FEG
1023 (dedicated-proc-buffer-name (format "*%s*" dedicated-proc-name))
1024 (global-proc-name (python-shell-get-process-name nil))
1025 (global-proc-buffer-name (format "*%s*" global-proc-name))
1026 (dedicated-running (comint-check-proc dedicated-proc-buffer-name))
1027 (global-running (comint-check-proc global-proc-buffer-name))
1028 (current-prefix-arg 4))
1029 (when (and (not dedicated-running) (not global-running))
1030 (if (call-interactively 'run-python)
1031 (setq dedicated-running t)
1032 (setq global-running t)))
1033 ;; Always prefer dedicated
79dafa51 1034 (switch-to-buffer old-buffer)
45c138ac
FEG
1035 (get-buffer-process (if dedicated-running
1036 dedicated-proc-buffer-name
1037 global-proc-buffer-name))))
1038
13d914ed 1039(defun python-shell-send-string (string &optional process)
138df813 1040 "Send STRING to inferior Python PROCESS."
45c138ac 1041 (interactive "sPython command: ")
13d914ed 1042 (let ((process (or process (python-shell-get-or-create-process))))
fc87f759 1043 (when (called-interactively-p 'interactive)
13d914ed 1044 (message (format "Sent: %s..." string)))
45c138ac
FEG
1045 (comint-send-string process string)
1046 (when (or (not (string-match "\n$" string))
1047 (string-match "\n[ \t].*\n?$" string))
1048 (comint-send-string process "\n"))))
1049
1050(defun python-shell-send-region (start end)
1051 "Send the region delimited by START and END to inferior Python process."
1052 (interactive "r")
1053 (let* ((contents (buffer-substring start end))
1054 (current-file (buffer-file-name))
1055 (process (python-shell-get-or-create-process))
66b0b492 1056 (temp-file (make-temp-file "py")))
45c138ac
FEG
1057 (with-temp-file temp-file
1058 (insert contents)
1059 (delete-trailing-whitespace)
1060 (goto-char (point-min))
1061 (message (format "Sent: %s..."
1062 (buffer-substring (point-min)
1063 (line-end-position)))))
6eb68dc2
FEG
1064 ;; Fix Windows/MS-DOS temp file path
1065 (when (or (eq system-type 'windows-nt)
1066 (eq system-type 'ms-dos)
1067 (eq system-type 'cygwin))
1068 (setq temp-file
1069 (with-temp-buffer
1070 (insert temp-file)
1071 (goto-char (point-min))
1072 (while (search-forward "/" nil t)
1073 (replace-match "\\" nil t))
1074 (buffer-substring (point-min) (point-max)))))
45c138ac
FEG
1075 (with-current-buffer (process-buffer process)
1076 (setq inferior-python-mode-current-file current-file)
66b0b492
FEG
1077 (setq inferior-python-mode-current-temp-file temp-file))
1078 (python-shell-send-file temp-file process)))
45c138ac
FEG
1079
1080(defun python-shell-send-buffer ()
1081 "Send the entire buffer to inferior Python process."
1082 (interactive)
1083 (save-restriction
1084 (widen)
1085 (python-shell-send-region (point-min) (point-max))))
1086
1087(defun python-shell-send-defun (arg)
1088 "Send the (inner|outer)most def or class to inferior Python process.
1089When argument ARG is non-nil sends the innermost defun."
1090 (interactive "P")
1091 (save-excursion
1092 (python-shell-send-region (progn
1093 (or (if arg
1094 (python-beginning-of-innermost-defun)
1095 (python-beginning-of-defun-function))
1096 (progn (beginning-of-line) (point-marker))))
1097 (progn
1098 (or (python-end-of-defun-function)
1099 (progn (end-of-line) (point-marker)))))))
1100
66b0b492 1101(defun python-shell-send-file (file-name &optional process)
4e531f7a 1102 "Send FILE-NAME to inferior Python PROCESS."
45c138ac 1103 (interactive "fFile to send: ")
b962ebad
FEG
1104 (let ((process (or process (python-shell-get-or-create-process)))
1105 (full-file-name (expand-file-name file-name)))
13d914ed 1106 (python-shell-send-string
b962ebad 1107 (format
13d914ed
FEG
1108 "__pyfile = open('%s'); exec(compile(__pyfile.read(), '%s', 'exec')); __pyfile.close()"
1109 full-file-name full-file-name)
1110 process)))
45c138ac 1111
138df813
FEG
1112(defun python-shell-clear-latest-output ()
1113 "Clear latest output from the Python shell.
1114Return the cleaned output."
1115 (interactive)
1116 (when (and comint-last-output-start
1117 comint-last-prompt-overlay)
1118 (save-excursion
1119 (let* ((last-output-end
1120 (save-excursion
1121 (goto-char
1122 (overlay-start comint-last-prompt-overlay))
1123 (forward-comment -1)
1124 (point-marker)))
1125 (last-output
1126 (buffer-substring-no-properties
1127 comint-last-output-start last-output-end)))
1128 (when (< 0 (length last-output))
1129 (goto-char comint-last-output-start)
1130 (delete-region comint-last-output-start last-output-end)
1131 (delete-char -1)
1132 last-output)))))
1133
1134(defun python-shell-send-and-clear-output (string process)
1135 "Send STRING to PROCESS and clear the output.
1136Return the cleaned output."
1137 (interactive)
1138 (python-shell-send-string string process)
1139 (accept-process-output process)
1140 (with-current-buffer (process-buffer process)
1141 (let ((output (python-shell-clear-latest-output)))
1142 (forward-line -1)
1143 (kill-whole-line)
1144 (goto-char (overlay-end comint-last-prompt-overlay))
1145 output)))
1146
45c138ac
FEG
1147(defun python-shell-switch-to-shell ()
1148 "Switch to inferior Python process buffer."
1149 (interactive)
1150 (pop-to-buffer (process-buffer (python-shell-get-or-create-process)) t))
1151
1152\f
1153;;; Shell completion
1154
1155(defvar python-shell-completion-setup-code
1156 "try:
1157 import readline
1158except ImportError:
1159 def __COMPLETER_all_completions(text): []
1160else:
1161 import rlcompleter
1162 readline.set_completer(rlcompleter.Completer().complete)
1163 def __COMPLETER_all_completions(text):
1164 import sys
1165 completions = []
1166 try:
1167 i = 0
1168 while True:
1169 res = readline.get_completer()(text, i)
1170 if not res: break
1171 i += 1
1172 completions.append(res)
1173 except NameError:
1174 pass
1175 return completions"
1176 "Code used to setup completion in inferior Python processes.")
1177
1178(defvar python-shell-completion-strings-code
1179 "';'.join(__COMPLETER_all_completions('''%s'''))\n"
1180 "Python code used to get a string of completions separated by semicolons.")
1181
1182(defun python-shell-completion-setup ()
1183 "Send `python-shell-completion-setup-code' to inferior Python process.
1184Also binds <tab> to `python-shell-complete-or-indent' in the
1185`inferior-python-mode-map' and adds
1186`python-shell-completion-complete-at-point' to the
1187`comint-dynamic-complete-functions' list.
1188It is specially designed to be added to the
1189`inferior-python-mode-hook'."
1190 (when python-shell-completion-setup-code
1191 (let ((temp-file (make-temp-file "py"))
1192 (process (get-buffer-process (current-buffer))))
1193 (with-temp-file temp-file
1194 (insert python-shell-completion-setup-code)
1195 (delete-trailing-whitespace)
1196 (goto-char (point-min)))
66b0b492 1197 (python-shell-send-file temp-file process)
45c138ac
FEG
1198 (message (format "Completion setup code sent.")))
1199 (add-to-list (make-local-variable
1200 'comint-dynamic-complete-functions)
1201 'python-shell-completion-complete-at-point)
1202 (define-key inferior-python-mode-map (kbd "<tab>")
1203 'python-shell-completion-complete-or-indent)))
1204
075a0f61
FEG
1205(defun python-shell-completion--get-completions (input process)
1206 "Retrieve available completions for INPUT using PROCESS."
1207 (with-current-buffer (process-buffer process)
138df813
FEG
1208 (split-string
1209 (or (python-shell-send-and-clear-output
1210 (format python-shell-completion-strings-code input)
1211 process) "")
1212 ";\\|\"\\|'\\|(" t)))
075a0f61
FEG
1213
1214(defun python-shell-completion--get-completion (input completions)
1215 "Get completion for INPUT using COMPLETIONS."
1216 (let ((completion (when completions
1217 (try-completion input completions))))
1218 (cond ((eq completion t)
1219 input)
1220 ((null completion)
1221 (message "Can't find completion for \"%s\"" input)
1222 (ding)
1223 input)
1224 ((not (string= input completion))
1225 completion)
1226 (t
1227 (message "Making completion list...")
1228 (with-output-to-temp-buffer "*Python Completions*"
1229 (display-completion-list
1230 (all-completions input completions)))
1231 input))))
1232
45c138ac
FEG
1233(defun python-shell-completion-complete-at-point ()
1234 "Perform completion at point in inferior Python process."
1235 (interactive)
3d6913c7
FEG
1236 (with-syntax-table python-dotty-syntax-table
1237 (when (and comint-last-prompt-overlay
1238 (> (point-marker) (overlay-end comint-last-prompt-overlay)))
1239 (let* ((process (get-buffer-process (current-buffer)))
075a0f61
FEG
1240 (input (substring-no-properties
1241 (or (comint-word (current-word)) "") nil nil)))
1242 (delete-char (- (length input)))
1243 (insert
1244 (python-shell-completion--get-completion
1245 input (python-shell-completion--get-completions input process)))))))
45c138ac 1246
45c138ac
FEG
1247(defun python-shell-completion-complete-or-indent ()
1248 "Complete or indent depending on the context.
1249If content before pointer is all whitespace indent. If not try to
1250complete."
1251 (interactive)
1252 (if (string-match "^[[:space:]]*$"
1253 (buffer-substring (comint-line-beginning-position)
1254 (point-marker)))
1255 (indent-for-tab-command)
1256 (comint-dynamic-complete)))
1257
1258(add-hook 'inferior-python-mode-hook
1259 #'python-shell-completion-setup)
1260
1261\f
1262;;; PDB Track integration
1263
1264(defvar python-pdbtrack-stacktrace-info-regexp
1265 "> %s(\\([0-9]+\\))\\([?a-zA-Z0-9_<>]+\\)()"
1266 "Regexp matching stacktrace information.
1267It is used to extract the current line and module beign
1268inspected.
1269The regexp should not start with a caret (^) and can contain a
1270string placeholder (\%s) which is replaced with the filename
1271beign inspected (so other files in the debugging process are not
1272opened)")
1273
1274(defvar python-pdbtrack-tracking-buffers '()
1275 "Alist containing elements of form (#<buffer> . #<buffer>).
1276The car of each element of the alist is the tracking buffer and
1277the cdr is the tracked buffer.")
1278
1279(defun python-pdbtrack-get-or-add-tracking-buffers ()
1280 "Get/Add a tracked buffer for the current buffer.
1281Internally it uses the `python-pdbtrack-tracking-buffers' alist.
1282Returns a cons with the form:
1283 * (#<tracking buffer> . #< tracked buffer>)."
1284 (or
1285 (assq (current-buffer) python-pdbtrack-tracking-buffers)
1286 (let* ((file (with-current-buffer (current-buffer)
1287 (or inferior-python-mode-current-file
1288 inferior-python-mode-current-temp-file)))
1289 (tracking-buffers
1290 `(,(current-buffer) .
1291 ,(or (get-file-buffer file)
1292 (find-file-noselect file)))))
1293 (set-buffer (cdr tracking-buffers))
1294 (python-mode)
1295 (set-buffer (car tracking-buffers))
1296 (setq python-pdbtrack-tracking-buffers
1297 (cons tracking-buffers python-pdbtrack-tracking-buffers))
1298 tracking-buffers)))
1299
1300(defun python-pdbtrack-comint-output-filter-function (output)
1301 "Move overlay arrow to current pdb line in tracked buffer.
1302Argument OUTPUT is a string with the output from the comint process."
1303 (when (not (string= output ""))
1304 (let ((full-output (ansi-color-filter-apply
1305 (buffer-substring comint-last-input-end
1306 (point-max)))))
1307 (if (string-match python-shell-prompt-pdb-regexp full-output)
1308 (let* ((tracking-buffers (python-pdbtrack-get-or-add-tracking-buffers))
1309 (line-num
1310 (save-excursion
1311 (string-match
1312 (format python-pdbtrack-stacktrace-info-regexp
1313 (regexp-quote
1314 inferior-python-mode-current-temp-file))
1315 full-output)
1316 (string-to-number (or (match-string-no-properties 1 full-output) ""))))
1317 (tracked-buffer-window (get-buffer-window (cdr tracking-buffers)))
1318 (tracked-buffer-line-pos))
1319 (when line-num
1320 (with-current-buffer (cdr tracking-buffers)
1321 (set (make-local-variable 'overlay-arrow-string) "=>")
1322 (set (make-local-variable 'overlay-arrow-position) (make-marker))
1323 (setq tracked-buffer-line-pos (progn
1324 (goto-char (point-min))
1325 (forward-line (1- line-num))
1326 (point-marker)))
1327 (when tracked-buffer-window
1328 (set-window-point tracked-buffer-window tracked-buffer-line-pos))
1329 (set-marker overlay-arrow-position tracked-buffer-line-pos)))
1330 (pop-to-buffer (cdr tracking-buffers))
1331 (switch-to-buffer-other-window (car tracking-buffers)))
1332 (let ((tracking-buffers (assq (current-buffer)
1333 python-pdbtrack-tracking-buffers)))
1334 (when tracking-buffers
1335 (if inferior-python-mode-current-file
1336 (with-current-buffer (cdr tracking-buffers)
1337 (set-marker overlay-arrow-position nil))
1338 (kill-buffer (cdr tracking-buffers)))
1339 (setq python-pdbtrack-tracking-buffers
1340 (assq-delete-all (current-buffer)
1341 python-pdbtrack-tracking-buffers)))))))
1342 output)
1343
1344\f
1345;;; Symbol completion
1346
1347(defun python-completion-complete-at-point ()
1348 "Complete current symbol at point.
1349For this to work the best as possible you should call
1350`python-shell-send-buffer' from time to time so context in
1351inferior python process is updated properly."
1352 (interactive)
1353 (let ((process (python-shell-get-process)))
1354 (if (not process)
4e531f7a 1355 (error "Completion needs an inferior Python process running")
075a0f61
FEG
1356 (with-syntax-table python-dotty-syntax-table
1357 (let* ((input (substring-no-properties
1358 (or (comint-word (current-word)) "") nil nil))
1359 (completions (python-shell-completion--get-completions
1360 input process)))
1361 (delete-char (- (length input)))
1362 (insert
1363 (python-shell-completion--get-completion
1364 input completions)))))))
45c138ac
FEG
1365
1366(add-to-list 'debug-ignored-errors "^Completion needs an inferior Python process running.")
1367
1368\f
1369;;; Fill paragraph
1370
1371(defun python-fill-paragraph-function (&optional justify)
1372 "`fill-paragraph-function' handling multi-line strings and possibly comments.
1373If any of the current line is in or at the end of a multi-line string,
1374fill the string or the paragraph of it that point is in, preserving
4e531f7a
FEG
1375the string's indentation.
1376Optional argument JUSTIFY defines if the paragraph should be justified."
45c138ac
FEG
1377 (interactive "P")
1378 (save-excursion
1379 (back-to-indentation)
1380 (cond
1381 ;; Comments
1382 ((fill-comment-paragraph justify))
1383 ;; Docstrings
1384 ((save-excursion (skip-chars-forward "\"'uUrR")
1385 (nth 3 (syntax-ppss)))
1386 (let ((marker (point-marker))
1387 (string-start-marker
1388 (progn
1389 (skip-chars-forward "\"'uUrR")
1390 (goto-char (nth 8 (syntax-ppss)))
1391 (skip-chars-forward "\"'uUrR")
1392 (point-marker)))
1393 (reg-start (line-beginning-position))
1394 (string-end-marker
1395 (progn
1396 (while (nth 3 (syntax-ppss)) (goto-char (1+ (point-marker))))
1397 (skip-chars-backward "\"'")
1398 (point-marker)))
1399 (reg-end (line-end-position))
1400 (fill-paragraph-function))
1401 (save-restriction
1402 (narrow-to-region reg-start reg-end)
1403 (save-excursion
1404 (goto-char string-start-marker)
1405 (delete-region (point-marker) (progn
1406 (skip-syntax-forward "> ")
1407 (point-marker)))
1408 (goto-char string-end-marker)
1409 (delete-region (point-marker) (progn
1410 (skip-syntax-backward "> ")
1411 (point-marker)))
1412 (save-excursion
1413 (goto-char marker)
1414 (fill-paragraph justify))
1415 ;; If there is a newline in the docstring lets put triple
1416 ;; quote in it's own line to follow pep 8
1417 (when (save-excursion
1418 (re-search-backward "\n" string-start-marker t))
1419 (newline)
1420 (newline-and-indent))
1421 (fill-paragraph justify)))) t)
1422 ;; Decorators
1423 ((equal (char-after (save-excursion
1424 (back-to-indentation)
1425 (point-marker))) ?@) t)
1426 ;; Parens
1427 ((or (> (nth 0 (syntax-ppss)) 0)
1428 (looking-at (python-rx open-paren))
1429 (save-excursion
1430 (skip-syntax-forward "^(" (line-end-position))
1431 (looking-at (python-rx open-paren))))
1432 (save-restriction
1433 (narrow-to-region (progn
1434 (while (> (nth 0 (syntax-ppss)) 0)
1435 (goto-char (1- (point-marker))))
1436 (point-marker)
1437 (line-beginning-position))
1438 (progn
1439 (when (not (> (nth 0 (syntax-ppss)) 0))
1440 (end-of-line)
1441 (when (not (> (nth 0 (syntax-ppss)) 0))
1442 (skip-syntax-backward "^)")))
1443 (while (> (nth 0 (syntax-ppss)) 0)
1444 (goto-char (1+ (point-marker))))
1445 (point-marker)))
1446 (let ((paragraph-start "\f\\|[ \t]*$")
1447 (paragraph-separate ",")
1448 (fill-paragraph-function))
1449 (goto-char (point-min))
1450 (fill-paragraph justify))
1451 (while (not (eobp))
1452 (forward-line 1)
1453 (python-indent-line)
1454 (goto-char (line-end-position)))) t)
1455 (t t))))
1456
1457\f
046428d3
FEG
1458;;; FFAP
1459
1460(defvar python-ffap-setup-code
1461 "def __FFAP_get_module_path(module):
1462 try:
1463 import os
1464 path = __import__(module).__file__
1465 if path[-4:] == '.pyc' and os.path.exists(path[0:-1]):
1466 path = path[:-1]
1467 return path
1468 except:
1469 return ''"
1470 "Python code to get a module path.")
1471
1472(defvar python-ffap-string-code
1473 "__FFAP_get_module_path('''%s''')\n"
1474 "Python code used to get a string with the path of a module.")
1475
1476(defun python-ffap-setup ()
1477 "Send `python-ffap-setup-code' to inferior Python process.
1478It is specially designed to be added to the
1479`inferior-python-mode-hook'."
1480 (when python-ffap-setup-code
1481 (let ((temp-file (make-temp-file "py")))
1482 (with-temp-file temp-file
1483 (insert python-ffap-setup-code)
1484 (delete-trailing-whitespace)
1485 (goto-char (point-min)))
1486 (python-shell-send-file temp-file (get-buffer-process (current-buffer)))
1487 (message (format "FFAP setup code sent.")))))
1488
1489(defun python-ffap-module-path (module)
1490 "Function for `ffap-alist' to return path for MODULE."
1491 (let ((process (or
1492 (and (eq major-mode 'inferior-python-mode)
1493 (get-buffer-process (current-buffer)))
1494 (python-shell-get-process))))
1495 (if (not process)
1496 nil
1497 (let ((module-file
1498 (python-shell-send-and-clear-output
1499 (format python-ffap-string-code module) process)))
1500 (when module-file
2947016a 1501 (substring-no-properties module-file 1 -1))))))
046428d3
FEG
1502
1503(eval-after-load "ffap"
1504 '(progn
1505 (push '(python-mode . python-ffap-module-path) ffap-alist)
1506 (push '(inferior-python-mode . python-ffap-module-path) ffap-alist)))
1507
1508(add-hook 'inferior-python-mode-hook
1509 #'python-ffap-setup)
1510
1511\f
8b3e0e76
FEG
1512;;; Code check
1513
1514(defvar python-check-command
1515 "pychecker --stdlib"
1516 "Command used to check a Python file.")
1517
1518(defvar python-check-custom-command nil
1519 "Internal use.")
1520
1521(defun python-check (command)
1522 "Check a Python file (default current buffer's file).
1523Runs COMMAND, a shell command, as if by `compile'. See
1524`python-check-command' for the default."
1525 (interactive
1526 (list (read-string "Check command: "
1527 (or python-check-custom-command
1528 (concat python-check-command " "
1529 (shell-quote-argument
1530 (or
1531 (let ((name (buffer-file-name)))
1532 (and name
1533 (file-name-nondirectory name)))
1534 "")))))))
1535 (setq python-check-custom-command command)
1536 (save-some-buffers (not compilation-ask-about-save) nil)
1537 (compilation-start command))
1538
1539\f
45c138ac
FEG
1540;;; Eldoc
1541
1542(defvar python-eldoc-setup-code
1543 "def __PYDOC_get_help(obj):
1544 try:
1545 import pydoc
9e662938
FEG
1546 if hasattr(obj, 'startswith'):
1547 obj = eval(obj, globals())
1548 doc = pydoc.getdoc(obj)
45c138ac 1549 except:
9e662938
FEG
1550 doc = ''
1551 try:
1552 exec('print doc')
1553 except SyntaxError:
1554 print(doc)"
45c138ac
FEG
1555 "Python code to setup documentation retrieval.")
1556
1557(defvar python-eldoc-string-code
9e662938 1558 "__PYDOC_get_help('''%s''')\n"
45c138ac
FEG
1559 "Python code used to get a string with the documentation of an object.")
1560
1561(defun python-eldoc-setup ()
1562 "Send `python-eldoc-setup-code' to inferior Python process.
1563It is specially designed to be added to the
1564`inferior-python-mode-hook'."
1565 (when python-eldoc-setup-code
1566 (let ((temp-file (make-temp-file "py")))
1567 (with-temp-file temp-file
1568 (insert python-eldoc-setup-code)
1569 (delete-trailing-whitespace)
1570 (goto-char (point-min)))
66b0b492 1571 (python-shell-send-file temp-file (get-buffer-process (current-buffer)))
046428d3 1572 (message (format "Eldoc setup code sent.")))))
45c138ac 1573
78334b43
FEG
1574(defun python-eldoc--get-doc-at-point (&optional force-input force-process)
1575 (let ((process (or force-process (python-shell-get-process))))
45c138ac
FEG
1576 (if (not process)
1577 "Eldoc needs an inferior Python process running."
1578 (let* ((current-defun (python-info-current-defun))
78334b43
FEG
1579 (input (or force-input
1580 (with-syntax-table python-dotty-syntax-table
1581 (if (not current-defun)
1582 (current-word)
1583 (concat current-defun "." (current-word))))))
45c138ac
FEG
1584 (ppss (syntax-ppss))
1585 (help (when (and input
1586 (not (string= input (concat current-defun ".")))
1587 (eq nil (nth 3 ppss))
1588 (eq nil (nth 4 ppss)))
1589 (when (string-match (concat
1590 (regexp-quote (concat current-defun "."))
1591 "self\\.") input)
1592 (with-temp-buffer
1593 (insert input)
1594 (goto-char (point-min))
1595 (forward-word)
1596 (forward-char)
1597 (delete-region (point-marker) (search-forward "self."))
1598 (setq input (buffer-substring (point-min) (point-max)))))
1066882c
FEG
1599 (python-shell-send-and-clear-output
1600 (format python-eldoc-string-code input) process))))
45c138ac
FEG
1601 (with-current-buffer (process-buffer process)
1602 (when comint-last-prompt-overlay
1603 (delete-region comint-last-input-end
1604 (overlay-start comint-last-prompt-overlay))))
1605 (when (and help
1606 (not (string= help "\n")))
1607 help)))))
1608
78334b43
FEG
1609(defun python-eldoc-function ()
1610 "`eldoc-documentation-function' for Python.
1611For this to work the best as possible you should call
1612`python-shell-send-buffer' from time to time so context in
1613inferior python process is updated properly."
1614 (python-eldoc--get-doc-at-point))
1615
1616(defun python-eldoc-at-point (symbol)
1617 "Get help on SYMBOL using `help'.
1618Interactively, prompt for symbol."
1619 (interactive
1620 (let ((symbol (with-syntax-table python-dotty-syntax-table
1621 (current-word)))
1622 (enable-recursive-minibuffers t))
1623 (list (read-string (if symbol
1624 (format "Describe symbol (default %s): " symbol)
1625 "Describe symbol: ")
1626 nil nil symbol))))
1627 (let ((process (python-shell-get-process)))
1628 (if (not process)
1629 (message "Eldoc needs an inferior Python process running.")
1630 (let ((temp-buffer-show-hook
1631 (lambda ()
1632 (toggle-read-only 1)
1633 (setq view-return-to-alist
1634 (list (cons (selected-window) help-return-method))))))
1635 (with-output-to-temp-buffer (help-buffer)
1636 (with-current-buffer standard-output
1637 (insert
1638 (python-eldoc--get-doc-at-point symbol process))
1639 (help-print-return-message)))))))
1640
45c138ac
FEG
1641(add-hook 'inferior-python-mode-hook
1642 #'python-eldoc-setup)
1643
1644\f
1645;;; Misc helpers
1646
1647(defun python-info-current-defun ()
1648 "Return name of surrounding function with Python compatible dotty syntax.
1649This function is compatible to be used as
1650`add-log-current-defun-function' since it returns nil if point is
1651not inside a defun."
1652 (let ((names '()))
1653 (save-restriction
1654 (widen)
1655 (save-excursion
1656 (beginning-of-line)
1657 (when (not (>= (current-indentation) python-indent-offset))
1658 (while (and (not (eobp)) (forward-comment 1))))
1659 (while (and (not (equal 0 (current-indentation)))
1660 (python-beginning-of-innermost-defun))
1661 (back-to-indentation)
1662 (looking-at "\\(?:def\\|class\\) +\\([^(]+\\)[^:]+:\\s-*\n")
1663 (setq names (cons (match-string-no-properties 1) names)))))
1664 (when names
1665 (mapconcat (lambda (string) string) names "."))))
1666
1667(defun python-info-closing-block ()
1668 "Return the point of the block that the current line closes."
1669 (let ((closing-word (save-excursion
1670 (back-to-indentation)
1671 (current-word)))
1672 (indentation (current-indentation)))
1673 (when (member closing-word python-indent-dedenters)
1674 (save-excursion
1675 (forward-line -1)
1676 (while (and (> (current-indentation) indentation)
1677 (not (bobp))
1678 (not (back-to-indentation))
1679 (forward-line -1)))
1680 (back-to-indentation)
1681 (cond
1682 ((not (equal indentation (current-indentation))) nil)
1683 ((string= closing-word "elif")
1684 (when (member (current-word) '("if" "elif"))
1685 (point-marker)))
1686 ((string= closing-word "else")
1687 (when (member (current-word) '("if" "elif" "except" "for" "while"))
1688 (point-marker)))
1689 ((string= closing-word "except")
1690 (when (member (current-word) '("try"))
1691 (point-marker)))
1692 ((string= closing-word "finally")
1693 (when (member (current-word) '("except" "else"))
1694 (point-marker))))))))
1695
1696(defun python-info-line-ends-backslash-p ()
1697 "Return non-nil if current line ends with backslash."
1698 (string= (or (ignore-errors
1699 (buffer-substring
1700 (line-end-position)
1701 (- (line-end-position) 1))) "") "\\"))
1702
1703(defun python-info-continuation-line-p ()
1704 "Return non-nil if current line is continuation of another."
1705 (or (python-info-line-ends-backslash-p)
1706 (string-match ",[[:space:]]*$" (buffer-substring
1707 (line-beginning-position)
1708 (line-end-position)))
1709 (save-excursion
1710 (let ((innermost-paren (progn
1711 (goto-char (line-end-position))
1712 (nth 1 (syntax-ppss)))))
1713 (when (and innermost-paren
1714 (and (<= (line-beginning-position) innermost-paren)
1715 (>= (line-end-position) innermost-paren)))
1716 (goto-char innermost-paren)
1717 (looking-at (python-rx open-paren (* space) line-end)))))
1718 (save-excursion
1719 (back-to-indentation)
1720 (nth 1 (syntax-ppss)))))
1721
1722(defun python-info-block-continuation-line-p ()
1723 "Return non-nil if current line is a continuation of a block."
1724 (save-excursion
1725 (while (and (not (bobp))
1726 (python-info-continuation-line-p))
1727 (forward-line -1))
1728 (forward-line 1)
1729 (back-to-indentation)
1730 (when (looking-at (python-rx block-start))
1731 (point-marker))))
1732
1733(defun python-info-assignment-continuation-line-p ()
1734 "Return non-nil if current line is a continuation of an assignment."
1735 (save-excursion
1736 (while (and (not (bobp))
1737 (python-info-continuation-line-p))
1738 (forward-line -1))
1739 (forward-line 1)
1740 (back-to-indentation)
1741 (when (and (not (looking-at (python-rx block-start)))
1742 (save-excursion
1743 (and (re-search-forward (python-rx not-simple-operator
1744 assignment-operator
1745 not-simple-operator)
1746 (line-end-position) t)
1747 (not (syntax-ppss-context (syntax-ppss))))))
1748 (point-marker))))
1749
1750\f
1751;;;###autoload
1752(define-derived-mode python-mode fundamental-mode "Python"
1753 "A major mode for editing Python files."
1754 (set (make-local-variable 'tab-width) 8)
1755 (set (make-local-variable 'indent-tabs-mode) nil)
1756
1757 (set (make-local-variable 'comment-start) "# ")
1758 (set (make-local-variable 'comment-start-skip) "#+\\s-*")
1759
1760 (set (make-local-variable 'parse-sexp-lookup-properties) t)
1761 (set (make-local-variable 'parse-sexp-ignore-comments) t)
1762
1763 (set (make-local-variable 'font-lock-defaults)
1764 '(python-font-lock-keywords
1765 nil nil nil nil
1766 (font-lock-syntactic-keywords . python-font-lock-syntactic-keywords)))
1767
1768 (set (make-local-variable 'indent-line-function) #'python-indent-line-function)
1769 (set (make-local-variable 'indent-region-function) #'python-indent-region)
1770
1771 (set (make-local-variable 'paragraph-start) "\\s-*$")
1772 (set (make-local-variable 'fill-paragraph-function) 'python-fill-paragraph-function)
1773
1774 (set (make-local-variable 'beginning-of-defun-function)
1775 #'python-beginning-of-defun-function)
1776 (set (make-local-variable 'end-of-defun-function)
1777 #'python-end-of-defun-function)
1778
1779 (add-hook 'completion-at-point-functions
1780 'python-completion-complete-at-point nil 'local)
1781
1782 (set (make-local-variable 'add-log-current-defun-function)
1783 #'python-info-current-defun)
1784
1785 (set (make-local-variable 'eldoc-documentation-function)
1786 #'python-eldoc-function)
1787
1788 (add-to-list 'hs-special-modes-alist
1789 `(python-mode "^\\s-*\\(?:def\\|class\\)\\>" nil "#"
1790 ,(lambda (arg)
1791 (python-end-of-defun-function)) nil))
1792
1793 (set (make-local-variable 'outline-regexp)
1794 (python-rx (* space) block-start))
1795 (set (make-local-variable 'outline-heading-end-regexp) ":\\s-*\n")
1796 (set (make-local-variable 'outline-level)
1797 #'(lambda ()
1798 "`outline-level' function for Python mode."
1799 (1+ (/ (current-indentation) python-indent-offset))))
1800
1801 (when python-indent-guess-indent-offset
1802 (python-indent-guess-indent-offset)))
1803
1804
1805(provide 'python)
1806;;; python.el ends here