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