comparison lisp/progmodes/python.el @ 78755:38a441bc4532

Merge changes from Dave Love's v2007-Sep-10. (python-font-lock-keywords): Update to the 2.5 version of the language. (python-quote-syntax): Let-bind font-lock-syntactic-keywords to nil. (python-backspace): Only behave funny in code. (python-compilation-regexp-alist): Add PDB stack trace regexp. (inferior-python-mode): Add PDB prompt regexp. (python-fill-paragraph): Refine the fenced-string regexp. (python-find-imports): Handle imports spanning several lines. (python-mode): Add `class' to hideshow support.
author Stefan Monnier <monnier@iro.umontreal.ca>
date Mon, 10 Sep 2007 20:02:31 +0000
parents 419c5c316b51
children 9aa24f503773
comparison
equal deleted inserted replaced
78754:a09b799218f8 78755:38a441bc4532
1 ;;; python.el --- silly walks for Python 1 ;;; python.el --- silly walks for Python -*- coding: iso-8859-1 -*-
2 2
3 ;; Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. 3 ;; Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
4 4
5 ;; Author: Dave Love <fx@gnu.org> 5 ;; Author: Dave Love <fx@gnu.org>
6 ;; Maintainer: FSF 6 ;; Maintainer: FSF
87 87
88 ;;;; Font lock 88 ;;;; Font lock
89 89
90 (defvar python-font-lock-keywords 90 (defvar python-font-lock-keywords
91 `(,(rx symbol-start 91 `(,(rx symbol-start
92 ;; From v 2.4 reference. 92 ;; From v 2.5 reference, § keywords.
93 ;; def and class dealt with separately below 93 ;; def and class dealt with separately below
94 (or "and" "assert" "break" "continue" "del" "elif" "else" 94 (or "and" "as" "assert" "break" "continue" "del" "elif" "else"
95 "except" "exec" "finally" "for" "from" "global" "if" 95 "except" "exec" "finally" "for" "from" "global" "if"
96 "import" "in" "is" "lambda" "not" "or" "pass" "print" 96 "import" "in" "is" "lambda" "not" "or" "pass" "print"
97 "raise" "return" "try" "while" "yield" 97 "raise" "return" "try" "while" "with" "yield"
98 ;; Future keywords
99 "as" "None" "with"
100 ;; Not real keywords, but close enough to be fontified as such 98 ;; Not real keywords, but close enough to be fontified as such
101 "self" "True" "False") 99 "self" "True" "False")
102 symbol-end) 100 symbol-end)
101 (,(rx symbol-start "None" symbol-end) ; See § Keywords in 2.5 manual.
102 . font-lock-constant-face)
103 ;; Definitions 103 ;; Definitions
104 (,(rx symbol-start (group "class") (1+ space) (group (1+ (or word ?_)))) 104 (,(rx symbol-start (group "class") (1+ space) (group (1+ (or word ?_))))
105 (1 font-lock-keyword-face) (2 font-lock-type-face)) 105 (1 font-lock-keyword-face) (2 font-lock-type-face))
106 (,(rx symbol-start (group "def") (1+ space) (group (1+ (or word ?_)))) 106 (,(rx symbol-start (group "def") (1+ space) (group (1+ (or word ?_))))
107 (1 font-lock-keyword-face) (2 font-lock-function-name-face)) 107 (1 font-lock-keyword-face) (2 font-lock-function-name-face))
149 (save-excursion 149 (save-excursion
150 (goto-char (match-beginning 0)) 150 (goto-char (match-beginning 0))
151 (cond 151 (cond
152 ;; Consider property for the last char if in a fenced string. 152 ;; Consider property for the last char if in a fenced string.
153 ((= n 3) 153 ((= n 3)
154 (let ((syntax (syntax-ppss))) 154 (let* ((font-lock-syntactic-keywords nil)
155 (syntax (syntax-ppss)))
155 (when (eq t (nth 3 syntax)) ; after unclosed fence 156 (when (eq t (nth 3 syntax)) ; after unclosed fence
156 (goto-char (nth 8 syntax)) ; fence position 157 (goto-char (nth 8 syntax)) ; fence position
157 (skip-chars-forward "uUrR") ; skip any prefix 158 (skip-chars-forward "uUrR") ; skip any prefix
158 ;; Is it a matching sequence? 159 ;; Is it a matching sequence?
159 (if (eq (char-after) (char-after (match-beginning 2))) 160 (if (eq (char-after) (char-after (match-beginning 2)))
161 ;; Consider property for initial char, accounting for prefixes. 162 ;; Consider property for initial char, accounting for prefixes.
162 ((or (and (= n 2) ; leading quote (not prefix) 163 ((or (and (= n 2) ; leading quote (not prefix)
163 (= (match-beginning 1) (match-end 1))) ; prefix is null 164 (= (match-beginning 1) (match-end 1))) ; prefix is null
164 (and (= n 1) ; prefix 165 (and (= n 1) ; prefix
165 (/= (match-beginning 1) (match-end 1)))) ; non-empty 166 (/= (match-beginning 1) (match-end 1)))) ; non-empty
166 (unless (nth 3 (syntax-ppss)) 167 (let ((font-lock-syntactic-keywords nil))
167 (eval-when-compile (string-to-syntax "|")))) 168 (unless (nth 3 (syntax-ppss))
169 (eval-when-compile (string-to-syntax "|")))))
168 ;; Otherwise (we're in a non-matching string) the property is 170 ;; Otherwise (we're in a non-matching string) the property is
169 ;; nil, which is OK. 171 ;; nil, which is OK.
170 ))) 172 )))
171 173
172 ;; This isn't currently in `font-lock-defaults' as probably not worth 174 ;; This isn't currently in `font-lock-defaults' as probably not worth
346 (condition-case () 348 (condition-case ()
347 (progn (backward-up-list) t) ; actually within brackets 349 (progn (backward-up-list) t) ; actually within brackets
348 (error nil)))))))) 350 (error nil))))))))
349 351
350 (defun python-comment-line-p () 352 (defun python-comment-line-p ()
351 "Return non-nil if current line has only a comment." 353 "Return non-nil iff current line has only a comment."
352 (save-excursion 354 (save-excursion
353 (end-of-line) 355 (end-of-line)
354 (when (eq 'comment (syntax-ppss-context (syntax-ppss))) 356 (when (eq 'comment (syntax-ppss-context (syntax-ppss)))
355 (back-to-indentation) 357 (back-to-indentation)
356 (looking-at (rx (or (syntax comment-start) line-end)))))) 358 (looking-at (rx (or (syntax comment-start) line-end))))))
357 359
358 (defun python-blank-line-p () 360 (defun python-blank-line-p ()
359 "Return non-nil if current line is blank." 361 "Return non-nil iff current line is blank."
360 (save-excursion 362 (save-excursion
361 (beginning-of-line) 363 (beginning-of-line)
362 (looking-at "\\s-*$"))) 364 (looking-at "\\s-*$")))
363 365
364 (defun python-beginning-of-string () 366 (defun python-beginning-of-string ()
848 850
849 (defun python-skip-out (&optional forward syntax) 851 (defun python-skip-out (&optional forward syntax)
850 "Skip out of any nested brackets. 852 "Skip out of any nested brackets.
851 Skip forward if FORWARD is non-nil, else backward. 853 Skip forward if FORWARD is non-nil, else backward.
852 If SYNTAX is non-nil it is the state returned by `syntax-ppss' at point. 854 If SYNTAX is non-nil it is the state returned by `syntax-ppss' at point.
853 Return non-nil if skipping was done." 855 Return non-nil iff skipping was done."
854 (let ((depth (syntax-ppss-depth (or syntax (syntax-ppss)))) 856 (let ((depth (syntax-ppss-depth (or syntax (syntax-ppss))))
855 (forward (if forward -1 1))) 857 (forward (if forward -1 1)))
856 (unless (zerop depth) 858 (unless (zerop depth)
857 (if (> depth 0) 859 (if (> depth 0)
858 ;; Skip forward out of nested brackets. 860 ;; Skip forward out of nested brackets.
1073 (python-indent-line))) ; OK, do it 1075 (python-indent-line))) ; OK, do it
1074 (put 'python-electric-colon 'delete-selection t) 1076 (put 'python-electric-colon 'delete-selection t)
1075 1077
1076 (defun python-backspace (arg) 1078 (defun python-backspace (arg)
1077 "Maybe delete a level of indentation on the current line. 1079 "Maybe delete a level of indentation on the current line.
1078 Do so if point is at the end of the line's indentation. 1080 Do so if point is at the end of the line's indentation outside
1081 strings and comments.
1079 Otherwise just call `backward-delete-char-untabify'. 1082 Otherwise just call `backward-delete-char-untabify'.
1080 Repeat ARG times." 1083 Repeat ARG times."
1081 (interactive "*p") 1084 (interactive "*p")
1082 (if (or (/= (current-indentation) (current-column)) 1085 (if (or (/= (current-indentation) (current-column))
1083 (bolp) 1086 (bolp)
1084 (python-continuation-line-p)) 1087 (python-continuation-line-p)
1088 (python-in-string/comment))
1085 (backward-delete-char-untabify arg) 1089 (backward-delete-char-untabify arg)
1086 ;; Look for the largest valid indentation which is smaller than 1090 ;; Look for the largest valid indentation which is smaller than
1087 ;; the current indentation. 1091 ;; the current indentation.
1088 (let ((indent 0) 1092 (let ((indent 0)
1089 (ci (current-indentation)) 1093 (ci (current-indentation))
1180 (group (1+ (not (any "\"<")))) ; avoid `<stdin>' &c 1184 (group (1+ (not (any "\"<")))) ; avoid `<stdin>' &c
1181 "\", line " (group (1+ digit))) 1185 "\", line " (group (1+ digit)))
1182 1 2) 1186 1 2)
1183 (,(rx " in file " (group (1+ not-newline)) " on line " 1187 (,(rx " in file " (group (1+ not-newline)) " on line "
1184 (group (1+ digit))) 1188 (group (1+ digit)))
1189 1 2)
1190 ;; pdb stack trace
1191 (,(rx line-start "> " (group (1+ (not (any "(\"<"))))
1192 "(" (group (1+ digit)) ")" (1+ (not (any "("))) "()")
1185 1 2)) 1193 1 2))
1186 "`compilation-error-regexp-alist' for inferior Python.") 1194 "`compilation-error-regexp-alist' for inferior Python.")
1187 1195
1188 (defvar inferior-python-mode-map 1196 (defvar inferior-python-mode-map
1189 (let ((map (make-sparse-keymap))) 1197 (let ((map (make-sparse-keymap)))
1190 ;; This will inherit from comint-mode-map. 1198 ;; This will inherit from comint-mode-map.
1191 (define-key map "\C-c\C-l" 'python-load-file) 1199 (define-key map "\C-c\C-l" 'python-load-file)
1192 (define-key map "\C-c\C-v" 'python-check) 1200 (define-key map "\C-c\C-v" 'python-check)
1193 ;; Note that we _can_ still use these commands which send to the 1201 ;; Note that we _can_ still use these commands which send to the
1194 ;; Python process even at the prompt provided we have a normal prompt, 1202 ;; Python process even at the prompt iff we have a normal prompt,
1195 ;; i.e. '>>> ' and not '... '. See the comment before 1203 ;; i.e. '>>> ' and not '... '. See the comment before
1196 ;; python-send-region. Fixme: uncomment these if we address that. 1204 ;; python-send-region. Fixme: uncomment these if we address that.
1197 1205
1198 ;; (define-key map [(meta ?\t)] 'python-complete-symbol) 1206 ;; (define-key map [(meta ?\t)] 'python-complete-symbol)
1199 ;; (define-key map "\C-c\C-f" 'python-describe-symbol) 1207 ;; (define-key map "\C-c\C-f" 'python-describe-symbol)
1235 (add-hook 'comint-preoutput-filter-functions #'python-preoutput-filter 1243 (add-hook 'comint-preoutput-filter-functions #'python-preoutput-filter
1236 nil t) 1244 nil t)
1237 ;; Still required by `comint-redirect-send-command', for instance 1245 ;; Still required by `comint-redirect-send-command', for instance
1238 ;; (and we need to match things like `>>> ... >>> '): 1246 ;; (and we need to match things like `>>> ... >>> '):
1239 (set (make-local-variable 'comint-prompt-regexp) 1247 (set (make-local-variable 'comint-prompt-regexp)
1240 (rx line-start (1+ (and (repeat 3 (any ">.")) " ")))) 1248 (rx line-start (1+ (and (or (repeat 3 (any ">.")) "(Pdb)") " "))))
1241 (set (make-local-variable 'compilation-error-regexp-alist) 1249 (set (make-local-variable 'compilation-error-regexp-alist)
1242 python-compilation-regexp-alist) 1250 python-compilation-regexp-alist)
1243 (compilation-shell-minor-mode 1)) 1251 (compilation-shell-minor-mode 1))
1244 1252
1245 (defcustom inferior-python-filter-regexp "\\`\\s-*\\S-?\\S-?\\s-*\\'" 1253 (defcustom inferior-python-filter-regexp "\\`\\s-*\\S-?\\S-?\\s-*\\'"
1727 (if (member (match-string 1) python-jython-packages) 1735 (if (member (match-string 1) python-jython-packages)
1728 (throw 'done t)))) 1736 (throw 'done t))))
1729 (jython-mode))))))) 1737 (jython-mode)))))))
1730 1738
1731 (defun python-fill-paragraph (&optional justify) 1739 (defun python-fill-paragraph (&optional justify)
1732 "`fill-paragraph-function' handling comments and multi-line strings. 1740 "`fill-paragraph-function' handling multi-line strings and possibly comments.
1733 If any of the current line is a comment, fill the comment or the 1741 If any of the current line is in or at the end of a multi-line string,
1734 paragraph of it that point is in, preserving the comment's 1742 fill the string or the paragraph of it that point is in, preserving
1735 indentation and initial comment characters. Similarly if the end 1743 the strings's indentation."
1736 of the current line is in or at the end of a multi-line string.
1737 Otherwise, do nothing."
1738 (interactive "P") 1744 (interactive "P")
1739 (or (fill-comment-paragraph justify) 1745 (or (fill-comment-paragraph justify)
1740 ;; The `paragraph-start' and `paragraph-separate' variables
1741 ;; don't allow us to delimit the last paragraph in a multi-line
1742 ;; string properly, so narrow to the string and then fill around
1743 ;; (the end of) the current line.
1744 (save-excursion 1746 (save-excursion
1745 (end-of-line) 1747 (end-of-line)
1746 (let* ((syntax (syntax-ppss)) 1748 (let* ((syntax (syntax-ppss))
1747 (orig (point)) 1749 (orig (point))
1748 (start (nth 8 syntax)) 1750 start end)
1749 end) 1751 (cond ((nth 4 syntax) ; comment. fixme: loses with trailing one
1750 (cond ((eq t (nth 3 syntax)) ; in fenced string 1752 (let (fill-paragraph-function)
1751 (goto-char (nth 8 syntax)) ; string start 1753 (fill-paragraph justify)))
1754 ;; The `paragraph-start' and `paragraph-separate'
1755 ;; variables don't allow us to delimit the last
1756 ;; paragraph in a multi-line string properly, so narrow
1757 ;; to the string and then fill around (the end of) the
1758 ;; current line.
1759 ((eq t (nth 3 syntax)) ; in fenced string
1760 (goto-char (nth 8 syntax)) ; string start
1761 (setq start (line-beginning-position))
1752 (setq end (condition-case () ; for unbalanced quotes 1762 (setq end (condition-case () ; for unbalanced quotes
1753 (progn (forward-sexp) (point)) 1763 (progn (forward-sexp)
1764 (- (point) 3))
1754 (error (point-max))))) 1765 (error (point-max)))))
1755 ((re-search-backward "\\s|\\s-*\\=" nil t) ; end of fenced 1766 ((re-search-backward "\\s|\\s-*\\=" nil t) ; end of fenced string
1756 ; string
1757 (forward-char) 1767 (forward-char)
1758 (setq end (point)) 1768 (setq end (point))
1759 (condition-case () 1769 (condition-case ()
1760 (progn (backward-sexp) 1770 (progn (backward-sexp)
1761 (setq start (point))) 1771 (setq start (line-beginning-position)))
1762 (error (setq end nil))))) 1772 (error nil))))
1763 (when end 1773 (when end
1764 (save-restriction 1774 (save-restriction
1765 (narrow-to-region start end) 1775 (narrow-to-region start end)
1766 (goto-char orig) 1776 (goto-char orig)
1767 (let ((paragraph-separate 1777 ;; Avoid losing leading and trailing newlines in doc
1768 ;; Make sure that fenced-string delimiters that stand 1778 ;; strings written like:
1769 ;; on their own line stay there. 1779 ;; """
1770 (concat "[ \t]*['\"]+[ \t]*$\\|" paragraph-separate))) 1780 ;; ...
1771 (fill-paragraph justify)))))) 1781 ;; """
1772 t)) 1782 (let* ((paragraph-separate
1783 (concat ".*\\s|\"\"$" ; newline after opening quotes
1784 "\\|\\(?:" paragraph-separate "\\)"))
1785 (paragraph-start
1786 (concat ".*\\s|\"\"[ \t]*[^ \t].*" ; not newline after
1787 ; opening quotes
1788 "\\|\\(?:" paragraph-separate "\\)"))
1789 (fill-paragraph-function))
1790 (fill-paragraph justify))))))) t)
1773 1791
1774 (defun python-shift-left (start end &optional count) 1792 (defun python-shift-left (start end &optional count)
1775 "Shift lines in region COUNT (the prefix arg) columns to the left. 1793 "Shift lines in region COUNT (the prefix arg) columns to the left.
1776 COUNT defaults to `python-indent'. If region isn't active, just shift 1794 COUNT defaults to `python-indent'. If region isn't active, just shift
1777 current line. The region shifted includes the lines in which START and 1795 current line. The region shifted includes the lines in which START and
1864 (save-excursion 1882 (save-excursion
1865 (let (lines) 1883 (let (lines)
1866 (goto-char (point-min)) 1884 (goto-char (point-min))
1867 (while (re-search-forward "^import\\>\\|^from\\>" nil t) 1885 (while (re-search-forward "^import\\>\\|^from\\>" nil t)
1868 (unless (syntax-ppss-context (syntax-ppss)) 1886 (unless (syntax-ppss-context (syntax-ppss))
1869 (push (buffer-substring (line-beginning-position) 1887 (let ((start (line-beginning-position)))
1870 (line-beginning-position 2)) 1888 ;; Skip over continued lines.
1871 lines))) 1889 (while (and (eq ?\\ (char-before (line-end-position)))
1890 (= 0 (forward-line 1))))
1891 (push (buffer-substring start (line-beginning-position 2))
1892 lines))))
1872 (setq python-imports 1893 (setq python-imports
1873 (if lines 1894 (if lines
1874 (apply #'concat 1895 (apply #'concat
1875 ;; This is probably best left out since you're unlikely to need the 1896 ;; This is probably best left out since you're unlikely to need the
1876 ;; doc for a function in the buffer and the import will lose if the 1897 ;; doc for a function in the buffer and the import will lose if the
2257 nil t) 2278 nil t)
2258 ;; Fixme: should be in hideshow. This seems to be of limited use 2279 ;; Fixme: should be in hideshow. This seems to be of limited use
2259 ;; since it isn't (can't be) indentation-based. Also hide-level 2280 ;; since it isn't (can't be) indentation-based. Also hide-level
2260 ;; doesn't seem to work properly. 2281 ;; doesn't seem to work properly.
2261 (add-to-list 'hs-special-modes-alist 2282 (add-to-list 'hs-special-modes-alist
2262 `(python-mode "^\\s-*def\\>" nil "#" 2283 `(python-mode "^\\s-*\\(?:def\\|class\\)\\>" nil "#"
2263 ,(lambda (arg) 2284 ,(lambda (arg)
2264 (python-end-of-defun) 2285 (python-end-of-defun)
2265 (skip-chars-backward " \t\n")) 2286 (skip-chars-backward " \t\n"))
2266 nil)) 2287 nil))
2267 (set (make-local-variable 'skeleton-further-elements) 2288 (set (make-local-variable 'skeleton-further-elements)