aboutsummaryrefslogtreecommitdiffstats
path: root/lisp/progmodes/python.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/progmodes/python.el')
-rw-r--r--lisp/progmodes/python.el115
1 files changed, 72 insertions, 43 deletions
diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el
index 949b0252bf1..a2c8453a011 100644
--- a/lisp/progmodes/python.el
+++ b/lisp/progmodes/python.el
@@ -33,7 +33,7 @@
33;; Implements Syntax highlighting, Indentation, Movement, Shell 33;; Implements Syntax highlighting, Indentation, Movement, Shell
34;; interaction, Shell completion, Shell virtualenv support, Pdb 34;; interaction, Shell completion, Shell virtualenv support, Pdb
35;; tracking, Symbol completion, Skeletons, FFAP, Code Check, Eldoc, 35;; tracking, Symbol completion, Skeletons, FFAP, Code Check, Eldoc,
36;; imenu. 36;; Imenu.
37 37
38;; Syntax highlighting: Fontification of code is provided and supports 38;; Syntax highlighting: Fontification of code is provided and supports
39;; python's triple quoted strings properly. 39;; python's triple quoted strings properly.
@@ -169,10 +169,12 @@
169;; might guessed you should run `python-shell-send-buffer' from time 169;; might guessed you should run `python-shell-send-buffer' from time
170;; to time to get better results too. 170;; to time to get better results too.
171 171
172;; imenu: This mode supports imenu in its most basic form, letting it 172;; Imenu: This mode supports Imenu in its most basic form, letting it
173;; build the necessary alist via `imenu-default-create-index-function' 173;; build the necessary alist via `imenu-default-create-index-function'
174;; by having set `imenu-extract-index-name-function' to 174;; by having set `imenu-extract-index-name-function' to
175;; `python-info-current-defun'. 175;; `python-info-current-defun' and
176;; `imenu-prev-index-position-function' to
177;; `python-imenu-prev-index-position'.
176 178
177;; If you used python-mode.el you probably will miss auto-indentation 179;; If you used python-mode.el you probably will miss auto-indentation
178;; when inserting newlines. To achieve the same behavior you have 180;; when inserting newlines. To achieve the same behavior you have
@@ -202,13 +204,12 @@
202 204
203(require 'ansi-color) 205(require 'ansi-color)
204(require 'comint) 206(require 'comint)
207(eval-when-compile (require 'cl-lib))
205 208
206(eval-when-compile 209;; Avoid compiler warnings
207 (require 'cl) 210(defvar view-return-to-alist)
208 ;; Avoid compiler warnings 211(defvar compilation-error-regexp-alist)
209 (defvar view-return-to-alist) 212(defvar outline-heading-end-regexp)
210 (defvar compilation-error-regexp-alist)
211 (defvar outline-heading-end-regexp))
212 213
213(autoload 'comint-mode "comint") 214(autoload 'comint-mode "comint")
214 215
@@ -364,12 +365,24 @@ This variant of `rx' supports common python named REGEXPS."
364 "Return non-nil if point is on TYPE using SYNTAX-PPSS. 365 "Return non-nil if point is on TYPE using SYNTAX-PPSS.
365TYPE can be `comment', `string' or `paren'. It returns the start 366TYPE can be `comment', `string' or `paren'. It returns the start
366character address of the specified TYPE." 367character address of the specified TYPE."
368 (declare (compiler-macro
369 (lambda (form)
370 (pcase type
371 (`'comment
372 `(let ((ppss (or ,syntax-ppss (syntax-ppss))))
373 (and (nth 4 ppss) (nth 8 ppss))))
374 (`'string
375 `(let ((ppss (or ,syntax-ppss (syntax-ppss))))
376 (and (nth 3 ppss) (nth 8 ppss))))
377 (`'paren
378 `(nth 1 (or ,syntax-ppss (syntax-ppss))))
379 (_ form)))))
367 (let ((ppss (or syntax-ppss (syntax-ppss)))) 380 (let ((ppss (or syntax-ppss (syntax-ppss))))
368 (case type 381 (pcase type
369 (comment (and (nth 4 ppss) (nth 8 ppss))) 382 (`comment (and (nth 4 ppss) (nth 8 ppss)))
370 (string (and (not (nth 4 ppss)) (nth 8 ppss))) 383 (`string (and (nth 3 ppss) (nth 8 ppss)))
371 (paren (nth 1 ppss)) 384 (`paren (nth 1 ppss))
372 (t nil)))) 385 (_ nil))))
373 386
374(defun python-syntax-context-type (&optional syntax-ppss) 387(defun python-syntax-context-type (&optional syntax-ppss)
375 "Return the context type using SYNTAX-PPSS. 388 "Return the context type using SYNTAX-PPSS.
@@ -481,8 +494,8 @@ The type returned can be `comment', `string' or `paren'."
481 (when (re-search-forward re limit t) 494 (when (re-search-forward re limit t)
482 (while (and (python-syntax-context 'paren) 495 (while (and (python-syntax-context 'paren)
483 (re-search-forward re limit t))) 496 (re-search-forward re limit t)))
484 (if (and (not (python-syntax-context 'paren)) 497 (if (not (or (python-syntax-context 'paren)
485 (not (equal (char-after (point-marker)) ?=))) 498 (equal (char-after (point-marker)) ?=)))
486 t 499 t
487 (set-match-data nil))))) 500 (set-match-data nil)))))
488 (1 font-lock-variable-name-face nil nil)) 501 (1 font-lock-variable-name-face nil nil))
@@ -516,7 +529,7 @@ is used to limit the scan."
516 (while (and (< i 3) 529 (while (and (< i 3)
517 (or (not limit) (< (+ point i) limit)) 530 (or (not limit) (< (+ point i) limit))
518 (eq (char-after (+ point i)) quote-char)) 531 (eq (char-after (+ point i)) quote-char))
519 (incf i)) 532 (cl-incf i))
520 i)) 533 i))
521 534
522(defun python-syntax-stringify () 535(defun python-syntax-stringify ()
@@ -645,7 +658,7 @@ These make `python-indent-calculate-indentation' subtract the value of
645 (python-util-forward-comment) 658 (python-util-forward-comment)
646 (current-indentation)))) 659 (current-indentation))))
647 (if indentation 660 (if indentation
648 (setq python-indent-offset indentation) 661 (set (make-local-variable 'python-indent-offset) indentation)
649 (message "Can't guess python-indent-offset, using defaults: %s" 662 (message "Can't guess python-indent-offset, using defaults: %s"
650 python-indent-offset))))))) 663 python-indent-offset)))))))
651 664
@@ -723,17 +736,17 @@ START is the buffer position where the sexp starts."
723 (save-restriction 736 (save-restriction
724 (widen) 737 (widen)
725 (save-excursion 738 (save-excursion
726 (case context-status 739 (pcase context-status
727 ('no-indent 0) 740 (`no-indent 0)
728 ;; When point is after beginning of block just add one level 741 ;; When point is after beginning of block just add one level
729 ;; of indentation relative to the context-start 742 ;; of indentation relative to the context-start
730 ('after-beginning-of-block 743 (`after-beginning-of-block
731 (goto-char context-start) 744 (goto-char context-start)
732 (+ (current-indentation) python-indent-offset)) 745 (+ (current-indentation) python-indent-offset))
733 ;; When after a simple line just use previous line 746 ;; When after a simple line just use previous line
734 ;; indentation, in the case current line starts with a 747 ;; indentation, in the case current line starts with a
735 ;; `python-indent-dedenters' de-indent one level. 748 ;; `python-indent-dedenters' de-indent one level.
736 ('after-line 749 (`after-line
737 (- 750 (-
738 (save-excursion 751 (save-excursion
739 (goto-char context-start) 752 (goto-char context-start)
@@ -746,11 +759,11 @@ START is the buffer position where the sexp starts."
746 ;; When inside of a string, do nothing. just use the current 759 ;; When inside of a string, do nothing. just use the current
747 ;; indentation. XXX: perhaps it would be a good idea to 760 ;; indentation. XXX: perhaps it would be a good idea to
748 ;; invoke standard text indentation here 761 ;; invoke standard text indentation here
749 ('inside-string 762 (`inside-string
750 (goto-char context-start) 763 (goto-char context-start)
751 (current-indentation)) 764 (current-indentation))
752 ;; After backslash we have several possibilities. 765 ;; After backslash we have several possibilities.
753 ('after-backslash 766 (`after-backslash
754 (cond 767 (cond
755 ;; Check if current line is a dot continuation. For this 768 ;; Check if current line is a dot continuation. For this
756 ;; the current line must start with a dot and previous 769 ;; the current line must start with a dot and previous
@@ -816,7 +829,7 @@ START is the buffer position where the sexp starts."
816 (+ (current-indentation) python-indent-offset))))) 829 (+ (current-indentation) python-indent-offset)))))
817 ;; When inside a paren there's a need to handle nesting 830 ;; When inside a paren there's a need to handle nesting
818 ;; correctly 831 ;; correctly
819 ('inside-paren 832 (`inside-paren
820 (cond 833 (cond
821 ;; If current line closes the outermost open paren use the 834 ;; If current line closes the outermost open paren use the
822 ;; current indentation of the context-start line. 835 ;; current indentation of the context-start line.
@@ -1087,12 +1100,12 @@ With positive ARG search backwards, else search forwards."
1087 (beg-indentation 1100 (beg-indentation
1088 (and (> arg 0) 1101 (and (> arg 0)
1089 (save-excursion 1102 (save-excursion
1090 (and (python-info-current-line-empty-p) 1103 (while (and
1091 (python-util-forward-comment -1)) 1104 (not (python-info-looking-at-beginning-of-defun))
1092 (python-nav-beginning-of-statement) 1105 (python-nav-backward-block)))
1093 (if (python-info-looking-at-beginning-of-defun) 1106 (or (and (python-info-looking-at-beginning-of-defun)
1094 (+ (current-indentation) python-indent-offset) 1107 (+ (current-indentation) python-indent-offset))
1095 (current-indentation))))) 1108 0))))
1096 (found 1109 (found
1097 (progn 1110 (progn
1098 (when (and (< arg 0) 1111 (when (and (< arg 0)
@@ -2164,11 +2177,11 @@ INPUT."
2164 'default) 2177 'default)
2165 (t nil))) 2178 (t nil)))
2166 (completion-code 2179 (completion-code
2167 (case completion-context 2180 (pcase completion-context
2168 (pdb python-shell-completion-pdb-string-code) 2181 (`pdb python-shell-completion-pdb-string-code)
2169 (import python-shell-completion-module-string-code) 2182 (`import python-shell-completion-module-string-code)
2170 (default python-shell-completion-string-code) 2183 (`default python-shell-completion-string-code)
2171 (t nil))) 2184 (_ nil)))
2172 (input 2185 (input
2173 (if (eq completion-context 'import) 2186 (if (eq completion-context 'import)
2174 (replace-regexp-in-string "^[ \t]+" "" line) 2187 (replace-regexp-in-string "^[ \t]+" "" line)
@@ -2492,17 +2505,17 @@ JUSTIFY should be used (if applicable) as in `fill-paragraph'."
2492 ;; Docstring styles may vary for oneliners and multi-liners. 2505 ;; Docstring styles may vary for oneliners and multi-liners.
2493 (> (count-matches "\n" str-start-pos str-end-pos) 0)) 2506 (> (count-matches "\n" str-start-pos str-end-pos) 0))
2494 (delimiters-style 2507 (delimiters-style
2495 (case python-fill-docstring-style 2508 (pcase python-fill-docstring-style
2496 ;; delimiters-style is a cons cell with the form 2509 ;; delimiters-style is a cons cell with the form
2497 ;; (START-NEWLINES . END-NEWLINES). When any of the sexps 2510 ;; (START-NEWLINES . END-NEWLINES). When any of the sexps
2498 ;; is NIL means to not add any newlines for start or end 2511 ;; is NIL means to not add any newlines for start or end
2499 ;; of docstring. See `python-fill-docstring-style' for a 2512 ;; of docstring. See `python-fill-docstring-style' for a
2500 ;; graphic idea of each style. 2513 ;; graphic idea of each style.
2501 (django (cons 1 1)) 2514 (`django (cons 1 1))
2502 (onetwo (and multi-line-p (cons 1 2))) 2515 (`onetwo (and multi-line-p (cons 1 2)))
2503 (pep-257 (and multi-line-p (cons nil 2))) 2516 (`pep-257 (and multi-line-p (cons nil 2)))
2504 (pep-257-nn (and multi-line-p (cons nil 1))) 2517 (`pep-257-nn (and multi-line-p (cons nil 1)))
2505 (symmetric (and multi-line-p (cons 1 1))))) 2518 (`symmetric (and multi-line-p (cons 1 1)))))
2506 (docstring-p (save-excursion 2519 (docstring-p (save-excursion
2507 ;; Consider docstrings those strings which 2520 ;; Consider docstrings those strings which
2508 ;; start on a line by themselves. 2521 ;; start on a line by themselves.
@@ -2703,7 +2716,7 @@ The skeleton will be bound to python-skeleton-NAME."
2703 (easy-menu-add-item 2716 (easy-menu-add-item
2704 nil '("Python" "Skeletons") 2717 nil '("Python" "Skeletons")
2705 `[,(format 2718 `[,(format
2706 "Insert %s" (caddr (split-string (symbol-name skeleton) "-"))) 2719 "Insert %s" (nth 2 (split-string (symbol-name skeleton) "-")))
2707 ,skeleton t])))) 2720 ,skeleton t]))))
2708 2721
2709;;; FFAP 2722;;; FFAP
@@ -2870,6 +2883,19 @@ Interactively, prompt for symbol."
2870 "^Eldoc needs an inferior Python process running.") 2883 "^Eldoc needs an inferior Python process running.")
2871 2884
2872 2885
2886;;; Imenu
2887
2888(defun python-imenu-prev-index-position ()
2889 "Python mode's `imenu-prev-index-position-function'."
2890 (let ((found))
2891 (while (and (setq found
2892 (re-search-backward python-nav-beginning-of-defun-regexp nil t))
2893 (not (python-info-looking-at-beginning-of-defun))))
2894 (and found
2895 (python-info-looking-at-beginning-of-defun)
2896 (python-info-current-defun))))
2897
2898
2873;;; Misc helpers 2899;;; Misc helpers
2874 2900
2875(defun python-info-current-defun (&optional include-type) 2901(defun python-info-current-defun (&optional include-type)
@@ -3214,6 +3240,9 @@ if that value is non-nil."
3214 (set (make-local-variable 'imenu-extract-index-name-function) 3240 (set (make-local-variable 'imenu-extract-index-name-function)
3215 #'python-info-current-defun) 3241 #'python-info-current-defun)
3216 3242
3243 (set (make-local-variable 'imenu-prev-index-position-function)
3244 #'python-imenu-prev-index-position)
3245
3217 (set (make-local-variable 'add-log-current-defun-function) 3246 (set (make-local-variable 'add-log-current-defun-function)
3218 #'python-info-current-defun) 3247 #'python-info-current-defun)
3219 3248