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