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