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