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