Indentation enhancements on after-backslash
[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)
9787f829
FEG
684 (if (not
685 (save-excursion
686 (back-to-indentation)
687 (looking-at
688 "\\(?:return\\|from\\|import\\)\s+")))
107c2439
FEG
689 (current-indentation)
690 (+ (current-indentation)
9787f829
FEG
691 (length
692 (match-string-no-properties 0))))))))
45c138ac
FEG
693 indentation))
694 ('inside-paren
17d13b85 695 (or (save-excursion
f8994527 696 (skip-syntax-forward "\s" (line-end-position))
f9471190
FEG
697 (when (and (looking-at (regexp-opt '(")" "]" "}")))
698 (not (forward-char 1))
699 (not (python-info-ppss-context 'paren)))
17d13b85
FEG
700 (goto-char context-start)
701 (back-to-indentation)
702 (current-column)))
703 (-
704 (save-excursion
705 (goto-char context-start)
706 (forward-char)
707 (save-restriction
708 (narrow-to-region
709 (line-beginning-position)
710 (line-end-position))
589cefd7 711 (forward-comment 9999))
17d13b85
FEG
712 (if (looking-at "$")
713 (+ (current-indentation) python-indent-offset)
589cefd7 714 (forward-comment 9999)
17d13b85
FEG
715 (current-column)))
716 (if (progn
717 (back-to-indentation)
718 (looking-at (regexp-opt '(")" "]" "}"))))
719 python-indent-offset
720 0)))))))))
45c138ac
FEG
721
722(defun python-indent-calculate-levels ()
723 "Calculate `python-indent-levels' and reset `python-indent-current-level'."
724 (let* ((indentation (python-indent-calculate-indentation))
725 (remainder (% indentation python-indent-offset))
726 (steps (/ (- indentation remainder) python-indent-offset)))
65e4f764 727 (setq python-indent-levels (list 0))
45c138ac 728 (dotimes (step steps)
65e4f764 729 (push (* python-indent-offset (1+ step)) python-indent-levels))
45c138ac 730 (when (not (eq 0 remainder))
65e4f764 731 (push (+ (* python-indent-offset steps) remainder) python-indent-levels))
45c138ac
FEG
732 (setq python-indent-levels (nreverse python-indent-levels))
733 (setq python-indent-current-level (1- (length python-indent-levels)))))
734
735(defun python-indent-toggle-levels ()
736 "Toggle `python-indent-current-level' over `python-indent-levels'."
737 (setq python-indent-current-level (1- python-indent-current-level))
738 (when (< python-indent-current-level 0)
739 (setq python-indent-current-level (1- (length python-indent-levels)))))
740
741(defun python-indent-line (&optional force-toggle)
742 "Internal implementation of `python-indent-line-function'.
45c138ac
FEG
743Uses the offset calculated in
744`python-indent-calculate-indentation' and available levels
e2d8d479
FEG
745indicated by the variable `python-indent-levels' to set the
746current indentation.
45c138ac
FEG
747
748When the variable `last-command' is equal to
e2d8d479
FEG
749`indent-for-tab-command' or FORCE-TOGGLE is non-nil it cycles
750levels indicated in the variable `python-indent-levels' by
751setting the current level in the variable
752`python-indent-current-level'.
45c138ac
FEG
753
754When the variable `last-command' is not equal to
e2d8d479
FEG
755`indent-for-tab-command' and FORCE-TOGGLE is nil it calculates
756possible indentation levels and saves it in the variable
757`python-indent-levels'. Afterwards it sets the variable
758`python-indent-current-level' correctly so offset is equal
759to (`nth' `python-indent-current-level' `python-indent-levels')"
45c138ac
FEG
760 (if (or (and (eq this-command 'indent-for-tab-command)
761 (eq last-command this-command))
762 force-toggle)
86f1889a
FEG
763 (if (not (equal python-indent-levels '(0)))
764 (python-indent-toggle-levels)
765 (python-indent-calculate-levels))
45c138ac
FEG
766 (python-indent-calculate-levels))
767 (beginning-of-line)
768 (delete-horizontal-space)
769 (indent-to (nth python-indent-current-level python-indent-levels))
770 (save-restriction
771 (widen)
772 (let ((closing-block-point (python-info-closing-block)))
773 (when closing-block-point
774 (message "Closes %s" (buffer-substring
775 closing-block-point
776 (save-excursion
777 (goto-char closing-block-point)
778 (line-end-position))))))))
779
780(defun python-indent-line-function ()
781 "`indent-line-function' for Python mode.
e2d8d479 782See `python-indent-line' for details."
45c138ac
FEG
783 (python-indent-line))
784
785(defun python-indent-dedent-line ()
e2d8d479 786 "De-indent current line."
45c138ac 787 (interactive "*")
14a78495
FEG
788 (when (and (not (or (python-info-ppss-context 'string)
789 (python-info-ppss-context 'comment)))
45c138ac
FEG
790 (<= (point-marker) (save-excursion
791 (back-to-indentation)
792 (point-marker)))
793 (> (current-column) 0))
794 (python-indent-line t)
795 t))
796
797(defun python-indent-dedent-line-backspace (arg)
e2d8d479 798 "De-indent current line.
45c138ac 799Argument ARG is passed to `backward-delete-char-untabify' when
e2d8d479 800point is not in between the indentation."
45c138ac
FEG
801 (interactive "*p")
802 (when (not (python-indent-dedent-line))
803 (backward-delete-char-untabify arg)))
183f9296 804(put 'python-indent-dedent-line-backspace 'delete-selection 'supersede)
45c138ac
FEG
805
806(defun python-indent-region (start end)
807 "Indent a python region automagically.
808
809Called from a program, START and END specify the region to indent."
cb42456f
FEG
810 (let ((deactivate-mark nil))
811 (save-excursion
812 (goto-char end)
813 (setq end (point-marker))
814 (goto-char start)
815 (or (bolp) (forward-line 1))
816 (while (< (point) end)
817 (or (and (bolp) (eolp))
818 (let (word)
819 (forward-line -1)
820 (back-to-indentation)
821 (setq word (current-word))
822 (forward-line 1)
823 (when word
824 (beginning-of-line)
825 (delete-horizontal-space)
826 (indent-to (python-indent-calculate-indentation)))))
827 (forward-line 1))
828 (move-marker end nil))))
45c138ac
FEG
829
830(defun python-indent-shift-left (start end &optional count)
831 "Shift lines contained in region START END by COUNT columns to the left.
e2d8d479
FEG
832COUNT defaults to `python-indent-offset'. If region isn't
833active, the current line is shifted. The shifted region includes
834the lines in which START and END lie. An error is signaled if
835any lines in the region are indented less than COUNT columns."
45c138ac
FEG
836 (interactive
837 (if mark-active
838 (list (region-beginning) (region-end) current-prefix-arg)
839 (list (line-beginning-position) (line-end-position) current-prefix-arg)))
840 (if count
841 (setq count (prefix-numeric-value count))
842 (setq count python-indent-offset))
843 (when (> count 0)
cb42456f
FEG
844 (let ((deactivate-mark nil))
845 (save-excursion
846 (goto-char start)
847 (while (< (point) end)
848 (if (and (< (current-indentation) count)
849 (not (looking-at "[ \t]*$")))
850 (error "Can't shift all lines enough"))
851 (forward-line))
852 (indent-rigidly start end (- count))))))
45c138ac
FEG
853
854(add-to-list 'debug-ignored-errors "^Can't shift all lines enough")
855
856(defun python-indent-shift-right (start end &optional count)
857 "Shift lines contained in region START END by COUNT columns to the left.
e2d8d479
FEG
858COUNT defaults to `python-indent-offset'. If region isn't
859active, the current line is shifted. The shifted region includes
860the lines in which START and END lie."
45c138ac
FEG
861 (interactive
862 (if mark-active
863 (list (region-beginning) (region-end) current-prefix-arg)
864 (list (line-beginning-position) (line-end-position) current-prefix-arg)))
cb42456f
FEG
865 (let ((deactivate-mark nil))
866 (if count
867 (setq count (prefix-numeric-value count))
868 (setq count python-indent-offset))
869 (indent-rigidly start end count)))
45c138ac 870
ffdb56c3 871(defun python-indent-electric-colon (arg)
e2d8d479
FEG
872 "Insert a colon and maybe de-indent the current line.
873With numeric ARG, just insert that many colons. With
874\\[universal-argument], just insert a single colon."
ffdb56c3
FEG
875 (interactive "*P")
876 (self-insert-command (if (not (integerp arg)) 1 arg))
c43cd8b1
FEG
877 (when (and (not arg)
878 (eolp)
879 (not (equal ?: (char-after (- (point-marker) 2))))
880 (not (or (python-info-ppss-context 'string)
881 (python-info-ppss-context 'comment))))
882 (let ((indentation (current-indentation))
883 (calculated-indentation (python-indent-calculate-indentation)))
884 (when (> indentation calculated-indentation)
885 (save-excursion
886 (indent-line-to calculated-indentation)
887 (when (not (python-info-closing-block))
888 (indent-line-to indentation)))))))
ffdb56c3
FEG
889(put 'python-indent-electric-colon 'delete-selection t)
890
45c138ac
FEG
891\f
892;;; Navigation
893
0567effb 894(defvar python-nav-beginning-of-defun-regexp
af5c1beb
FEG
895 (python-rx line-start (* space) defun (+ space) (group symbol-name))
896 "Regular expresion matching beginning of class or function.
fc2dc7df
FEG
897The name of the defun should be grouped so it can be retrieved
898via `match-string'.")
45c138ac 899
6b432853 900(defun python-nav-beginning-of-defun (&optional nodecorators)
053a6c72 901 "Move point to `beginning-of-defun'.
6b432853
FEG
902When NODECORATORS is non-nil decorators are not included. This
903is the main part of`python-beginning-of-defun-function'
74d7b605 904implementation. Return non-nil if point is moved to the
fc2dc7df 905`beginning-of-defun'."
0567effb
FEG
906 (let ((indent-pos (save-excursion
907 (back-to-indentation)
908 (point-marker)))
74d7b605 909 (found)
0567effb
FEG
910 (include-decorators
911 (lambda ()
6b432853
FEG
912 (when (not nodecorators)
913 (when (save-excursion
914 (forward-line -1)
915 (looking-at (python-rx decorator)))
916 (while (and (not (bobp))
917 (forward-line -1)
918 (looking-at (python-rx decorator))))
919 (when (not (bobp)) (forward-line 1)))))))
0567effb
FEG
920 (if (and (> (point) indent-pos)
921 (save-excursion
922 (goto-char (line-beginning-position))
923 (looking-at python-nav-beginning-of-defun-regexp)))
45c138ac 924 (progn
0567effb 925 (goto-char (line-beginning-position))
74d7b605
FEG
926 (funcall include-decorators)
927 (setq found t))
0567effb 928 (goto-char (line-beginning-position))
74d7b605
FEG
929 (when (re-search-backward python-nav-beginning-of-defun-regexp nil t)
930 (setq found t))
0567effb 931 (goto-char (or (python-info-ppss-context 'string) (point)))
74d7b605
FEG
932 (funcall include-decorators))
933 found))
0567effb 934
6b432853 935(defun python-beginning-of-defun-function (&optional arg nodecorators)
0567effb
FEG
936 "Move point to the beginning of def or class.
937With positive ARG move that number of functions forward. With
6b432853 938negative do the same but backwards. When NODECORATORS is non-nil
74d7b605 939decorators are not included. Return non-nil if point is moved to the
fc2dc7df 940`beginning-of-defun'."
0567effb
FEG
941 (when (or (null arg) (= arg 0)) (setq arg 1))
942 (if (> arg 0)
74d7b605
FEG
943 (dotimes (i arg (python-nav-beginning-of-defun nodecorators)))
944 (let ((found))
945 (dotimes (i (- arg) found)
946 (python-end-of-defun-function)
589cefd7 947 (forward-comment 9999)
74d7b605
FEG
948 (goto-char (line-end-position))
949 (when (not (eobp))
950 (setq found
951 (python-nav-beginning-of-defun nodecorators)))))))
45c138ac
FEG
952
953(defun python-end-of-defun-function ()
954 "Move point to the end of def or class.
955Returns nil if point is not in a def or class."
0567effb
FEG
956 (interactive)
957 (let ((beg-defun-indent)
958 (decorator-regexp "[[:space:]]*@"))
959 (when (looking-at decorator-regexp)
960 (while (and (not (eobp))
961 (forward-line 1)
962 (looking-at decorator-regexp))))
963 (when (not (looking-at python-nav-beginning-of-defun-regexp))
964 (python-beginning-of-defun-function))
965 (setq beg-defun-indent (current-indentation))
966 (forward-line 1)
967 (while (and (forward-line 1)
968 (not (eobp))
969 (or (not (current-word))
970 (> (current-indentation) beg-defun-indent))))
589cefd7 971 (forward-comment 9999)
0567effb 972 (goto-char (line-beginning-position))))
45c138ac 973
3697b531
FEG
974(defun python-nav-sentence-start ()
975 "Move to start of current sentence."
976 (interactive "^")
977 (while (and (not (back-to-indentation))
978 (not (bobp))
979 (when (or
980 (save-excursion
981 (forward-line -1)
982 (python-info-line-ends-backslash-p))
9fff1858 983 (python-info-ppss-context 'string)
3697b531
FEG
984 (python-info-ppss-context 'paren))
985 (forward-line -1)))))
986
987(defun python-nav-sentence-end ()
988 "Move to end of current sentence."
989 (interactive "^")
990 (while (and (goto-char (line-end-position))
991 (not (eobp))
992 (when (or
993 (python-info-line-ends-backslash-p)
9fff1858 994 (python-info-ppss-context 'string)
3697b531
FEG
995 (python-info-ppss-context 'paren))
996 (forward-line 1)))))
997
9fff1858 998(defun python-nav-backward-sentence (&optional arg)
4cafacb5 999 "Move backward to start of sentence. With ARG, do it arg times.
9fff1858
FEG
1000See `python-nav-forward-sentence' for more information."
1001 (interactive "^p")
1002 (or arg (setq arg 1))
1003 (python-nav-forward-sentence (- arg)))
1004
1005(defun python-nav-forward-sentence (&optional arg)
4cafacb5 1006 "Move forward to next end of sentence. With ARG, repeat.
9fff1858
FEG
1007With negative argument, move backward repeatedly to start of sentence."
1008 (interactive "^p")
1009 (or arg (setq arg 1))
1010 (while (> arg 0)
1011 (forward-comment 9999)
1012 (python-nav-sentence-end)
1013 (forward-line 1)
1014 (setq arg (1- arg)))
1015 (while (< arg 0)
1016 (python-nav-sentence-end)
1017 (forward-comment -9999)
1018 (python-nav-sentence-start)
1019 (forward-line -1)
1020 (setq arg (1+ arg))))
1021
45c138ac
FEG
1022\f
1023;;; Shell integration
1024
1025(defvar python-shell-buffer-name "Python"
1026 "Default buffer name for Python interpreter.")
1027
1028(defcustom python-shell-interpreter "python"
1029 "Default Python interpreter for shell."
45c138ac 1030 :type 'string
c0428ba0 1031 :group 'python
45c138ac
FEG
1032 :safe 'stringp)
1033
1034(defcustom python-shell-interpreter-args "-i"
1035 "Default arguments for the Python interpreter."
45c138ac 1036 :type 'string
c0428ba0 1037 :group 'python
45c138ac
FEG
1038 :safe 'stringp)
1039
1040(defcustom python-shell-prompt-regexp ">>> "
e2d8d479
FEG
1041 "Regular Expression matching top\-level input prompt of python shell.
1042It should not contain a caret (^) at the beginning."
45c138ac
FEG
1043 :type 'string
1044 :group 'python
1045 :safe 'stringp)
1046
1047(defcustom python-shell-prompt-block-regexp "[.][.][.] "
e2d8d479
FEG
1048 "Regular Expression matching block input prompt of python shell.
1049It should not contain a caret (^) at the beginning."
45c138ac
FEG
1050 :type 'string
1051 :group 'python
1052 :safe 'stringp)
1053
62feb915 1054(defcustom python-shell-prompt-output-regexp nil
e2d8d479
FEG
1055 "Regular Expression matching output prompt of python shell.
1056It should not contain a caret (^) at the beginning."
62feb915
FEG
1057 :type 'string
1058 :group 'python
1059 :safe 'stringp)
1060
45c138ac 1061(defcustom python-shell-prompt-pdb-regexp "[(<]*[Ii]?[Pp]db[>)]+ "
e2d8d479
FEG
1062 "Regular Expression matching pdb input prompt of python shell.
1063It should not contain a caret (^) at the beginning."
45c138ac
FEG
1064 :type 'string
1065 :group 'python
1066 :safe 'stringp)
1067
30e429dd
FEG
1068(defcustom python-shell-send-setup-max-wait 5
1069 "Seconds to wait for process output before code setup.
1070If output is received before the especified time then control is
1071returned in that moment and not after waiting."
1072 :type 'number
1073 :group 'python
1074 :safe 'numberp)
1075
66bbb27f
FEG
1076(defcustom python-shell-process-environment nil
1077 "List of enviroment variables for Python shell.
1078This variable follows the same rules as `process-enviroment'
1079since it merges with it before the process creation routines are
1080called. When this variable is nil, the Python shell is run with
1081the default `process-enviroment'."
1082 :type '(repeat string)
1083 :group 'python
1084 :safe 'listp)
1085
1086(defcustom python-shell-exec-path nil
1087 "List of path to search for binaries.
1088This variable follows the same rules as `exec-path' since it
1089merges with it before the process creation routines are called.
1090When this variable is nil, the Python shell is run with the
1091default `exec-path'."
1092 :type '(repeat string)
1093 :group 'python
1094 :safe 'listp)
1095
c0428ba0
FEG
1096(defcustom python-shell-setup-codes '(python-shell-completion-setup-code
1097 python-ffap-setup-code
1098 python-eldoc-setup-code)
1099 "List of code run by `python-shell-send-setup-codes'.
e2d8d479 1100Each variable can contain either a simple string with the code to
c0428ba0
FEG
1101execute or a cons with the form (CODE . DESCRIPTION), where CODE
1102is a string with the code to execute and DESCRIPTION is the
1103description of it."
1104 :type '(repeat symbol)
1105 :group 'python
1106 :safe 'listp)
1107
45c138ac
FEG
1108(defcustom python-shell-compilation-regexp-alist
1109 `((,(rx line-start (1+ (any " \t")) "File \""
1110 (group (1+ (not (any "\"<")))) ; avoid `<stdin>' &c
1111 "\", line " (group (1+ digit)))
1112 1 2)
1113 (,(rx " in file " (group (1+ not-newline)) " on line "
1114 (group (1+ digit)))
1115 1 2)
1116 (,(rx line-start "> " (group (1+ (not (any "(\"<"))))
1117 "(" (group (1+ digit)) ")" (1+ (not (any "("))) "()")
1118 1 2))
1119 "`compilation-error-regexp-alist' for inferior Python."
1120 :type '(alist string)
1121 :group 'python)
1122
1123(defun python-shell-get-process-name (dedicated)
1124 "Calculate the appropiate process name for inferior Python process.
45c138ac
FEG
1125If DEDICATED is t and the variable `buffer-file-name' is non-nil
1126returns a string with the form
1127`python-shell-buffer-name'[variable `buffer-file-name'] else
e2d8d479
FEG
1128returns the value of `python-shell-buffer-name'. After
1129calculating the process name adds the buffer name for the process
1130in the `same-window-buffer-names' list."
45c138ac
FEG
1131 (let ((process-name
1132 (if (and dedicated
1133 buffer-file-name)
1134 (format "%s[%s]" python-shell-buffer-name buffer-file-name)
1135 (format "%s" python-shell-buffer-name))))
1136 (add-to-list 'same-window-buffer-names (purecopy
1137 (format "*%s*" process-name)))
1138 process-name))
1139
1140(defun python-shell-parse-command ()
e2d8d479 1141 "Calculate the string used to execute the inferior Python process."
45c138ac
FEG
1142 (format "%s %s" python-shell-interpreter python-shell-interpreter-args))
1143
1144(defun python-comint-output-filter-function (output)
1145 "Hook run after content is put into comint buffer.
1146OUTPUT is a string with the contents of the buffer."
1147 (ansi-color-filter-apply output))
1148
1149(defvar inferior-python-mode-current-file nil
1150 "Current file from which a region was sent.")
1151(make-variable-buffer-local 'inferior-python-mode-current-file)
1152
45c138ac 1153(define-derived-mode inferior-python-mode comint-mode "Inferior Python"
62feb915 1154 "Major mode for Python inferior process.
e2d8d479
FEG
1155Runs a Python interpreter as a subprocess of Emacs, with Python
1156I/O through an Emacs buffer. Variables
1157`python-shell-interpreter' and `python-shell-interpreter-args'
1158controls which Python interpreter is run. Variables
1159`python-shell-prompt-regexp',
1160`python-shell-prompt-output-regexp',
1161`python-shell-prompt-block-regexp',
1162`python-shell-completion-setup-code',
1163`python-shell-completion-string-code', `python-eldoc-setup-code',
1164`python-eldoc-string-code', `python-ffap-setup-code' and
1165`python-ffap-string-code' can customize this mode for different
1166Python interpreters.
1167
1168You can also add additional setup code to be run at
1169initialization of the interpreter via `python-shell-setup-codes'
1170variable.
1171
1172\(Type \\[describe-mode] in the process buffer for a list of commands.)"
45c138ac
FEG
1173 (set-syntax-table python-mode-syntax-table)
1174 (setq mode-line-process '(":%s"))
1175 (setq comint-prompt-regexp (format "^\\(?:%s\\|%s\\|%s\\)"
1176 python-shell-prompt-regexp
1177 python-shell-prompt-block-regexp
1178 python-shell-prompt-pdb-regexp))
1179 (make-local-variable 'comint-output-filter-functions)
1180 (add-hook 'comint-output-filter-functions
1181 'python-comint-output-filter-function)
1182 (add-hook 'comint-output-filter-functions
1183 'python-pdbtrack-comint-output-filter-function)
1184 (set (make-local-variable 'compilation-error-regexp-alist)
1185 python-shell-compilation-regexp-alist)
ed0eb594
FEG
1186 (define-key inferior-python-mode-map [remap complete-symbol]
1187 'completion-at-point)
1188 (add-hook 'completion-at-point-functions
1189 'python-shell-completion-complete-at-point nil 'local)
62feb915
FEG
1190 (add-to-list (make-local-variable 'comint-dynamic-complete-functions)
1191 'python-shell-completion-complete-at-point)
1192 (define-key inferior-python-mode-map (kbd "<tab>")
1193 'python-shell-completion-complete-or-indent)
45c138ac
FEG
1194 (compilation-shell-minor-mode 1))
1195
1196(defun run-python (dedicated cmd)
1197 "Run an inferior Python process.
e2d8d479
FEG
1198Input and output via buffer named after
1199`python-shell-buffer-name'. If there is a process already
1200running in that buffer, just switch to it.
1201With argument, allows you to define DEDICATED, so a dedicated
1202process for the current buffer is open, and define CMD so you can
1203edit the command used to call the interpreter (default is value
1204of `python-shell-interpreter' and arguments defined in
1205`python-shell-interpreter-args'). Runs the hook
1206`inferior-python-mode-hook' (after the `comint-mode-hook' is
1207run).
1208\(Type \\[describe-mode] in the process buffer for a list of commands.)"
45c138ac
FEG
1209 (interactive
1210 (if current-prefix-arg
1211 (list
1212 (y-or-n-p "Make dedicated process? ")
1213 (read-string "Run Python: " (python-shell-parse-command)))
1214 (list nil (python-shell-parse-command))))
1215 (let* ((proc-name (python-shell-get-process-name dedicated))
66bbb27f
FEG
1216 (proc-buffer-name (format "*%s*" proc-name))
1217 (process-environment
1218 (if python-shell-process-environment
c942de99
FEG
1219 (python-util-merge 'list python-shell-process-environment
1220 process-environment 'string=)
66bbb27f
FEG
1221 process-environment))
1222 (exec-path
1223 (if python-shell-exec-path
c942de99
FEG
1224 (python-util-merge 'list python-shell-exec-path
1225 exec-path 'string=)
66bbb27f 1226 exec-path)))
45c138ac
FEG
1227 (when (not (comint-check-proc proc-buffer-name))
1228 (let ((cmdlist (split-string-and-unquote cmd)))
1229 (set-buffer
1230 (apply 'make-comint proc-name (car cmdlist) nil
1231 (cdr cmdlist)))
1232 (inferior-python-mode)))
1233 (pop-to-buffer proc-buffer-name))
1234 dedicated)
1235
1236(defun python-shell-get-process ()
1237 "Get inferior Python process for current buffer and return it."
1238 (let* ((dedicated-proc-name (python-shell-get-process-name t))
1239 (dedicated-proc-buffer-name (format "*%s*" dedicated-proc-name))
1240 (global-proc-name (python-shell-get-process-name nil))
1241 (global-proc-buffer-name (format "*%s*" global-proc-name))
1242 (dedicated-running (comint-check-proc dedicated-proc-buffer-name))
1243 (global-running (comint-check-proc global-proc-buffer-name)))
1244 ;; Always prefer dedicated
1245 (get-buffer-process (or (and dedicated-running dedicated-proc-buffer-name)
1246 (and global-running global-proc-buffer-name)))))
1247
1248(defun python-shell-get-or-create-process ()
1249 "Get or create an inferior Python process for current buffer and return it."
79dafa51
FEG
1250 (let* ((old-buffer (current-buffer))
1251 (dedicated-proc-name (python-shell-get-process-name t))
45c138ac
FEG
1252 (dedicated-proc-buffer-name (format "*%s*" dedicated-proc-name))
1253 (global-proc-name (python-shell-get-process-name nil))
1254 (global-proc-buffer-name (format "*%s*" global-proc-name))
1255 (dedicated-running (comint-check-proc dedicated-proc-buffer-name))
1256 (global-running (comint-check-proc global-proc-buffer-name))
1257 (current-prefix-arg 4))
1258 (when (and (not dedicated-running) (not global-running))
1259 (if (call-interactively 'run-python)
1260 (setq dedicated-running t)
1261 (setq global-running t)))
1262 ;; Always prefer dedicated
79dafa51 1263 (switch-to-buffer old-buffer)
45c138ac
FEG
1264 (get-buffer-process (if dedicated-running
1265 dedicated-proc-buffer-name
1266 global-proc-buffer-name))))
1267
9ce938be
FEG
1268(defun python-shell-send-string (string &optional process msg)
1269 "Send STRING to inferior Python PROCESS.
1270When MSG is non-nil messages the first line of STRING."
45c138ac 1271 (interactive "sPython command: ")
9ce938be
FEG
1272 (let ((process (or process (python-shell-get-or-create-process)))
1273 (lines (split-string string "\n" t)))
1274 (when msg
1275 (message (format "Sent: %s..." (nth 0 lines))))
1276 (if (> (length lines) 1)
1277 (let* ((temp-file-name (make-temp-file "py"))
1278 (file-name (or (buffer-file-name) temp-file-name)))
1279 (with-temp-file temp-file-name
1280 (insert string)
1281 (delete-trailing-whitespace))
1282 (python-shell-send-file file-name process temp-file-name))
1283 (comint-send-string process string)
1284 (when (or (not (string-match "\n$" string))
1285 (string-match "\n[ \t].*\n?$" string))
1286 (comint-send-string process "\n")))))
1287
1288(defun python-shell-send-string-no-output (string &optional process msg)
1289 "Send STRING to PROCESS and inhibit output.
e2d8d479
FEG
1290When MSG is non-nil messages the first line of STRING. Return
1291the output."
9ce938be
FEG
1292 (let* ((output-buffer)
1293 (process (or process (python-shell-get-or-create-process)))
1294 (comint-preoutput-filter-functions
1295 (append comint-preoutput-filter-functions
1296 '(ansi-color-filter-apply
1297 (lambda (string)
1298 (setq output-buffer (concat output-buffer string))
1299 "")))))
1300 (python-shell-send-string string process msg)
1301 (accept-process-output process)
62feb915
FEG
1302 ;; Cleanup output prompt regexp
1303 (when (and (not (string= "" output-buffer))
1304 (> (length python-shell-prompt-output-regexp) 0))
1305 (setq output-buffer
1306 (with-temp-buffer
2db30ac5 1307 (insert output-buffer)
62feb915 1308 (goto-char (point-min))
589cefd7 1309 (forward-comment 9999)
62feb915
FEG
1310 (buffer-substring-no-properties
1311 (or
1312 (and (looking-at python-shell-prompt-output-regexp)
1313 (re-search-forward
1314 python-shell-prompt-output-regexp nil t 1))
1315 (point-marker))
1316 (point-max)))))
9ce938be
FEG
1317 (mapconcat
1318 (lambda (string) string)
1319 (butlast (split-string output-buffer "\n")) "\n")))
45c138ac
FEG
1320
1321(defun python-shell-send-region (start end)
1322 "Send the region delimited by START and END to inferior Python process."
1323 (interactive "r")
9ce938be
FEG
1324 (let ((deactivate-mark nil))
1325 (python-shell-send-string (buffer-substring start end) nil t)))
45c138ac
FEG
1326
1327(defun python-shell-send-buffer ()
1328 "Send the entire buffer to inferior Python process."
1329 (interactive)
1330 (save-restriction
1331 (widen)
1332 (python-shell-send-region (point-min) (point-max))))
1333
1334(defun python-shell-send-defun (arg)
2ed294c5 1335 "Send the current defun to inferior Python process.
45c138ac
FEG
1336When argument ARG is non-nil sends the innermost defun."
1337 (interactive "P")
1338 (save-excursion
2ed294c5
FEG
1339 (python-shell-send-region
1340 (progn
1341 (or (python-beginning-of-defun-function)
1342 (progn (beginning-of-line) (point-marker))))
1343 (progn
1344 (or (python-end-of-defun-function)
1345 (progn (end-of-line) (point-marker)))))))
45c138ac 1346
d439cda5
FEG
1347(defun python-shell-send-file (file-name &optional process temp-file-name)
1348 "Send FILE-NAME to inferior Python PROCESS.
1349If TEMP-FILE-NAME is passed then that file is used for processing
1350instead, while internally the shell will continue to use
1351FILE-NAME."
45c138ac 1352 (interactive "fFile to send: ")
9ce938be
FEG
1353 (let* ((process (or process (python-shell-get-or-create-process)))
1354 (temp-file-name (when temp-file-name
1355 (expand-file-name temp-file-name)))
1356 (file-name (or (expand-file-name file-name) temp-file-name)))
1357 (when (not file-name)
1358 (error "If FILE-NAME is nil then TEMP-FILE-NAME must be non-nil"))
d439cda5 1359 (with-current-buffer (process-buffer process)
24b68537
FEG
1360 (setq inferior-python-mode-current-file
1361 (convert-standard-filename file-name)))
13d914ed 1362 (python-shell-send-string
b962ebad 1363 (format
d439cda5
FEG
1364 (concat "__pyfile = open('''%s''');"
1365 "exec(compile(__pyfile.read(), '''%s''', 'exec'));"
1366 "__pyfile.close()")
1367 (or temp-file-name file-name) file-name)
13d914ed 1368 process)))
45c138ac
FEG
1369
1370(defun python-shell-switch-to-shell ()
1371 "Switch to inferior Python process buffer."
1372 (interactive)
1373 (pop-to-buffer (process-buffer (python-shell-get-or-create-process)) t))
1374
c0428ba0
FEG
1375(defun python-shell-send-setup-code ()
1376 "Send all setup code for shell.
1377This function takes the list of setup code to send from the
1378`python-shell-setup-codes' list."
1379 (let ((msg "Sent %s")
1380 (process (get-buffer-process (current-buffer))))
30e429dd 1381 (accept-process-output process python-shell-send-setup-max-wait)
c0428ba0
FEG
1382 (dolist (code python-shell-setup-codes)
1383 (when code
1384 (when (consp code)
1385 (setq msg (cdr code)))
1386 (message (format msg code))
1387 (python-shell-send-string-no-output
1388 (symbol-value code) process)))))
1389
1390(add-hook 'inferior-python-mode-hook
1391 #'python-shell-send-setup-code)
1392
45c138ac
FEG
1393\f
1394;;; Shell completion
1395
1396(defvar python-shell-completion-setup-code
1397 "try:
1398 import readline
1399except ImportError:
1400 def __COMPLETER_all_completions(text): []
1401else:
1402 import rlcompleter
1403 readline.set_completer(rlcompleter.Completer().complete)
1404 def __COMPLETER_all_completions(text):
1405 import sys
1406 completions = []
1407 try:
1408 i = 0
1409 while True:
1410 res = readline.get_completer()(text, i)
1411 if not res: break
1412 i += 1
1413 completions.append(res)
1414 except NameError:
1415 pass
1416 return completions"
1417 "Code used to setup completion in inferior Python processes.")
1418
62feb915 1419(defvar python-shell-completion-string-code
45c138ac
FEG
1420 "';'.join(__COMPLETER_all_completions('''%s'''))\n"
1421 "Python code used to get a string of completions separated by semicolons.")
1422
075a0f61
FEG
1423(defun python-shell-completion--get-completions (input process)
1424 "Retrieve available completions for INPUT using PROCESS."
1425 (with-current-buffer (process-buffer process)
62feb915
FEG
1426 (let ((completions (python-shell-send-string-no-output
1427 (format python-shell-completion-string-code input)
1428 process)))
1429 (when (> (length completions) 2)
1430 (split-string completions "^'\\|^\"\\|;\\|'$\\|\"$" t)))))
075a0f61
FEG
1431
1432(defun python-shell-completion--get-completion (input completions)
1433 "Get completion for INPUT using COMPLETIONS."
1434 (let ((completion (when completions
1435 (try-completion input completions))))
1436 (cond ((eq completion t)
1437 input)
1438 ((null completion)
1439 (message "Can't find completion for \"%s\"" input)
1440 (ding)
1441 input)
1442 ((not (string= input completion))
1443 completion)
1444 (t
1445 (message "Making completion list...")
1446 (with-output-to-temp-buffer "*Python Completions*"
1447 (display-completion-list
1448 (all-completions input completions)))
1449 input))))
1450
45c138ac
FEG
1451(defun python-shell-completion-complete-at-point ()
1452 "Perform completion at point in inferior Python process."
1453 (interactive)
3d6913c7
FEG
1454 (with-syntax-table python-dotty-syntax-table
1455 (when (and comint-last-prompt-overlay
1456 (> (point-marker) (overlay-end comint-last-prompt-overlay)))
1457 (let* ((process (get-buffer-process (current-buffer)))
075a0f61
FEG
1458 (input (substring-no-properties
1459 (or (comint-word (current-word)) "") nil nil)))
1460 (delete-char (- (length input)))
1461 (insert
1462 (python-shell-completion--get-completion
1463 input (python-shell-completion--get-completions input process)))))))
45c138ac 1464
45c138ac
FEG
1465(defun python-shell-completion-complete-or-indent ()
1466 "Complete or indent depending on the context.
e2d8d479
FEG
1467If content before pointer is all whitespace indent. If not try
1468to complete."
45c138ac
FEG
1469 (interactive)
1470 (if (string-match "^[[:space:]]*$"
1471 (buffer-substring (comint-line-beginning-position)
1472 (point-marker)))
1473 (indent-for-tab-command)
1474 (comint-dynamic-complete)))
1475
45c138ac
FEG
1476\f
1477;;; PDB Track integration
1478
1479(defvar python-pdbtrack-stacktrace-info-regexp
1480 "> %s(\\([0-9]+\\))\\([?a-zA-Z0-9_<>]+\\)()"
e2d8d479
FEG
1481 "Regular Expression matching stacktrace information.
1482Used to extract the current line and module beign inspected. The
1483regexp should not start with a caret (^) and can contain a string
1484placeholder (\%s) which is replaced with the filename beign
1485inspected (so other files in the debugging process are not
45c138ac
FEG
1486opened)")
1487
1488(defvar python-pdbtrack-tracking-buffers '()
1489 "Alist containing elements of form (#<buffer> . #<buffer>).
1490The car of each element of the alist is the tracking buffer and
1491the cdr is the tracked buffer.")
1492
1493(defun python-pdbtrack-get-or-add-tracking-buffers ()
1494 "Get/Add a tracked buffer for the current buffer.
1495Internally it uses the `python-pdbtrack-tracking-buffers' alist.
1496Returns a cons with the form:
1497 * (#<tracking buffer> . #< tracked buffer>)."
1498 (or
1499 (assq (current-buffer) python-pdbtrack-tracking-buffers)
1500 (let* ((file (with-current-buffer (current-buffer)
d439cda5 1501 inferior-python-mode-current-file))
45c138ac
FEG
1502 (tracking-buffers
1503 `(,(current-buffer) .
1504 ,(or (get-file-buffer file)
1505 (find-file-noselect file)))))
1506 (set-buffer (cdr tracking-buffers))
1507 (python-mode)
1508 (set-buffer (car tracking-buffers))
1509 (setq python-pdbtrack-tracking-buffers
1510 (cons tracking-buffers python-pdbtrack-tracking-buffers))
1511 tracking-buffers)))
1512
1513(defun python-pdbtrack-comint-output-filter-function (output)
1514 "Move overlay arrow to current pdb line in tracked buffer.
1515Argument OUTPUT is a string with the output from the comint process."
1516 (when (not (string= output ""))
1517 (let ((full-output (ansi-color-filter-apply
1518 (buffer-substring comint-last-input-end
1519 (point-max)))))
1520 (if (string-match python-shell-prompt-pdb-regexp full-output)
1521 (let* ((tracking-buffers (python-pdbtrack-get-or-add-tracking-buffers))
1522 (line-num
1523 (save-excursion
1524 (string-match
1525 (format python-pdbtrack-stacktrace-info-regexp
1526 (regexp-quote
d439cda5 1527 inferior-python-mode-current-file))
45c138ac
FEG
1528 full-output)
1529 (string-to-number (or (match-string-no-properties 1 full-output) ""))))
1530 (tracked-buffer-window (get-buffer-window (cdr tracking-buffers)))
1531 (tracked-buffer-line-pos))
1532 (when line-num
1533 (with-current-buffer (cdr tracking-buffers)
1534 (set (make-local-variable 'overlay-arrow-string) "=>")
1535 (set (make-local-variable 'overlay-arrow-position) (make-marker))
1536 (setq tracked-buffer-line-pos (progn
1537 (goto-char (point-min))
1538 (forward-line (1- line-num))
1539 (point-marker)))
1540 (when tracked-buffer-window
1541 (set-window-point tracked-buffer-window tracked-buffer-line-pos))
1542 (set-marker overlay-arrow-position tracked-buffer-line-pos)))
1543 (pop-to-buffer (cdr tracking-buffers))
1544 (switch-to-buffer-other-window (car tracking-buffers)))
1545 (let ((tracking-buffers (assq (current-buffer)
1546 python-pdbtrack-tracking-buffers)))
1547 (when tracking-buffers
1548 (if inferior-python-mode-current-file
1549 (with-current-buffer (cdr tracking-buffers)
1550 (set-marker overlay-arrow-position nil))
1551 (kill-buffer (cdr tracking-buffers)))
1552 (setq python-pdbtrack-tracking-buffers
1553 (assq-delete-all (current-buffer)
1554 python-pdbtrack-tracking-buffers)))))))
1555 output)
1556
1557\f
1558;;; Symbol completion
1559
1560(defun python-completion-complete-at-point ()
1561 "Complete current symbol at point.
1562For this to work the best as possible you should call
1563`python-shell-send-buffer' from time to time so context in
1564inferior python process is updated properly."
1565 (interactive)
1566 (let ((process (python-shell-get-process)))
1567 (if (not process)
4e531f7a 1568 (error "Completion needs an inferior Python process running")
075a0f61
FEG
1569 (with-syntax-table python-dotty-syntax-table
1570 (let* ((input (substring-no-properties
1571 (or (comint-word (current-word)) "") nil nil))
1572 (completions (python-shell-completion--get-completions
1573 input process)))
1574 (delete-char (- (length input)))
1575 (insert
1576 (python-shell-completion--get-completion
1577 input completions)))))))
45c138ac
FEG
1578
1579(add-to-list 'debug-ignored-errors "^Completion needs an inferior Python process running.")
1580
1581\f
1582;;; Fill paragraph
1583
c2cb97ae
FEG
1584(defcustom python-fill-comment-function 'python-fill-comment
1585 "Function to fill comments.
1586This is the function used by `python-fill-paragraph-function' to
1587fill comments."
1588 :type 'symbol
1589 :group 'python
1590 :safe 'symbolp)
1591
1592(defcustom python-fill-string-function 'python-fill-string
1593 "Function to fill strings.
1594This is the function used by `python-fill-paragraph-function' to
1595fill strings."
1596 :type 'symbol
1597 :group 'python
1598 :safe 'symbolp)
1599
1600(defcustom python-fill-decorator-function 'python-fill-decorator
1601 "Function to fill decorators.
1602This is the function used by `python-fill-paragraph-function' to
1603fill decorators."
1604 :type 'symbol
1605 :group 'python
1606 :safe 'symbolp)
1607
1608(defcustom python-fill-paren-function 'python-fill-paren
1609 "Function to fill parens.
1610This is the function used by `python-fill-paragraph-function' to
1611fill parens."
1612 :type 'symbol
1613 :group 'python
1614 :safe 'symbolp)
1615
45c138ac
FEG
1616(defun python-fill-paragraph-function (&optional justify)
1617 "`fill-paragraph-function' handling multi-line strings and possibly comments.
1618If any of the current line is in or at the end of a multi-line string,
1619fill the string or the paragraph of it that point is in, preserving
4e531f7a
FEG
1620the string's indentation.
1621Optional argument JUSTIFY defines if the paragraph should be justified."
45c138ac
FEG
1622 (interactive "P")
1623 (save-excursion
1624 (back-to-indentation)
1625 (cond
1626 ;; Comments
c2cb97ae
FEG
1627 ((funcall python-fill-comment-function justify))
1628 ;; Strings/Docstrings
45c138ac 1629 ((save-excursion (skip-chars-forward "\"'uUrR")
14a78495 1630 (python-info-ppss-context 'string))
c2cb97ae 1631 (funcall python-fill-string-function justify))
45c138ac
FEG
1632 ;; Decorators
1633 ((equal (char-after (save-excursion
1634 (back-to-indentation)
c2cb97ae
FEG
1635 (point-marker))) ?@)
1636 (funcall python-fill-decorator-function justify))
45c138ac 1637 ;; Parens
14a78495 1638 ((or (python-info-ppss-context 'paren)
45c138ac
FEG
1639 (looking-at (python-rx open-paren))
1640 (save-excursion
1641 (skip-syntax-forward "^(" (line-end-position))
1642 (looking-at (python-rx open-paren))))
c2cb97ae 1643 (funcall python-fill-paren-function justify))
45c138ac
FEG
1644 (t t))))
1645
c2cb97ae 1646(defun python-fill-comment (&optional justify)
053a6c72
FEG
1647 "Comment fill function for `python-fill-paragraph-function'.
1648JUSTIFY should be used (if applicable) as in `fill-paragraph'."
c2cb97ae
FEG
1649 (fill-comment-paragraph justify))
1650
1651(defun python-fill-string (&optional justify)
053a6c72
FEG
1652 "String fill function for `python-fill-paragraph-function'.
1653JUSTIFY should be used (if applicable) as in `fill-paragraph'."
c2cb97ae
FEG
1654 (let ((marker (point-marker))
1655 (string-start-marker
1656 (progn
1657 (skip-chars-forward "\"'uUrR")
1658 (goto-char (python-info-ppss-context 'string))
1659 (skip-chars-forward "\"'uUrR")
1660 (point-marker)))
1661 (reg-start (line-beginning-position))
1662 (string-end-marker
1663 (progn
1664 (while (python-info-ppss-context 'string)
1665 (goto-char (1+ (point-marker))))
1666 (skip-chars-backward "\"'")
1667 (point-marker)))
1668 (reg-end (line-end-position))
1669 (fill-paragraph-function))
1670 (save-restriction
1671 (narrow-to-region reg-start reg-end)
1672 (save-excursion
1673 (goto-char string-start-marker)
1674 (delete-region (point-marker) (progn
1675 (skip-syntax-forward "> ")
1676 (point-marker)))
1677 (goto-char string-end-marker)
1678 (delete-region (point-marker) (progn
1679 (skip-syntax-backward "> ")
1680 (point-marker)))
1681 (save-excursion
1682 (goto-char marker)
1683 (fill-paragraph justify))
1684 ;; If there is a newline in the docstring lets put triple
1685 ;; quote in it's own line to follow pep 8
1686 (when (save-excursion
1687 (re-search-backward "\n" string-start-marker t))
1688 (newline)
1689 (newline-and-indent))
1690 (fill-paragraph justify)))) t)
1691
1692(defun python-fill-decorator (&optional justify)
053a6c72
FEG
1693 "Decorator fill function for `python-fill-paragraph-function'.
1694JUSTIFY should be used (if applicable) as in `fill-paragraph'."
c2cb97ae
FEG
1695 t)
1696
1697(defun python-fill-paren (&optional justify)
053a6c72
FEG
1698 "Paren fill function for `python-fill-paragraph-function'.
1699JUSTIFY should be used (if applicable) as in `fill-paragraph'."
c2cb97ae
FEG
1700 (save-restriction
1701 (narrow-to-region (progn
1702 (while (python-info-ppss-context 'paren)
1703 (goto-char (1- (point-marker))))
1704 (point-marker)
1705 (line-beginning-position))
1706 (progn
1707 (when (not (python-info-ppss-context 'paren))
1708 (end-of-line)
1709 (when (not (python-info-ppss-context 'paren))
1710 (skip-syntax-backward "^)")))
1711 (while (python-info-ppss-context 'paren)
1712 (goto-char (1+ (point-marker))))
1713 (point-marker)))
1714 (let ((paragraph-start "\f\\|[ \t]*$")
1715 (paragraph-separate ",")
1716 (fill-paragraph-function))
1717 (goto-char (point-min))
1718 (fill-paragraph justify))
1719 (while (not (eobp))
1720 (forward-line 1)
1721 (python-indent-line)
1722 (goto-char (line-end-position)))) t)
1723
45c138ac 1724\f
e2803784
FEG
1725;;; Skeletons
1726
1727(defcustom python-skeleton-autoinsert nil
1728 "Non-nil means template skeletons will be automagically inserted.
1729This happens when pressing \"if<SPACE>\", for example, to prompt for
1730the if condition."
1731 :type 'boolean
1732 :group 'python)
1733
1734(defvar python-skeleton-available '()
1735 "Internal list of available skeletons.")
1736(make-variable-buffer-local 'inferior-python-mode-current-file)
1737
1738(define-abbrev-table 'python-mode-abbrev-table ()
1739 "Abbrev table for Python mode."
1740 :case-fixed t
1741 ;; Allow / inside abbrevs.
1742 :regexp "\\(?:^\\|[^/]\\)\\<\\([[:word:]/]+\\)\\W*"
1743 ;; Only expand in code.
1744 :enable-function (lambda ()
e2803784 1745 (and
14a78495
FEG
1746 (not (or (python-info-ppss-context 'string)
1747 (python-info-ppss-context 'comment)))
e2803784
FEG
1748 python-skeleton-autoinsert)))
1749
1750(defmacro python-skeleton-define (name doc &rest skel)
1751 "Define a `python-mode' skeleton using NAME DOC and SKEL.
1752The skeleton will be bound to python-skeleton-NAME and will
1753be added to `python-mode-abbrev-table'."
1754 (let* ((name (symbol-name name))
1755 (function-name (intern (concat "python-skeleton-" name))))
73ed6836
FEG
1756 `(progn
1757 (define-abbrev python-mode-abbrev-table ,name "" ',function-name)
1758 (setq python-skeleton-available
1759 (cons ',function-name python-skeleton-available))
1760 (define-skeleton ,function-name
1761 ,(or doc
1762 (format "Insert %s statement." name))
1763 ,@skel))))
e2803784
FEG
1764(put 'python-skeleton-define 'lisp-indent-function 2)
1765
1766(defmacro python-define-auxiliary-skeleton (name doc &optional &rest skel)
1767 "Define a `python-mode' auxiliary skeleton using NAME DOC and SKEL.
1768The skeleton will be bound to python-skeleton-NAME."
1769 (let* ((name (symbol-name name))
1770 (function-name (intern (concat "python-skeleton--" name)))
1771 (msg (format
1772 "Add '%s' clause? " name)))
1773 (when (not skel)
1774 (setq skel
1775 `(< ,(format "%s:" name) \n \n
1776 > _ \n)))
1777 `(define-skeleton ,function-name
1778 ,(or doc
1779 (format "Auxiliary skeleton for %s statement." name))
1780 nil
1781 (unless (y-or-n-p ,msg)
1782 (signal 'quit t))
1783 ,@skel)))
1784(put 'python-define-auxiliary-skeleton 'lisp-indent-function 2)
1785
1786(python-define-auxiliary-skeleton else nil)
1787
1788(python-define-auxiliary-skeleton except nil)
1789
1790(python-define-auxiliary-skeleton finally nil)
1791
1792(python-skeleton-define if nil
1793 "Condition: "
1794 "if " str ":" \n
1795 _ \n
1796 ("other condition, %s: "
1797 <
1798 "elif " str ":" \n
1799 > _ \n nil)
1800 '(python-skeleton--else) | ^)
1801
1802(python-skeleton-define while nil
1803 "Condition: "
1804 "while " str ":" \n
1805 > _ \n
1806 '(python-skeleton--else) | ^)
1807
1808(python-skeleton-define for nil
1809 "Iteration spec: "
1810 "for " str ":" \n
1811 > _ \n
1812 '(python-skeleton--else) | ^)
1813
1814(python-skeleton-define try nil
1815 nil
1816 "try:" \n
1817 > _ \n
1818 ("Exception, %s: "
1819 <
1820 "except " str ":" \n
1821 > _ \n nil)
1822 resume:
1823 '(python-skeleton--except)
1824 '(python-skeleton--else)
1825 '(python-skeleton--finally) | ^)
1826
1827(python-skeleton-define def nil
1828 "Function name: "
1829 "def " str " (" ("Parameter, %s: "
1830 (unless (equal ?\( (char-before)) ", ")
1831 str) "):" \n
1832 "\"\"\"" - "\"\"\"" \n
1833 > _ \n)
1834
1835(python-skeleton-define class nil
1836 "Class name: "
1837 "class " str " (" ("Inheritance, %s: "
1838 (unless (equal ?\( (char-before)) ", ")
1839 str)
1840 & ")" | -2
1841 ":" \n
1842 "\"\"\"" - "\"\"\"" \n
1843 > _ \n)
1844
1845(defun python-skeleton-add-menu-items ()
1846 "Add menu items to Python->Skeletons menu."
1847 (let ((skeletons (sort python-skeleton-available 'string<))
1848 (items))
1849 (dolist (skeleton skeletons)
1850 (easy-menu-add-item
1851 nil '("Python" "Skeletons")
1852 `[,(format
1853 "Insert %s" (caddr (split-string (symbol-name skeleton) "-")))
1854 ,skeleton t]))))
1855\f
046428d3
FEG
1856;;; FFAP
1857
1858(defvar python-ffap-setup-code
1859 "def __FFAP_get_module_path(module):
1860 try:
1861 import os
1862 path = __import__(module).__file__
1863 if path[-4:] == '.pyc' and os.path.exists(path[0:-1]):
1864 path = path[:-1]
1865 return path
1866 except:
1867 return ''"
1868 "Python code to get a module path.")
1869
1870(defvar python-ffap-string-code
1871 "__FFAP_get_module_path('''%s''')\n"
1872 "Python code used to get a string with the path of a module.")
1873
046428d3
FEG
1874(defun python-ffap-module-path (module)
1875 "Function for `ffap-alist' to return path for MODULE."
1876 (let ((process (or
1877 (and (eq major-mode 'inferior-python-mode)
1878 (get-buffer-process (current-buffer)))
1879 (python-shell-get-process))))
1880 (if (not process)
1881 nil
1882 (let ((module-file
9ce938be 1883 (python-shell-send-string-no-output
046428d3
FEG
1884 (format python-ffap-string-code module) process)))
1885 (when module-file
2947016a 1886 (substring-no-properties module-file 1 -1))))))
046428d3
FEG
1887
1888(eval-after-load "ffap"
1889 '(progn
1890 (push '(python-mode . python-ffap-module-path) ffap-alist)
1891 (push '(inferior-python-mode . python-ffap-module-path) ffap-alist)))
1892
046428d3 1893\f
8b3e0e76
FEG
1894;;; Code check
1895
1896(defvar python-check-command
1897 "pychecker --stdlib"
1898 "Command used to check a Python file.")
1899
1900(defvar python-check-custom-command nil
1901 "Internal use.")
1902
1903(defun python-check (command)
1904 "Check a Python file (default current buffer's file).
1905Runs COMMAND, a shell command, as if by `compile'. See
1906`python-check-command' for the default."
1907 (interactive
1908 (list (read-string "Check command: "
1909 (or python-check-custom-command
1910 (concat python-check-command " "
1911 (shell-quote-argument
1912 (or
1913 (let ((name (buffer-file-name)))
1914 (and name
1915 (file-name-nondirectory name)))
1916 "")))))))
1917 (setq python-check-custom-command command)
1918 (save-some-buffers (not compilation-ask-about-save) nil)
1919 (compilation-start command))
1920
1921\f
45c138ac
FEG
1922;;; Eldoc
1923
1924(defvar python-eldoc-setup-code
1925 "def __PYDOC_get_help(obj):
1926 try:
1927 import pydoc
9e662938
FEG
1928 if hasattr(obj, 'startswith'):
1929 obj = eval(obj, globals())
1930 doc = pydoc.getdoc(obj)
45c138ac 1931 except:
9e662938
FEG
1932 doc = ''
1933 try:
1934 exec('print doc')
1935 except SyntaxError:
1936 print(doc)"
45c138ac
FEG
1937 "Python code to setup documentation retrieval.")
1938
1939(defvar python-eldoc-string-code
9e662938 1940 "__PYDOC_get_help('''%s''')\n"
45c138ac
FEG
1941 "Python code used to get a string with the documentation of an object.")
1942
78334b43 1943(defun python-eldoc--get-doc-at-point (&optional force-input force-process)
d439cda5
FEG
1944 "Internal implementation to get documentation at point.
1945If not FORCE-INPUT is passed then what `current-word' returns
1946will be used. If not FORCE-PROCESS is passed what
1947`python-shell-get-process' returns is used."
78334b43 1948 (let ((process (or force-process (python-shell-get-process))))
45c138ac
FEG
1949 (if (not process)
1950 "Eldoc needs an inferior Python process running."
1951 (let* ((current-defun (python-info-current-defun))
78334b43
FEG
1952 (input (or force-input
1953 (with-syntax-table python-dotty-syntax-table
1954 (if (not current-defun)
1955 (current-word)
1956 (concat current-defun "." (current-word))))))
45c138ac
FEG
1957 (ppss (syntax-ppss))
1958 (help (when (and input
1959 (not (string= input (concat current-defun ".")))
14a78495
FEG
1960 (not (or (python-info-ppss-context 'string ppss)
1961 (python-info-ppss-context 'comment ppss))))
45c138ac
FEG
1962 (when (string-match (concat
1963 (regexp-quote (concat current-defun "."))
1964 "self\\.") input)
1965 (with-temp-buffer
1966 (insert input)
1967 (goto-char (point-min))
1968 (forward-word)
1969 (forward-char)
1970 (delete-region (point-marker) (search-forward "self."))
1971 (setq input (buffer-substring (point-min) (point-max)))))
9ce938be 1972 (python-shell-send-string-no-output
1066882c 1973 (format python-eldoc-string-code input) process))))
45c138ac
FEG
1974 (with-current-buffer (process-buffer process)
1975 (when comint-last-prompt-overlay
1976 (delete-region comint-last-input-end
1977 (overlay-start comint-last-prompt-overlay))))
1978 (when (and help
1979 (not (string= help "\n")))
1980 help)))))
1981
78334b43
FEG
1982(defun python-eldoc-function ()
1983 "`eldoc-documentation-function' for Python.
1984For this to work the best as possible you should call
1985`python-shell-send-buffer' from time to time so context in
1986inferior python process is updated properly."
1987 (python-eldoc--get-doc-at-point))
1988
1989(defun python-eldoc-at-point (symbol)
1990 "Get help on SYMBOL using `help'.
1991Interactively, prompt for symbol."
1992 (interactive
1993 (let ((symbol (with-syntax-table python-dotty-syntax-table
1994 (current-word)))
1995 (enable-recursive-minibuffers t))
1996 (list (read-string (if symbol
1997 (format "Describe symbol (default %s): " symbol)
1998 "Describe symbol: ")
1999 nil nil symbol))))
2000 (let ((process (python-shell-get-process)))
2001 (if (not process)
2002 (message "Eldoc needs an inferior Python process running.")
2003 (let ((temp-buffer-show-hook
2004 (lambda ()
2005 (toggle-read-only 1)
2006 (setq view-return-to-alist
2007 (list (cons (selected-window) help-return-method))))))
2008 (with-output-to-temp-buffer (help-buffer)
2009 (with-current-buffer standard-output
2010 (insert
2011 (python-eldoc--get-doc-at-point symbol process))
2012 (help-print-return-message)))))))
2013
45c138ac 2014\f
fc2dc7df
FEG
2015;;; Imenu
2016
2017(defcustom python-imenu-include-defun-type t
2018 "Non-nil make imenu items to include its type."
2019 :type 'boolean
2020 :group 'python
2021 :safe 'booleanp)
2022
c942de99 2023(defcustom python-imenu-make-tree t
fc2dc7df
FEG
2024 "Non-nil make imenu to build a tree menu.
2025Set to nil for speed."
2026 :type 'boolean
2027 :group 'python
2028 :safe 'booleanp)
2029
2030(defcustom python-imenu-subtree-root-label "<Jump to %s>"
2031 "Label displayed to navigate to root from a subtree.
2032It can contain a \"%s\" which will be replaced with the root name."
2033 :type 'string
2034 :group 'python
2035 :safe 'stringp)
2036
2037(defvar python-imenu-index-alist nil
2038 "Calculated index tree for imenu.")
2039
2040(defun python-imenu-tree-assoc (keylist tree)
2041 "Using KEYLIST traverse TREE."
2042 (if keylist
2043 (python-imenu-tree-assoc (cdr keylist)
2044 (ignore-errors (assoc (car keylist) tree)))
2045 tree))
2046
2047(defun python-imenu-make-element-tree (element-list full-element plain-index)
2048 "Make a tree from plain alist of module names.
2049ELEMENT-LIST is the defun name splitted by \".\" and FULL-ELEMENT
2050is the same thing, the difference is that FULL-ELEMENT remains
2051untouched in all recursive calls.
2052Argument PLAIN-INDEX is the calculated plain index used to build the tree."
2053 (when (not (python-imenu-tree-assoc full-element python-imenu-index-alist))
2054 (when element-list
2055 (let* ((subelement-point (cdr (assoc
2056 (mapconcat #'identity full-element ".")
2057 plain-index)))
2058 (subelement-name (car element-list))
c942de99
FEG
2059 (subelement-position (python-util-position
2060 subelement-name full-element))
fc2dc7df
FEG
2061 (subelement-path (when subelement-position
2062 (butlast
2063 full-element
2064 (- (length full-element)
2065 subelement-position)))))
2066 (let ((path-ref (python-imenu-tree-assoc subelement-path
2067 python-imenu-index-alist)))
2068 (if (not path-ref)
2069 (push (cons subelement-name subelement-point)
2070 python-imenu-index-alist)
2071 (when (not (listp (cdr path-ref)))
2072 ;; Modifiy root cdr to be a list
2073 (setcdr path-ref
2074 (list (cons (format python-imenu-subtree-root-label
2075 (car path-ref))
2076 (cdr (assoc
2077 (mapconcat #'identity
2078 subelement-path ".")
2079 plain-index))))))
2080 (when (not (assoc subelement-name path-ref))
2081 (push (cons subelement-name subelement-point) (cdr path-ref))))))
2082 (python-imenu-make-element-tree (cdr element-list)
2083 full-element plain-index))))
2084
2085(defun python-imenu-make-tree (index)
2086"Build the imenu alist tree from plain INDEX.
2087
2088The idea of this function is that given the alist:
2089
2090 '((\"Test\" . 100)
2091 (\"Test.__init__\" . 200)
2092 (\"Test.some_method\" . 300)
2093 (\"Test.some_method.another\" . 400)
2094 (\"Test.something_else\" . 500)
2095 (\"test\" . 600)
2096 (\"test.reprint\" . 700)
2097 (\"test.reprint\" . 800))
2098
2099This tree gets built:
2100
2101 '((\"Test\" . ((\"jump to...\" . 100)
2102 (\"__init__\" . 200)
2103 (\"some_method\" . ((\"jump to...\" . 300)
2104 (\"another\" . 400)))
2105 (\"something_else\" . 500)))
2106 (\"test\" . ((\"jump to...\" . 600)
2107 (\"reprint\" . 700)
2108 (\"reprint\" . 800))))
2109
2110Internally it uses `python-imenu-make-element-tree' to create all
2111branches for each element."
2112(setq python-imenu-index-alist nil)
c942de99
FEG
2113(mapc (lambda (element)
2114 (python-imenu-make-element-tree element element index))
2115 (mapcar (lambda (element)
2116 (split-string (car element) "\\." t)) index))
fc2dc7df
FEG
2117python-imenu-index-alist)
2118
2119(defun python-imenu-create-index ()
2120 "`imenu-create-index-function' for Python."
2121 (let ((index))
2122 (goto-char (point-max))
2123 (while (python-beginning-of-defun-function 1 t)
2124 (let ((defun-dotted-name
2125 (python-info-current-defun python-imenu-include-defun-type)))
2126 (push (cons defun-dotted-name (point)) index)))
2127 (if python-imenu-make-tree
2128 (python-imenu-make-tree index)
2129 index)))
2130
2131\f
45c138ac
FEG
2132;;; Misc helpers
2133
fc2dc7df 2134(defun python-info-current-defun (&optional include-type)
45c138ac 2135 "Return name of surrounding function with Python compatible dotty syntax.
fc2dc7df 2136Optional argument INCLUDE-TYPE indicates to include the type of the defun.
45c138ac
FEG
2137This function is compatible to be used as
2138`add-log-current-defun-function' since it returns nil if point is
2139not inside a defun."
6b432853
FEG
2140 (let ((names '())
2141 (min-indent))
45c138ac
FEG
2142 (save-restriction
2143 (widen)
2144 (save-excursion
6b432853 2145 (goto-char (line-end-position))
589cefd7 2146 (forward-comment -9999)
fc2dc7df 2147 (while (python-beginning-of-defun-function 1 t)
6b432853
FEG
2148 (when (or (not min-indent)
2149 (< (current-indentation) min-indent))
2150 (setq min-indent (current-indentation))
af5c1beb 2151 (looking-at python-nav-beginning-of-defun-regexp)
fc2dc7df
FEG
2152 (setq names (cons
2153 (if (not include-type)
2154 (match-string-no-properties 1)
2155 (mapconcat 'identity
2156 (split-string
2157 (match-string-no-properties 0)) " "))
2158 names))))))
45c138ac
FEG
2159 (when names
2160 (mapconcat (lambda (string) string) names "."))))
2161
2162(defun python-info-closing-block ()
e2d8d479 2163 "Return the point of the block the current line closes."
45c138ac
FEG
2164 (let ((closing-word (save-excursion
2165 (back-to-indentation)
2166 (current-word)))
2167 (indentation (current-indentation)))
2168 (when (member closing-word python-indent-dedenters)
2169 (save-excursion
2170 (forward-line -1)
2171 (while (and (> (current-indentation) indentation)
2172 (not (bobp))
2173 (not (back-to-indentation))
2174 (forward-line -1)))
2175 (back-to-indentation)
2176 (cond
2177 ((not (equal indentation (current-indentation))) nil)
2178 ((string= closing-word "elif")
2179 (when (member (current-word) '("if" "elif"))
2180 (point-marker)))
2181 ((string= closing-word "else")
2182 (when (member (current-word) '("if" "elif" "except" "for" "while"))
2183 (point-marker)))
2184 ((string= closing-word "except")
2185 (when (member (current-word) '("try"))
2186 (point-marker)))
2187 ((string= closing-word "finally")
2188 (when (member (current-word) '("except" "else"))
2189 (point-marker))))))))
2190
2191(defun python-info-line-ends-backslash-p ()
2192 "Return non-nil if current line ends with backslash."
2193 (string= (or (ignore-errors
2194 (buffer-substring
2195 (line-end-position)
2196 (- (line-end-position) 1))) "") "\\"))
2197
2198(defun python-info-continuation-line-p ()
2199 "Return non-nil if current line is continuation of another."
2200 (or (python-info-line-ends-backslash-p)
2201 (string-match ",[[:space:]]*$" (buffer-substring
2202 (line-beginning-position)
2203 (line-end-position)))
2204 (save-excursion
2205 (let ((innermost-paren (progn
2206 (goto-char (line-end-position))
14a78495 2207 (python-info-ppss-context 'paren))))
45c138ac
FEG
2208 (when (and innermost-paren
2209 (and (<= (line-beginning-position) innermost-paren)
2210 (>= (line-end-position) innermost-paren)))
2211 (goto-char innermost-paren)
2212 (looking-at (python-rx open-paren (* space) line-end)))))
2213 (save-excursion
2214 (back-to-indentation)
14a78495 2215 (python-info-ppss-context 'paren))))
45c138ac
FEG
2216
2217(defun python-info-block-continuation-line-p ()
2218 "Return non-nil if current line is a continuation of a block."
2219 (save-excursion
2220 (while (and (not (bobp))
2221 (python-info-continuation-line-p))
2222 (forward-line -1))
2223 (forward-line 1)
2224 (back-to-indentation)
2225 (when (looking-at (python-rx block-start))
2226 (point-marker))))
2227
2228(defun python-info-assignment-continuation-line-p ()
2229 "Return non-nil if current line is a continuation of an assignment."
2230 (save-excursion
2231 (while (and (not (bobp))
2232 (python-info-continuation-line-p))
2233 (forward-line -1))
2234 (forward-line 1)
2235 (back-to-indentation)
2236 (when (and (not (looking-at (python-rx block-start)))
2237 (save-excursion
2238 (and (re-search-forward (python-rx not-simple-operator
2239 assignment-operator
2240 not-simple-operator)
2241 (line-end-position) t)
14a78495 2242 (not (or (python-info-ppss-context 'string)
9f1537ef 2243 (python-info-ppss-context 'paren)
14a78495 2244 (python-info-ppss-context 'comment))))))
45c138ac
FEG
2245 (point-marker))))
2246
14a78495
FEG
2247(defun python-info-ppss-context (type &optional syntax-ppss)
2248 "Return non-nil if point is on TYPE using SYNTAX-PPSS.
2249TYPE can be 'comment, 'string or 'parent. It returns the start
2250character address of the specified TYPE."
2251 (let ((ppss (or syntax-ppss (syntax-ppss))))
2252 (case type
2253 ('comment
2254 (and (nth 4 ppss)
2255 (nth 8 ppss)))
2256 ('string
2257 (nth 8 ppss))
2258 ('paren
2259 (nth 1 ppss))
2260 (t nil))))
2261
45c138ac 2262\f
c942de99
FEG
2263;;; Utility functions
2264
2265;; Stolen from GNUS
2266(defun python-util-merge (type list1 list2 pred)
4cafacb5
FEG
2267 "Destructively merge lists to produce a new one.
2268Argument TYPE is for compatibility and ignored. LIST1 and LIST2
2269are the list to be merged. Ordering of the elements is preserved
2270according to PRED, a `less-than' predicate on the elements."
c942de99
FEG
2271 (let ((res nil))
2272 (while (and list1 list2)
2273 (if (funcall pred (car list2) (car list1))
2274 (push (pop list2) res)
2275 (push (pop list1) res)))
2276 (nconc (nreverse res) list1 list2)))
2277
2278(defun python-util-position (item seq)
2279 "Find the first occurrence of ITEM in SEQ.
2280Return the index of the matching item, or nil if not found."
2281 (let ((member-result (member item seq)))
2282 (when member-result
2283 (- (length seq) (length member-result)))))
2284
2285\f
45c138ac
FEG
2286;;;###autoload
2287(define-derived-mode python-mode fundamental-mode "Python"
e2d8d479
FEG
2288 "Major mode for editing Python files.
2289
2290\\{python-mode-map}
2291Entry to this mode calls the value of `python-mode-hook'
2292if that value is non-nil."
45c138ac
FEG
2293 (set (make-local-variable 'tab-width) 8)
2294 (set (make-local-variable 'indent-tabs-mode) nil)
2295
2296 (set (make-local-variable 'comment-start) "# ")
2297 (set (make-local-variable 'comment-start-skip) "#+\\s-*")
2298
2299 (set (make-local-variable 'parse-sexp-lookup-properties) t)
2300 (set (make-local-variable 'parse-sexp-ignore-comments) t)
2301
2302 (set (make-local-variable 'font-lock-defaults)
2303 '(python-font-lock-keywords
2304 nil nil nil nil
2305 (font-lock-syntactic-keywords . python-font-lock-syntactic-keywords)))
2306
2307 (set (make-local-variable 'indent-line-function) #'python-indent-line-function)
2308 (set (make-local-variable 'indent-region-function) #'python-indent-region)
2309
2310 (set (make-local-variable 'paragraph-start) "\\s-*$")
2311 (set (make-local-variable 'fill-paragraph-function) 'python-fill-paragraph-function)
2312
2313 (set (make-local-variable 'beginning-of-defun-function)
2314 #'python-beginning-of-defun-function)
2315 (set (make-local-variable 'end-of-defun-function)
2316 #'python-end-of-defun-function)
2317
2318 (add-hook 'completion-at-point-functions
2319 'python-completion-complete-at-point nil 'local)
2320
fc2dc7df
FEG
2321 (setq imenu-create-index-function #'python-imenu-create-index)
2322
45c138ac
FEG
2323 (set (make-local-variable 'add-log-current-defun-function)
2324 #'python-info-current-defun)
2325
e2803784
FEG
2326 (set (make-local-variable 'skeleton-further-elements)
2327 '((abbrev-mode nil)
2328 (< '(backward-delete-char-untabify (min python-indent-offset
2329 (current-column))))
2330 (^ '(- (1+ (current-indentation))))))
2331
45c138ac
FEG
2332 (set (make-local-variable 'eldoc-documentation-function)
2333 #'python-eldoc-function)
2334
2335 (add-to-list 'hs-special-modes-alist
2336 `(python-mode "^\\s-*\\(?:def\\|class\\)\\>" nil "#"
2337 ,(lambda (arg)
2338 (python-end-of-defun-function)) nil))
2339
2340 (set (make-local-variable 'outline-regexp)
2341 (python-rx (* space) block-start))
2342 (set (make-local-variable 'outline-heading-end-regexp) ":\\s-*\n")
2343 (set (make-local-variable 'outline-level)
2344 #'(lambda ()
2345 "`outline-level' function for Python mode."
2346 (1+ (/ (current-indentation) python-indent-offset))))
2347
e2803784
FEG
2348 (python-skeleton-add-menu-items)
2349
45c138ac
FEG
2350 (when python-indent-guess-indent-offset
2351 (python-indent-guess-indent-offset)))
2352
2353
2354(provide 'python)
2355;;; python.el ends here