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