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